Skip to content

Commit 0ab4fd7

Browse files
author
Tony Kay
committed
refactored support of arrays to generalize and clean up code
1 parent fb65778 commit 0ab4fd7

File tree

7 files changed

+64
-52
lines changed

7 files changed

+64
-52
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ class PostgreSqlAdapter extends DatabaseAdapter {
4040
override def bigDecimalTypeDeclaration = "numeric"
4141
override def bigDecimalTypeDeclaration(precision:Int, scale:Int) = "numeric(" + precision + "," + scale + ")"
4242
override def binaryTypeDeclaration = "bytea"
43-
override def uuidTypeDeclaration = "uuid"
44-
43+
override def uuidTypeDeclaration = "uuid"
44+
4545
override def foreignKeyConstraintName(foreignKeyTable: Table[_], idWithinSchema: Int) =
4646
foreignKeyTable.name + "FK" + idWithinSchema
4747

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package org.squeryl.internals
2+
3+
import java.sql.ResultSet
4+
import org.squeryl.Session
5+
import org.squeryl.dsl.TypedExpressionFactory
6+
import org.squeryl.dsl.ArrayJdbcMapper
7+
8+
abstract class ArrayTEF[P, TE] extends TypedExpressionFactory[Array[P], TE] with ArrayJdbcMapper[java.sql.Array, Array[P]] {
9+
// must define "sample" that includes an element. e.g. Array[Int](0)
10+
def sample : Array[P]
11+
def toWrappedJDBCType(element: P) : java.lang.Object
12+
def fromWrappedJDBCType(element: Array[java.lang.Object]) : Array[P]
13+
val defaultColumnLength = 1
14+
def extractNativeJdbcValue(rs: ResultSet, i: Int) = rs.getArray(i)
15+
def convertToJdbc(v: Array[P]): java.sql.Array = {
16+
val content: Array[java.lang.Object] = v.map(toWrappedJDBCType(_))
17+
val s = Session.currentSession
18+
val con = s.connection
19+
var rv: java.sql.Array = null
20+
try {
21+
rv = con.createArrayOf(s.databaseAdapter.arrayCreationType(sample(0).getClass), content)
22+
} catch {
23+
case e: Exception => s.log("Cannot create JDBC array: " + e.getMessage());
24+
}
25+
rv
26+
}
27+
def convertFromJdbc(v: java.sql.Array): Array[P] = {
28+
val s = Session.currentSession
29+
var rv : Array[P] = sample.take(0)
30+
try {
31+
val obj = v.getArray();
32+
rv = fromWrappedJDBCType(obj.asInstanceOf[Array[java.lang.Object]])
33+
} catch {
34+
case e: Exception => s.log("Cannot obtain array from JDBC: " + e.getMessage)
35+
}
36+
rv
37+
}
38+
}

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

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,22 @@ trait DatabaseAdapter {
181181
def bigDecimalTypeDeclaration(precision:Int, scale:Int) = "decimal(" + precision + "," + scale + ")"
182182
def timestampTypeDeclaration = "timestamp"
183183
def binaryTypeDeclaration = "binary"
184-
def uuidTypeDeclaration = "char(36)"
184+
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"
190+
191+
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+
}
198+
}
199+
185200
/*
186201
private val _declarationHandler = new FieldTypeHandler[String] {
187202

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

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -108,24 +108,10 @@ trait FieldMapper {
108108
val deOptionizer = binaryTEF
109109
}
110110

111-
val intArrayTEF = new TypedExpressionFactory[Array[Int],TIntArray] with ArrayJdbcMapper[java.sql.Array, Array[Int]] {
111+
val intArrayTEF = new ArrayTEF[Int, TIntArray] {
112112
val sample = Array(0)
113-
val defaultColumnLength = 1
114-
def extractNativeJdbcValue(rs: ResultSet, i: Int) = rs.getArray(i)
115-
def convertToJdbc(v: Array[Int]): java.sql.Array = {
116-
val content : Array[java.lang.Object] = v.map(i => new java.lang.Integer(i.toInt));
117-
Session.currentSession.connection.createArrayOf("int4", content)
118-
}
119-
def convertFromJdbc(v: java.sql.Array): Array[Int] = {
120-
var rv = Array[Int]()
121-
try {
122-
val obj = v.getArray();
123-
rv = obj.asInstanceOf[Array[java.lang.Integer]].map(_.toInt)
124-
} catch {
125-
case _ => // TODO: Log error somehow
126-
}
127-
rv
128-
}
113+
def toWrappedJDBCType(element: Int) : java.lang.Object = new java.lang.Integer(element)
114+
def fromWrappedJDBCType(elements: Array[java.lang.Object]) : Array[Int] = elements.map(i => i.asInstanceOf[java.lang.Integer].toInt)
129115
}
130116

131117
//val optionIntArrayTEF = new TypedExpressionFactory[Option[Array[Int]],TOptionIntArray] with DeOptionizer[Array[Int], Array[Int], TIntArray, Option[Array[Int]], TOptionIntArray] {

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

Lines changed: 0 additions & 31 deletions
This file was deleted.

src/test/scala/org/squeryl/postgres/PostgresTests.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ trait Postgresql_Connection extends DBConnector{
2828
}
2929

3030
class Postgresql_ArrayTests extends PrimitiveArrayTest with Postgresql_Connection
31+
/*
3132
class Postgresql_UuidTests extends UuidTests with Postgresql_Connection
3233
class Postgresql_NestedLeftOuterJoinTest extends NestedLeftOuterJoinTest with Postgresql_Connection
3334
class Postgresql_SchoolDbMutableRelations extends mutablerelations.SchoolDb2MetableRelations with Postgresql_Connection
@@ -43,6 +44,7 @@ class Postgresql_LeftJoinTest extends LeftJoinTest with Postgresql_Connection
4344
class Postgresql_ConnectionClosing extends ConnectionClosingTest with Postgresql_Connection {
4445
def dbSpecificSelectNow: String = "select now()"
4546
}
47+
*/
4648

4749

4850

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ abstract class PrimitiveArrayTest extends SchemaTester with RunTestsInsideTransa
1010

1111
import PrimitiveArraySchema._
1212

13-
test("can see array values in database") {
13+
test("can insert and query integer array values in database") {
1414
transaction {
1515
schema.drop
1616
schema.create
@@ -24,6 +24,8 @@ abstract class PrimitiveArrayTest extends SchemaTester with RunTestsInsideTransa
2424
res.size should equal(1)
2525
res(0).lap_times.size should equal(3)
2626
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)
2729
}
2830
}
2931

0 commit comments

Comments
 (0)