Talk on Nov. 14, 2013 SF Scala Meet up lighting talk.
Presented SPA --- Scala Persistence API (spa), a JDBC wrapper. A simple query API with out ORM or functional to relational mapping. It supports batch update, transaction and query return list or single objects
2. What is SPA about ?
A JDBC wrapper to make query database easier
S
F
T
P
L
• Simple and Resource safe
• Flexible: handle results via toList, toSingle, Iterator as well as
customized row extractor
• Support Transaction and batch update
• Plain SQL: SQL is enough
• Failure SQL logging
3. What SPA is not?
OR
• Not a Object Relation mapping
tool
FR
• Not a Function Relation mapping
Tool
Pool
• Not Supporting Connection Pool
4. Rest of SPA talk
•API examples
•SPA implementations
5. SPA Select Query
Show me the code
def getConnection : Connection = ...
val qm = QueryManager(open = getConnection )
val table = "dummy"
//mySQL table
val parsedSql = sql"select count(*) from
information_schema.tables where table_name=$table"
val count = qm.selectQuery(parsedSql).toSingle[Int]
6. SPA Select Query: Simple Data Type
Show me the code
val parsedSql = sql"select table_name from
information_schema.tables”
val r = qm.selectQuery(parsedSql).toList[String]
val tuple4Value = qm.selectQuery(sql" select 1,2,3,4 from
dual").toSingle[(Int,Int, Int,Int )]
assert(tuple4Value.get === ( 1,2,3,4 ))
7. SPA Select Query: Class Structure
Coffee again
case class Coffee(
@Column("COF_NAME") name: String,
@Column("SUP_ID")
supId: Int,
@Column("PRICE")
price: Double)
8. SPA Select Query: Class Structure
Show me the code
val qm = QueryManager(open = geConnection)
val results1 = qm.selectQuery(sql" select * from COFFEES
").toList[Coffee]
val q = qm.selectQuery(sql" select * from mytest.COFFEES ")
val results2 = q.withIterator { it: Iterator[Option[Coffee]] =>
it.foldLeft(List[Coffee]())( (acc, a) => a.get :: acc).reverse
}
9. SPA Update Query
Show me the code
valcreateTableSql= sql"createtable test( id MEDIUMINT NOT NULL
AUTO_INCREMENT primary key, x Integer)”
qm.updateQuery(createTableSql).executeUpdate
//return the generated id.
valid1 = qm.updateQuery(sql" INSERT INTO test(x) values (1) ").executeUpdate
assert(id1 == 1)
valid2 = qm.updateQuery(sql" INSERT INTO test(x) values (2) ").executeUpdate
assert(id2 == 2)
10. SPA Update Query: transaction
Show me the code
Update the value to 2 in the table, assume it was 1,
After update, throw exception within the same transaction.
the exception should cause transaction rollback
the database table should still have the value before transaction : i.e. 1
intercept[ExecuteQueryException] {
qm.transaction() { implicit trans =>
qm.updateQuery(sql"updatemytest.testset x = 2").executeUpdate
//simulate some code cause it to throw exception
throw new ExecuteQueryException("see if I can rollback")
}
}
//verify that the database table still have value 1
valvalue2 = qm.selectQuery(sql"selectx from mytest.test").toSingle[Long]
assert(value2 === Some(1))
11. SPA Update Query: batch update
Show me the code
valq = qm.batchUpdateQuery(sql"insertinto mytest.test(x, y) values(?, ?) ")
//index is zero-based
val size = 10
for (i<-0 until size ) {
val pa = Map(0 -> i, 1 -> i*20) // x is 0, y is 1
q.addBatch(pa) //use JDBC add batch
}
q.executeBatchUpdate
12. SPA: Logging
Show me the code
Automatically logs the SQL statement as well corresponding parameters to stdout,
One can use sqllogging to debug on individual SQL
For example,
val q = qm.updateQuery(....)
.logSql(true)
.executeUpdate
13. SPA Implementation
val a = “c”
val s= sql”select * from table where colume1 = $a”
• How is this implemented ?
• How does SPA ensure resource safe ?
14. SPA: Parse SQL with String Interpolation
Show me the code
case class ParsedSql(sql: String, parameterPositions: Map[Int, SQLParameter])
implicit class SqlContext(sc: StringContext) {
def sql( args:Any*): ParsedSql = {
val parameters = (args.indiceszip args).foldLeft(Map[Int, SQLParameter]())( (acc, a)
=> acc + (a._1 -> toSqlParameter(a._2)))
val placeHolders= args.map( a=> "?")
val sql = sc.s(placeHolders:_*)
ParsedSql(sql, parameters)
}
}
15. SPA: Transaction
The original transaction construct is borrowed from Querulous.
def transaction[T](transaction : Option[Transaction] = None)
(f: Option[Transaction] => T):T = {
withTransaction(transaction) { tran =>
try {
tran.begin()
val value = f(Some(tran))
tran.commit()
value
} catch {
case e: Throwable=>
tran.rollback()
throw e
}
}
}
16. SPA: Select Query
Show me the code
class SelectQuery(queryManager : QueryManager, /* skip other args*/
(transaction: Option[Transaction] = None)
extends CoreQuery[SelectQuery](parsedSql, /* skip others */) {
deftoList[A : ClassTag : TypeTag]: List[A] = {
definnerToList(trans: Transaction)=
withQuery(trans, forwardOnly= true) { rs=>
valprocessor = new SeqResultSetProcessor()
valextractor = rowProcessor.getOrElse( new ClassRowProcessor[A])
.asInstanceOf[RowExtractor[A]]
processor.processResultSet[A](rs, extractor).toList
}
transactionmatch {
case None => queryManager.transaction() { trans => innerToList(trans.get)}
case Some(trans) => innerToList(trans)
}
}
Play the slide show for this presentation to listen to the audio commentary by Peter Walsh and view slide timings. Or, click the sound icon on a slide for controls that you can use to hear the audio at your own pace.A little organization will go a long way to enhancing your PowerPoint presentation. Your title slide should be catching and relevant to your audience – offer something in the title that your audience wants. Keep some basic principles in mind:Your slides should complement what you have to say, not say it for you. Keep slides direct and to the point - less is more!Choose a background color or design that enhances and complements your presentation rather than competes with it. Don’t get too fancy - a simple font, elegant color scheme and clear message is more important than lots of information (clutter!) on the slide.Keep it simple! The purpose of the PowerPoint slide is to keep the mind of your audience focused – fewer words are better. Note: You understand that Microsoft does not endorse or control the content provided in the following presentation.
Keep your presentation logical and be sure that one point flows to the next. If there are sub-points, add them with an additional slide. Make sure that when you move to a new main bullet point your audience knows where they are in the presentation.If you sense that you’re losing your audience – summarize what you’ve said and pick up the pace.
Keep your presentation logical and be sure that one point flows to the next. If there are sub-points, add them with an additional slide. Make sure that when you move to a new main bullet point your audience knows where they are in the presentation.If you sense that you’re losing your audience – summarize what you’ve said and pick up the pace.
Keep your presentation logical and be sure that one point flows to the next. If there are sub-points, add them with an additional slide. Make sure that when you move to a new main bullet point your audience knows where they are in the presentation.If you sense that you’re losing your audience – summarize what you’ve said and pick up the pace.
Watch your timing! Allocate a time for each slide and stick to it so as to keep track of your presentation and avoid speaking too much.
Watch your timing! Allocate a time for each slide and stick to it so as to keep track of your presentation and avoid speaking too much.
Watch your timing! Allocate a time for each slide and stick to it so as to keep track of your presentation and avoid speaking too much.
Watch your timing! Allocate a time for each slide and stick to it so as to keep track of your presentation and avoid speaking too much.
Watch your timing! Allocate a time for each slide and stick to it so as to keep track of your presentation and avoid speaking too much.
Watch your timing! Allocate a time for each slide and stick to it so as to keep track of your presentation and avoid speaking too much.
Watch your timing! Allocate a time for each slide and stick to it so as to keep track of your presentation and avoid speaking too much.
Watch your timing! Allocate a time for each slide and stick to it so as to keep track of your presentation and avoid speaking too much.
Keep your presentation logical and be sure that one point flows to the next. If there are sub-points, add them with an additional slide. Make sure that when you move to a new main bullet point your audience knows where they are in the presentation.If you sense that you’re losing your audience – summarize what you’ve said and pick up the pace.
Watch your timing! Allocate a time for each slide and stick to it so as to keep track of your presentation and avoid speaking too much.
Watch your timing! Allocate a time for each slide and stick to it so as to keep track of your presentation and avoid speaking too much.
Watch your timing! Allocate a time for each slide and stick to it so as to keep track of your presentation and avoid speaking too much.
Watch your timing! Allocate a time for each slide and stick to it so as to keep track of your presentation and avoid speaking too much.