src/Pure/Tools/sql.scala
changeset 63779 9da65bc75610
parent 63778 e06e899b78d0
child 63780 163244cefb4e
equal deleted inserted replaced
63778:e06e899b78d0 63779:9da65bc75610
     1 /*  Title:      Pure/Tools/sql.scala
     1 /*  Title:      Pure/Tools/sql.scala
     2     Author:     Makarius
     2     Author:     Makarius
     3 
     3 
     4 Support for SQL.
     4 Generic support for SQL.
     5 */
     5 */
     6 
     6 
     7 package isabelle
     7 package isabelle
       
     8 
       
     9 
       
    10 import java.sql.ResultSet
     8 
    11 
     9 
    12 
    10 object SQL
    13 object SQL
    11 {
    14 {
    12   /* concrete syntax */
    15   /* concrete syntax */
    26     }
    29     }
    27 
    30 
    28   def quote_string(s: String): String =
    31   def quote_string(s: String): String =
    29     quote(s.map(quote_char(_)).mkString)
    32     quote(s.map(quote_char(_)).mkString)
    30 
    33 
    31   def quote_ident(s: String): String = "`" + s + "`"
    34   def quote_ident(s: String): String =
       
    35   {
       
    36     require(!s.contains('`'))
       
    37     "`" + s + "`"
       
    38   }
       
    39 
       
    40 
       
    41   /* columns */
       
    42 
       
    43   object Column
       
    44   {
       
    45     def int(name: String, strict: Boolean = true): Column[Int] = new Column_Int(name, strict)
       
    46     def long(name: String, strict: Boolean = true): Column[Long] = new Column_Long(name, strict)
       
    47     def double(name: String, strict: Boolean = true): Column[Double] = new Column_Double(name, strict)
       
    48     def string(name: String, strict: Boolean = true): Column[String] = new Column_String(name, strict)
       
    49     def bytes(name: String, strict: Boolean = true): Column[Bytes] = new Column_Bytes(name, strict)
       
    50   }
       
    51 
       
    52   abstract class Column[A] private[SQL](val name: String, val strict: Boolean)
       
    53   {
       
    54     def sql_name: String = quote_ident(name)
       
    55     def sql_type: String
       
    56     def sql_decl: String = sql_name + " " + sql_type + (if (strict) " NOT NULL" else "")
       
    57     def result(rs: ResultSet): A
       
    58     def result_string(rs: ResultSet): String = rs.getString(name)
       
    59 
       
    60     override def toString: String = sql_decl
       
    61   }
       
    62 
       
    63   class Column_Int private[SQL](name: String, strict: Boolean)
       
    64     extends Column[Int](name, strict)
       
    65   {
       
    66     def sql_type: String = "INTEGER"
       
    67     def result(rs: ResultSet): Int = rs.getInt(name)
       
    68   }
       
    69 
       
    70   class Column_Long private[SQL](name: String, strict: Boolean)
       
    71     extends Column[Long](name, strict)
       
    72   {
       
    73     def sql_type: String = "INTEGER"
       
    74     def result(rs: ResultSet): Long = rs.getLong(name)
       
    75   }
       
    76 
       
    77   class Column_Double private[SQL](name: String, strict: Boolean)
       
    78     extends Column[Double](name, strict)
       
    79   {
       
    80     def sql_type: String = "REAL"
       
    81     def result(rs: ResultSet): Double = rs.getDouble(name)
       
    82   }
       
    83 
       
    84   class Column_String private[SQL](name: String, strict: Boolean)
       
    85     extends Column[String](name, strict)
       
    86   {
       
    87     def sql_type: String = "TEXT"
       
    88     def result(rs: ResultSet): String = rs.getString(name)
       
    89   }
       
    90 
       
    91   class Column_Bytes private[SQL](name: String, strict: Boolean)
       
    92     extends Column[Bytes](name, strict)
       
    93   {
       
    94     def sql_type: String = "BLOB"
       
    95     def result(rs: ResultSet): Bytes =
       
    96     {
       
    97       val bs = rs.getBytes(name)
       
    98       if (bs == null) null else Bytes(bs)
       
    99     }
       
   100   }
    32 }
   101 }