src/Pure/Thy/export.scala
changeset 75770 62e2c6f65f9a
parent 75769 4d27b520622a
child 75771 26b71e1dd262
equal deleted inserted replaced
75769:4d27b520622a 75770:62e2c6f65f9a
   304           (for {
   304           (for {
   305             (name, _) <- snapshot.version.nodes.iterator
   305             (name, _) <- snapshot.version.nodes.iterator
   306             if name.is_theory && !resources.session_base.loaded_theory(name)
   306             if name.is_theory && !resources.session_base.loaded_theory(name)
   307           } yield name.theory).toList
   307           } yield name.theory).toList
   308 
   308 
   309         override def apply(export_name: String): Option[Entry] =
   309         override def apply(name: String): Option[Entry] =
   310           snapshot.exports_map.get(export_name)
   310           snapshot.all_exports.get(
       
   311             Entry_Name(session = Sessions.DRAFT, theory = snapshot.node_name.theory, name = name))
   311 
   312 
   312         override def focus(other_theory: String): Provider =
   313         override def focus(other_theory: String): Provider =
   313           if (other_theory == snapshot.node_name.theory) this
   314           if (other_theory == snapshot.node_name.theory) this
   314           else {
   315           else {
   315             val node_name =
   316             val node_name =
   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 =