.qetz format 3: one project database (stage D3a)

project.sqlite now holds both what QElectroTech keeps in its project
database (the index D2 wrote as index.sqlite) and the document's
engineering data, the latter's tables named doc_<name> beside the
former's -- element, element_info, link and conductor exist in both
(QetContainerDb's SQL names them as before; Database::sql() puts the
prefix on). The manifest says format 3, min-reader 3: a format 2 reader
would find no tables of its names. Format 2 files, with or without an
index.sqlite entry, are read as before: the prefix is found from the
file (doc_meta).

A .qetz with an index opens from project.sqlite. Measured: the 136-folio
f2099 1.8 s, 5.2 MB (the two table sets still overlap: D3b).

Checked: tst_qetcontainer with the format 3 names, 34/34; a format 2 file
of the last commit opens from its index.sqlite and saves the same; corpus
342: 340 .qetz carry the index in project.sqlite and open from it, saved
back = eager = master on all 342. ctest 96/96 with and without
QET_LAZY_FOLIOS=1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ispyisail
2026-10-11 19:32:27 +13:00
parent e89ccf2a40
commit 2f98872d7a
6 changed files with 101 additions and 52 deletions
+11 -8
View File
@@ -478,11 +478,15 @@ QETProject::ProjectState QETProject::openFile(QFile *file)
files.insert(entry.name, entry.data);
QStringList folio_files;
QDomDocument document;
if (files.contains(QStringLiteral("index.sqlite"))
//The index: in project.sqlite from format 3, its own entry
//before
const QByteArray index = files.contains(QStringLiteral("index.sqlite"))
? files.value(QStringLiteral("index.sqlite"))
: files.value(QStringLiteral("project.sqlite"));
if (!index.isEmpty() && index.contains("folio_header")
&& QetContainer::join(entries, &document, &why, &folio_files))
{
if (m_data_base.fillFromIndex(files.value(QStringLiteral("index.sqlite")),
&m_folio_headers, &why)
if (m_data_base.fillFromIndex(index, &m_folio_headers, &why)
&& m_folio_headers.size() == folio_files.size()) {
xml_project = document;
m_container_files = files;
@@ -2518,14 +2522,13 @@ bool QETProject::isContainerPath(const QString &path)
bool QETProject::writeContainer(const QDomDocument &project, const QString &path, QString *error,
const QByteArray &index)
{
//The project database, for opening without reading the folios
//(stage D2), is in project.sqlite with the
//document's engineering data (format 3, D3)
QList<QetZip::Entry> entries = QetContainer::split(
project,
QStringLiteral("QElectroTech %1").arg(QetVersion::currentVersion().toString()),
error);
//The project database, for opening without reading the folios
//(stage D2); a reader that does not know it skips it
if (!entries.isEmpty() && !index.isEmpty())
entries.append(QetZip::Entry{QStringLiteral("index.sqlite"), index, true});
error, index);
return !entries.isEmpty() && QetZip::write(path, entries, error);
}