Skip to content

Commit a282e85

Browse files
author
Tony Kay
committed
Refactored code, and added support for long and double arrays (with tests)
1 parent 0ab4fd7 commit a282e85

File tree

6 files changed

+63
-25
lines changed

6 files changed

+63
-25
lines changed

src/main/scala/org/squeryl/adapters/PostgreSqlAdapter.scala

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,16 @@ class PostgreSqlAdapter extends DatabaseAdapter {
3636
override def booleanTypeDeclaration = "boolean"
3737
override def doubleTypeDeclaration = "double precision"
3838
override def longTypeDeclaration = "bigint"
39-
override def arrayIntTypeDeclaration = "integer[]"
4039
override def bigDecimalTypeDeclaration = "numeric"
4140
override def bigDecimalTypeDeclaration(precision:Int, scale:Int) = "numeric(" + precision + "," + scale + ")"
4241
override def binaryTypeDeclaration = "bytea"
4342
override def uuidTypeDeclaration = "uuid"
4443

44+
45+
override def jdbcIntArrayCreationType = "int4"
46+
override def jdbcLongArrayCreationType = "int8"
47+
override def jdbcDoubleArrayCreationType = "float8"
48+
4549
override def foreignKeyConstraintName(foreignKeyTable: Table[_], idWithinSchema: Int) =
4650
foreignKeyTable.name + "FK" + idWithinSchema
4751

src/main/scala/org/squeryl/dsl/TypedExpression.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,15 @@ sealed trait TDate extends TOptionDate with TNonOption
6565
sealed trait TTimestamp extends TOptionTimestamp with TNonOption
6666
sealed trait TByteArray extends TOptionByteArray with TNonOption
6767
sealed trait TIntArray extends TOptionIntArray with TNonOption
68+
sealed trait TLongArray extends TOptionLongArray with TNonOption
69+
sealed trait TDoubleArray extends TOptionDoubleArray with TNonOption
6870
sealed trait TOptionString
6971
sealed trait TOptionDate
7072
sealed trait TOptionTimestamp
7173
sealed trait TOptionByteArray
7274
sealed trait TOptionIntArray
75+
sealed trait TOptionLongArray
76+
sealed trait TOptionDoubleArray
7377
sealed trait TBoolean extends TOptionBoolean with TNonOption
7478
sealed trait TOptionBoolean
7579
sealed trait TUUID extends TOptionUUID with TNonOption

src/main/scala/org/squeryl/internals/ArrayTEF.scala

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,11 @@ abstract class ArrayTEF[P, TE] extends TypedExpressionFactory[Array[P], TE] with
1717
val s = Session.currentSession
1818
val con = s.connection
1919
var rv: java.sql.Array = null
20-
try {
21-
rv = con.createArrayOf(s.databaseAdapter.arrayCreationType(sample(0).getClass), content)
20+
try {
21+
val typ = s.databaseAdapter.arrayCreationType(sample(0).getClass)
22+
rv = con.createArrayOf(typ, content)
2223
} catch {
23-
case e: Exception => s.log("Cannot create JDBC array: " + e.getMessage());
24+
case e: Exception => s.log("Cannot create JDBC array: " + e.getMessage)
2425
}
2526
rv
2627
}

src/main/scala/org/squeryl/internals/DatabaseAdapter.scala

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -177,24 +177,26 @@ trait DatabaseAdapter {
177177
def longTypeDeclaration = "bigint"
178178
def floatTypeDeclaration = "real"
179179
def bigDecimalTypeDeclaration = "decimal"
180-
def arrayIntTypeDeclaration = "int array"
181180
def bigDecimalTypeDeclaration(precision:Int, scale:Int) = "decimal(" + precision + "," + scale + ")"
182181
def timestampTypeDeclaration = "timestamp"
183182
def binaryTypeDeclaration = "binary"
184183
def uuidTypeDeclaration = "char(36)"
185-
186-
// These are needed by the jdbc connection when creating arrays
187-
def intArrayCreationType = "integer"
188-
def doubleArrayCreationType = "double"
189-
def longArrayCreationType = "bigint"
184+
def intArrayTypeDeclaration = intTypeDeclaration + "[]"
185+
def longArrayTypeDeclaration = longTypeDeclaration + "[]"
186+
def doubleArrayTypeDeclaration = doubleTypeDeclaration + "[]"
187+
188+
def jdbcIntArrayCreationType = intTypeDeclaration
189+
def jdbcLongArrayCreationType = longTypeDeclaration
190+
def jdbcDoubleArrayCreationType = doubleTypeDeclaration
190191

191192
final def arrayCreationType(ptype : Class[_]) : String = {
192-
ptype.getName() match {
193-
case "java.lang.Integer" => intArrayCreationType
194-
case "java.lang.Double" => doubleArrayCreationType
195-
case "java.lang.Long" => longArrayCreationType
196-
case _ => throw new SQLException("Unable to create an sql array for " + ptype.getName())
197-
}
193+
val rv = ptype.getName() match {
194+
case "java.lang.Integer" => jdbcIntArrayCreationType
195+
case "java.lang.Double" => jdbcDoubleArrayCreationType
196+
case "java.lang.Long" => jdbcLongArrayCreationType
197+
case _ => ""
198+
}
199+
rv
198200
}
199201

200202
/*
@@ -813,10 +815,14 @@ trait DatabaseAdapter {
813815
else if(classOf[BigDecimal].isAssignableFrom(c))
814816
bigDecimalTypeDeclaration
815817
else if(classOf[scala.Array[Int]].isAssignableFrom(c))
816-
arrayIntTypeDeclaration
818+
intArrayTypeDeclaration
819+
else if(classOf[scala.Array[Long]].isAssignableFrom(c))
820+
longArrayTypeDeclaration
821+
else if(classOf[scala.Array[Double]].isAssignableFrom(c))
822+
doubleArrayTypeDeclaration
817823
else
818-
Utils.throwError("unsupported type " + ar.getClass.getCanonicalName)
819-
824+
Utils.throwError("unsupported type " + ar.getClass.getCanonicalName)
825+
820826
decl
821827
}
822828

src/main/scala/org/squeryl/internals/FieldMapper.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,19 @@ trait FieldMapper {
114114
def fromWrappedJDBCType(elements: Array[java.lang.Object]) : Array[Int] = elements.map(i => i.asInstanceOf[java.lang.Integer].toInt)
115115
}
116116

117+
val longArrayTEF = new ArrayTEF[Long, TLongArray] {
118+
val sample = Array(0L)
119+
def toWrappedJDBCType(element: Long) : java.lang.Object = new java.lang.Long(element)
120+
def fromWrappedJDBCType(elements: Array[java.lang.Object]) : Array[Long] = elements.map(i => i.asInstanceOf[java.lang.Long].toLong)
121+
}
122+
123+
val doubleArrayTEF = new ArrayTEF[Double, TDoubleArray] {
124+
val sample : Array[Double] = Array(0.0)
125+
def toWrappedJDBCType(element: Double) : java.lang.Object = new java.lang.Double(element)
126+
def fromWrappedJDBCType(elements: Array[java.lang.Object]) : Array[Double] = elements.map(i => i.asInstanceOf[java.lang.Double].toDouble)
127+
}
128+
129+
// FIXME: Get this to work...
117130
//val optionIntArrayTEF = new TypedExpressionFactory[Option[Array[Int]],TOptionIntArray] with DeOptionizer[Array[Int], Array[Int], TIntArray, Option[Array[Int]], TOptionIntArray] {
118131
//val deOptionizer = intArrayTEF
119132
//}
@@ -235,6 +248,8 @@ trait FieldMapper {
235248
register(dateTEF)
236249
register(uuidTEF)
237250
register(intArrayTEF)
251+
register(longArrayTEF)
252+
register(doubleArrayTEF)
238253

239254
val re = enumValueTEF(DummyEnum.DummyEnumerationValue)
240255

src/test/scala/org/squeryl/test/arrays/PrimitiveArrayTest.scala

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,26 @@ abstract class PrimitiveArrayTest extends SchemaTester with RunTestsInsideTransa
1414
transaction {
1515
schema.drop
1616
schema.create
17-
swimmers.insert(new Swimmer(1, Array(1055, 1299, 1532)))
17+
swimmers.insert(new Swimmer(1, Array(10.55, 12.99, 15.32), Array(100,110,20), Array(9876543210L,123456789L)))
1818
}
1919

2020
val query = from(swimmers)((s) => select(s))
21-
println(query.toString)
2221
val res = transaction { query.toList }
2322

2423
res.size should equal(1)
2524
res(0).lap_times.size should equal(3)
26-
res(0).lap_times(0) should equal(1055)
27-
res(0).lap_times(1) should equal(1299)
28-
res(0).lap_times(2) should equal(1532)
25+
res(0).lap_times(0) should equal(10.55)
26+
res(0).lap_times(1) should equal(12.99)
27+
res(0).lap_times(2) should equal(15.32)
28+
29+
res(0).scores.size should equal(3)
30+
res(0).scores(0) should equal(100)
31+
res(0).scores(1) should equal(110)
32+
res(0).scores(2) should equal(20)
33+
34+
res(0).orgids.size should equal(2)
35+
res(0).orgids(0) should equal(9876543210L)
36+
res(0).orgids(1) should equal(123456789L)
2937
}
3038
}
3139

@@ -39,4 +47,4 @@ object PrimitiveArraySchema extends Schema {
3947
override def drop = super.drop
4048
}
4149

42-
class Swimmer(val id: Int, val lap_times: Array[Int])
50+
class Swimmer(val id: Int, val lap_times: Array[Double], val scores : Array[Int], val orgids : Array[Long])

0 commit comments

Comments
 (0)