346 |
347 |
347 class Session_Database private[Export](val session: String, val db: SQL.Database) { |
348 class Session_Database private[Export](val session: String, val db: SQL.Database) { |
348 def close(): Unit = () |
349 def close(): Unit = () |
349 |
350 |
350 lazy val theory_names: List[String] = read_theory_names(db, session) |
351 lazy val theory_names: List[String] = read_theory_names(db, session) |
|
352 lazy val entry_names: List[Entry_Name] = read_entry_names(db, session) |
351 } |
353 } |
352 |
354 |
353 class Context private[Export](val db_context: Sessions.Database_Context) extends AutoCloseable { |
355 class Context private[Export](val db_context: Sessions.Database_Context) extends AutoCloseable { |
354 def close(): Unit = () |
356 def close(): Unit = () |
355 |
357 |
356 def open_session( |
358 def open_session( |
357 session: String, |
359 session: String, |
358 resources: Resources, |
360 resources: Resources, |
359 snapshot: Document.Snapshot = Document.Snapshot.init |
361 document_snapshot: Option[Document.Snapshot] = None |
360 ): Session_Context = { |
362 ): Session_Context = { |
361 val session_hierarchy = resources.sessions_structure.build_hierarchy(session) |
363 val session_hierarchy = resources.sessions_structure.build_hierarchy(session) |
362 db_context.database_server match { |
364 db_context.database_server match { |
363 case Some(db) => |
365 case Some(db) => |
364 val session_databases = session_hierarchy.map(name => new Session_Database(name, db)) |
366 val session_databases = session_hierarchy.map(name => new Session_Database(name, db)) |
365 new Session_Context(resources, snapshot, db_context.cache, session_databases) |
367 new Session_Context(resources, db_context.cache, session_databases, document_snapshot) |
366 case None => |
368 case None => |
367 val store = db_context.store |
369 val store = db_context.store |
368 val session_databases = { |
370 val session_databases = { |
369 val res = session_hierarchy.map(name => name -> store.try_open_database(name)) |
371 val res = session_hierarchy.map(name => name -> store.try_open_database(name)) |
370 res.collectFirst({ case (name, None) => name }) match { |
372 res.collectFirst({ case (name, None) => name }) match { |
376 case Some(bad) => |
378 case Some(bad) => |
377 for ((_, Some(db)) <- res) db.close() |
379 for ((_, Some(db)) <- res) db.close() |
378 store.bad_database(bad) |
380 store.bad_database(bad) |
379 } |
381 } |
380 } |
382 } |
381 new Session_Context(resources, snapshot, db_context.cache, session_databases) { |
383 new Session_Context(resources, db_context.cache, session_databases, document_snapshot) { |
382 override def close(): Unit = db_hierarchy.foreach(_.close()) |
384 override def close(): Unit = session_databases.foreach(_.close()) |
383 } |
385 } |
384 } |
386 } |
385 } |
387 } |
386 |
388 |
387 override def toString: String = db_context.toString |
389 override def toString: String = db_context.toString |
388 } |
390 } |
389 |
391 |
390 class Session_Context private[Export]( |
392 class Session_Context private[Export]( |
391 val resources: Resources, |
393 val resources: Resources, |
392 val snapshot: Document.Snapshot, |
|
393 val cache: Term.Cache, |
394 val cache: Term.Cache, |
394 val db_hierarchy: List[Session_Database] |
395 db_hierarchy: List[Session_Database], |
|
396 document_snapshot: Option[Document.Snapshot] |
395 ) extends AutoCloseable { |
397 ) extends AutoCloseable { |
396 session_context => |
398 session_context => |
397 |
399 |
398 def close(): Unit = () |
400 def close(): Unit = () |
399 |
401 |
|
402 def session_name: String = |
|
403 if (document_snapshot.isDefined) Sessions.DRAFT |
|
404 else resources.session_base.session_name |
|
405 |
|
406 def session_stack: List[String] = |
|
407 ((if (document_snapshot.isDefined) List(session_name) else Nil) ::: |
|
408 db_hierarchy.map(_.session)).reverse |
|
409 |
|
410 private def select[A]( |
|
411 session: String, |
|
412 select1: Entry_Name => Option[A], |
|
413 select2: Session_Database => List[A] |
|
414 ): List[A] = { |
|
415 def sel(name: String): List[A] = |
|
416 if (name == Sessions.DRAFT) { |
|
417 (for { |
|
418 snapshot <- document_snapshot.iterator |
|
419 entry_name <- snapshot.all_exports.keysIterator |
|
420 res <- select1(entry_name).iterator |
|
421 } yield entry_name -> res).toList.sortBy(_._1.compound_name).map(_._2) |
|
422 } |
|
423 else { db_hierarchy.find(_.session == name).map(select2).getOrElse(Nil) } |
|
424 if (session.nonEmpty) sel(session) else session_stack.flatMap(sel) |
|
425 } |
|
426 |
|
427 def entry_names(session: String = session_name): List[Entry_Name] = |
|
428 select(session, Some(_), _.entry_names) |
|
429 |
|
430 def theory_names(session: String = session_name): List[String] = |
|
431 select(session, a => if(a.name == THEORY_PARENTS) Some(a.theory) else None, _.theory_names) |
|
432 |
400 def get(theory: String, name: String): Option[Entry] = |
433 def get(theory: String, name: String): Option[Entry] = |
401 snapshot.exports_map.get(name) orElse |
434 { |
|
435 def snapshot_entry = |
|
436 for { |
|
437 snapshot <- document_snapshot |
|
438 entry_name = Entry_Name(session = Sessions.DRAFT, theory = theory, name = name) |
|
439 entry <- snapshot.all_exports.get(entry_name) |
|
440 } yield entry |
|
441 def db_entry = |
402 db_hierarchy.view.map(session_db => |
442 db_hierarchy.view.map(session_db => |
403 Export.Entry_Name(session = session_db.session, theory = theory, name = name) |
443 Export.Entry_Name(session = session_db.session, theory = theory, name = name) |
404 .read(session_db.db, cache)) |
444 .read(session_db.db, cache)) |
405 .collectFirst({ case Some(entry) => entry }) |
445 .collectFirst({ case Some(entry) => entry }) |
|
446 |
|
447 snapshot_entry orElse db_entry |
|
448 } |
406 |
449 |
407 def apply(theory: String, name: String, permissive: Boolean = false): Entry = |
450 def apply(theory: String, name: String, permissive: Boolean = false): Entry = |
408 get(theory, name) match { |
451 get(theory, name) match { |
409 case None if permissive => empty_entry(theory, name) |
452 case None if permissive => empty_entry(theory, name) |
410 case None => error("Missing export entry " + quote(compound_name(theory, name))) |
453 case None => error("Missing export entry " + quote(compound_name(theory, name))) |
411 case Some(entry) => entry |
454 case Some(entry) => entry |
412 } |
455 } |
413 |
456 |
414 def theory_names(session: String): List[String] = |
|
415 db_hierarchy.find(_.session == session).map(_.theory_names).getOrElse(Nil) |
|
416 |
|
417 def theory(theory: String): Theory_Context = |
457 def theory(theory: String): Theory_Context = |
418 new Theory_Context(session_context, theory) |
458 new Theory_Context(session_context, theory) |
419 |
459 |
420 override def toString: String = |
460 override def toString: String = |
421 "Export.Session_Context(" + commas_quote(db_hierarchy.map(_.session)) + ")" |
461 "Export.Session_Context(" + commas_quote(session_stack) + ")" |
422 } |
462 } |
423 |
463 |
424 class Theory_Context private[Export](session_context: Session_Context, theory: String) { |
464 class Theory_Context private[Export](session_context: Session_Context, theory: String) { |
425 def get(name: String): Option[Entry] = session_context.get(theory, name) |
465 def get(name: String): Option[Entry] = session_context.get(theory, name) |
426 def apply(name: String, permissive: Boolean = false): Entry = |
466 def apply(name: String, permissive: Boolean = false): Entry = |