src/Pure/General/sqlite.scala
author haftmann
Mon, 06 Feb 2017 20:56:34 +0100
changeset 64990 c6a7de505796
parent 64142 954451356017
child 65002 0c44e3e9126f
permissions -rw-r--r--
more explicit errors in pathological cases
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
63788
3160826b92f8 clarified modules;
wenzelm
parents: 63780
diff changeset
     1
/*  Title:      Pure/General/sqlite.scala
63776
f1968429e339 minimal support for SQLite databases;
wenzelm
parents:
diff changeset
     2
    Author:     Makarius
f1968429e339 minimal support for SQLite databases;
wenzelm
parents:
diff changeset
     3
f1968429e339 minimal support for SQLite databases;
wenzelm
parents:
diff changeset
     4
Support for SQLite databases.
f1968429e339 minimal support for SQLite databases;
wenzelm
parents:
diff changeset
     5
*/
f1968429e339 minimal support for SQLite databases;
wenzelm
parents:
diff changeset
     6
f1968429e339 minimal support for SQLite databases;
wenzelm
parents:
diff changeset
     7
package isabelle
f1968429e339 minimal support for SQLite databases;
wenzelm
parents:
diff changeset
     8
f1968429e339 minimal support for SQLite databases;
wenzelm
parents:
diff changeset
     9
63780
163244cefb4e more operations;
wenzelm
parents: 63779
diff changeset
    10
import java.sql.{DriverManager, Connection, PreparedStatement}
63776
f1968429e339 minimal support for SQLite databases;
wenzelm
parents:
diff changeset
    11
f1968429e339 minimal support for SQLite databases;
wenzelm
parents:
diff changeset
    12
f1968429e339 minimal support for SQLite databases;
wenzelm
parents:
diff changeset
    13
object SQLite
f1968429e339 minimal support for SQLite databases;
wenzelm
parents:
diff changeset
    14
{
63780
163244cefb4e more operations;
wenzelm
parents: 63779
diff changeset
    15
  /** database connection **/
63776
f1968429e339 minimal support for SQLite databases;
wenzelm
parents:
diff changeset
    16
63790
3d723062dc70 more operations;
wenzelm
parents: 63788
diff changeset
    17
  def open_database(path: Path): Database =
3d723062dc70 more operations;
wenzelm
parents: 63788
diff changeset
    18
  {
3d723062dc70 more operations;
wenzelm
parents: 63788
diff changeset
    19
    val path0 = path.expand
3d723062dc70 more operations;
wenzelm
parents: 63788
diff changeset
    20
    val s0 = File.platform_path(path0)
3d723062dc70 more operations;
wenzelm
parents: 63788
diff changeset
    21
    val s1 = if (Platform.is_windows) s0.replace('\\', '/') else s0
3d723062dc70 more operations;
wenzelm
parents: 63788
diff changeset
    22
    val connection = DriverManager.getConnection("jdbc:sqlite:" + s1)
3d723062dc70 more operations;
wenzelm
parents: 63788
diff changeset
    23
    new Database(path0, connection)
3d723062dc70 more operations;
wenzelm
parents: 63788
diff changeset
    24
  }
3d723062dc70 more operations;
wenzelm
parents: 63788
diff changeset
    25
63996
3f47fec9edfc tuned whitespace;
wenzelm
parents: 63811
diff changeset
    26
  class Database private[SQLite](path: Path, val connection: Connection)
63776
f1968429e339 minimal support for SQLite databases;
wenzelm
parents:
diff changeset
    27
  {
63778
e06e899b78d0 clarified modules;
wenzelm
parents: 63777
diff changeset
    28
    override def toString: String = path.toString
63776
f1968429e339 minimal support for SQLite databases;
wenzelm
parents:
diff changeset
    29
64142
954451356017 proper type for Library.using;
wenzelm
parents: 63996
diff changeset
    30
    def close() { connection.close }
63779
9da65bc75610 more operations;
wenzelm
parents: 63778
diff changeset
    31
63811
3a75593e9b6d more operations;
wenzelm
parents: 63791
diff changeset
    32
    def rebuild { using(statement("VACUUM"))(_.execute()) }
3a75593e9b6d more operations;
wenzelm
parents: 63791
diff changeset
    33
63779
9da65bc75610 more operations;
wenzelm
parents: 63778
diff changeset
    34
    def transaction[A](body: => A): A =
9da65bc75610 more operations;
wenzelm
parents: 63778
diff changeset
    35
    {
9da65bc75610 more operations;
wenzelm
parents: 63778
diff changeset
    36
      val auto_commit = connection.getAutoCommit
9da65bc75610 more operations;
wenzelm
parents: 63778
diff changeset
    37
      val savepoint = connection.setSavepoint
9da65bc75610 more operations;
wenzelm
parents: 63778
diff changeset
    38
9da65bc75610 more operations;
wenzelm
parents: 63778
diff changeset
    39
      try {
9da65bc75610 more operations;
wenzelm
parents: 63778
diff changeset
    40
        connection.setAutoCommit(false)
9da65bc75610 more operations;
wenzelm
parents: 63778
diff changeset
    41
        val result = body
9da65bc75610 more operations;
wenzelm
parents: 63778
diff changeset
    42
        connection.commit
9da65bc75610 more operations;
wenzelm
parents: 63778
diff changeset
    43
        result
9da65bc75610 more operations;
wenzelm
parents: 63778
diff changeset
    44
      }
9da65bc75610 more operations;
wenzelm
parents: 63778
diff changeset
    45
      catch { case exn: Throwable => connection.rollback(savepoint); throw exn }
9da65bc75610 more operations;
wenzelm
parents: 63778
diff changeset
    46
      finally { connection.setAutoCommit(auto_commit) }
9da65bc75610 more operations;
wenzelm
parents: 63778
diff changeset
    47
    }
63780
163244cefb4e more operations;
wenzelm
parents: 63779
diff changeset
    48
63790
3d723062dc70 more operations;
wenzelm
parents: 63788
diff changeset
    49
63791
c6cbdfaae19e more operations;
wenzelm
parents: 63790
diff changeset
    50
    /* statements */
63790
3d723062dc70 more operations;
wenzelm
parents: 63788
diff changeset
    51
3d723062dc70 more operations;
wenzelm
parents: 63788
diff changeset
    52
    def statement(sql: String): PreparedStatement = connection.prepareStatement(sql)
3d723062dc70 more operations;
wenzelm
parents: 63788
diff changeset
    53
3d723062dc70 more operations;
wenzelm
parents: 63788
diff changeset
    54
    def insert_statement(table: SQL.Table): PreparedStatement = statement(table.sql_insert)
63780
163244cefb4e more operations;
wenzelm
parents: 63779
diff changeset
    55
63791
c6cbdfaae19e more operations;
wenzelm
parents: 63790
diff changeset
    56
    def select_statement(table: SQL.Table, columns: List[SQL.Column[Any]],
c6cbdfaae19e more operations;
wenzelm
parents: 63790
diff changeset
    57
        sql: String = "", distinct: Boolean = false): PreparedStatement =
c6cbdfaae19e more operations;
wenzelm
parents: 63790
diff changeset
    58
      statement(table.sql_select(columns, distinct) + (if (sql == "") "" else " " + sql))
c6cbdfaae19e more operations;
wenzelm
parents: 63790
diff changeset
    59
63780
163244cefb4e more operations;
wenzelm
parents: 63779
diff changeset
    60
163244cefb4e more operations;
wenzelm
parents: 63779
diff changeset
    61
    /* tables */
163244cefb4e more operations;
wenzelm
parents: 63779
diff changeset
    62
63790
3d723062dc70 more operations;
wenzelm
parents: 63788
diff changeset
    63
    def tables: List[String] =
3d723062dc70 more operations;
wenzelm
parents: 63788
diff changeset
    64
      SQL.iterator(connection.getMetaData.getTables(null, null, "%", null))(_.getString(3)).toList
3d723062dc70 more operations;
wenzelm
parents: 63788
diff changeset
    65
63780
163244cefb4e more operations;
wenzelm
parents: 63779
diff changeset
    66
    def create_table(table: SQL.Table, strict: Boolean = true, rowid: Boolean = true): Unit =
63790
3d723062dc70 more operations;
wenzelm
parents: 63788
diff changeset
    67
      using(statement(table.sql_create(strict, rowid)))(_.execute())
63780
163244cefb4e more operations;
wenzelm
parents: 63779
diff changeset
    68
163244cefb4e more operations;
wenzelm
parents: 63779
diff changeset
    69
    def drop_table(table: SQL.Table, strict: Boolean = true): Unit =
63790
3d723062dc70 more operations;
wenzelm
parents: 63788
diff changeset
    70
      using(statement(table.sql_drop(strict)))(_.execute())
63791
c6cbdfaae19e more operations;
wenzelm
parents: 63790
diff changeset
    71
c6cbdfaae19e more operations;
wenzelm
parents: 63790
diff changeset
    72
    def create_index(table: SQL.Table, name: String, columns: List[SQL.Column[Any]],
c6cbdfaae19e more operations;
wenzelm
parents: 63790
diff changeset
    73
        strict: Boolean = true, unique: Boolean = false): Unit =
c6cbdfaae19e more operations;
wenzelm
parents: 63790
diff changeset
    74
      using(statement(table.sql_create_index(name, columns, strict, unique)))(_.execute())
c6cbdfaae19e more operations;
wenzelm
parents: 63790
diff changeset
    75
c6cbdfaae19e more operations;
wenzelm
parents: 63790
diff changeset
    76
    def drop_index(table: SQL.Table, name: String, strict: Boolean = true): Unit =
c6cbdfaae19e more operations;
wenzelm
parents: 63790
diff changeset
    77
      using(statement(table.sql_drop_index(name, strict)))(_.execute())
63778
e06e899b78d0 clarified modules;
wenzelm
parents: 63777
diff changeset
    78
  }
63776
f1968429e339 minimal support for SQLite databases;
wenzelm
parents:
diff changeset
    79
}