280 /** digested meta info: produced by Admin/build_history in log.xz file **/ |
280 /** digested meta info: produced by Admin/build_history in log.xz file **/ |
281 |
281 |
282 object Meta_Info |
282 object Meta_Info |
283 { |
283 { |
284 val empty: Meta_Info = Meta_Info(Nil, Nil) |
284 val empty: Meta_Info = Meta_Info(Nil, Nil) |
|
285 |
|
286 val log_filename = SQL.Column.string("log_filename", primary_key = true) |
|
287 val settings = SQL.Column.bytes("settings") |
|
288 |
|
289 val table = |
|
290 SQL.Table("isabelle_build_log_meta_info", log_filename :: Prop.columns ::: List(settings)) |
285 } |
291 } |
286 |
292 |
287 sealed case class Meta_Info(props: Properties.T, settings: List[(String, String)]) |
293 sealed case class Meta_Info(props: Properties.T, settings: List[(String, String)]) |
288 { |
294 { |
289 def is_empty: Boolean = props.isEmpty && settings.isEmpty |
295 def is_empty: Boolean = props.isEmpty && settings.isEmpty |
651 Bytes(YXML.string_of_body(Build_Info.encode(build_info))).compress(options) |
650 Bytes(YXML.string_of_body(Build_Info.encode(build_info))).compress(options) |
652 |
651 |
653 def uncompress_build_info(bytes: Bytes): Build_Info = |
652 def uncompress_build_info(bytes: Bytes): Build_Info = |
654 Build_Info.decode(xml_cache.body(YXML.parse_body(bytes.uncompress().text))) |
653 Build_Info.decode(xml_cache.body(YXML.parse_body(bytes.uncompress().text))) |
655 |
654 |
656 def filter_files(db: SQL.Database, files: List[JFile]): List[JFile] = |
655 def filter_files(db: SQL.Database, table: SQL.Table, files: List[JFile]): List[JFile] = |
657 { |
656 { |
|
657 val key = Meta_Info.log_filename |
658 val known_files = |
658 val known_files = |
659 using(db.select_statement(Info.table, List(Info.log_filename)))(stmt => |
659 using(db.select_statement(table, List(key)))(stmt => |
660 SQL.iterator(stmt.executeQuery)(rs => db.string(rs, Info.log_filename)).toSet) |
660 SQL.iterator(stmt.executeQuery)(rs => db.string(rs, key)).toSet) |
661 |
661 |
662 val unique_files = |
662 val unique_files = |
663 (Map.empty[String, JFile] /: files.iterator)({ case (m, file) => |
663 (Map.empty[String, JFile] /: files.iterator)({ case (m, file) => |
664 val name = file.getName |
664 val name = file.getName |
665 if (known_files(name)) m else m + (name -> file) |
665 if (known_files(name)) m else m + (name -> file) |
666 }) |
666 }) |
667 |
667 |
668 unique_files.iterator.map(_._2).toList |
668 unique_files.iterator.map(_._2).toList |
669 } |
669 } |
670 |
670 |
671 def write_infos(db: SQL.Database, files: List[JFile]) |
671 def write_meta_info(db: SQL.Database, files: List[JFile]) |
672 { |
672 { |
673 db.transaction { |
673 db.transaction { |
674 db.create_table(Info.table) |
674 db.create_table(Meta_Info.table) |
675 |
675 |
676 using(db.insert_statement(Info.table))(stmt => |
676 using(db.insert_statement(Meta_Info.table))(stmt => |
677 { |
677 { |
678 for (file <- filter_files(db, files)) { |
678 for (file <- filter_files(db, Meta_Info.table, files)) { |
679 val log_file = Log_File(file) |
679 val meta_info = Log_File(file).parse_meta_info() |
680 val meta_info = log_file.parse_meta_info() |
|
681 val build_info = log_file.parse_build_info() |
|
682 |
|
683 stmt.clearParameters |
|
684 |
680 |
685 db.set_string(stmt, 1, file.getName) |
681 db.set_string(stmt, 1, file.getName) |
686 |
|
687 for ((c, i) <- Prop.columns.zipWithIndex) { |
682 for ((c, i) <- Prop.columns.zipWithIndex) { |
688 if (c.T == SQL.Type.Date) |
683 if (c.T == SQL.Type.Date) |
689 db.set_date(stmt, i + 2, meta_info.get_date(c).orNull) |
684 db.set_date(stmt, i + 2, meta_info.get_date(c).orNull) |
690 else |
685 else |
691 db.set_string(stmt, i + 2, meta_info.get(c).map(Prop.multiple_lines(_)).orNull) |
686 db.set_string(stmt, i + 2, meta_info.get(c).map(Prop.multiple_lines(_)).orNull) |
692 } |
687 } |
693 |
688 db.set_bytes(stmt, Meta_Info.table.columns.length, encode_properties(meta_info.settings)) |
694 val n = Info.table.columns.length |
|
695 db.set_bytes(stmt, n - 1, encode_properties(meta_info.settings)) |
|
696 db.set_bytes(stmt, n, compress_build_info(build_info)) |
|
697 |
689 |
698 stmt.execute() |
690 stmt.execute() |
699 } |
691 } |
700 }) |
692 }) |
701 } |
693 } |
702 } |
694 } |
|
695 |
|
696 def write_build_info(db: SQL.Database, files: List[JFile]) |
|
697 { |
|
698 db.transaction { |
|
699 db.create_table(Build_Info.table) |
|
700 |
|
701 using(db.insert_statement(Build_Info.table))(stmt => |
|
702 { |
|
703 for (file <- filter_files(db, Build_Info.table, files)) { |
|
704 val build_info = Log_File(file).parse_build_info() |
|
705 |
|
706 db.set_string(stmt, 1, file.getName) |
|
707 db.set_bytes(stmt, 2, compress_build_info(build_info)) |
|
708 |
|
709 stmt.execute() |
|
710 } |
|
711 }) |
|
712 } |
|
713 } |
703 } |
714 } |
704 } |
715 } |