src/Pure/Build/export.scala
author wenzelm
Sat, 08 Jun 2024 23:17:20 +0200
changeset 80303 11fee9e6ba43
parent 79844 ac40138234ce
child 80350 96843eb96493
permissions -rw-r--r--
more robust: prefer synchronous compression (usually <= 1ms, sometimes 1..5ms);
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
79502
c7a98469c0e7 clarified directories;
wenzelm
parents: 78592
diff changeset
     1
/*  Title:      Pure/Build/export.scala
68092
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
79502
c7a98469c0e7 clarified directories;
wenzelm
parents: 78592
diff changeset
     4
Manage per-session 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
78541
d95497dcd9bc more scalable write_entries and Export.consumer via db.execute_batch_statement;
wenzelm
parents: 78531
diff changeset
    12
import scala.collection.mutable
68116
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
    13
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
    14
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 74686
diff changeset
    15
object Export {
72691
2126cf946086 clarified signature;
wenzelm
parents: 72683
diff changeset
    16
  /* artefact names */
2126cf946086 clarified signature;
wenzelm
parents: 72683
diff changeset
    17
78531
ec761aa6cc64 tuned signature;
wenzelm
parents: 78396
diff changeset
    18
  val DOCUMENT_ID: String = "PIDE/document_id"
ec761aa6cc64 tuned signature;
wenzelm
parents: 78396
diff changeset
    19
  val FILES: String = "PIDE/files"
ec761aa6cc64 tuned signature;
wenzelm
parents: 78396
diff changeset
    20
  val MARKUP: String = "PIDE/markup"
ec761aa6cc64 tuned signature;
wenzelm
parents: 78396
diff changeset
    21
  val MESSAGES: String = "PIDE/messages"
ec761aa6cc64 tuned signature;
wenzelm
parents: 78396
diff changeset
    22
  val DOCUMENT_PREFIX: String = "document/"
ec761aa6cc64 tuned signature;
wenzelm
parents: 78396
diff changeset
    23
  val DOCUMENT_LATEX: String = DOCUMENT_PREFIX + "latex"
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/"
69634
70f1994988d4 more operations;
wenzelm
parents: 69630
diff changeset
    26
69756
1907222d974e clarified modules;
wenzelm
parents: 69671
diff changeset
    27
  def explode_name(s: String): List[String] = space_explode('/', s)
1907222d974e clarified modules;
wenzelm
parents: 69671
diff changeset
    28
  def implode_name(elems: Iterable[String]): String = elems.mkString("/")
69634
70f1994988d4 more operations;
wenzelm
parents: 69630
diff changeset
    29
70f1994988d4 more operations;
wenzelm
parents: 69630
diff changeset
    30
68092
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
    31
  /* SQL data model */
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
    32
78396
7853d9072d1b renamed object Data to private_data, to emphasize its intended scope (but it is publicly accessible in the database);
wenzelm
parents: 78379
diff changeset
    33
  object private_data extends SQL.Data() {
79844
ac40138234ce tuned signature: more uniform SQL.Data instances;
wenzelm
parents: 79675
diff changeset
    34
    override lazy val tables: SQL.Tables = SQL.Tables(Base.table)
78210
2a92a60cc9d1 tuned signature;
wenzelm
parents: 78209
diff changeset
    35
78208
27fa23851cd1 tuned signature;
wenzelm
parents: 78206
diff changeset
    36
    object Base {
27fa23851cd1 tuned signature;
wenzelm
parents: 78206
diff changeset
    37
      val session_name = SQL.Column.string("session_name").make_primary_key
27fa23851cd1 tuned signature;
wenzelm
parents: 78206
diff changeset
    38
      val theory_name = SQL.Column.string("theory_name").make_primary_key
27fa23851cd1 tuned signature;
wenzelm
parents: 78206
diff changeset
    39
      val name = SQL.Column.string("name").make_primary_key
27fa23851cd1 tuned signature;
wenzelm
parents: 78206
diff changeset
    40
      val executable = SQL.Column.bool("executable")
27fa23851cd1 tuned signature;
wenzelm
parents: 78206
diff changeset
    41
      val compressed = SQL.Column.bool("compressed")
27fa23851cd1 tuned signature;
wenzelm
parents: 78206
diff changeset
    42
      val body = SQL.Column.bytes("body")
68092
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
    43
78208
27fa23851cd1 tuned signature;
wenzelm
parents: 78206
diff changeset
    44
      val table =
27fa23851cd1 tuned signature;
wenzelm
parents: 78206
diff changeset
    45
        SQL.Table("isabelle_exports",
27fa23851cd1 tuned signature;
wenzelm
parents: 78206
diff changeset
    46
          List(session_name, theory_name, name, executable, compressed, body))
27fa23851cd1 tuned signature;
wenzelm
parents: 78206
diff changeset
    47
    }
68092
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
    48
68116
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
    49
    def where_equal(session_name: String, theory_name: String = "", name: String = ""): SQL.Source =
78153
55a6aa77f3d8 tuned signature: more operations;
wenzelm
parents: 77681
diff changeset
    50
      SQL.where_and(
78208
27fa23851cd1 tuned signature;
wenzelm
parents: 78206
diff changeset
    51
        Base.session_name.equal(session_name),
27fa23851cd1 tuned signature;
wenzelm
parents: 78206
diff changeset
    52
        if_proper(theory_name, Base.theory_name.equal(theory_name)),
27fa23851cd1 tuned signature;
wenzelm
parents: 78206
diff changeset
    53
        if_proper(name, Base.name.equal(name)))
78209
50c5be88ad59 tuned signature;
wenzelm
parents: 78208
diff changeset
    54
78260
0a7f7abbe4f0 more robust transaction_lock: avoid overlapping data spaces;
wenzelm
parents: 78211
diff changeset
    55
    def clean_session(db: SQL.Database, session_name: String): Unit =
0a7f7abbe4f0 more robust transaction_lock: avoid overlapping data spaces;
wenzelm
parents: 78211
diff changeset
    56
      db.execute_statement(Base.table.delete(sql = where_equal(session_name)))
0a7f7abbe4f0 more robust transaction_lock: avoid overlapping data spaces;
wenzelm
parents: 78211
diff changeset
    57
78541
d95497dcd9bc more scalable write_entries and Export.consumer via db.execute_batch_statement;
wenzelm
parents: 78531
diff changeset
    58
    def known_entries(db: SQL.Database, entry_names: Iterable[Entry_Name]): Set[Entry_Name] = {
d95497dcd9bc more scalable write_entries and Export.consumer via db.execute_batch_statement;
wenzelm
parents: 78531
diff changeset
    59
      val it = entry_names.iterator
d95497dcd9bc more scalable write_entries and Export.consumer via db.execute_batch_statement;
wenzelm
parents: 78531
diff changeset
    60
      if (it.isEmpty) Set.empty[Entry_Name]
d95497dcd9bc more scalable write_entries and Export.consumer via db.execute_batch_statement;
wenzelm
parents: 78531
diff changeset
    61
      else {
d95497dcd9bc more scalable write_entries and Export.consumer via db.execute_batch_statement;
wenzelm
parents: 78531
diff changeset
    62
        val sql_preds =
d95497dcd9bc more scalable write_entries and Export.consumer via db.execute_batch_statement;
wenzelm
parents: 78531
diff changeset
    63
          List.from(
d95497dcd9bc more scalable write_entries and Export.consumer via db.execute_batch_statement;
wenzelm
parents: 78531
diff changeset
    64
            for (entry_name <- it) yield {
d95497dcd9bc more scalable write_entries and Export.consumer via db.execute_batch_statement;
wenzelm
parents: 78531
diff changeset
    65
              SQL.and(
d95497dcd9bc more scalable write_entries and Export.consumer via db.execute_batch_statement;
wenzelm
parents: 78531
diff changeset
    66
                Base.session_name.equal(entry_name.session),
d95497dcd9bc more scalable write_entries and Export.consumer via db.execute_batch_statement;
wenzelm
parents: 78531
diff changeset
    67
                Base.theory_name.equal(entry_name.theory),
d95497dcd9bc more scalable write_entries and Export.consumer via db.execute_batch_statement;
wenzelm
parents: 78531
diff changeset
    68
                Base.name.equal(entry_name.name)
d95497dcd9bc more scalable write_entries and Export.consumer via db.execute_batch_statement;
wenzelm
parents: 78531
diff changeset
    69
              )
d95497dcd9bc more scalable write_entries and Export.consumer via db.execute_batch_statement;
wenzelm
parents: 78531
diff changeset
    70
            })
d95497dcd9bc more scalable write_entries and Export.consumer via db.execute_batch_statement;
wenzelm
parents: 78531
diff changeset
    71
        db.execute_query_statement(
d95497dcd9bc more scalable write_entries and Export.consumer via db.execute_batch_statement;
wenzelm
parents: 78531
diff changeset
    72
          Base.table.select(List(Base.session_name, Base.theory_name, Base.name),
d95497dcd9bc more scalable write_entries and Export.consumer via db.execute_batch_statement;
wenzelm
parents: 78531
diff changeset
    73
            sql = SQL.where(SQL.OR(sql_preds))),
d95497dcd9bc more scalable write_entries and Export.consumer via db.execute_batch_statement;
wenzelm
parents: 78531
diff changeset
    74
          Set.from[Entry_Name],
d95497dcd9bc more scalable write_entries and Export.consumer via db.execute_batch_statement;
wenzelm
parents: 78531
diff changeset
    75
          { res =>
d95497dcd9bc more scalable write_entries and Export.consumer via db.execute_batch_statement;
wenzelm
parents: 78531
diff changeset
    76
            val session_name = res.string(Base.session_name)
d95497dcd9bc more scalable write_entries and Export.consumer via db.execute_batch_statement;
wenzelm
parents: 78531
diff changeset
    77
            val theory_name = res.string(Base.theory_name)
d95497dcd9bc more scalable write_entries and Export.consumer via db.execute_batch_statement;
wenzelm
parents: 78531
diff changeset
    78
            val name = res.string(Base.name)
d95497dcd9bc more scalable write_entries and Export.consumer via db.execute_batch_statement;
wenzelm
parents: 78531
diff changeset
    79
            Entry_Name(session_name, theory_name, name)
d95497dcd9bc more scalable write_entries and Export.consumer via db.execute_batch_statement;
wenzelm
parents: 78531
diff changeset
    80
          })
d95497dcd9bc more scalable write_entries and Export.consumer via db.execute_batch_statement;
wenzelm
parents: 78531
diff changeset
    81
      }
78209
50c5be88ad59 tuned signature;
wenzelm
parents: 78208
diff changeset
    82
    }
50c5be88ad59 tuned signature;
wenzelm
parents: 78208
diff changeset
    83
50c5be88ad59 tuned signature;
wenzelm
parents: 78208
diff changeset
    84
    def read_entry(db: SQL.Database, entry_name: Entry_Name, cache: XML.Cache): Option[Entry] =
50c5be88ad59 tuned signature;
wenzelm
parents: 78208
diff changeset
    85
      db.execute_query_statementO[Entry](
78210
2a92a60cc9d1 tuned signature;
wenzelm
parents: 78209
diff changeset
    86
        Base.table.select(List(Base.executable, Base.compressed, Base.body),
78396
7853d9072d1b renamed object Data to private_data, to emphasize its intended scope (but it is publicly accessible in the database);
wenzelm
parents: 78379
diff changeset
    87
          sql = private_data.where_equal(entry_name.session, entry_name.theory, entry_name.name)),
78209
50c5be88ad59 tuned signature;
wenzelm
parents: 78208
diff changeset
    88
        { res =>
78210
2a92a60cc9d1 tuned signature;
wenzelm
parents: 78209
diff changeset
    89
          val executable = res.bool(Base.executable)
2a92a60cc9d1 tuned signature;
wenzelm
parents: 78209
diff changeset
    90
          val compressed = res.bool(Base.compressed)
80303
11fee9e6ba43 more robust: prefer synchronous compression (usually <= 1ms, sometimes 1..5ms);
wenzelm
parents: 79844
diff changeset
    91
          val body = res.bytes(Base.body)
11fee9e6ba43 more robust: prefer synchronous compression (usually <= 1ms, sometimes 1..5ms);
wenzelm
parents: 79844
diff changeset
    92
          Entry(entry_name, executable, compressed, body, cache)
78209
50c5be88ad59 tuned signature;
wenzelm
parents: 78208
diff changeset
    93
        }
50c5be88ad59 tuned signature;
wenzelm
parents: 78208
diff changeset
    94
      )
50c5be88ad59 tuned signature;
wenzelm
parents: 78208
diff changeset
    95
78554
54991440905e clarified signature: proper treatment of implicit state (amending d0c9d277620e);
wenzelm
parents: 78551
diff changeset
    96
    def write_entries(db: SQL.Database, entries: List[Entry]): Unit =
78551
d0c9d277620e clarified signature: more robust treatment of implicit state;
wenzelm
parents: 78543
diff changeset
    97
      db.execute_batch_statement(Base.table.insert(), batch =
78554
54991440905e clarified signature: proper treatment of implicit state (amending d0c9d277620e);
wenzelm
parents: 78551
diff changeset
    98
        for (entry <- entries) yield { (stmt: SQL.Statement) =>
54991440905e clarified signature: proper treatment of implicit state (amending d0c9d277620e);
wenzelm
parents: 78551
diff changeset
    99
          stmt.string(1) = entry.session_name
54991440905e clarified signature: proper treatment of implicit state (amending d0c9d277620e);
wenzelm
parents: 78551
diff changeset
   100
          stmt.string(2) = entry.theory_name
54991440905e clarified signature: proper treatment of implicit state (amending d0c9d277620e);
wenzelm
parents: 78551
diff changeset
   101
          stmt.string(3) = entry.name
54991440905e clarified signature: proper treatment of implicit state (amending d0c9d277620e);
wenzelm
parents: 78551
diff changeset
   102
          stmt.bool(4) = entry.executable
80303
11fee9e6ba43 more robust: prefer synchronous compression (usually <= 1ms, sometimes 1..5ms);
wenzelm
parents: 79844
diff changeset
   103
          stmt.bool(5) = entry.compressed
11fee9e6ba43 more robust: prefer synchronous compression (usually <= 1ms, sometimes 1..5ms);
wenzelm
parents: 79844
diff changeset
   104
          stmt.bytes(6) = entry.body
78541
d95497dcd9bc more scalable write_entries and Export.consumer via db.execute_batch_statement;
wenzelm
parents: 78531
diff changeset
   105
        })
78210
2a92a60cc9d1 tuned signature;
wenzelm
parents: 78209
diff changeset
   106
2a92a60cc9d1 tuned signature;
wenzelm
parents: 78209
diff changeset
   107
    def read_theory_names(db: SQL.Database, session_name: String): List[String] =
2a92a60cc9d1 tuned signature;
wenzelm
parents: 78209
diff changeset
   108
      db.execute_query_statement(
2a92a60cc9d1 tuned signature;
wenzelm
parents: 78209
diff changeset
   109
        Base.table.select(List(Base.theory_name), distinct = true,
78396
7853d9072d1b renamed object Data to private_data, to emphasize its intended scope (but it is publicly accessible in the database);
wenzelm
parents: 78379
diff changeset
   110
          sql = private_data.where_equal(session_name) + SQL.order_by(List(Base.theory_name))),
78210
2a92a60cc9d1 tuned signature;
wenzelm
parents: 78209
diff changeset
   111
        List.from[String], res => res.string(Base.theory_name))
2a92a60cc9d1 tuned signature;
wenzelm
parents: 78209
diff changeset
   112
2a92a60cc9d1 tuned signature;
wenzelm
parents: 78209
diff changeset
   113
    def read_entry_names(db: SQL.Database, session_name: String): List[Entry_Name] =
2a92a60cc9d1 tuned signature;
wenzelm
parents: 78209
diff changeset
   114
      db.execute_query_statement(
2a92a60cc9d1 tuned signature;
wenzelm
parents: 78209
diff changeset
   115
        Base.table.select(List(Base.theory_name, Base.name),
78396
7853d9072d1b renamed object Data to private_data, to emphasize its intended scope (but it is publicly accessible in the database);
wenzelm
parents: 78379
diff changeset
   116
          sql = private_data.where_equal(session_name)) + SQL.order_by(List(Base.theory_name, Base.name)),
78210
2a92a60cc9d1 tuned signature;
wenzelm
parents: 78209
diff changeset
   117
        List.from[Entry_Name],
2a92a60cc9d1 tuned signature;
wenzelm
parents: 78209
diff changeset
   118
        { res =>
2a92a60cc9d1 tuned signature;
wenzelm
parents: 78209
diff changeset
   119
          Entry_Name(
2a92a60cc9d1 tuned signature;
wenzelm
parents: 78209
diff changeset
   120
            session = session_name,
2a92a60cc9d1 tuned signature;
wenzelm
parents: 78209
diff changeset
   121
            theory = res.string(Base.theory_name),
2a92a60cc9d1 tuned signature;
wenzelm
parents: 78209
diff changeset
   122
            name = res.string(Base.name))
2a92a60cc9d1 tuned signature;
wenzelm
parents: 78209
diff changeset
   123
        })
68116
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   124
  }
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   125
75674
c8e6078fee73 clarified signature;
wenzelm
parents: 75673
diff changeset
   126
  def compound_name(a: String, b: String): String =
c8e6078fee73 clarified signature;
wenzelm
parents: 75673
diff changeset
   127
    if (a.isEmpty) b else a + ":" + b
c8e6078fee73 clarified signature;
wenzelm
parents: 75673
diff changeset
   128
75672
88598f7c9614 clarified signature;
wenzelm
parents: 75671
diff changeset
   129
  sealed case class Entry_Name(session: String = "", theory: String = "", name: String = "") {
75674
c8e6078fee73 clarified signature;
wenzelm
parents: 75673
diff changeset
   130
    val compound_name: String = Export.compound_name(theory, name)
c8e6078fee73 clarified signature;
wenzelm
parents: 75673
diff changeset
   131
75680
605f4b6b5785 clarified signature;
wenzelm
parents: 75675
diff changeset
   132
    def make_path(prune: Int = 0): Path = {
75675
abd4db50ff1e clarified signature;
wenzelm
parents: 75674
diff changeset
   133
      val elems = theory :: space_explode('/', name)
abd4db50ff1e clarified signature;
wenzelm
parents: 75674
diff changeset
   134
      if (elems.length < prune + 1) {
abd4db50ff1e clarified signature;
wenzelm
parents: 75674
diff changeset
   135
        error("Cannot prune path by " + prune + " element(s): " + Path.make(elems))
abd4db50ff1e clarified signature;
wenzelm
parents: 75674
diff changeset
   136
      }
75680
605f4b6b5785 clarified signature;
wenzelm
parents: 75675
diff changeset
   137
      else Path.make(elems.drop(prune))
75675
abd4db50ff1e clarified signature;
wenzelm
parents: 75674
diff changeset
   138
    }
68222
3c1a716e7f59 tuned queries;
wenzelm
parents: 68221
diff changeset
   139
  }
3c1a716e7f59 tuned queries;
wenzelm
parents: 68221
diff changeset
   140
68104
wenzelm
parents: 68103
diff changeset
   141
  def message(msg: String, theory_name: String, name: String): String =
wenzelm
parents: 68103
diff changeset
   142
    msg + " " + quote(name) + " for theory " + quote(theory_name)
wenzelm
parents: 68103
diff changeset
   143
76851
69f6895dd7d4 clarified signature;
wenzelm
parents: 76656
diff changeset
   144
  object Entry {
69f6895dd7d4 clarified signature;
wenzelm
parents: 76656
diff changeset
   145
    def apply(
69f6895dd7d4 clarified signature;
wenzelm
parents: 76656
diff changeset
   146
      entry_name: Entry_Name,
69f6895dd7d4 clarified signature;
wenzelm
parents: 76656
diff changeset
   147
      executable: Boolean,
80303
11fee9e6ba43 more robust: prefer synchronous compression (usually <= 1ms, sometimes 1..5ms);
wenzelm
parents: 79844
diff changeset
   148
      compressed: Boolean,
11fee9e6ba43 more robust: prefer synchronous compression (usually <= 1ms, sometimes 1..5ms);
wenzelm
parents: 79844
diff changeset
   149
      body: Bytes,
76851
69f6895dd7d4 clarified signature;
wenzelm
parents: 76656
diff changeset
   150
      cache: XML.Cache
80303
11fee9e6ba43 more robust: prefer synchronous compression (usually <= 1ms, sometimes 1..5ms);
wenzelm
parents: 79844
diff changeset
   151
    ): Entry = new Entry(entry_name, executable, compressed, body, cache)
76851
69f6895dd7d4 clarified signature;
wenzelm
parents: 76656
diff changeset
   152
69f6895dd7d4 clarified signature;
wenzelm
parents: 76656
diff changeset
   153
    def empty(theory_name: String, name: String): Entry =
69f6895dd7d4 clarified signature;
wenzelm
parents: 76656
diff changeset
   154
      Entry(Entry_Name(theory = theory_name, name = name),
80303
11fee9e6ba43 more robust: prefer synchronous compression (usually <= 1ms, sometimes 1..5ms);
wenzelm
parents: 79844
diff changeset
   155
        false, false, Bytes.empty, XML.Cache.none)
72634
5cea0993ee4f clarified access to single database server vs. collection of database files;
wenzelm
parents: 72375
diff changeset
   156
76851
69f6895dd7d4 clarified signature;
wenzelm
parents: 76656
diff changeset
   157
    def make(
69f6895dd7d4 clarified signature;
wenzelm
parents: 76656
diff changeset
   158
      session_name: String,
69f6895dd7d4 clarified signature;
wenzelm
parents: 76656
diff changeset
   159
      args: Protocol.Export.Args,
69f6895dd7d4 clarified signature;
wenzelm
parents: 76656
diff changeset
   160
      bytes: Bytes,
69f6895dd7d4 clarified signature;
wenzelm
parents: 76656
diff changeset
   161
      cache: XML.Cache
69f6895dd7d4 clarified signature;
wenzelm
parents: 76656
diff changeset
   162
    ): Entry = {
80303
11fee9e6ba43 more robust: prefer synchronous compression (usually <= 1ms, sometimes 1..5ms);
wenzelm
parents: 79844
diff changeset
   163
      val (compressed, body) =
11fee9e6ba43 more robust: prefer synchronous compression (usually <= 1ms, sometimes 1..5ms);
wenzelm
parents: 79844
diff changeset
   164
        if (args.compress) bytes.maybe_compress(cache = cache.compress)
11fee9e6ba43 more robust: prefer synchronous compression (usually <= 1ms, sometimes 1..5ms);
wenzelm
parents: 79844
diff changeset
   165
        else (false, bytes)
76851
69f6895dd7d4 clarified signature;
wenzelm
parents: 76656
diff changeset
   166
      val entry_name =
69f6895dd7d4 clarified signature;
wenzelm
parents: 76656
diff changeset
   167
        Entry_Name(session = session_name, theory = args.theory_name, name = args.name)
80303
11fee9e6ba43 more robust: prefer synchronous compression (usually <= 1ms, sometimes 1..5ms);
wenzelm
parents: 79844
diff changeset
   168
      Entry(entry_name, args.executable, compressed, body, cache)
76851
69f6895dd7d4 clarified signature;
wenzelm
parents: 76656
diff changeset
   169
    }
69f6895dd7d4 clarified signature;
wenzelm
parents: 76656
diff changeset
   170
  }
69f6895dd7d4 clarified signature;
wenzelm
parents: 76656
diff changeset
   171
69f6895dd7d4 clarified signature;
wenzelm
parents: 76656
diff changeset
   172
  final class Entry private(
69f6895dd7d4 clarified signature;
wenzelm
parents: 76656
diff changeset
   173
    val entry_name: Entry_Name,
69f6895dd7d4 clarified signature;
wenzelm
parents: 76656
diff changeset
   174
    val executable: Boolean,
80303
11fee9e6ba43 more robust: prefer synchronous compression (usually <= 1ms, sometimes 1..5ms);
wenzelm
parents: 79844
diff changeset
   175
    val compressed: Boolean,
11fee9e6ba43 more robust: prefer synchronous compression (usually <= 1ms, sometimes 1..5ms);
wenzelm
parents: 79844
diff changeset
   176
    val body: Bytes,
78209
50c5be88ad59 tuned signature;
wenzelm
parents: 78208
diff changeset
   177
    val cache: XML.Cache
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 74686
diff changeset
   178
  ) {
75671
ca8ae1ffd2b8 tuned signature: more explicit types;
wenzelm
parents: 75658
diff changeset
   179
    def session_name: String = entry_name.session
ca8ae1ffd2b8 tuned signature: more explicit types;
wenzelm
parents: 75658
diff changeset
   180
    def theory_name: String = entry_name.theory
ca8ae1ffd2b8 tuned signature: more explicit types;
wenzelm
parents: 75658
diff changeset
   181
    def name: String = entry_name.name
69635
95dc926fa39c clarified output (again);
wenzelm
parents: 69634
diff changeset
   182
    override def toString: String = name
69630
aaa0b5f571e8 clarified output;
wenzelm
parents: 69629
diff changeset
   183
75674
c8e6078fee73 clarified signature;
wenzelm
parents: 75673
diff changeset
   184
    def compound_name: String = entry_name.compound_name
71141
b1c555d3cd71 tuned signature -- more operations;
wenzelm
parents: 71014
diff changeset
   185
72691
2126cf946086 clarified signature;
wenzelm
parents: 72683
diff changeset
   186
    def name_has_prefix(s: String): Boolean = name.startsWith(s)
69634
70f1994988d4 more operations;
wenzelm
parents: 69630
diff changeset
   187
    val name_elems: List[String] = explode_name(name)
70f1994988d4 more operations;
wenzelm
parents: 69630
diff changeset
   188
70f1994988d4 more operations;
wenzelm
parents: 69630
diff changeset
   189
    def name_extends(elems: List[String]): Boolean =
70f1994988d4 more operations;
wenzelm
parents: 69630
diff changeset
   190
      name_elems.startsWith(elems) && name_elems != elems
70f1994988d4 more operations;
wenzelm
parents: 69630
diff changeset
   191
80303
11fee9e6ba43 more robust: prefer synchronous compression (usually <= 1ms, sometimes 1..5ms);
wenzelm
parents: 79844
diff changeset
   192
    def bytes: Bytes =
11fee9e6ba43 more robust: prefer synchronous compression (usually <= 1ms, sometimes 1..5ms);
wenzelm
parents: 79844
diff changeset
   193
      if (compressed) body.uncompress(cache = cache.compress) else body
69629
wenzelm
parents: 68924
diff changeset
   194
76852
2915740fce1f tunes signature;
wenzelm
parents: 76851
diff changeset
   195
    def text: String = bytes.text
2915740fce1f tunes signature;
wenzelm
parents: 76851
diff changeset
   196
2915740fce1f tunes signature;
wenzelm
parents: 76851
diff changeset
   197
    def yxml: XML.Body = YXML.parse_body(UTF8.decode_permissive(bytes), cache = cache)
68116
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   198
  }
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   199
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 74686
diff changeset
   200
  def make_regex(pattern: String): Regex = {
68116
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   201
    @tailrec def make(result: List[String], depth: Int, chs: List[Char]): Regex =
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   202
      chs match {
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   203
        case '*' :: '*' :: rest => make("[^:]*" :: result, depth, rest)
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   204
        case '*' :: rest => make("[^:/]*" :: result, depth, rest)
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   205
        case '?' :: rest => make("[^:/]" :: result, depth, rest)
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   206
        case '\\' :: c :: rest => make(("\\" + c) :: result, depth, rest)
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   207
        case '{' :: rest => make("(" :: result, depth + 1, rest)
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   208
        case ',' :: rest if depth > 0 => make("|" :: result, depth, rest)
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   209
        case '}' :: rest if depth > 0 => make(")" :: result, depth - 1, rest)
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   210
        case c :: rest if ".+()".contains(c) => make(("\\" + c) :: result, depth, rest)
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   211
        case c :: rest => make(c.toString :: result, depth, rest)
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   212
        case Nil => result.reverse.mkString.r
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   213
      }
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   214
    make(Nil, 0, pattern.toList)
68092
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
   215
  }
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
   216
75674
c8e6078fee73 clarified signature;
wenzelm
parents: 75673
diff changeset
   217
  def make_matcher(pats: List[String]): Entry_Name => Boolean = {
75658
5905c7f484b3 clarified signature: read_theory_exports is already ordered;
wenzelm
parents: 75394
diff changeset
   218
    val regs = pats.map(make_regex)
76098
bcca0fbb8a34 tuned: prefer Scala Regex operations;
wenzelm
parents: 75970
diff changeset
   219
    (entry_name: Entry_Name) => regs.exists(_.matches(entry_name.compound_name))
68151
wenzelm
parents: 68116
diff changeset
   220
  }
wenzelm
parents: 68116
diff changeset
   221
78260
0a7f7abbe4f0 more robust transaction_lock: avoid overlapping data spaces;
wenzelm
parents: 78211
diff changeset
   222
  def clean_session(db: SQL.Database, session_name: String): Unit =
78396
7853d9072d1b renamed object Data to private_data, to emphasize its intended scope (but it is publicly accessible in the database);
wenzelm
parents: 78379
diff changeset
   223
    private_data.transaction_lock(db, create = true, label = "Export.clean_session") {
7853d9072d1b renamed object Data to private_data, to emphasize its intended scope (but it is publicly accessible in the database);
wenzelm
parents: 78379
diff changeset
   224
      private_data.clean_session(db, session_name)
78356
974dbe256a37 more informative trace;
wenzelm
parents: 78298
diff changeset
   225
    }
78260
0a7f7abbe4f0 more robust transaction_lock: avoid overlapping data spaces;
wenzelm
parents: 78211
diff changeset
   226
78211
e74d96a40a48 more robust: proper transaction_lock;
wenzelm
parents: 78210
diff changeset
   227
  def read_theory_names(db: SQL.Database, session_name: String): List[String] =
78396
7853d9072d1b renamed object Data to private_data, to emphasize its intended scope (but it is publicly accessible in the database);
wenzelm
parents: 78379
diff changeset
   228
    private_data.transaction_lock(db, label = "Export.read_theory_names") {
7853d9072d1b renamed object Data to private_data, to emphasize its intended scope (but it is publicly accessible in the database);
wenzelm
parents: 78379
diff changeset
   229
      private_data.read_theory_names(db, session_name)
78356
974dbe256a37 more informative trace;
wenzelm
parents: 78298
diff changeset
   230
    }
78211
e74d96a40a48 more robust: proper transaction_lock;
wenzelm
parents: 78210
diff changeset
   231
e74d96a40a48 more robust: proper transaction_lock;
wenzelm
parents: 78210
diff changeset
   232
  def read_entry_names(db: SQL.Database, session_name: String): List[Entry_Name] =
78396
7853d9072d1b renamed object Data to private_data, to emphasize its intended scope (but it is publicly accessible in the database);
wenzelm
parents: 78379
diff changeset
   233
    private_data.transaction_lock(db, label = "Export.read_entry_names") {
7853d9072d1b renamed object Data to private_data, to emphasize its intended scope (but it is publicly accessible in the database);
wenzelm
parents: 78379
diff changeset
   234
      private_data.read_entry_names(db, session_name)
78356
974dbe256a37 more informative trace;
wenzelm
parents: 78298
diff changeset
   235
    }
78211
e74d96a40a48 more robust: proper transaction_lock;
wenzelm
parents: 78210
diff changeset
   236
e74d96a40a48 more robust: proper transaction_lock;
wenzelm
parents: 78210
diff changeset
   237
  def read_entry(db: SQL.Database, entry_name: Entry_Name, cache: XML.Cache): Option[Entry] =
78396
7853d9072d1b renamed object Data to private_data, to emphasize its intended scope (but it is publicly accessible in the database);
wenzelm
parents: 78379
diff changeset
   238
    private_data.transaction_lock(db, label = "Export.read_entry") {
7853d9072d1b renamed object Data to private_data, to emphasize its intended scope (but it is publicly accessible in the database);
wenzelm
parents: 78379
diff changeset
   239
      private_data.read_entry(db, entry_name, cache)
78356
974dbe256a37 more informative trace;
wenzelm
parents: 78298
diff changeset
   240
    }
78211
e74d96a40a48 more robust: proper transaction_lock;
wenzelm
parents: 78210
diff changeset
   241
68092
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
   242
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
   243
  /* database consumer thread */
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
   244
74255
e117e0c29204 more reactive interrupt;
wenzelm
parents: 74215
diff changeset
   245
  def consumer(db: SQL.Database, cache: XML.Cache, progress: Progress = new Progress): Consumer =
e117e0c29204 more reactive interrupt;
wenzelm
parents: 74215
diff changeset
   246
    new Consumer(db, cache, progress)
68092
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
   247
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 74686
diff changeset
   248
  class Consumer private[Export](db: SQL.Database, cache: XML.Cache, progress: Progress) {
68924
wenzelm
parents: 68832
diff changeset
   249
    private val errors = Synchronized[List[String]](Nil)
68092
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
   250
78564
8ba186dc9bc8 clarified source structure;
wenzelm
parents: 78554
diff changeset
   251
    private def consume(args: List[(Entry, Boolean)]): List[Exn.Result[Unit]] = {
8ba186dc9bc8 clarified source structure;
wenzelm
parents: 78554
diff changeset
   252
      private_data.transaction_lock(db, label = "Export.consumer(" + args.length + ")") {
8ba186dc9bc8 clarified source structure;
wenzelm
parents: 78554
diff changeset
   253
        var known = private_data.known_entries(db, args.map(p => p._1.entry_name))
8ba186dc9bc8 clarified source structure;
wenzelm
parents: 78554
diff changeset
   254
        val buffer = new mutable.ListBuffer[Option[Entry]]
8ba186dc9bc8 clarified source structure;
wenzelm
parents: 78554
diff changeset
   255
8ba186dc9bc8 clarified source structure;
wenzelm
parents: 78554
diff changeset
   256
        for ((entry, strict) <- args) {
8ba186dc9bc8 clarified source structure;
wenzelm
parents: 78554
diff changeset
   257
          if (progress.stopped || known(entry.entry_name)) {
8ba186dc9bc8 clarified source structure;
wenzelm
parents: 78554
diff changeset
   258
            buffer += None
8ba186dc9bc8 clarified source structure;
wenzelm
parents: 78554
diff changeset
   259
            if (strict && known(entry.entry_name)) {
8ba186dc9bc8 clarified source structure;
wenzelm
parents: 78554
diff changeset
   260
              val msg = message("Duplicate export", entry.theory_name, entry.name)
8ba186dc9bc8 clarified source structure;
wenzelm
parents: 78554
diff changeset
   261
              errors.change(msg :: _)
8ba186dc9bc8 clarified source structure;
wenzelm
parents: 78554
diff changeset
   262
            }
8ba186dc9bc8 clarified source structure;
wenzelm
parents: 78554
diff changeset
   263
          }
8ba186dc9bc8 clarified source structure;
wenzelm
parents: 78554
diff changeset
   264
          else {
8ba186dc9bc8 clarified source structure;
wenzelm
parents: 78554
diff changeset
   265
            buffer += Some(entry)
8ba186dc9bc8 clarified source structure;
wenzelm
parents: 78554
diff changeset
   266
            known += entry.entry_name
8ba186dc9bc8 clarified source structure;
wenzelm
parents: 78554
diff changeset
   267
          }
8ba186dc9bc8 clarified source structure;
wenzelm
parents: 78554
diff changeset
   268
        }
8ba186dc9bc8 clarified source structure;
wenzelm
parents: 78554
diff changeset
   269
8ba186dc9bc8 clarified source structure;
wenzelm
parents: 78554
diff changeset
   270
        val entries = buffer.toList
8ba186dc9bc8 clarified source structure;
wenzelm
parents: 78554
diff changeset
   271
        try {
8ba186dc9bc8 clarified source structure;
wenzelm
parents: 78554
diff changeset
   272
          private_data.write_entries(db, entries.flatten)
8ba186dc9bc8 clarified source structure;
wenzelm
parents: 78554
diff changeset
   273
          val ok = Exn.Res[Unit](())
8ba186dc9bc8 clarified source structure;
wenzelm
parents: 78554
diff changeset
   274
          entries.map(_ => ok)
8ba186dc9bc8 clarified source structure;
wenzelm
parents: 78554
diff changeset
   275
        }
8ba186dc9bc8 clarified source structure;
wenzelm
parents: 78554
diff changeset
   276
        catch {
8ba186dc9bc8 clarified source structure;
wenzelm
parents: 78554
diff changeset
   277
          case exn: Throwable =>
8ba186dc9bc8 clarified source structure;
wenzelm
parents: 78554
diff changeset
   278
            val err = Exn.Exn[Unit](exn)
8ba186dc9bc8 clarified source structure;
wenzelm
parents: 78554
diff changeset
   279
            entries.map(_ => err)
8ba186dc9bc8 clarified source structure;
wenzelm
parents: 78554
diff changeset
   280
        }
8ba186dc9bc8 clarified source structure;
wenzelm
parents: 78554
diff changeset
   281
      }
8ba186dc9bc8 clarified source structure;
wenzelm
parents: 78554
diff changeset
   282
    }
8ba186dc9bc8 clarified source structure;
wenzelm
parents: 78554
diff changeset
   283
68092
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
   284
    private val consumer =
71145
2f782d5f5d5a improved performance of session exports via bulk transactions;
wenzelm
parents: 71141
diff changeset
   285
      Consumer_Thread.fork_bulk[(Entry, Boolean)](name = "export")(
80303
11fee9e6ba43 more robust: prefer synchronous compression (usually <= 1ms, sometimes 1..5ms);
wenzelm
parents: 79844
diff changeset
   286
        bulk = _ => true,
78564
8ba186dc9bc8 clarified source structure;
wenzelm
parents: 78554
diff changeset
   287
        consume = args => (args.grouped(20).toList.flatMap(consume), true))
68092
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
   288
77681
1db732e6c3d2 back to compression in Isabelle/Scala (in contrast to f7174238b5e3), e.g. relevant for old_command_timings_blob, but also for prospective heaps;
wenzelm
parents: 77599
diff changeset
   289
    def make_entry(session_name: String, args: Protocol.Export.Args, body: Bytes): Unit = {
75762
985c3a64748c clarified signature: more uniform treatment of empty exports;
wenzelm
parents: 75759
diff changeset
   290
      if (!progress.stopped && !body.is_empty) {
76851
69f6895dd7d4 clarified signature;
wenzelm
parents: 76656
diff changeset
   291
        consumer.send(Entry.make(session_name, args, body, cache) -> args.strict)
74257
bda7a7b3bd41 more reactive interrupt;
wenzelm
parents: 74256
diff changeset
   292
      }
bda7a7b3bd41 more reactive interrupt;
wenzelm
parents: 74256
diff changeset
   293
    }
68092
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
   294
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 74686
diff changeset
   295
    def shutdown(close: Boolean = false): List[String] = {
68092
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
   296
      consumer.shutdown()
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
   297
      if (close) db.close()
74255
e117e0c29204 more reactive interrupt;
wenzelm
parents: 74215
diff changeset
   298
      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
   299
    }
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
   300
  }
68116
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   301
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   302
75786
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   303
  /* context for database access */
75772
9dbcc4c66e1c tuned signature: more operations;
wenzelm
parents: 75771
diff changeset
   304
78379
f6ec57648894 reuse SSH.Server connection for database server;
wenzelm
parents: 78367
diff changeset
   305
  def open_database_context(store: Store, server: SSH.Server = SSH.no_server): Database_Context =
f6ec57648894 reuse SSH.Server connection for database server;
wenzelm
parents: 78367
diff changeset
   306
    new Database_Context(store, store.maybe_open_database_server(server = server))
75786
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   307
78379
f6ec57648894 reuse SSH.Server connection for database server;
wenzelm
parents: 78367
diff changeset
   308
  def open_session_context0(
f6ec57648894 reuse SSH.Server connection for database server;
wenzelm
parents: 78367
diff changeset
   309
    store: Store,
f6ec57648894 reuse SSH.Server connection for database server;
wenzelm
parents: 78367
diff changeset
   310
    session: String,
f6ec57648894 reuse SSH.Server connection for database server;
wenzelm
parents: 78367
diff changeset
   311
    server: SSH.Server = SSH.no_server
f6ec57648894 reuse SSH.Server connection for database server;
wenzelm
parents: 78367
diff changeset
   312
  ): Session_Context = {
f6ec57648894 reuse SSH.Server connection for database server;
wenzelm
parents: 78367
diff changeset
   313
    open_database_context(store, server = server)
f6ec57648894 reuse SSH.Server connection for database server;
wenzelm
parents: 78367
diff changeset
   314
      .open_session0(session, close_database_context = true)
f6ec57648894 reuse SSH.Server connection for database server;
wenzelm
parents: 78367
diff changeset
   315
  }
75772
9dbcc4c66e1c tuned signature: more operations;
wenzelm
parents: 75771
diff changeset
   316
75786
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   317
  def open_session_context(
78178
a177f71dc79f clarified modules;
wenzelm
parents: 78164
diff changeset
   318
    store: Store,
76656
a8f452f7c503 clarified names;
wenzelm
parents: 76363
diff changeset
   319
    session_background: Sessions.Background,
78379
f6ec57648894 reuse SSH.Server connection for database server;
wenzelm
parents: 78367
diff changeset
   320
    document_snapshot: Option[Document.Snapshot] = None,
f6ec57648894 reuse SSH.Server connection for database server;
wenzelm
parents: 78367
diff changeset
   321
    server: SSH.Server = SSH.no_server
75786
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   322
  ): Session_Context = {
78379
f6ec57648894 reuse SSH.Server connection for database server;
wenzelm
parents: 78367
diff changeset
   323
    open_database_context(store, server = server).open_session(
76656
a8f452f7c503 clarified names;
wenzelm
parents: 76363
diff changeset
   324
      session_background, document_snapshot = document_snapshot, close_database_context = true)
75786
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   325
  }
75771
26b71e1dd262 misc tuning and clarification;
wenzelm
parents: 75770
diff changeset
   326
75786
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   327
  class Database_Context private[Export](
78178
a177f71dc79f clarified modules;
wenzelm
parents: 78164
diff changeset
   328
    val store: Store,
75786
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   329
    val database_server: Option[SQL.Database]
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   330
  ) extends AutoCloseable {
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   331
    database_context =>
75782
dba571dd0ba9 clarified signature: prefer Export.Session_Context over Sessions.Database_Context;
wenzelm
parents: 75780
diff changeset
   332
75786
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   333
    override def toString: String = {
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   334
      val s =
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   335
        database_server match {
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   336
          case Some(db) => db.toString
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   337
          case None => "input_dirs = " + store.input_dirs.map(_.absolute).mkString(", ")
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   338
        }
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   339
      "Database_Context(" + s + ")"
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   340
    }
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   341
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   342
    def cache: Term.Cache = store.cache
75759
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   343
75786
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   344
    def close(): Unit = database_server.foreach(_.close())
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   345
75970
b4a04fa01677 tuned signature: more general operations;
wenzelm
parents: 75921
diff changeset
   346
    def open_database(session: String, output: Boolean = false): Session_Database =
75786
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   347
      database_server match {
75787
f9fcf06aa2eb clarified signature;
wenzelm
parents: 75786
diff changeset
   348
        case Some(db) => new Session_Database(session, db)
f9fcf06aa2eb clarified signature;
wenzelm
parents: 75786
diff changeset
   349
        case None =>
75970
b4a04fa01677 tuned signature: more general operations;
wenzelm
parents: 75921
diff changeset
   350
          new Session_Database(session, store.open_database(session, output = output)) {
75787
f9fcf06aa2eb clarified signature;
wenzelm
parents: 75786
diff changeset
   351
            override def close(): Unit = db.close()
f9fcf06aa2eb clarified signature;
wenzelm
parents: 75786
diff changeset
   352
          }
75786
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   353
      }
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   354
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   355
    def open_session0(session: String, close_database_context: Boolean = false): Session_Context =
76656
a8f452f7c503 clarified names;
wenzelm
parents: 76363
diff changeset
   356
      open_session(Sessions.background0(session), close_database_context = close_database_context)
75779
5470c67bd772 clarified signature: prefer Export.Session_Context;
wenzelm
parents: 75778
diff changeset
   357
75759
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   358
    def open_session(
76656
a8f452f7c503 clarified names;
wenzelm
parents: 76363
diff changeset
   359
      session_background: Sessions.Background,
75772
9dbcc4c66e1c tuned signature: more operations;
wenzelm
parents: 75771
diff changeset
   360
      document_snapshot: Option[Document.Snapshot] = None,
75786
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   361
      close_database_context: Boolean = false
75759
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   362
    ): Session_Context = {
76656
a8f452f7c503 clarified names;
wenzelm
parents: 76363
diff changeset
   363
      val session_name = session_background.check_errors.session_name
a8f452f7c503 clarified names;
wenzelm
parents: 76363
diff changeset
   364
      val session_hierarchy = session_background.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
   365
      val session_databases =
75786
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   366
        database_server match {
75771
26b71e1dd262 misc tuning and clarification;
wenzelm
parents: 75770
diff changeset
   367
          case Some(db) => session_hierarchy.map(name => new Session_Database(name, db))
26b71e1dd262 misc tuning and clarification;
wenzelm
parents: 75770
diff changeset
   368
          case None =>
75775
70a65ee4a738 clarified signature: more robust treatment of server;
wenzelm
parents: 75774
diff changeset
   369
            val attempts =
78367
4978a158dc4c tuned signature;
wenzelm
parents: 78360
diff changeset
   370
              for (name <- session_hierarchy)
4978a158dc4c tuned signature;
wenzelm
parents: 78360
diff changeset
   371
                yield name -> store.try_open_database(name, server_mode = false)
75771
26b71e1dd262 misc tuning and clarification;
wenzelm
parents: 75770
diff changeset
   372
            attempts.collectFirst({ case (name, None) => name }) match {
26b71e1dd262 misc tuning and clarification;
wenzelm
parents: 75770
diff changeset
   373
              case Some(bad) =>
78592
fdfe9b91d96e misc tuning: support "scalac -source 3.3";
wenzelm
parents: 78564
diff changeset
   374
                for (case (_, Some(db)) <- attempts) db.close()
75791
fb12433208aa tuned signature;
wenzelm
parents: 75790
diff changeset
   375
                store.error_database(bad)
75764
07e097f60b85 clarified signature: more robust close operation;
wenzelm
parents: 75762
diff changeset
   376
              case None =>
78592
fdfe9b91d96e misc tuning: support "scalac -source 3.3";
wenzelm
parents: 78564
diff changeset
   377
                for (case (name, Some(db)) <- attempts) yield {
75764
07e097f60b85 clarified signature: more robust close operation;
wenzelm
parents: 75762
diff changeset
   378
                  new Session_Database(name, db) { override def close(): Unit = this.db.close() }
07e097f60b85 clarified signature: more robust close operation;
wenzelm
parents: 75762
diff changeset
   379
                }
07e097f60b85 clarified signature: more robust close operation;
wenzelm
parents: 75762
diff changeset
   380
            }
75771
26b71e1dd262 misc tuning and clarification;
wenzelm
parents: 75770
diff changeset
   381
        }
76656
a8f452f7c503 clarified names;
wenzelm
parents: 76363
diff changeset
   382
      new Session_Context(
a8f452f7c503 clarified names;
wenzelm
parents: 76363
diff changeset
   383
          database_context, session_background, session_databases, document_snapshot) {
75772
9dbcc4c66e1c tuned signature: more operations;
wenzelm
parents: 75771
diff changeset
   384
        override def close(): Unit = {
9dbcc4c66e1c tuned signature: more operations;
wenzelm
parents: 75771
diff changeset
   385
          session_databases.foreach(_.close())
75786
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   386
          if (close_database_context) database_context.close()
75772
9dbcc4c66e1c tuned signature: more operations;
wenzelm
parents: 75771
diff changeset
   387
        }
75759
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   388
      }
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   389
    }
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   390
  }
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   391
75789
wenzelm
parents: 75788
diff changeset
   392
  class Session_Database private[Export](val session: String, val db: SQL.Database)
wenzelm
parents: 75788
diff changeset
   393
  extends AutoCloseable {
wenzelm
parents: 75788
diff changeset
   394
    def close(): Unit = ()
wenzelm
parents: 75788
diff changeset
   395
78211
e74d96a40a48 more robust: proper transaction_lock;
wenzelm
parents: 78210
diff changeset
   396
    lazy private [Export] val theory_names: List[String] = read_theory_names(db, session)
e74d96a40a48 more robust: proper transaction_lock;
wenzelm
parents: 78210
diff changeset
   397
    lazy private [Export] val entry_names: List[Entry_Name] = read_entry_names(db, session)
75789
wenzelm
parents: 75788
diff changeset
   398
  }
wenzelm
parents: 75788
diff changeset
   399
75759
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   400
  class Session_Context private[Export](
75786
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   401
    val database_context: Database_Context,
76656
a8f452f7c503 clarified names;
wenzelm
parents: 76363
diff changeset
   402
    session_background: Sessions.Background,
75770
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   403
    db_hierarchy: List[Session_Database],
77005
86cc9b0e1b13 proper line positions for PIDE document;
wenzelm
parents: 76934
diff changeset
   404
    val document_snapshot: Option[Document.Snapshot]
75759
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   405
  ) extends AutoCloseable {
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   406
    session_context =>
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   407
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   408
    def close(): Unit = ()
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   409
75786
ff6c1a82270f clarified modules;
wenzelm
parents: 75784
diff changeset
   410
    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
   411
76656
a8f452f7c503 clarified names;
wenzelm
parents: 76363
diff changeset
   412
    def sessions_structure: Sessions.Structure = session_background.sessions_structure
75778
d18c96b9b955 prefer Export.Context/Session_Context/Theory_Context over Sessions.Database_Context;
wenzelm
parents: 75775
diff changeset
   413
76656
a8f452f7c503 clarified names;
wenzelm
parents: 76363
diff changeset
   414
    def session_base: Sessions.Base = session_background.base
75778
d18c96b9b955 prefer Export.Context/Session_Context/Theory_Context over Sessions.Database_Context;
wenzelm
parents: 75775
diff changeset
   415
75770
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   416
    def session_name: String =
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   417
      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
   418
      else session_base.session_name
75770
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   419
75780
f49c4f160b84 clarified signature: find session_database within Session_Context.db_hierarchy;
wenzelm
parents: 75779
diff changeset
   420
    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
   421
      db_hierarchy.find(_.session == session)
f49c4f160b84 clarified signature: find session_database within Session_Context.db_hierarchy;
wenzelm
parents: 75779
diff changeset
   422
f49c4f160b84 clarified signature: find session_database within Session_Context.db_hierarchy;
wenzelm
parents: 75779
diff changeset
   423
    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
   424
      session_database(session = session).map(_.db)
f49c4f160b84 clarified signature: find session_database within Session_Context.db_hierarchy;
wenzelm
parents: 75779
diff changeset
   425
75770
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   426
    def session_stack: List[String] =
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   427
      ((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
   428
        db_hierarchy.map(_.session)).reverse
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   429
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   430
    private def select[A](
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   431
      session: String,
75860
2b2c09f4e7b5 proper export theory_names: theory/parents are not necessarily present (amending 4d27b520622a);
wenzelm
parents: 75825
diff changeset
   432
      select: Session_Database => List[A],
2b2c09f4e7b5 proper export theory_names: theory/parents are not necessarily present (amending 4d27b520622a);
wenzelm
parents: 75825
diff changeset
   433
      project: Entry_Name => A,
2b2c09f4e7b5 proper export theory_names: theory/parents are not necessarily present (amending 4d27b520622a);
wenzelm
parents: 75825
diff changeset
   434
      sort_key: A => String
75770
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   435
    ): List[A] = {
75860
2b2c09f4e7b5 proper export theory_names: theory/parents are not necessarily present (amending 4d27b520622a);
wenzelm
parents: 75825
diff changeset
   436
      def result(name: String): List[A] =
75770
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   437
        if (name == Sessions.DRAFT) {
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   438
          (for {
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   439
            snapshot <- document_snapshot.iterator
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   440
            entry_name <- snapshot.all_exports.keysIterator
75860
2b2c09f4e7b5 proper export theory_names: theory/parents are not necessarily present (amending 4d27b520622a);
wenzelm
parents: 75825
diff changeset
   441
          } yield project(entry_name)).toSet.toList.sortBy(sort_key)
75770
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   442
        }
75860
2b2c09f4e7b5 proper export theory_names: theory/parents are not necessarily present (amending 4d27b520622a);
wenzelm
parents: 75825
diff changeset
   443
        else session_database(name).map(select).getOrElse(Nil)
2b2c09f4e7b5 proper export theory_names: theory/parents are not necessarily present (amending 4d27b520622a);
wenzelm
parents: 75825
diff changeset
   444
2b2c09f4e7b5 proper export theory_names: theory/parents are not necessarily present (amending 4d27b520622a);
wenzelm
parents: 75825
diff changeset
   445
      if (session.nonEmpty) result(session) else session_stack.flatMap(result)
75770
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   446
    }
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   447
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   448
    def entry_names(session: String = session_name): List[Entry_Name] =
75860
2b2c09f4e7b5 proper export theory_names: theory/parents are not necessarily present (amending 4d27b520622a);
wenzelm
parents: 75825
diff changeset
   449
      select(session, _.entry_names, identity, _.compound_name)
75770
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   450
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   451
    def theory_names(session: String = session_name): List[String] =
75860
2b2c09f4e7b5 proper export theory_names: theory/parents are not necessarily present (amending 4d27b520622a);
wenzelm
parents: 75825
diff changeset
   452
      select(session, _.theory_names, _.theory, identity)
75770
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   453
75759
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   454
    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
   455
    {
75784
wenzelm
parents: 75782
diff changeset
   456
      def snapshot_entry: Option[Entry] =
75770
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   457
        for {
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   458
          snapshot <- document_snapshot
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   459
          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
   460
          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
   461
        } yield entry
75784
wenzelm
parents: 75782
diff changeset
   462
      def db_entry: Option[Entry] =
78209
50c5be88ad59 tuned signature;
wenzelm
parents: 78208
diff changeset
   463
        db_hierarchy.view.map { database =>
50c5be88ad59 tuned signature;
wenzelm
parents: 78208
diff changeset
   464
          val entry_name = Export.Entry_Name(session = database.session, theory = theory, name = name)
78211
e74d96a40a48 more robust: proper transaction_lock;
wenzelm
parents: 78210
diff changeset
   465
          read_entry(database.db, entry_name, cache)
78209
50c5be88ad59 tuned signature;
wenzelm
parents: 78208
diff changeset
   466
        }.collectFirst({ case Some(entry) => entry })
75759
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   467
75770
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   468
      snapshot_entry orElse db_entry
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   469
    }
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   470
75759
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   471
    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
   472
      get(theory, name) match {
76851
69f6895dd7d4 clarified signature;
wenzelm
parents: 76656
diff changeset
   473
        case None if permissive => Entry.empty(theory, name)
75759
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   474
        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
   475
        case Some(entry) => entry
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   476
      }
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   477
75790
0ab8a9177e41 clarified signature: more uniform treatment of cache for Export.read_session vs. Export.read_theory;
wenzelm
parents: 75789
diff changeset
   478
    def theory(theory: String, other_cache: Option[Term.Cache] = None): Theory_Context =
0ab8a9177e41 clarified signature: more uniform treatment of cache for Export.read_session vs. Export.read_theory;
wenzelm
parents: 75789
diff changeset
   479
      new Theory_Context(session_context, theory, other_cache)
75759
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   480
78178
a177f71dc79f clarified modules;
wenzelm
parents: 78164
diff changeset
   481
    def get_source_file(name: String): Option[Store.Source_File] = {
76909
e6f324723308 clarified signature: more operations;
wenzelm
parents: 76870
diff changeset
   482
      val store = database_context.store
e6f324723308 clarified signature: more operations;
wenzelm
parents: 76870
diff changeset
   483
      (for {
e6f324723308 clarified signature: more operations;
wenzelm
parents: 76870
diff changeset
   484
        database <- db_hierarchy.iterator
e6f324723308 clarified signature: more operations;
wenzelm
parents: 76870
diff changeset
   485
        file <- store.read_sources(database.db, database.session, name = name).iterator
e6f324723308 clarified signature: more operations;
wenzelm
parents: 76870
diff changeset
   486
      } yield file).nextOption()
e6f324723308 clarified signature: more operations;
wenzelm
parents: 76870
diff changeset
   487
    }
e6f324723308 clarified signature: more operations;
wenzelm
parents: 76870
diff changeset
   488
78178
a177f71dc79f clarified modules;
wenzelm
parents: 78164
diff changeset
   489
    def source_file(name: String): Store.Source_File =
76910
c27fcf4a7495 clarified signature: more operations;
wenzelm
parents: 76909
diff changeset
   490
      get_source_file(name).getOrElse(error("Missing session source file " + quote(name)))
c27fcf4a7495 clarified signature: more operations;
wenzelm
parents: 76909
diff changeset
   491
77023
474a07221c27 more robust theory_source -- in contrast to node_source from fffb978dd683: theory name is more reliable than Document.Node.Name, explicit unicode_symbols;
wenzelm
parents: 77005
diff changeset
   492
    def theory_source(theory: String, unicode_symbols: Boolean = false): String = {
474a07221c27 more robust theory_source -- in contrast to node_source from fffb978dd683: theory name is more reliable than Document.Node.Name, explicit unicode_symbols;
wenzelm
parents: 77005
diff changeset
   493
      def snapshot_source: Option[String] =
474a07221c27 more robust theory_source -- in contrast to node_source from fffb978dd683: theory name is more reliable than Document.Node.Name, explicit unicode_symbols;
wenzelm
parents: 77005
diff changeset
   494
        for {
474a07221c27 more robust theory_source -- in contrast to node_source from fffb978dd683: theory name is more reliable than Document.Node.Name, explicit unicode_symbols;
wenzelm
parents: 77005
diff changeset
   495
          snapshot <- document_snapshot
474a07221c27 more robust theory_source -- in contrast to node_source from fffb978dd683: theory name is more reliable than Document.Node.Name, explicit unicode_symbols;
wenzelm
parents: 77005
diff changeset
   496
          text <- snapshot.version.nodes.iterator.collectFirst(
474a07221c27 more robust theory_source -- in contrast to node_source from fffb978dd683: theory name is more reliable than Document.Node.Name, explicit unicode_symbols;
wenzelm
parents: 77005
diff changeset
   497
            { case (name, node) if name.theory == theory => node.source })
474a07221c27 more robust theory_source -- in contrast to node_source from fffb978dd683: theory name is more reliable than Document.Node.Name, explicit unicode_symbols;
wenzelm
parents: 77005
diff changeset
   498
          if text.nonEmpty
474a07221c27 more robust theory_source -- in contrast to node_source from fffb978dd683: theory name is more reliable than Document.Node.Name, explicit unicode_symbols;
wenzelm
parents: 77005
diff changeset
   499
        } yield Symbol.output(unicode_symbols, text)
474a07221c27 more robust theory_source -- in contrast to node_source from fffb978dd683: theory name is more reliable than Document.Node.Name, explicit unicode_symbols;
wenzelm
parents: 77005
diff changeset
   500
474a07221c27 more robust theory_source -- in contrast to node_source from fffb978dd683: theory name is more reliable than Document.Node.Name, explicit unicode_symbols;
wenzelm
parents: 77005
diff changeset
   501
      def db_source: Option[String] = {
474a07221c27 more robust theory_source -- in contrast to node_source from fffb978dd683: theory name is more reliable than Document.Node.Name, explicit unicode_symbols;
wenzelm
parents: 77005
diff changeset
   502
        val theory_context = session_context.theory(theory)
474a07221c27 more robust theory_source -- in contrast to node_source from fffb978dd683: theory name is more reliable than Document.Node.Name, explicit unicode_symbols;
wenzelm
parents: 77005
diff changeset
   503
        for {
474a07221c27 more robust theory_source -- in contrast to node_source from fffb978dd683: theory name is more reliable than Document.Node.Name, explicit unicode_symbols;
wenzelm
parents: 77005
diff changeset
   504
          name <- theory_context.files0(permissive = true).headOption
474a07221c27 more robust theory_source -- in contrast to node_source from fffb978dd683: theory name is more reliable than Document.Node.Name, explicit unicode_symbols;
wenzelm
parents: 77005
diff changeset
   505
          file <- get_source_file(name)
77168
547d140f0780 more uniform use of Symbol.output, even in situations where its Symbol.encode is usually redundant;
wenzelm
parents: 77026
diff changeset
   506
        } yield Symbol.output(unicode_symbols, file.bytes.text)
77023
474a07221c27 more robust theory_source -- in contrast to node_source from fffb978dd683: theory name is more reliable than Document.Node.Name, explicit unicode_symbols;
wenzelm
parents: 77005
diff changeset
   507
      }
474a07221c27 more robust theory_source -- in contrast to node_source from fffb978dd683: theory name is more reliable than Document.Node.Name, explicit unicode_symbols;
wenzelm
parents: 77005
diff changeset
   508
474a07221c27 more robust theory_source -- in contrast to node_source from fffb978dd683: theory name is more reliable than Document.Node.Name, explicit unicode_symbols;
wenzelm
parents: 77005
diff changeset
   509
      snapshot_source orElse db_source getOrElse ""
474a07221c27 more robust theory_source -- in contrast to node_source from fffb978dd683: theory name is more reliable than Document.Node.Name, explicit unicode_symbols;
wenzelm
parents: 77005
diff changeset
   510
    }
474a07221c27 more robust theory_source -- in contrast to node_source from fffb978dd683: theory name is more reliable than Document.Node.Name, explicit unicode_symbols;
wenzelm
parents: 77005
diff changeset
   511
75825
ad00fbf64bff clarified signature --- simplified types;
wenzelm
parents: 75824
diff changeset
   512
    def classpath(): List[File.Content] = {
75782
dba571dd0ba9 clarified signature: prefer Export.Session_Context over Sessions.Database_Context;
wenzelm
parents: 75780
diff changeset
   513
      (for {
dba571dd0ba9 clarified signature: prefer Export.Session_Context over Sessions.Database_Context;
wenzelm
parents: 75780
diff changeset
   514
        session <- session_stack.iterator
dba571dd0ba9 clarified signature: prefer Export.Session_Context over Sessions.Database_Context;
wenzelm
parents: 75780
diff changeset
   515
        info <- sessions_structure.get(session).iterator
dba571dd0ba9 clarified signature: prefer Export.Session_Context over Sessions.Database_Context;
wenzelm
parents: 75780
diff changeset
   516
        if info.export_classpath.nonEmpty
dba571dd0ba9 clarified signature: prefer Export.Session_Context over Sessions.Database_Context;
wenzelm
parents: 75780
diff changeset
   517
        matcher = make_matcher(info.export_classpath)
dba571dd0ba9 clarified signature: prefer Export.Session_Context over Sessions.Database_Context;
wenzelm
parents: 75780
diff changeset
   518
        entry_name <- entry_names(session = session).iterator
dba571dd0ba9 clarified signature: prefer Export.Session_Context over Sessions.Database_Context;
wenzelm
parents: 75780
diff changeset
   519
        if matcher(entry_name)
dba571dd0ba9 clarified signature: prefer Export.Session_Context over Sessions.Database_Context;
wenzelm
parents: 75780
diff changeset
   520
        entry <- get(entry_name.theory, entry_name.name).iterator
76852
2915740fce1f tunes signature;
wenzelm
parents: 76851
diff changeset
   521
      } yield File.content(entry.entry_name.make_path(), entry.bytes)).toList
75918
16a53676ebbd tuned whitespace;
wenzelm
parents: 75901
diff changeset
   522
    }
75782
dba571dd0ba9 clarified signature: prefer Export.Session_Context over Sessions.Database_Context;
wenzelm
parents: 75780
diff changeset
   523
75918
16a53676ebbd tuned whitespace;
wenzelm
parents: 75901
diff changeset
   524
    override def toString: String =
75770
62e2c6f65f9a clarified Document.Snapshot.all_exports: refer to material from this (virtual) session;
wenzelm
parents: 75769
diff changeset
   525
      "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
   526
  }
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   527
75774
efc25bf4b795 discontinued Export.Provider in favour of Export.Context and its derivatives;
wenzelm
parents: 75773
diff changeset
   528
  class Theory_Context private[Export](
efc25bf4b795 discontinued Export.Provider in favour of Export.Context and its derivatives;
wenzelm
parents: 75773
diff changeset
   529
    val session_context: Session_Context,
75790
0ab8a9177e41 clarified signature: more uniform treatment of cache for Export.read_session vs. Export.read_theory;
wenzelm
parents: 75789
diff changeset
   530
    val theory: String,
0ab8a9177e41 clarified signature: more uniform treatment of cache for Export.read_session vs. Export.read_theory;
wenzelm
parents: 75789
diff changeset
   531
    other_cache: Option[Term.Cache]
75774
efc25bf4b795 discontinued Export.Provider in favour of Export.Context and its derivatives;
wenzelm
parents: 75773
diff changeset
   532
  ) {
75790
0ab8a9177e41 clarified signature: more uniform treatment of cache for Export.read_session vs. Export.read_theory;
wenzelm
parents: 75789
diff changeset
   533
    def cache: Term.Cache = other_cache getOrElse session_context.cache
75778
d18c96b9b955 prefer Export.Context/Session_Context/Theory_Context over Sessions.Database_Context;
wenzelm
parents: 75775
diff changeset
   534
75759
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   535
    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
   536
    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
   537
      session_context.apply(theory, name, permissive = permissive)
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   538
76854
f3ca8478e59e tuned signature;
wenzelm
parents: 76852
diff changeset
   539
    def yxml(name: String): XML.Body =
75774
efc25bf4b795 discontinued Export.Provider in favour of Export.Context and its derivatives;
wenzelm
parents: 75773
diff changeset
   540
      get(name) match {
76852
2915740fce1f tunes signature;
wenzelm
parents: 76851
diff changeset
   541
        case Some(entry) => entry.yxml
75774
efc25bf4b795 discontinued Export.Provider in favour of Export.Context and its derivatives;
wenzelm
parents: 75773
diff changeset
   542
        case None => Nil
efc25bf4b795 discontinued Export.Provider in favour of Export.Context and its derivatives;
wenzelm
parents: 75773
diff changeset
   543
      }
efc25bf4b795 discontinued Export.Provider in favour of Export.Context and its derivatives;
wenzelm
parents: 75773
diff changeset
   544
75778
d18c96b9b955 prefer Export.Context/Session_Context/Theory_Context over Sessions.Database_Context;
wenzelm
parents: 75775
diff changeset
   545
    def document_id(): Option[Long] =
d18c96b9b955 prefer Export.Context/Session_Context/Theory_Context over Sessions.Database_Context;
wenzelm
parents: 75775
diff changeset
   546
      apply(DOCUMENT_ID, permissive = true).text match {
d18c96b9b955 prefer Export.Context/Session_Context/Theory_Context over Sessions.Database_Context;
wenzelm
parents: 75775
diff changeset
   547
        case Value.Long(id) => Some(id)
d18c96b9b955 prefer Export.Context/Session_Context/Theory_Context over Sessions.Database_Context;
wenzelm
parents: 75775
diff changeset
   548
        case _ => None
d18c96b9b955 prefer Export.Context/Session_Context/Theory_Context over Sessions.Database_Context;
wenzelm
parents: 75775
diff changeset
   549
      }
d18c96b9b955 prefer Export.Context/Session_Context/Theory_Context over Sessions.Database_Context;
wenzelm
parents: 75775
diff changeset
   550
75901
475fedc02737 clarified signature;
wenzelm
parents: 75860
diff changeset
   551
    def files0(permissive: Boolean = false): List[String] =
475fedc02737 clarified signature;
wenzelm
parents: 75860
diff changeset
   552
      split_lines(apply(FILES, permissive = permissive).text)
475fedc02737 clarified signature;
wenzelm
parents: 75860
diff changeset
   553
475fedc02737 clarified signature;
wenzelm
parents: 75860
diff changeset
   554
    def files(permissive: Boolean = false): Option[(String, List[String])] =
475fedc02737 clarified signature;
wenzelm
parents: 75860
diff changeset
   555
      files0(permissive = permissive) match {
75778
d18c96b9b955 prefer Export.Context/Session_Context/Theory_Context over Sessions.Database_Context;
wenzelm
parents: 75775
diff changeset
   556
        case Nil => None
75901
475fedc02737 clarified signature;
wenzelm
parents: 75860
diff changeset
   557
        case a :: bs => Some((a, bs))
75778
d18c96b9b955 prefer Export.Context/Session_Context/Theory_Context over Sessions.Database_Context;
wenzelm
parents: 75775
diff changeset
   558
      }
d18c96b9b955 prefer Export.Context/Session_Context/Theory_Context over Sessions.Database_Context;
wenzelm
parents: 75775
diff changeset
   559
75759
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   560
    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
   561
  }
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   562
0cdccd0d1699 clarified context for retrieval: more explicit types, with optional close() operation;
wenzelm
parents: 75757
diff changeset
   563
68288
d20770229f99 tuned signature;
wenzelm
parents: 68222
diff changeset
   564
  /* export to file-system */
d20770229f99 tuned signature;
wenzelm
parents: 68222
diff changeset
   565
d20770229f99 tuned signature;
wenzelm
parents: 68222
diff changeset
   566
  def export_files(
78178
a177f71dc79f clarified modules;
wenzelm
parents: 78164
diff changeset
   567
    store: Store,
68288
d20770229f99 tuned signature;
wenzelm
parents: 68222
diff changeset
   568
    session_name: String,
d20770229f99 tuned signature;
wenzelm
parents: 68222
diff changeset
   569
    export_dir: Path,
71726
a5fda30edae2 clarified signature: more uniform treatment of stopped/interrupted state;
wenzelm
parents: 71624
diff changeset
   570
    progress: Progress = new Progress,
69671
2486792eaf61 support pruning of export names;
wenzelm
parents: 69635
diff changeset
   571
    export_prune: Int = 0,
68288
d20770229f99 tuned signature;
wenzelm
parents: 68222
diff changeset
   572
    export_list: Boolean = false,
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 74686
diff changeset
   573
    export_patterns: List[String] = Nil
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 74686
diff changeset
   574
  ): Unit = {
75394
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   575
    using(store.open_database(session_name)) { db =>
78211
e74d96a40a48 more robust: proper transaction_lock;
wenzelm
parents: 78210
diff changeset
   576
      val entry_names = read_entry_names(db, session_name)
68288
d20770229f99 tuned signature;
wenzelm
parents: 68222
diff changeset
   577
75739
5b37466c1463 removed somewhat pointless transaction: db is meant to be finished (or updated monotonically);
wenzelm
parents: 75736
diff changeset
   578
      // list
5b37466c1463 removed somewhat pointless transaction: db is meant to be finished (or updated monotonically);
wenzelm
parents: 75736
diff changeset
   579
      if (export_list) {
5b37466c1463 removed somewhat pointless transaction: db is meant to be finished (or updated monotonically);
wenzelm
parents: 75736
diff changeset
   580
        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
   581
      }
68288
d20770229f99 tuned signature;
wenzelm
parents: 68222
diff changeset
   582
75739
5b37466c1463 removed somewhat pointless transaction: db is meant to be finished (or updated monotonically);
wenzelm
parents: 75736
diff changeset
   583
      // export
5b37466c1463 removed somewhat pointless transaction: db is meant to be finished (or updated monotonically);
wenzelm
parents: 75736
diff changeset
   584
      if (export_patterns.nonEmpty) {
5b37466c1463 removed somewhat pointless transaction: db is meant to be finished (or updated monotonically);
wenzelm
parents: 75736
diff changeset
   585
        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
   586
        for {
5b37466c1463 removed somewhat pointless transaction: db is meant to be finished (or updated monotonically);
wenzelm
parents: 75736
diff changeset
   587
          entry_name <- entry_names if matcher(entry_name)
78211
e74d96a40a48 more robust: proper transaction_lock;
wenzelm
parents: 78210
diff changeset
   588
          entry <- read_entry(db, entry_name, store.cache)
75739
5b37466c1463 removed somewhat pointless transaction: db is meant to be finished (or updated monotonically);
wenzelm
parents: 75736
diff changeset
   589
        } {
5b37466c1463 removed somewhat pointless transaction: db is meant to be finished (or updated monotonically);
wenzelm
parents: 75736
diff changeset
   590
          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
   591
          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
   592
          Isabelle_System.make_directory(path.dir)
76852
2915740fce1f tunes signature;
wenzelm
parents: 76851
diff changeset
   593
          val bytes = entry.bytes
75739
5b37466c1463 removed somewhat pointless transaction: db is meant to be finished (or updated monotonically);
wenzelm
parents: 75736
diff changeset
   594
          if (!path.is_file || Bytes.read(path) != bytes) Bytes.write(path, bytes)
78298
3b0f8f1010f2 clarified signature, with subtle change of semantics (amending 8b5a2e4b16d4);
wenzelm
parents: 78260
diff changeset
   595
          File.set_executable(path, reset = !entry.executable)
68288
d20770229f99 tuned signature;
wenzelm
parents: 68222
diff changeset
   596
        }
d20770229f99 tuned signature;
wenzelm
parents: 68222
diff changeset
   597
      }
75394
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   598
    }
68288
d20770229f99 tuned signature;
wenzelm
parents: 68222
diff changeset
   599
  }
d20770229f99 tuned signature;
wenzelm
parents: 68222
diff changeset
   600
d20770229f99 tuned signature;
wenzelm
parents: 68222
diff changeset
   601
68116
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   602
  /* Isabelle tool wrapper */
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   603
71601
97ccf48c2f0c misc tuning based on hints by IntelliJ IDEA;
wenzelm
parents: 71145
diff changeset
   604
  val default_export_dir: Path = Path.explode("export")
68116
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   605
75394
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   606
  val isabelle_tool =
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   607
    Isabelle_Tool("export", "retrieve theory exports", Scala_Project.here,
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   608
      { args =>
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   609
        /* arguments */
68116
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   610
75394
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   611
        var export_dir = default_export_dir
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   612
        var dirs: List[Path] = Nil
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   613
        var export_list = false
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   614
        var no_build = false
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   615
        var options = Options.init()
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   616
        var export_prune = 0
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   617
        var export_patterns: List[String] = Nil
68116
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   618
75394
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   619
        val getopts = Getopts("""
68116
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   620
Usage: isabelle export [OPTIONS] SESSION
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   621
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   622
  Options are:
68314
2acbf8129d8b clarified option -O: avoid conflict with build/dump option -D;
wenzelm
parents: 68305
diff changeset
   623
    -O DIR       output directory for exported files (default: """ + default_export_dir + """)
68116
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   624
    -d DIR       include session directory
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   625
    -l           list exports
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   626
    -n           no build of session
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   627
    -o OPTION    override Isabelle system OPTION (via NAME=VAL or NAME)
69671
2486792eaf61 support pruning of export names;
wenzelm
parents: 69635
diff changeset
   628
    -p NUM       prune path of exported files by NUM elements
68116
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   629
    -x PATTERN   extract files matching pattern (e.g. "*:**" for all)
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   630
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   631
  List or export theory exports for SESSION: named blobs produced by
68290
f1f5ccc85b25 support multiple patterns;
wenzelm
parents: 68289
diff changeset
   632
  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
   633
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   634
  The PATTERN language resembles glob patterns in the shell, with ? and *
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   635
  (both excluding ":" and "/"), ** (excluding ":"), and [abc] or [^abc],
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   636
  and variants {pattern1,pattern2,pattern3}.
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   637
""",
75394
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   638
          "O:" -> (arg => export_dir = Path.explode(arg)),
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   639
          "d:" -> (arg => dirs = dirs ::: List(Path.explode(arg))),
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   640
          "l" -> (_ => export_list = true),
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   641
          "n" -> (_ => no_build = true),
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   642
          "o:" -> (arg => options = options + arg),
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   643
          "p:" -> (arg => export_prune = Value.Int.parse(arg)),
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   644
          "x:" -> (arg => export_patterns ::= arg))
68116
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   645
75394
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   646
        val more_args = getopts(args)
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   647
        val session_name =
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   648
          more_args match {
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   649
            case List(session_name) if export_list || export_patterns.nonEmpty => session_name
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   650
            case _ => getopts.usage()
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   651
          }
68116
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   652
75394
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   653
        val progress = new Console_Progress()
68305
5321218147d3 clarified signature;
wenzelm
parents: 68291
diff changeset
   654
68116
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   655
75394
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   656
        /* build */
68116
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   657
75394
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   658
        if (!no_build) {
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   659
          val rc =
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   660
            progress.interrupt_handler {
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   661
              Build.build_logic(options, session_name, progress = progress, dirs = dirs)
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   662
            }
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   663
          if (rc != Process_Result.RC.ok) sys.exit(rc)
68331
7eaaa8f48331 clarified outermost progress.interrupt_handler;
wenzelm
parents: 68314
diff changeset
   664
        }
68116
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   665
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   666
75394
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   667
        /* export files */
68116
ac82ee617a75 command-line tool "isabelle export";
wenzelm
parents: 68115
diff changeset
   668
79675
wenzelm
parents: 79502
diff changeset
   669
        export_files(Store(options), session_name, export_dir, progress = progress,
wenzelm
parents: 79502
diff changeset
   670
          export_prune = export_prune, export_list = export_list, export_patterns = export_patterns)
75394
42267c650205 tuned formatting;
wenzelm
parents: 75393
diff changeset
   671
      })
68092
888d35a19866 store exports in session database, with asynchronous / parallel compression;
wenzelm
parents:
diff changeset
   672
}