[Assorted-commits] SF.net SVN: assorted:[1573] scala-commons/trunk
Brought to you by:
yangzhang
From: <yan...@us...> - 2010-03-03 00:12:40
|
Revision: 1573 http://assorted.svn.sourceforge.net/assorted/?rev=1573&view=rev Author: yangzhang Date: 2010-03-03 00:12:34 +0000 (Wed, 03 Mar 2010) Log Message: ----------- imported code from RelationalCloud project; more fixes to build on scala 2.8 Modified Paths: -------------- scala-commons/trunk/README scala-commons/trunk/src/commons/Collections.scala scala-commons/trunk/src/commons/Control.scala scala-commons/trunk/src/commons/Io.scala scala-commons/trunk/src/commons/Misc.scala Added Paths: ----------- scala-commons/trunk/src/commons/Jdbc.scala scala-commons/trunk/src/commons/RichIterator.scala scala-commons/trunk/src/commons/TableFormatter.scala scala-commons/trunk/src/commons/Timer.scala Modified: scala-commons/trunk/README =================================================================== --- scala-commons/trunk/README 2010-03-02 22:53:31 UTC (rev 1572) +++ scala-commons/trunk/README 2010-03-03 00:12:34 UTC (rev 1573) @@ -44,6 +44,14 @@ version 0.3 - updated for Scala 2.8 +- imported code from RelationalCloud project + - Closeable views + - Jdbc + - RichIterator + - TableFormatter + - Timer + - `in` operator + - removeCBlockComments - removed unnecessary functions - `Collections.sortCounts` deprecated by `SeqLike.sortBy` - `Collections.take` deprecated by `List.take Modified: scala-commons/trunk/src/commons/Collections.scala =================================================================== --- scala-commons/trunk/src/commons/Collections.scala 2010-03-02 22:53:31 UTC (rev 1572) +++ scala-commons/trunk/src/commons/Collections.scala 2010-03-03 00:12:34 UTC (rev 1573) @@ -12,6 +12,19 @@ object Collections { // + // Convenience + // + + /** + * Let yourself write `x in xs`. + **/ + class InOperand[A](x: A) { + def in(xs: Seq[A]) = xs contains x + def notIn(xs: Seq[A]) = !(xs contains x) + } + implicit def toInOperand[A](x: A) = new InOperand(x) + + // // Tuples // @@ -141,10 +154,7 @@ // TODO: The next line induces a bug in Scala. // val (x,y): (Seq[a],Seq[a]) = spanBy(s)(f(_) == cur) val (x,y) = spanBy(s)(f(_) == cur) - Stream.cons( - Stream fromIterator x.iterator, - r(Stream fromIterator y.iterator) - ) + Stream.cons(x.toStream, r(y.toStream)) } case Stream.Empty => Stream.Empty } @@ -518,7 +528,7 @@ */ def indexGroups[a,b](xs: Seq[a])(f: a => b) = { val i = Iterator from 0 - xs.toStream.iterator chunkBy f map (_ map (x => i.next)) + xs.iterator.toStream chunkBy f map (_ map (x => i.next)) } /** @@ -658,7 +668,7 @@ */ def show(showLeaf: a => String): String = { def r(t: Tree[a]): Stream[String] = t match { - case Branch(ts) => (ts map r flatten) map (" " + _) + case Branch(ts) => (ts.toStream map r flatten) map (" " + _) case Leaf(x) => List(showLeaf(x)) toStream } r(this) mkString "\n" @@ -675,7 +685,7 @@ * Flatten the leaves into a single stream. */ def flatten: Stream[a] = this match { - case Branch(ts) => (ts map (_.flatten) flatten) + case Branch(ts) => (ts.toStream map (_.flatten) flatten) case Leaf(x) => Stream cons (x, Stream empty) } } @@ -699,7 +709,7 @@ def r(n: TreeNode[a], lvl: Int): Stream[String] = { Stream cons ( " " * lvl + n.value, - (n.children map (n => r(n, lvl+1)) flatten) + (n.children.toStream map (n => r(n, lvl+1)) flatten) ) } r(this,0) mkString "\n" @@ -724,8 +734,8 @@ case Leaf(x) => Leaf(f(x)) } def flatten[b](f: a => b): Stream[b] = this match { - case And(ts) => (ts map (_ flatten f) flatten) - case Or(ts) => (ts map (_ flatten f) flatten) + case And(ts) => (ts.toStream map (_ flatten f) flatten) + case Or(ts) => (ts.toStream map (_ flatten f) flatten) case Not(t) => t flatten f case Leaf(x) => Stream cons (f(x), Stream empty) } Modified: scala-commons/trunk/src/commons/Control.scala =================================================================== --- scala-commons/trunk/src/commons/Control.scala 2010-03-02 22:53:31 UTC (rev 1572) +++ scala-commons/trunk/src/commons/Control.scala 2010-03-03 00:12:34 UTC (rev 1573) @@ -43,7 +43,7 @@ /** * Invoke f(i) for all i from 0 on. */ - def loop[a](f: Int => a) = for (val x <- Stream from 0) f(x) + def loop[a](f: Int => a) = for (x <- Stream from 0) f(x) /** * Stream the repetition of f. Modified: scala-commons/trunk/src/commons/Io.scala =================================================================== --- scala-commons/trunk/src/commons/Io.scala 2010-03-02 22:53:31 UTC (rev 1572) +++ scala-commons/trunk/src/commons/Io.scala 2010-03-03 00:12:34 UTC (rev 1573) @@ -22,6 +22,13 @@ implicit def Reader2TextReader(r: Reader) = TextReader(r) implicit def TextReader2Reader(tr: TextReader) = tr.in + implicit def writer2closeable(w: java.io.Writer) = + new Closeable { def close = w.close } + implicit def raf2closeable(f: java.io.RandomAccessFile) = + new Closeable { def close = f.close } + implicit def istream2closeable(i: java.io.InputStream) = + new Closeable { def close = i.close } + // // Files // Added: scala-commons/trunk/src/commons/Jdbc.scala =================================================================== --- scala-commons/trunk/src/commons/Jdbc.scala (rev 0) +++ scala-commons/trunk/src/commons/Jdbc.scala 2010-03-03 00:12:34 UTC (rev 1573) @@ -0,0 +1,120 @@ +// Based on <http://scala.sygneca.com/code/simplifying-jdbc>. + +package commons + +import java.sql.{DriverManager, Connection, ResultSet, PreparedStatement, Statement, Date, Timestamp}; + +object Jdbc { + private def strm[X](f: RichResultSet => X, rs: ResultSet): Stream[X] = + if (rs.next) Stream.cons(f(new RichResultSet(rs)), strm(f, rs)) + else { rs.close(); Stream.empty }; + + implicit def conn2Statement(conn: Connection): Statement = conn.createStatement; + + implicit def query[X](s: String, f: RichResultSet => X)(implicit stat: Statement) = { + strm(f,stat.executeQuery(s)); + } + + private def iter[X](f: RichResultSet => X, rs: ResultSet) = new Iterator[X] { + var lastNext = rs.next + def hasNext = lastNext + def next = { + if (!lastNext) throw new Exception + val ret = f(new RichResultSet(rs)) + lastNext = rs.next + ret + } + } + + implicit def iquery[X](s: String, f: RichResultSet => X)(implicit stmt: Statement) = { + iter(f,stmt.executeQuery(s)) + } + + implicit def rrs2Boolean(rs: RichResultSet) = rs.nextBoolean; + implicit def rrs2Byte(rs: RichResultSet) = rs.nextByte; + implicit def rrs2Int(rs: RichResultSet) = rs.nextInt; + implicit def rrs2Long(rs: RichResultSet) = rs.nextLong; + implicit def rrs2Float(rs: RichResultSet) = rs.nextFloat; + implicit def rrs2Double(rs: RichResultSet) = rs.nextDouble; + implicit def rrs2String(rs: RichResultSet) = rs.nextString; + implicit def rrs2Date(rs: RichResultSet) = rs.nextDate; + implicit def rrs2Timestamp(rs: RichResultSet) = rs.nextTimestamp; + + implicit def resultSet2Rich(rs: ResultSet) = new RichResultSet(rs); + implicit def rich2ResultSet(r: RichResultSet) = r.rs; + class RichResultSet(val rs: ResultSet) { + + var pos = 1 + def apply(i: Int) = { pos = i; this } + + def nextBoolean: Boolean = { val ret = rs.getBoolean(pos); pos = pos + 1; ret } + def nextByte: Byte = { val ret = rs.getByte(pos); pos = pos + 1; ret } + def nextInt: Int = { val ret = rs.getInt(pos); pos = pos + 1; ret } + def nextLong: Long = { val ret = rs.getLong(pos); pos = pos + 1; ret } + def nextFloat: Float = { val ret = rs.getFloat(pos); pos = pos + 1; ret } + def nextDouble: Double = { val ret = rs.getDouble(pos); pos = pos + 1; ret } + def nextString: String = { val ret = rs.getString(pos); pos = pos + 1; ret } + def nextDate: Date = { val ret = rs.getDate(pos); pos = pos + 1; ret } + def nextTimestamp: Timestamp = { val ret = rs.getTimestamp(pos); pos = pos + 1; ret } + + def foldLeft[X](init: X)(f: (ResultSet, X) => X): X = rs.next match { + case false => init + case true => foldLeft(f(rs, init))(f) + } + def map[X](f: ResultSet => X) = { + var ret = List[X]() + while (rs.next()) + ret = f(rs) :: ret + ret.reverse; // ret should be in the same order as the ResultSet + } + } + + implicit def ps2Rich(ps: PreparedStatement) = new RichPreparedStatement(ps); + implicit def rich2PS(r: RichPreparedStatement) = r.ps; + + implicit def str2RichPrepared(s: String)(implicit conn: Connection): RichPreparedStatement = conn prepareStatement(s); + + class RichPreparedStatement(val ps: PreparedStatement) { + var pos = 1; + private def inc = { pos = pos + 1; this } + + def execute[X](f: RichResultSet => X): Stream[X] = { + pos = 1; strm(f, ps.executeQuery) + } + def <<: Stream[X] = execute(f); + + def execute = { pos = 1; ps.execute } + def <<! = execute; + + def addBatch = { pos = 1; ps.addBatch } + def executeBatch = { pos = 1; ps.executeBatch } + + def <<(b: Boolean) = { ps.setBoolean(pos, b); inc } + def <<(x: Byte) = { ps.setByte(pos, x); inc } + def <<(i: Int) = { ps.setInt(pos, i); inc } + def <<(x: Long) = { ps.setLong(pos, x); inc } + def <<(f: Float) = { ps.setFloat(pos, f); inc } + def <<(d: Double) = { ps.setDouble(pos, d); inc } + def <<(o: String) = { ps.setString(pos, o); inc } + def <<(x: Date) = { ps.setDate(pos, x); inc } + def <<(x: Timestamp) = { ps.setTimestamp(pos, x); inc } + } + + implicit def conn2Rich(conn: Connection) = new RichConnection(conn); + + class RichConnection(val conn: Connection) { + def <<(sql: String) = new RichStatement(conn.createStatement) << sql; + def <<(sql: Seq[String]) = new RichStatement(conn.createStatement) << sql; + } + + implicit def st2Rich(s: Statement) = new RichStatement(s); + implicit def rich2St(rs: RichStatement) = rs.s; + + class RichStatement(val s: Statement) { + def <<(sql: String) = { s.execute(sql); this } + def <<(sql: Seq[String]) = { for (x <- sql) s.execute(x); this } + } + + def queryOne(s: String)(implicit stat: Statement) = + query(s, rs => rs:Int).head +} Modified: scala-commons/trunk/src/commons/Misc.scala =================================================================== --- scala-commons/trunk/src/commons/Misc.scala 2010-03-02 22:53:31 UTC (rev 1572) +++ scala-commons/trunk/src/commons/Misc.scala 2010-03-03 00:12:34 UTC (rev 1573) @@ -90,4 +90,10 @@ override def next = base + i.next override def hasNext = i.hasNext } + + /** + * Remove C block comments. + */ + def removeCBlockComments(s: String) = s.replaceAll("/\\*(?:.|[\\n\\r])*?\\*/", "") + } Added: scala-commons/trunk/src/commons/RichIterator.scala =================================================================== --- scala-commons/trunk/src/commons/RichIterator.scala (rev 0) +++ scala-commons/trunk/src/commons/RichIterator.scala 2010-03-03 00:12:34 UTC (rev 1573) @@ -0,0 +1,72 @@ +package commons + +import scala.collection.{mutable => mut} + +class RichIterator[X](it: Iterator[X]) { + /** Note that this is dangerous in that the states of the sub-iterators and + * the iterator are tightly coupled. */ + def iterChunkAs[K,Y](f: X => (K,Y)) = new Iterator[(K,Iterator[Y])] { + var xform = if (it.hasNext) Some(f(it.next)) else None + def hasNext = xform != None + def next = { + if (!hasNext) throw new Exception + val key = xform.get._1 + val subiter = new Iterator[Y] { + def hasNext = xform != None && xform.get._1 == key + // as long as we're not past the end and we're on the active key + def next = { + if (!hasNext) throw new Exception + val ret = xform.get._2 + xform = if (it.hasNext) Some(f(it.next)) else None + ret + } + } + (key, subiter) + } + } + def iterChunkBy[K](f: X => K) = iterChunkAs(x => (f(x), x)) + + def iterSplitOn(isCut: X => Boolean) = new Iterator[Iterator[X]] { + var fresh = true + def next: Iterator[X] = { + if (fresh) fresh = false + else it dropWhile isCut + it takeWhile (!isCut(_)) + } + def hasNext:Boolean = fresh || { it dropWhile isCut; it hasNext } + } + + def chunkAs[K,Y](f: X => (K,Y)) = new Iterator[(K,Seq[Y])] { + val bit = it.buffered + def hasNext = bit.hasNext // nextElt != None + def next = { + if (!bit.hasNext) throw new Exception + val chunk = new mut.ArrayBuffer[Y] + var xform = f(bit.head) // (nextElt.get) + val key = xform._1 + // as long as we're not past the end and we're on the active key + while (bit.hasNext && xform._1 == key) { + chunk += xform._2 + bit.next // consume it + if (bit.hasNext) xform = f(bit.head) + } + (key, chunk) + } + } + def chunkBy[K](f: X => K) = chunkAs(x => (f(x), x)) +} + +class CachedIterator[X](it: Iterator[X]) extends Iterator[X] { + var last: X = _ + def hasNext = it.hasNext + def next = { + last = it.next + last + } +} + +object RichIterator { + implicit def toRichIterator[X](it: Iterator[X]) = new RichIterator(it) + implicit def toRichIterator[X](it: Iterable[X]) = new RichIterator(it.iterator) + implicit def toRichIterator[X](it: Array[X]) = new RichIterator(it.iterator) +} Added: scala-commons/trunk/src/commons/TableFormatter.scala =================================================================== --- scala-commons/trunk/src/commons/TableFormatter.scala (rev 0) +++ scala-commons/trunk/src/commons/TableFormatter.scala 2010-03-03 00:12:34 UTC (rev 1573) @@ -0,0 +1,13 @@ +package commons + +case class TableFormatter(val rows: Iterable[List[Any]]) { + val xss = rows map (_ map (_ toString) toArray) toArray + override def toString = { + val fmt = ( + for ((x,i) <- xss(0).zipWithIndex) yield { + "%" + (xss map (_(i).length) reduceLeft (Math.max(_,_))) + "s" + } + ).mkString(" | ") + xss map (String.format(fmt, _: _*)) mkString "\n" + } +} Added: scala-commons/trunk/src/commons/Timer.scala =================================================================== --- scala-commons/trunk/src/commons/Timer.scala (rev 0) +++ scala-commons/trunk/src/commons/Timer.scala 2010-03-03 00:12:34 UTC (rev 1573) @@ -0,0 +1,26 @@ +package commons + +object Timer { + + /** + * Return the time in milliseconds taken to run f. + */ + def time(f: =>Any): Long = { + val start = System.currentTimeMillis + f + val stop = System.currentTimeMillis + stop - start + } + + /** + * Evaluate f, printing the time it took. + */ + def printTime[A](f: =>A) = { + val start = System.currentTimeMillis + val ret = f + val stop = System.currentTimeMillis + println("...took " + (stop - start) / 1000. + " s") + ret + } + +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |