src/Pure/Thy/export.scala
author wenzelm
Sun, 07 Aug 2022 12:22:43 +0200
changeset 75786 ff6c1a82270f
parent 75784 d31193963e2d
child 75787 f9fcf06aa2eb
permissions -rw-r--r--
clarified modules;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
68092
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
     1
/*  Title:      Pure/Thy/export.scala
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
     2
    Author:     Makarius
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
     3
68102
813b5d0904c6 clarified signature;
wenzelm
parents: 68101
diff changeset
     4
Manage theory exports: compressed blobs.
68092
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
     5
*/
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
     6
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
     7
package isabelle
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
     8
68116
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
     9
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
    10
import scala.annotation.tailrec
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
    11
import scala.util.matching.Regex
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
    12
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
    13
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 74686
diff changeset
    14
object Export {
72691
2126cf946086 clarified signature;
wenzelm
parents: 72683
diff changeset
    15
  /* artefact names */
2126cf946086 clarified signature;
wenzelm
parents: 72683
diff changeset
    16
72844
240c8a0f6337 clarified exports;
wenzelm
parents: 72816
diff changeset
    17
  val DOCUMENT_ID = "PIDE/document_id"
240c8a0f6337 clarified exports;
wenzelm
parents: 72816
diff changeset
    18
  val FILES = "PIDE/files"
72702
79a19657c170 clarified names;
wenzelm
parents: 72691
diff changeset
    19
  val MARKUP = "PIDE/markup"
79a19657c170 clarified names;
wenzelm
parents: 72691
diff changeset
    20
  val MESSAGES = "PIDE/messages"
72691
2126cf946086 clarified signature;
wenzelm
parents: 72683
diff changeset
    21
  val DOCUMENT_PREFIX = "document/"
73785
b5fb99b985b4 clarified document export names;
wenzelm
parents: 73693
diff changeset
    22
  val DOCUMENT_LATEX = DOCUMENT_PREFIX + "latex"
b5fb99b985b4 clarified document export names;
wenzelm
parents: 73693
diff changeset
    23
  val DOCUMENT_CITATIONS = DOCUMENT_PREFIX + "citations"
72691
2126cf946086 clarified signature;
wenzelm
parents: 72683
diff changeset
    24
  val THEORY_PREFIX: String = "theory/"
2126cf946086 clarified signature;
wenzelm
parents: 72683
diff changeset
    25
  val PROOFS_PREFIX: String = "proofs/"
75769
4d27b520622a clarified database query: refer to semantic theories;
wenzelm
parents: 75767
diff changeset
    26
  val THEORY_PARENTS: String = THEORY_PREFIX + "parents"
69634
70f1994988d4 more operations;
wenzelm
parents: 69630
diff changeset
    27
69756
1907222d974e clarified modules;
wenzelm
parents: 69671
diff changeset
    28
  def explode_name(s: String): List[String] = space_explode('/', s)
1907222d974e clarified modules;
wenzelm
parents: 69671
diff changeset
    29
  def implode_name(elems: Iterable[String]): String = elems.mkString("/")
69634
70f1994988d4 more operations;
wenzelm
parents: 69630
diff changeset
    30
70f1994988d4 more operations;
wenzelm
parents: 69630
diff changeset
    31
68092
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
    32
  /* SQL data model */
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
    33
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 74686
diff changeset
    34
  object Data {
68092
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
    35
    val session_name = SQL.Column.string("session_name").make_primary_key
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
    36
    val theory_name = SQL.Column.string("theory_name").make_primary_key
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
    37
    val name = SQL.Column.string("name").make_primary_key
69788
c175499a7537 added executable flag for exports;
wenzelm
parents: 69756
diff changeset
    38
    val executable = SQL.Column.bool("executable")
68092
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
    39
    val compressed = SQL.Column.bool("compressed")
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
    40
    val body = SQL.Column.bytes("body")
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
    41
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
    42
    val table =
69788
c175499a7537 added executable flag for exports;
wenzelm
parents: 69756
diff changeset
    43
      SQL.Table("isabelle_exports",
c175499a7537 added executable flag for exports;
wenzelm
parents: 69756
diff changeset
    44
        List(session_name, theory_name, name, executable, compressed, body))
68092
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
    45
68116
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
    46
    def where_equal(session_name: String, theory_name: String = "", name: String = ""): SQL.Source =
68092
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
    47
      "WHERE " + Data.session_name.equal(session_name) +
68116
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
    48
        (if (theory_name == "") "" else " AND " + Data.theory_name.equal(theory_name)) +
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
    49
        (if (name == "") "" else " AND " + Data.name.equal(name))
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
    50
  }
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
    51
75674
c8e6078fee73 clarified signature;
wenzelm
parents: 75673
diff changeset
    52
  def compound_name(a: String, b: String): String =
c8e6078fee73 clarified signature;
wenzelm
parents: 75673
diff changeset
    53
    if (a.isEmpty) b else a + ":" + b
c8e6078fee73 clarified signature;
wenzelm
parents: 75673
diff changeset
    54
75672
88598f7c9614 clarified signature;
wenzelm
parents: 75671
diff changeset
    55
  sealed case class Entry_Name(session: String = "", theory: String = "", name: String = "") {
75674
c8e6078fee73 clarified signature;
wenzelm
parents: 75673
diff changeset
    56
    val compound_name: String = Export.compound_name(theory, name)
c8e6078fee73 clarified signature;
wenzelm
parents: 75673
diff changeset
    57
75680
605f4b6b5785 clarified signature;
wenzelm
parents: 75675
diff changeset
    58
    def make_path(prune: Int = 0): Path = {
75675
abd4db50ff1e clarified signature;
wenzelm
parents: 75674
diff changeset
    59
      val elems = theory :: space_explode('/', name)
abd4db50ff1e clarified signature;
wenzelm
parents: 75674
diff changeset
    60
      if (elems.length < prune + 1) {
abd4db50ff1e clarified signature;
wenzelm
parents: 75674
diff changeset
    61
        error("Cannot prune path by " + prune + " element(s): " + Path.make(elems))
abd4db50ff1e clarified signature;
wenzelm
parents: 75674
diff changeset
    62
      }
75680
605f4b6b5785 clarified signature;
wenzelm
parents: 75675
diff changeset
    63
      else Path.make(elems.drop(prune))
75675
abd4db50ff1e clarified signature;
wenzelm
parents: 75674
diff changeset
    64
    }
abd4db50ff1e clarified signature;
wenzelm
parents: 75674
diff changeset
    65
75671
ca8ae1ffd2b8 tuned signature: more explicit types;
wenzelm
parents: 75658
diff changeset
    66
    def readable(db: SQL.Database): Boolean = {
ca8ae1ffd2b8 tuned signature: more explicit types;
wenzelm
parents: 75658
diff changeset
    67
      val select = Data.table.select(List(Data.name), Data.where_equal(session, theory, name))
ca8ae1ffd2b8 tuned signature: more explicit types;
wenzelm
parents: 75658
diff changeset
    68
      db.using_statement(select)(stmt => stmt.execute_query().next())
ca8ae1ffd2b8 tuned signature: more explicit types;
wenzelm
parents: 75658
diff changeset
    69
    }
ca8ae1ffd2b8 tuned signature: more explicit types;
wenzelm
parents: 75658
diff changeset
    70
ca8ae1ffd2b8 tuned signature: more explicit types;
wenzelm
parents: 75658
diff changeset
    71
    def read(db: SQL.Database, cache: XML.Cache): Option[Entry] = {
ca8ae1ffd2b8 tuned signature: more explicit types;
wenzelm
parents: 75658
diff changeset
    72
      val select =
ca8ae1ffd2b8 tuned signature: more explicit types;
wenzelm
parents: 75658
diff changeset
    73
        Data.table.select(List(Data.executable, Data.compressed, Data.body),
ca8ae1ffd2b8 tuned signature: more explicit types;
wenzelm
parents: 75658
diff changeset
    74
          Data.where_equal(session, theory, name))
ca8ae1ffd2b8 tuned signature: more explicit types;
wenzelm
parents: 75658
diff changeset
    75
      db.using_statement(select) { stmt =>
ca8ae1ffd2b8 tuned signature: more explicit types;
wenzelm
parents: 75658
diff changeset
    76
        val res = stmt.execute_query()
ca8ae1ffd2b8 tuned signature: more explicit types;
wenzelm
parents: 75658
diff changeset
    77
        if (res.next()) {
ca8ae1ffd2b8 tuned signature: more explicit types;
wenzelm
parents: 75658
diff changeset
    78
          val executable = res.bool(Data.executable)
ca8ae1ffd2b8 tuned signature: more explicit types;
wenzelm
parents: 75658
diff changeset
    79
          val compressed = res.bool(Data.compressed)
ca8ae1ffd2b8 tuned signature: more explicit types;
wenzelm
parents: 75658
diff changeset
    80
          val bytes = res.bytes(Data.body)
ca8ae1ffd2b8 tuned signature: more explicit types;
wenzelm
parents: 75658
diff changeset
    81
          val body = Future.value(compressed, bytes)
ca8ae1ffd2b8 tuned signature: more explicit types;
wenzelm
parents: 75658
diff changeset
    82
          Some(Entry(this, executable, body, cache))
ca8ae1ffd2b8 tuned signature: more explicit types;
wenzelm
parents: 75658
diff changeset
    83
        }
ca8ae1ffd2b8 tuned signature: more explicit types;
wenzelm
parents: 75658
diff changeset
    84
        else None
ca8ae1ffd2b8 tuned signature: more explicit types;
wenzelm
parents: 75658
diff changeset
    85
      }
ca8ae1ffd2b8 tuned signature: more explicit types;
wenzelm
parents: 75658
diff changeset
    86
    }
68092
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
    87
  }
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
    88
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 74686
diff changeset
    89
  def read_theory_names(db: SQL.Database, session_name: String): List[String] = {
68222
3c1a716e7f59 tuned queries;
wenzelm
parents: 68221
diff changeset
    90
    val select =
75769
4d27b520622a clarified database query: refer to semantic theories;
wenzelm
parents: 75767
diff changeset
    91
      Data.table.select(List(Data.theory_name),
4d27b520622a clarified database query: refer to semantic theories;
wenzelm
parents: 75767
diff changeset
    92
        Data.where_equal(session_name, name = THEORY_PARENTS)) +
75767
87f9748b214a clarified signature: persistent theory_names in lexical order;
wenzelm
parents: 75766
diff changeset
    93
      " ORDER BY " + Data.theory_name
68222
3c1a716e7f59 tuned queries;
wenzelm
parents: 68221
diff changeset
    94
    db.using_statement(select)(stmt =>
3c1a716e7f59 tuned queries;
wenzelm
parents: 68221
diff changeset
    95
      stmt.execute_query().iterator(_.string(Data.theory_name)).toList)
3c1a716e7f59 tuned queries;
wenzelm
parents: 68221
diff changeset
    96
  }
3c1a716e7f59 tuned queries;
wenzelm
parents: 68221
diff changeset
    97
75674
c8e6078fee73 clarified signature;
wenzelm
parents: 75673
diff changeset
    98
  def read_entry_names(db: SQL.Database, session_name: String): List[Entry_Name] = {
75658
5905c7f484b3 clarified signature: read_theory_exports is already ordered;
wenzelm
parents: 75394
diff changeset
    99
    val select =
5905c7f484b3 clarified signature: read_theory_exports is already ordered;
wenzelm
parents: 75394
diff changeset
   100
      Data.table.select(List(Data.theory_name, Data.name), Data.where_equal(session_name)) +
5905c7f484b3 clarified signature: read_theory_exports is already ordered;
wenzelm
parents: 75394
diff changeset
   101
      " ORDER BY " + Data.theory_name + ", " + Data.name
68116
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   102
    db.using_statement(select)(stmt =>
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   103
      stmt.execute_query().iterator(res =>
75674
c8e6078fee73 clarified signature;
wenzelm
parents: 75673
diff changeset
   104
        Entry_Name(session = session_name,
c8e6078fee73 clarified signature;
wenzelm
parents: 75673
diff changeset
   105
          theory = res.string(Data.theory_name),
c8e6078fee73 clarified signature;
wenzelm
parents: 75673
diff changeset
   106
          name = res.string(Data.name))).toList)
68115
23c6ae3dd3a0 more efficient query;
wenzelm
parents: 68104
diff changeset
   107
  }
23c6ae3dd3a0 more efficient query;
wenzelm
parents: 68104
diff changeset
   108
68104
wenzelm
parents: 68103
diff changeset
   109
  def message(msg: String, theory_name: String, name: String): String =
wenzelm
parents: 68103
diff changeset
   110
    msg + " " + quote(name) + " for theory " + quote(theory_name)
wenzelm
parents: 68103
diff changeset
   111
72854
6c660f05f70c clarified signature;
wenzelm
parents: 72847
diff changeset
   112
  def empty_entry(theory_name: String, name: String): Entry =
75672
88598f7c9614 clarified signature;
wenzelm
parents: 75671
diff changeset
   113
    Entry(Entry_Name(theory = theory_name, name = name),
88598f7c9614 clarified signature;
wenzelm
parents: 75671
diff changeset
   114
      false, Future.value(false, Bytes.empty), XML.Cache.none)
72634
5cea0993ee4f clarified access to single database server vs. collection of database files;
wenzelm
parents: 72375
diff changeset
   115
68092
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
   116
  sealed case class Entry(
75671
ca8ae1ffd2b8 tuned signature: more explicit types;
wenzelm
parents: 75658
diff changeset
   117
    entry_name: Entry_Name,
69788
c175499a7537 added executable flag for exports;
wenzelm
parents: 69756
diff changeset
   118
    executable: Boolean,
72847
9dda93a753b1 clarified signature: provide XZ.Cache where Export.Entry is created;
wenzelm
parents: 72844
diff changeset
   119
    body: Future[(Boolean, Bytes)],
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 74686
diff changeset
   120
    cache: XML.Cache
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 74686
diff changeset
   121
  ) {
75671
ca8ae1ffd2b8 tuned signature: more explicit types;
wenzelm
parents: 75658
diff changeset
   122
    def session_name: String = entry_name.session
ca8ae1ffd2b8 tuned signature: more explicit types;
wenzelm
parents: 75658
diff changeset
   123
    def theory_name: String = entry_name.theory
ca8ae1ffd2b8 tuned signature: more explicit types;
wenzelm
parents: 75658
diff changeset
   124
    def name: String = entry_name.name
69635
95dc926fa39c clarified output (again);
wenzelm
parents: 69634
diff changeset
   125
    override def toString: String = name
69630
aaa0b5f571e8 clarified output;
wenzelm
parents: 69629
diff changeset
   126
75674
c8e6078fee73 clarified signature;
wenzelm
parents: 75673
diff changeset
   127
    def compound_name: String = entry_name.compound_name
71141
b1c555d3cd71 tuned signature -- more operations;
wenzelm
parents: 71014
diff changeset
   128
72691
2126cf946086 clarified signature;
wenzelm
parents: 72683
diff changeset
   129
    def name_has_prefix(s: String): Boolean = name.startsWith(s)
69634
70f1994988d4 more operations;
wenzelm
parents: 69630
diff changeset
   130
    val name_elems: List[String] = explode_name(name)
70f1994988d4 more operations;
wenzelm
parents: 69630
diff changeset
   131
70f1994988d4 more operations;
wenzelm
parents: 69630
diff changeset
   132
    def name_extends(elems: List[String]): Boolean =
70f1994988d4 more operations;
wenzelm
parents: 69630
diff changeset
   133
      name_elems.startsWith(elems) && name_elems != elems
70f1994988d4 more operations;
wenzelm
parents: 69630
diff changeset
   134
72847
9dda93a753b1 clarified signature: provide XZ.Cache where Export.Entry is created;
wenzelm
parents: 72844
diff changeset
   135
    def text: String = uncompressed.text
68092
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
   136
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 74686
diff changeset
   137
    def uncompressed: Bytes = {
69629
wenzelm
parents: 68924
diff changeset
   138
      val (compressed, bytes) = body.join
73031
f93f0597f4fb clarified signature: absorb XZ.Cache into XML.Cache;
wenzelm
parents: 73024
diff changeset
   139
      if (compressed) bytes.uncompress(cache = cache.xz) else bytes
69629
wenzelm
parents: 68924
diff changeset
   140
    }
wenzelm
parents: 68924
diff changeset
   141
72847
9dda93a753b1 clarified signature: provide XZ.Cache where Export.Entry is created;
wenzelm
parents: 72844
diff changeset
   142
    def uncompressed_yxml: XML.Body =
73033
d2690444c00a clarified caching;
wenzelm
parents: 73031
diff changeset
   143
      YXML.parse_body(UTF8.decode_permissive(uncompressed), cache = cache)
69629
wenzelm
parents: 68924
diff changeset
   144
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 74686
diff changeset
   145
    def write(db: SQL.Database): Unit = {
68167
327bb0f5f768 clarified implicit compression;
wenzelm
parents: 68166
diff changeset
   146
      val (compressed, bytes) = body.join
75394
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   147
      db.using_statement(Data.table.insert()) { stmt =>
68092
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
   148
        stmt.string(1) = session_name
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
   149
        stmt.string(2) = theory_name
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
   150
        stmt.string(3) = name
69788
c175499a7537 added executable flag for exports;
wenzelm
parents: 69756
diff changeset
   151
        stmt.bool(4) = executable
c175499a7537 added executable flag for exports;
wenzelm
parents: 69756
diff changeset
   152
        stmt.bool(5) = compressed
c175499a7537 added executable flag for exports;
wenzelm
parents: 69756
diff changeset
   153
        stmt.bytes(6) = bytes
68092
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
   154
        stmt.execute()
75394
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   155
      }
68092
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
   156
    }
68116
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   157
  }
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   158
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 74686
diff changeset
   159
  def make_regex(pattern: String): Regex = {
68116
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   160
    @tailrec def make(result: List[String], depth: Int, chs: List[Char]): Regex =
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   161
      chs match {
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   162
        case '*' :: '*' :: rest => make("[^:]*" :: result, depth, rest)
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   163
        case '*' :: rest => make("[^:/]*" :: result, depth, rest)
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   164
        case '?' :: rest => make("[^:/]" :: result, depth, rest)
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   165
        case '\\' :: c :: rest => make(("\\" + c) :: result, depth, rest)
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   166
        case '{' :: rest => make("(" :: result, depth + 1, rest)
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   167
        case ',' :: rest if depth > 0 => make("|" :: result, depth, rest)
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   168
        case '}' :: rest if depth > 0 => make(")" :: result, depth - 1, rest)
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   169
        case c :: rest if ".+()".contains(c) => make(("\\" + c) :: result, depth, rest)
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   170
        case c :: rest => make(c.toString :: result, depth, rest)
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   171
        case Nil => result.reverse.mkString.r
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   172
      }
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   173
    make(Nil, 0, pattern.toList)
68092
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
   174
  }
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
   175
75674
c8e6078fee73 clarified signature;
wenzelm
parents: 75673
diff changeset
   176
  def make_matcher(pats: List[String]): Entry_Name => Boolean = {
75658
5905c7f484b3 clarified signature: read_theory_exports is already ordered;
wenzelm
parents: 75394
diff changeset
   177
    val regs = pats.map(make_regex)
75674
c8e6078fee73 clarified signature;
wenzelm
parents: 75673
diff changeset
   178
    (entry_name: Entry_Name) =>
c8e6078fee73 clarified signature;
wenzelm
parents: 75673
diff changeset
   179
      regs.exists(_.pattern.matcher(entry_name.compound_name).matches)
68151
wenzelm
parents: 68116
diff changeset
   180
  }
wenzelm
parents: 68116
diff changeset
   181
72847
9dda93a753b1 clarified signature: provide XZ.Cache where Export.Entry is created;
wenzelm
parents: 72844
diff changeset
   182
  def make_entry(
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 74686
diff changeset
   183
    session_name: String,
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 74686
diff changeset
   184
    args: Protocol.Export.Args,
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 74686
diff changeset
   185
    bytes: Bytes,
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 74686
diff changeset
   186
    cache: XML.Cache
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 74686
diff changeset
   187
  ): Entry = {
72847
9dda93a753b1 clarified signature: provide XZ.Cache where Export.Entry is created;
wenzelm
parents: 72844
diff changeset
   188
    val body =
73031
f93f0597f4fb clarified signature: absorb XZ.Cache into XML.Cache;
wenzelm
parents: 73024
diff changeset
   189
      if (args.compress) Future.fork(bytes.maybe_compress(cache = cache.xz))
72847
9dda93a753b1 clarified signature: provide XZ.Cache where Export.Entry is created;
wenzelm
parents: 72844
diff changeset
   190
      else Future.value((false, bytes))
75672
88598f7c9614 clarified signature;
wenzelm
parents: 75671
diff changeset
   191
    val entry_name = Entry_Name(session = session_name, theory = args.theory_name, name = args.name)
75671
ca8ae1ffd2b8 tuned signature: more explicit types;
wenzelm
parents: 75658
diff changeset
   192
    Entry(entry_name, args.executable, body, cache)
68831
a6c69599ab99 Export.Provider for "isabelle dump" output_dir;
wenzelm
parents: 68418
diff changeset
   193
  }
a6c69599ab99 Export.Provider for "isabelle dump" output_dir;
wenzelm
parents: 68418
diff changeset
   194
68092
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
   195
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
   196
  /* database consumer thread */
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
   197
74255
e117e0c29204 more reactive interrupt;
wenzelm
parents: 74215
diff changeset
   198
  def consumer(db: SQL.Database, cache: XML.Cache, progress: Progress = new Progress): Consumer =
e117e0c29204 more reactive interrupt;
wenzelm
parents: 74215
diff changeset
   199
    new Consumer(db, cache, progress)
68092
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
   200
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 74686
diff changeset
   201
  class Consumer private[Export](db: SQL.Database, cache: XML.Cache, progress: Progress) {
68924
wenzelm
parents: 68832
diff changeset
   202
    private val errors = Synchronized[List[String]](Nil)
68092
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
   203
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
   204
    private val consumer =
71145
2f782d5f5d5a improved performance of session exports via bulk transactions;
wenzelm
parents: 71141
diff changeset
   205
      Consumer_Thread.fork_bulk[(Entry, Boolean)](name = "export")(
2f782d5f5d5a improved performance of session exports via bulk transactions;
wenzelm
parents: 71141
diff changeset
   206
        bulk = { case (entry, _) => entry.body.is_finished },
2f782d5f5d5a improved performance of session exports via bulk transactions;
wenzelm
parents: 71141
diff changeset
   207
        consume =
75394
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   208
          { (args: List[(Entry, Boolean)]) =>
71145
2f782d5f5d5a improved performance of session exports via bulk transactions;
wenzelm
parents: 71141
diff changeset
   209
            val results =
2f782d5f5d5a improved performance of session exports via bulk transactions;
wenzelm
parents: 71141
diff changeset
   210
              db.transaction {
74256
0ba3952f409a more robust: retain length of results;
wenzelm
parents: 74255
diff changeset
   211
                for ((entry, strict) <- args)
71145
2f782d5f5d5a improved performance of session exports via bulk transactions;
wenzelm
parents: 71141
diff changeset
   212
                yield {
74257
bda7a7b3bd41 more reactive interrupt;
wenzelm
parents: 74256
diff changeset
   213
                  if (progress.stopped) {
bda7a7b3bd41 more reactive interrupt;
wenzelm
parents: 74256
diff changeset
   214
                    entry.body.cancel()
bda7a7b3bd41 more reactive interrupt;
wenzelm
parents: 74256
diff changeset
   215
                    Exn.Res(())
bda7a7b3bd41 more reactive interrupt;
wenzelm
parents: 74256
diff changeset
   216
                  }
75671
ca8ae1ffd2b8 tuned signature: more explicit types;
wenzelm
parents: 75658
diff changeset
   217
                  else if (entry.entry_name.readable(db)) {
71145
2f782d5f5d5a improved performance of session exports via bulk transactions;
wenzelm
parents: 71141
diff changeset
   218
                    if (strict) {
2f782d5f5d5a improved performance of session exports via bulk transactions;
wenzelm
parents: 71141
diff changeset
   219
                      val msg = message("Duplicate export", entry.theory_name, entry.name)
2f782d5f5d5a improved performance of session exports via bulk transactions;
wenzelm
parents: 71141
diff changeset
   220
                      errors.change(msg :: _)
2f782d5f5d5a improved performance of session exports via bulk transactions;
wenzelm
parents: 71141
diff changeset
   221
                    }
2f782d5f5d5a improved performance of session exports via bulk transactions;
wenzelm
parents: 71141
diff changeset
   222
                    Exn.Res(())
2f782d5f5d5a improved performance of session exports via bulk transactions;
wenzelm
parents: 71141
diff changeset
   223
                  }
2f782d5f5d5a improved performance of session exports via bulk transactions;
wenzelm
parents: 71141
diff changeset
   224
                  else Exn.capture { entry.write(db) }
2f782d5f5d5a improved performance of session exports via bulk transactions;
wenzelm
parents: 71141
diff changeset
   225
                }
70499
f389019024ce allow duplicate exports via strict = false;
wenzelm
parents: 69854
diff changeset
   226
              }
71145
2f782d5f5d5a improved performance of session exports via bulk transactions;
wenzelm
parents: 71141
diff changeset
   227
            (results, true)
2f782d5f5d5a improved performance of session exports via bulk transactions;
wenzelm
parents: 71141
diff changeset
   228
          })
68092
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
   229
75762
985c3a64748c clarified signature: more uniform treatment of empty exports;
wenzelm
parents: 75759
diff changeset
   230
    def make_entry(session_name: String, args: Protocol.Export.Args, body: Bytes): Unit = {
985c3a64748c clarified signature: more uniform treatment of empty exports;
wenzelm
parents: 75759
diff changeset
   231
      if (!progress.stopped && !body.is_empty) {
985c3a64748c clarified signature: more uniform treatment of empty exports;
wenzelm
parents: 75759
diff changeset
   232
        consumer.send(Export.make_entry(session_name, args, body, cache) -> args.strict)
74257
bda7a7b3bd41 more reactive interrupt;
wenzelm
parents: 74256
diff changeset
   233
      }
bda7a7b3bd41 more reactive interrupt;
wenzelm
parents: 74256
diff changeset
   234
    }
68092
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
   235
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 74686
diff changeset
   236
    def shutdown(close: Boolean = false): List[String] = {
68092
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
   237
      consumer.shutdown()
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
   238
      if (close) db.close()
74255
e117e0c29204 more reactive interrupt;
wenzelm
parents: 74215
diff changeset
   239
      errors.value.reverse ::: (if (progress.stopped) List("Export stopped") else Nil)
68092
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
   240
    }
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
   241
  }
68116
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   242
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   243
75786
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   244
  /* context for database access */
75772
9dbcc4c66e1c tuned signature: more operations;
wenzelm
parents: 75771
diff changeset
   245
75764
07e097f60b85 clarified signature: more robust close operation;
wenzelm
parents: 75762
diff changeset
   246
  class Session_Database private[Export](val session: String, val db: SQL.Database) {
07e097f60b85 clarified signature: more robust close operation;
wenzelm
parents: 75762
diff changeset
   247
    def close(): Unit = ()
75767
87f9748b214a clarified signature: persistent theory_names in lexical order;
wenzelm
parents: 75766
diff changeset
   248
87f9748b214a clarified signature: persistent theory_names in lexical order;
wenzelm
parents: 75766
diff changeset
   249
    lazy val theory_names: List[String] = read_theory_names(db, session)
75770
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   250
    lazy val entry_names: List[Entry_Name] = read_entry_names(db, session)
75764
07e097f60b85 clarified signature: more robust close operation;
wenzelm
parents: 75762
diff changeset
   251
  }
07e097f60b85 clarified signature: more robust close operation;
wenzelm
parents: 75762
diff changeset
   252
75786
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   253
  def open_database_context(store: Sessions.Store): Database_Context = {
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   254
    val database_server = if (store.database_server) Some(store.open_database_server()) else None
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   255
    new Database_Context(store, database_server)
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   256
  }
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   257
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   258
  def open_session_context0(store: Sessions.Store, session: String): Session_Context =
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   259
    open_database_context(store).open_session0(session, close_database_context = true)
75772
9dbcc4c66e1c tuned signature: more operations;
wenzelm
parents: 75771
diff changeset
   260
75786
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   261
  def open_session_context(
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   262
    store: Sessions.Store,
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   263
    session_base_info: Sessions.Base_Info,
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   264
    document_snapshot: Option[Document.Snapshot] = None
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   265
  ): Session_Context = {
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   266
    open_database_context(store).open_session(
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   267
      session_base_info, document_snapshot = document_snapshot, close_database_context = true)
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   268
  }
75771
26b71e1dd262 misc tuning and clarification;
wenzelm
parents: 75770
diff changeset
   269
75786
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   270
  class Database_Context private[Export](
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   271
    val store: Sessions.Store,
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   272
    val database_server: Option[SQL.Database]
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   273
  ) extends AutoCloseable {
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   274
    database_context =>
75782
dba571dd0ba9 clarified signature: prefer Export.Session_Context over Sessions.Database_Context;
wenzelm
parents: 75780
diff changeset
   275
75786
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   276
    override def toString: String = {
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   277
      val s =
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   278
        database_server match {
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   279
          case Some(db) => db.toString
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   280
          case None => "input_dirs = " + store.input_dirs.map(_.absolute).mkString(", ")
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   281
        }
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   282
      "Database_Context(" + s + ")"
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   283
    }
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   284
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   285
    def cache: Term.Cache = store.cache
75759
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   286
75786
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   287
    def close(): Unit = database_server.foreach(_.close())
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   288
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   289
    def database_output[A](session: String)(f: SQL.Database => A): A =
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   290
      database_server match {
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   291
        case Some(db) => f(db)
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   292
        case None => using(store.open_database(session, output = true))(f)
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   293
      }
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   294
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   295
    def open_session0(session: String, close_database_context: Boolean = false): Session_Context =
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   296
      open_session(Sessions.base_info0(session), close_database_context = close_database_context)
75779
5470c67bd772 clarified signature: prefer Export.Session_Context;
wenzelm
parents: 75778
diff changeset
   297
75759
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   298
    def open_session(
75773
11b2bf6f90d8 clarified signature: less redundant -- Sessions.Base_Info already specifies the main session;
wenzelm
parents: 75772
diff changeset
   299
      session_base_info: Sessions.Base_Info,
75772
9dbcc4c66e1c tuned signature: more operations;
wenzelm
parents: 75771
diff changeset
   300
      document_snapshot: Option[Document.Snapshot] = None,
75786
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   301
      close_database_context: Boolean = false
75759
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   302
    ): Session_Context = {
75778
d18c96b9b955 prefer Export.Context/Session_Context/Theory_Context over Sessions.Database_Context;
wenzelm
parents: 75775
diff changeset
   303
      val session_name = session_base_info.check.base.session_name
d18c96b9b955 prefer Export.Context/Session_Context/Theory_Context over Sessions.Database_Context;
wenzelm
parents: 75775
diff changeset
   304
      val session_hierarchy = session_base_info.sessions_structure.build_hierarchy(session_name)
75773
11b2bf6f90d8 clarified signature: less redundant -- Sessions.Base_Info already specifies the main session;
wenzelm
parents: 75772
diff changeset
   305
      val session_databases =
75786
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   306
        database_server match {
75771
26b71e1dd262 misc tuning and clarification;
wenzelm
parents: 75770
diff changeset
   307
          case Some(db) => session_hierarchy.map(name => new Session_Database(name, db))
26b71e1dd262 misc tuning and clarification;
wenzelm
parents: 75770
diff changeset
   308
          case None =>
75775
70a65ee4a738 clarified signature: more robust treatment of server;
wenzelm
parents: 75774
diff changeset
   309
            val attempts =
70a65ee4a738 clarified signature: more robust treatment of server;
wenzelm
parents: 75774
diff changeset
   310
              session_hierarchy.map(name => name -> store.try_open_database(name, server = false))
75771
26b71e1dd262 misc tuning and clarification;
wenzelm
parents: 75770
diff changeset
   311
            attempts.collectFirst({ case (name, None) => name }) match {
26b71e1dd262 misc tuning and clarification;
wenzelm
parents: 75770
diff changeset
   312
              case Some(bad) =>
26b71e1dd262 misc tuning and clarification;
wenzelm
parents: 75770
diff changeset
   313
                for ((_, Some(db)) <- attempts) db.close()
26b71e1dd262 misc tuning and clarification;
wenzelm
parents: 75770
diff changeset
   314
                store.bad_database(bad)
75764
07e097f60b85 clarified signature: more robust close operation;
wenzelm
parents: 75762
diff changeset
   315
              case None =>
75771
26b71e1dd262 misc tuning and clarification;
wenzelm
parents: 75770
diff changeset
   316
                for ((name, Some(db)) <- attempts) yield {
75764
07e097f60b85 clarified signature: more robust close operation;
wenzelm
parents: 75762
diff changeset
   317
                  new Session_Database(name, db) { override def close(): Unit = this.db.close() }
07e097f60b85 clarified signature: more robust close operation;
wenzelm
parents: 75762
diff changeset
   318
                }
07e097f60b85 clarified signature: more robust close operation;
wenzelm
parents: 75762
diff changeset
   319
            }
75771
26b71e1dd262 misc tuning and clarification;
wenzelm
parents: 75770
diff changeset
   320
        }
75786
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   321
      new Session_Context(database_context, session_base_info, session_databases, document_snapshot) {
75772
9dbcc4c66e1c tuned signature: more operations;
wenzelm
parents: 75771
diff changeset
   322
        override def close(): Unit = {
9dbcc4c66e1c tuned signature: more operations;
wenzelm
parents: 75771
diff changeset
   323
          session_databases.foreach(_.close())
75786
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   324
          if (close_database_context) database_context.close()
75772
9dbcc4c66e1c tuned signature: more operations;
wenzelm
parents: 75771
diff changeset
   325
        }
75759
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   326
      }
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   327
    }
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   328
  }
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   329
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   330
  class Session_Context private[Export](
75786
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   331
    val database_context: Database_Context,
75778
d18c96b9b955 prefer Export.Context/Session_Context/Theory_Context over Sessions.Database_Context;
wenzelm
parents: 75775
diff changeset
   332
    session_base_info: Sessions.Base_Info,
75770
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   333
    db_hierarchy: List[Session_Database],
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   334
    document_snapshot: Option[Document.Snapshot]
75759
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   335
  ) extends AutoCloseable {
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   336
    session_context =>
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   337
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   338
    def close(): Unit = ()
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   339
75786
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   340
    def cache: Term.Cache = database_context.cache
75778
d18c96b9b955 prefer Export.Context/Session_Context/Theory_Context over Sessions.Database_Context;
wenzelm
parents: 75775
diff changeset
   341
d18c96b9b955 prefer Export.Context/Session_Context/Theory_Context over Sessions.Database_Context;
wenzelm
parents: 75775
diff changeset
   342
    def sessions_structure: Sessions.Structure = session_base_info.sessions_structure
d18c96b9b955 prefer Export.Context/Session_Context/Theory_Context over Sessions.Database_Context;
wenzelm
parents: 75775
diff changeset
   343
d18c96b9b955 prefer Export.Context/Session_Context/Theory_Context over Sessions.Database_Context;
wenzelm
parents: 75775
diff changeset
   344
    def session_base: Sessions.Base = session_base_info.base
d18c96b9b955 prefer Export.Context/Session_Context/Theory_Context over Sessions.Database_Context;
wenzelm
parents: 75775
diff changeset
   345
75770
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   346
    def session_name: String =
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   347
      if (document_snapshot.isDefined) Sessions.DRAFT
75773
11b2bf6f90d8 clarified signature: less redundant -- Sessions.Base_Info already specifies the main session;
wenzelm
parents: 75772
diff changeset
   348
      else session_base.session_name
75770
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   349
75780
f49c4f160b84 clarified signature: find session_database within Session_Context.db_hierarchy;
wenzelm
parents: 75779
diff changeset
   350
    def session_database(session: String = session_name): Option[Session_Database] =
f49c4f160b84 clarified signature: find session_database within Session_Context.db_hierarchy;
wenzelm
parents: 75779
diff changeset
   351
      db_hierarchy.find(_.session == session)
f49c4f160b84 clarified signature: find session_database within Session_Context.db_hierarchy;
wenzelm
parents: 75779
diff changeset
   352
f49c4f160b84 clarified signature: find session_database within Session_Context.db_hierarchy;
wenzelm
parents: 75779
diff changeset
   353
    def session_db(session: String = session_name): Option[SQL.Database] =
f49c4f160b84 clarified signature: find session_database within Session_Context.db_hierarchy;
wenzelm
parents: 75779
diff changeset
   354
      session_database(session = session).map(_.db)
f49c4f160b84 clarified signature: find session_database within Session_Context.db_hierarchy;
wenzelm
parents: 75779
diff changeset
   355
75770
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   356
    def session_stack: List[String] =
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   357
      ((if (document_snapshot.isDefined) List(session_name) else Nil) :::
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   358
        db_hierarchy.map(_.session)).reverse
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   359
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   360
    private def select[A](
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   361
      session: String,
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   362
      select1: Entry_Name => Option[A],
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   363
      select2: Session_Database => List[A]
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   364
    ): List[A] = {
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   365
      def sel(name: String): List[A] =
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   366
        if (name == Sessions.DRAFT) {
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   367
          (for {
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   368
            snapshot <- document_snapshot.iterator
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   369
            entry_name <- snapshot.all_exports.keysIterator
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   370
            res <- select1(entry_name).iterator
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   371
          } yield entry_name -> res).toList.sortBy(_._1.compound_name).map(_._2)
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   372
        }
75780
f49c4f160b84 clarified signature: find session_database within Session_Context.db_hierarchy;
wenzelm
parents: 75779
diff changeset
   373
        else { session_database(name).map(select2).getOrElse(Nil) }
75770
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   374
      if (session.nonEmpty) sel(session) else session_stack.flatMap(sel)
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   375
    }
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   376
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   377
    def entry_names(session: String = session_name): List[Entry_Name] =
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   378
      select(session, Some(_), _.entry_names)
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   379
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   380
    def theory_names(session: String = session_name): List[String] =
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   381
      select(session, a => if(a.name == THEORY_PARENTS) Some(a.theory) else None, _.theory_names)
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   382
75759
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   383
    def get(theory: String, name: String): Option[Entry] =
75770
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   384
    {
75784
wenzelm
parents: 75782
diff changeset
   385
      def snapshot_entry: Option[Entry] =
75770
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   386
        for {
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   387
          snapshot <- document_snapshot
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   388
          entry_name = Entry_Name(session = Sessions.DRAFT, theory = theory, name = name)
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   389
          entry <- snapshot.all_exports.get(entry_name)
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   390
        } yield entry
75784
wenzelm
parents: 75782
diff changeset
   391
      def db_entry: Option[Entry] =
wenzelm
parents: 75782
diff changeset
   392
        db_hierarchy.view.map(database =>
wenzelm
parents: 75782
diff changeset
   393
          Export.Entry_Name(session = database.session, theory = theory, name = name)
wenzelm
parents: 75782
diff changeset
   394
            .read(database.db, cache))
75764
07e097f60b85 clarified signature: more robust close operation;
wenzelm
parents: 75762
diff changeset
   395
          .collectFirst({ case Some(entry) => entry })
75759
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   396
75770
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   397
      snapshot_entry orElse db_entry
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   398
    }
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   399
75759
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   400
    def apply(theory: String, name: String, permissive: Boolean = false): Entry =
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   401
      get(theory, name) match {
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   402
        case None if permissive => empty_entry(theory, name)
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   403
        case None => error("Missing export entry " + quote(compound_name(theory, name)))
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   404
        case Some(entry) => entry
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   405
      }
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   406
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   407
    def theory(theory: String): Theory_Context =
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   408
      new Theory_Context(session_context, theory)
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   409
75782
dba571dd0ba9 clarified signature: prefer Export.Session_Context over Sessions.Database_Context;
wenzelm
parents: 75780
diff changeset
   410
    def classpath(): List[File.Content_Bytes] = {
dba571dd0ba9 clarified signature: prefer Export.Session_Context over Sessions.Database_Context;
wenzelm
parents: 75780
diff changeset
   411
      (for {
dba571dd0ba9 clarified signature: prefer Export.Session_Context over Sessions.Database_Context;
wenzelm
parents: 75780
diff changeset
   412
        session <- session_stack.iterator
dba571dd0ba9 clarified signature: prefer Export.Session_Context over Sessions.Database_Context;
wenzelm
parents: 75780
diff changeset
   413
        info <- sessions_structure.get(session).iterator
dba571dd0ba9 clarified signature: prefer Export.Session_Context over Sessions.Database_Context;
wenzelm
parents: 75780
diff changeset
   414
        if info.export_classpath.nonEmpty
dba571dd0ba9 clarified signature: prefer Export.Session_Context over Sessions.Database_Context;
wenzelm
parents: 75780
diff changeset
   415
        matcher = make_matcher(info.export_classpath)
dba571dd0ba9 clarified signature: prefer Export.Session_Context over Sessions.Database_Context;
wenzelm
parents: 75780
diff changeset
   416
        entry_name <- entry_names(session = session).iterator
dba571dd0ba9 clarified signature: prefer Export.Session_Context over Sessions.Database_Context;
wenzelm
parents: 75780
diff changeset
   417
        if matcher(entry_name)
dba571dd0ba9 clarified signature: prefer Export.Session_Context over Sessions.Database_Context;
wenzelm
parents: 75780
diff changeset
   418
        entry <- get(entry_name.theory, entry_name.name).iterator
dba571dd0ba9 clarified signature: prefer Export.Session_Context over Sessions.Database_Context;
wenzelm
parents: 75780
diff changeset
   419
      } yield File.Content(entry.entry_name.make_path(), entry.uncompressed)).toList
dba571dd0ba9 clarified signature: prefer Export.Session_Context over Sessions.Database_Context;
wenzelm
parents: 75780
diff changeset
   420
  }
dba571dd0ba9 clarified signature: prefer Export.Session_Context over Sessions.Database_Context;
wenzelm
parents: 75780
diff changeset
   421
dba571dd0ba9 clarified signature: prefer Export.Session_Context over Sessions.Database_Context;
wenzelm
parents: 75780
diff changeset
   422
  override def toString: String =
75770
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   423
      "Export.Session_Context(" + commas_quote(session_stack) + ")"
75759
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   424
  }
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   425
75774
efc25bf4b795 discontinued Export.Provider in favour of Export.Context and its derivatives;
wenzelm
parents: 75773
diff changeset
   426
  class Theory_Context private[Export](
efc25bf4b795 discontinued Export.Provider in favour of Export.Context and its derivatives;
wenzelm
parents: 75773
diff changeset
   427
    val session_context: Session_Context,
efc25bf4b795 discontinued Export.Provider in favour of Export.Context and its derivatives;
wenzelm
parents: 75773
diff changeset
   428
    val theory: String
efc25bf4b795 discontinued Export.Provider in favour of Export.Context and its derivatives;
wenzelm
parents: 75773
diff changeset
   429
  ) {
75778
d18c96b9b955 prefer Export.Context/Session_Context/Theory_Context over Sessions.Database_Context;
wenzelm
parents: 75775
diff changeset
   430
    def cache: Term.Cache = session_context.cache
d18c96b9b955 prefer Export.Context/Session_Context/Theory_Context over Sessions.Database_Context;
wenzelm
parents: 75775
diff changeset
   431
75759
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   432
    def get(name: String): Option[Entry] = session_context.get(theory, name)
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   433
    def apply(name: String, permissive: Boolean = false): Entry =
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   434
      session_context.apply(theory, name, permissive = permissive)
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   435
75774
efc25bf4b795 discontinued Export.Provider in favour of Export.Context and its derivatives;
wenzelm
parents: 75773
diff changeset
   436
    def uncompressed_yxml(name: String): XML.Body =
efc25bf4b795 discontinued Export.Provider in favour of Export.Context and its derivatives;
wenzelm
parents: 75773
diff changeset
   437
      get(name) match {
efc25bf4b795 discontinued Export.Provider in favour of Export.Context and its derivatives;
wenzelm
parents: 75773
diff changeset
   438
        case Some(entry) => entry.uncompressed_yxml
efc25bf4b795 discontinued Export.Provider in favour of Export.Context and its derivatives;
wenzelm
parents: 75773
diff changeset
   439
        case None => Nil
efc25bf4b795 discontinued Export.Provider in favour of Export.Context and its derivatives;
wenzelm
parents: 75773
diff changeset
   440
      }
efc25bf4b795 discontinued Export.Provider in favour of Export.Context and its derivatives;
wenzelm
parents: 75773
diff changeset
   441
75778
d18c96b9b955 prefer Export.Context/Session_Context/Theory_Context over Sessions.Database_Context;
wenzelm
parents: 75775
diff changeset
   442
    def document_id(): Option[Long] =
d18c96b9b955 prefer Export.Context/Session_Context/Theory_Context over Sessions.Database_Context;
wenzelm
parents: 75775
diff changeset
   443
      apply(DOCUMENT_ID, permissive = true).text match {
d18c96b9b955 prefer Export.Context/Session_Context/Theory_Context over Sessions.Database_Context;
wenzelm
parents: 75775
diff changeset
   444
        case Value.Long(id) => Some(id)
d18c96b9b955 prefer Export.Context/Session_Context/Theory_Context over Sessions.Database_Context;
wenzelm
parents: 75775
diff changeset
   445
        case _ => None
d18c96b9b955 prefer Export.Context/Session_Context/Theory_Context over Sessions.Database_Context;
wenzelm
parents: 75775
diff changeset
   446
      }
d18c96b9b955 prefer Export.Context/Session_Context/Theory_Context over Sessions.Database_Context;
wenzelm
parents: 75775
diff changeset
   447
d18c96b9b955 prefer Export.Context/Session_Context/Theory_Context over Sessions.Database_Context;
wenzelm
parents: 75775
diff changeset
   448
    def files(): Option[(String, List[String])] =
d18c96b9b955 prefer Export.Context/Session_Context/Theory_Context over Sessions.Database_Context;
wenzelm
parents: 75775
diff changeset
   449
      split_lines(apply(FILES, permissive = true).text) match {
d18c96b9b955 prefer Export.Context/Session_Context/Theory_Context over Sessions.Database_Context;
wenzelm
parents: 75775
diff changeset
   450
        case Nil => None
d18c96b9b955 prefer Export.Context/Session_Context/Theory_Context over Sessions.Database_Context;
wenzelm
parents: 75775
diff changeset
   451
        case thy_file :: blobs_files => Some((thy_file, blobs_files))
d18c96b9b955 prefer Export.Context/Session_Context/Theory_Context over Sessions.Database_Context;
wenzelm
parents: 75775
diff changeset
   452
      }
d18c96b9b955 prefer Export.Context/Session_Context/Theory_Context over Sessions.Database_Context;
wenzelm
parents: 75775
diff changeset
   453
75759
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   454
    override def toString: String = "Export.Theory_Context(" + quote(theory) + ")"
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   455
  }
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   456
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   457
68288
d20770229f99 tuned signature;
wenzelm
parents: 68222
diff changeset
   458
  /* export to file-system */
d20770229f99 tuned signature;
wenzelm
parents: 68222
diff changeset
   459
d20770229f99 tuned signature;
wenzelm
parents: 68222
diff changeset
   460
  def export_files(
d20770229f99 tuned signature;
wenzelm
parents: 68222
diff changeset
   461
    store: Sessions.Store,
d20770229f99 tuned signature;
wenzelm
parents: 68222
diff changeset
   462
    session_name: String,
d20770229f99 tuned signature;
wenzelm
parents: 68222
diff changeset
   463
    export_dir: Path,
71726
a5fda30edae2 clarified signature: more uniform treatment of stopped/interrupted state;
wenzelm
parents: 71624
diff changeset
   464
    progress: Progress = new Progress,
69671
2486792eaf61 support pruning of export names;
wenzelm
parents: 69635
diff changeset
   465
    export_prune: Int = 0,
68288
d20770229f99 tuned signature;
wenzelm
parents: 68222
diff changeset
   466
    export_list: Boolean = false,
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 74686
diff changeset
   467
    export_patterns: List[String] = Nil
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 74686
diff changeset
   468
  ): Unit = {
75394
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   469
    using(store.open_database(session_name)) { db =>
75739
5b37466c1463 removed somewhat pointless transaction: db is meant to be finished (or updated monotonically);
wenzelm
parents: 75736
diff changeset
   470
      val entry_names = read_entry_names(db, session_name)
68288
d20770229f99 tuned signature;
wenzelm
parents: 68222
diff changeset
   471
75739
5b37466c1463 removed somewhat pointless transaction: db is meant to be finished (or updated monotonically);
wenzelm
parents: 75736
diff changeset
   472
      // list
5b37466c1463 removed somewhat pointless transaction: db is meant to be finished (or updated monotonically);
wenzelm
parents: 75736
diff changeset
   473
      if (export_list) {
5b37466c1463 removed somewhat pointless transaction: db is meant to be finished (or updated monotonically);
wenzelm
parents: 75736
diff changeset
   474
        for (entry_name <- entry_names) progress.echo(entry_name.compound_name)
5b37466c1463 removed somewhat pointless transaction: db is meant to be finished (or updated monotonically);
wenzelm
parents: 75736
diff changeset
   475
      }
68288
d20770229f99 tuned signature;
wenzelm
parents: 68222
diff changeset
   476
75739
5b37466c1463 removed somewhat pointless transaction: db is meant to be finished (or updated monotonically);
wenzelm
parents: 75736
diff changeset
   477
      // export
5b37466c1463 removed somewhat pointless transaction: db is meant to be finished (or updated monotonically);
wenzelm
parents: 75736
diff changeset
   478
      if (export_patterns.nonEmpty) {
5b37466c1463 removed somewhat pointless transaction: db is meant to be finished (or updated monotonically);
wenzelm
parents: 75736
diff changeset
   479
        val matcher = make_matcher(export_patterns)
5b37466c1463 removed somewhat pointless transaction: db is meant to be finished (or updated monotonically);
wenzelm
parents: 75736
diff changeset
   480
        for {
5b37466c1463 removed somewhat pointless transaction: db is meant to be finished (or updated monotonically);
wenzelm
parents: 75736
diff changeset
   481
          entry_name <- entry_names if matcher(entry_name)
5b37466c1463 removed somewhat pointless transaction: db is meant to be finished (or updated monotonically);
wenzelm
parents: 75736
diff changeset
   482
          entry <- entry_name.read(db, store.cache)
5b37466c1463 removed somewhat pointless transaction: db is meant to be finished (or updated monotonically);
wenzelm
parents: 75736
diff changeset
   483
        } {
5b37466c1463 removed somewhat pointless transaction: db is meant to be finished (or updated monotonically);
wenzelm
parents: 75736
diff changeset
   484
          val path = export_dir + entry_name.make_path(prune = export_prune)
5b37466c1463 removed somewhat pointless transaction: db is meant to be finished (or updated monotonically);
wenzelm
parents: 75736
diff changeset
   485
          progress.echo("export " + path + (if (entry.executable) " (executable)" else ""))
5b37466c1463 removed somewhat pointless transaction: db is meant to be finished (or updated monotonically);
wenzelm
parents: 75736
diff changeset
   486
          Isabelle_System.make_directory(path.dir)
5b37466c1463 removed somewhat pointless transaction: db is meant to be finished (or updated monotonically);
wenzelm
parents: 75736
diff changeset
   487
          val bytes = entry.uncompressed
5b37466c1463 removed somewhat pointless transaction: db is meant to be finished (or updated monotonically);
wenzelm
parents: 75736
diff changeset
   488
          if (!path.is_file || Bytes.read(path) != bytes) Bytes.write(path, bytes)
5b37466c1463 removed somewhat pointless transaction: db is meant to be finished (or updated monotonically);
wenzelm
parents: 75736
diff changeset
   489
          File.set_executable(path, entry.executable)
68288
d20770229f99 tuned signature;
wenzelm
parents: 68222
diff changeset
   490
        }
d20770229f99 tuned signature;
wenzelm
parents: 68222
diff changeset
   491
      }
75394
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   492
    }
68288
d20770229f99 tuned signature;
wenzelm
parents: 68222
diff changeset
   493
  }
d20770229f99 tuned signature;
wenzelm
parents: 68222
diff changeset
   494
d20770229f99 tuned signature;
wenzelm
parents: 68222
diff changeset
   495
68116
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   496
  /* Isabelle tool wrapper */
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   497
71601
97ccf48c2f0c misc tuning based on hints by IntelliJ IDEA;
wenzelm
parents: 71145
diff changeset
   498
  val default_export_dir: Path = Path.explode("export")
68116
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   499
75394
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   500
  val isabelle_tool =
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   501
    Isabelle_Tool("export", "retrieve theory exports", Scala_Project.here,
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   502
      { args =>
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   503
        /* arguments */
68116
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   504
75394
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   505
        var export_dir = default_export_dir
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   506
        var dirs: List[Path] = Nil
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   507
        var export_list = false
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   508
        var no_build = false
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   509
        var options = Options.init()
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   510
        var export_prune = 0
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   511
        var export_patterns: List[String] = Nil
68116
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   512
75394
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   513
        val getopts = Getopts("""
68116
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   514
Usage: isabelle export [OPTIONS] SESSION
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   515
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   516
  Options are:
68314
2acbf8129d8b clarified option -O: avoid conflict with build/dump option -D;
wenzelm
parents: 68305
diff changeset
   517
    -O DIR       output directory for exported files (default: """ + default_export_dir + """)
68116
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   518
    -d DIR       include session directory
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   519
    -l           list exports
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   520
    -n           no build of session
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   521
    -o OPTION    override Isabelle system OPTION (via NAME=VAL or NAME)
69671
2486792eaf61 support pruning of export names;
wenzelm
parents: 69635
diff changeset
   522
    -p NUM       prune path of exported files by NUM elements
68116
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   523
    -x PATTERN   extract files matching pattern (e.g. "*:**" for all)
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   524
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   525
  List or export theory exports for SESSION: named blobs produced by
68290
f1f5ccc85b25 support multiple patterns;
wenzelm
parents: 68289
diff changeset
   526
  isabelle build. Option -l or -x is required; option -x may be repeated.
68116
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   527
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   528
  The PATTERN language resembles glob patterns in the shell, with ? and *
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   529
  (both excluding ":" and "/"), ** (excluding ":"), and [abc] or [^abc],
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   530
  and variants {pattern1,pattern2,pattern3}.
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   531
""",
75394
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   532
          "O:" -> (arg => export_dir = Path.explode(arg)),
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   533
          "d:" -> (arg => dirs = dirs ::: List(Path.explode(arg))),
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   534
          "l" -> (_ => export_list = true),
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   535
          "n" -> (_ => no_build = true),
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   536
          "o:" -> (arg => options = options + arg),
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   537
          "p:" -> (arg => export_prune = Value.Int.parse(arg)),
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   538
          "x:" -> (arg => export_patterns ::= arg))
68116
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   539
75394
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   540
        val more_args = getopts(args)
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   541
        val session_name =
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   542
          more_args match {
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   543
            case List(session_name) if export_list || export_patterns.nonEmpty => session_name
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   544
            case _ => getopts.usage()
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   545
          }
68116
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   546
75394
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   547
        val progress = new Console_Progress()
68305
5321218147d3 clarified signature;
wenzelm
parents: 68291
diff changeset
   548
68116
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   549
75394
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   550
        /* build */
68116
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   551
75394
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   552
        if (!no_build) {
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   553
          val rc =
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   554
            progress.interrupt_handler {
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   555
              Build.build_logic(options, session_name, progress = progress, dirs = dirs)
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   556
            }
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   557
          if (rc != Process_Result.RC.ok) sys.exit(rc)
68331
7eaaa8f48331 clarified outermost progress.interrupt_handler;
wenzelm
parents: 68314
diff changeset
   558
        }
68116
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   559
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   560
75394
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   561
        /* export files */
68116
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   562
75394
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   563
        val store = Sessions.store(options)
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   564
        export_files(store, session_name, export_dir, progress = progress, export_prune = export_prune,
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   565
          export_list = export_list, export_patterns = export_patterns)
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   566
      })
68092
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
   567
}