src/Pure/Thy/sessions.scala
changeset 65320 52861eebf58d
parent 65318 342efc382558
child 65322 b2dc9e3b8ee5
equal deleted inserted replaced
65319:64da14387b2c 65320:52861eebf58d
     7 package isabelle
     7 package isabelle
     8 
     8 
     9 import java.nio.ByteBuffer
     9 import java.nio.ByteBuffer
    10 import java.nio.channels.FileChannel
    10 import java.nio.channels.FileChannel
    11 import java.nio.file.StandardOpenOption
    11 import java.nio.file.StandardOpenOption
       
    12 import java.sql.PreparedStatement
    12 
    13 
    13 import scala.collection.SortedSet
    14 import scala.collection.SortedSet
    14 import scala.collection.mutable
    15 import scala.collection.mutable
    15 
    16 
    16 
    17 
   532     val output_heap = SQL.Column.string("output_heap")
   533     val output_heap = SQL.Column.string("output_heap")
   533     val return_code = SQL.Column.int("return_code")
   534     val return_code = SQL.Column.int("return_code")
   534     val build_columns = List(sources, input_heaps, output_heap, return_code)
   535     val build_columns = List(sources, input_heaps, output_heap, return_code)
   535 
   536 
   536     val table = SQL.Table("isabelle_session_info", build_log_columns ::: build_columns)
   537     val table = SQL.Table("isabelle_session_info", build_log_columns ::: build_columns)
       
   538 
       
   539     def where_session_name(name: String): String =
       
   540       "WHERE " + SQL.quote_ident(session_name.name) + " = " + SQL.quote_string(name)
       
   541 
       
   542     def select_statement(db: SQL.Database, name: String, columns: List[SQL.Column])
       
   543         : PreparedStatement =
       
   544       db.select_statement(table, columns, where_session_name(name))
       
   545 
       
   546     def delete_statement(db: SQL.Database, name: String): PreparedStatement =
       
   547       db.delete_statement(table, where_session_name(name))
   537   }
   548   }
   538 
   549 
   539   def store(system_mode: Boolean = false): Store = new Store(system_mode)
   550   def store(system_mode: Boolean = false): Store = new Store(system_mode)
   540 
   551 
   541   class Store private[Sessions](system_mode: Boolean)
   552   class Store private[Sessions](system_mode: Boolean)
   569       else
   580       else
   570         XML.Decode.list(XML.Decode.properties)(YXML.parse_body(bs.uncompress().text)).
   581         XML.Decode.list(XML.Decode.properties)(YXML.parse_body(bs.uncompress().text)).
   571           map(xml_cache.props(_))
   582           map(xml_cache.props(_))
   572     }
   583     }
   573 
   584 
   574     def read_string(db: SQL.Database, table: SQL.Table, column: SQL.Column): String =
   585     def read_bytes(db: SQL.Database, name: String, column: SQL.Column): Bytes =
   575       using(db.select_statement(table, List(column)))(stmt =>
   586       using(Session_Info.select_statement(db, name, List(column)))(stmt =>
   576       {
       
   577         val rs = stmt.executeQuery
       
   578         if (!rs.next) "" else db.string(rs, column.name)
       
   579       })
       
   580 
       
   581     def read_bytes(db: SQL.Database, table: SQL.Table, column: SQL.Column): Bytes =
       
   582       using(db.select_statement(table, List(column)))(stmt =>
       
   583       {
   587       {
   584         val rs = stmt.executeQuery
   588         val rs = stmt.executeQuery
   585         if (!rs.next) Bytes.empty else db.bytes(rs, column.name)
   589         if (!rs.next) Bytes.empty else db.bytes(rs, column.name)
   586       })
   590       })
   587 
   591 
   588     def read_properties(db: SQL.Database, table: SQL.Table, column: SQL.Column)
   592     def read_properties(db: SQL.Database, name: String, column: SQL.Column): List[Properties.T] =
   589       : List[Properties.T] = uncompress_properties(read_bytes(db, table, column))
   593       uncompress_properties(read_bytes(db, name, column))
   590 
   594 
   591 
   595 
   592     /* output */
   596     /* output */
   593 
   597 
   594     val browser_info: Path =
   598     val browser_info: Path =
   628 
   632 
   629     /* session info */
   633     /* session info */
   630 
   634 
   631     def write_session_info(
   635     def write_session_info(
   632       db: SQL.Database,
   636       db: SQL.Database,
   633       session_name: String,
   637       name: String,
   634       build_log: Build_Log.Session_Info,
   638       build_log: Build_Log.Session_Info,
   635       build: Build.Session_Info)
   639       build: Build.Session_Info)
   636     {
   640     {
   637       db.transaction {
   641       db.transaction {
   638         db.drop_table(Session_Info.table)
       
   639         db.create_table(Session_Info.table)
   642         db.create_table(Session_Info.table)
       
   643         using(Session_Info.delete_statement(db, name))(_.execute)
   640         using(db.insert_statement(Session_Info.table))(stmt =>
   644         using(db.insert_statement(Session_Info.table))(stmt =>
   641         {
   645         {
   642           db.set_string(stmt, 1, session_name)
   646           db.set_string(stmt, 1, name)
   643           db.set_bytes(stmt, 2, encode_properties(build_log.session_timing))
   647           db.set_bytes(stmt, 2, encode_properties(build_log.session_timing))
   644           db.set_bytes(stmt, 3, compress_properties(build_log.command_timings))
   648           db.set_bytes(stmt, 3, compress_properties(build_log.command_timings))
   645           db.set_bytes(stmt, 4, compress_properties(build_log.ml_statistics))
   649           db.set_bytes(stmt, 4, compress_properties(build_log.ml_statistics))
   646           db.set_bytes(stmt, 5, compress_properties(build_log.task_statistics))
   650           db.set_bytes(stmt, 5, compress_properties(build_log.task_statistics))
   647           db.set_string(stmt, 6, cat_lines(build.sources))
   651           db.set_string(stmt, 6, cat_lines(build.sources))
   651           stmt.execute()
   655           stmt.execute()
   652         })
   656         })
   653       }
   657       }
   654     }
   658     }
   655 
   659 
   656     def read_session_timing(db: SQL.Database): Properties.T =
   660     def read_session_timing(db: SQL.Database, name: String): Properties.T =
   657       decode_properties(read_bytes(db, Session_Info.table, Session_Info.session_timing))
   661       decode_properties(read_bytes(db, name, Session_Info.session_timing))
   658 
   662 
   659     def read_command_timings(db: SQL.Database): List[Properties.T] =
   663     def read_command_timings(db: SQL.Database, name: String): List[Properties.T] =
   660       read_properties(db, Session_Info.table, Session_Info.command_timings)
   664       read_properties(db, name, Session_Info.command_timings)
   661 
   665 
   662     def read_ml_statistics(db: SQL.Database): List[Properties.T] =
   666     def read_ml_statistics(db: SQL.Database, name: String): List[Properties.T] =
   663       read_properties(db, Session_Info.table, Session_Info.ml_statistics)
   667       read_properties(db, name, Session_Info.ml_statistics)
   664 
   668 
   665     def read_task_statistics(db: SQL.Database): List[Properties.T] =
   669     def read_task_statistics(db: SQL.Database, name: String): List[Properties.T] =
   666       read_properties(db, Session_Info.table, Session_Info.task_statistics)
   670       read_properties(db, name, Session_Info.task_statistics)
   667 
   671 
   668     def read_build_log(db: SQL.Database,
   672     def read_build_log(db: SQL.Database, name: String,
   669       command_timings: Boolean = false,
   673       command_timings: Boolean = false,
   670       ml_statistics: Boolean = false,
   674       ml_statistics: Boolean = false,
   671       task_statistics: Boolean = false): Build_Log.Session_Info =
   675       task_statistics: Boolean = false): Build_Log.Session_Info =
   672     {
   676     {
   673       Build_Log.Session_Info(
   677       Build_Log.Session_Info(
   674         session_timing = read_session_timing(db),
   678         session_timing = read_session_timing(db, name),
   675         command_timings = if (command_timings) read_command_timings(db) else Nil,
   679         command_timings = if (command_timings) read_command_timings(db, name) else Nil,
   676         ml_statistics = if (ml_statistics) read_ml_statistics(db) else Nil,
   680         ml_statistics = if (ml_statistics) read_ml_statistics(db, name) else Nil,
   677         task_statistics = if (task_statistics) read_task_statistics(db) else Nil)
   681         task_statistics = if (task_statistics) read_task_statistics(db, name) else Nil)
   678     }
   682     }
   679 
   683 
   680     def read_build(db: SQL.Database): Option[Build.Session_Info] =
   684     def read_build(db: SQL.Database, name: String): Option[Build.Session_Info] =
   681       using(db.select_statement(Session_Info.table, Session_Info.build_columns))(stmt =>
   685       using(Session_Info.select_statement(db, name, Session_Info.build_columns))(stmt =>
   682       {
   686       {
   683         val rs = stmt.executeQuery
   687         val rs = stmt.executeQuery
   684         if (!rs.next) None
   688         if (!rs.next) None
   685         else {
   689         else {
   686           Some(
   690           Some(