mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-14 09:14:14 +02:00
.qetz: a property's show flag gets a column
The JSON column of a property row held only its show flag, in every project QElectroTech saves: the 25 examples and a 136-folio project used it for nothing else. Folio and project properties now store it as a number, as symbol information does, so a saved project's database holds no JSON; JSON is left for attributes QElectroTech does not write (an older or hand-edited file). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -48,8 +48,8 @@ namespace QetContainer
|
||||
/// The format written; files of a later format are refused by join()
|
||||
/// unless their min-reader allows this one.
|
||||
constexpr int Format = 3;
|
||||
/// 3: the database's rows keyed by the items' uuids, true/false as
|
||||
/// 1/0, its PRAGMA user_version the format, the symbols' type left
|
||||
/// 3: the database's rows keyed by the items' uuids, true/false and
|
||||
/// show flags as 1/0, its PRAGMA user_version the format, the symbols' type left
|
||||
/// in the folio files, no column for where a block sat. Format 2 is
|
||||
/// still read; a later format whose min-reader allows this one is
|
||||
/// read too, and said so through join()'s @p format.
|
||||
|
||||
@@ -121,11 +121,11 @@ QString schema()
|
||||
{
|
||||
return QStringLiteral(
|
||||
"CREATE TABLE meta (key TEXT PRIMARY KEY, value TEXT);"
|
||||
"CREATE TABLE project_property (ord INTEGER PRIMARY KEY, name TEXT, value TEXT, attrs TEXT);"
|
||||
"CREATE TABLE project_property (ord INTEGER PRIMARY KEY, name TEXT, value TEXT, show INTEGER, attrs TEXT);"
|
||||
"CREATE TABLE folio (uuid TEXT PRIMARY KEY, pos INTEGER NOT NULL UNIQUE, %1,"
|
||||
" props_attrs TEXT);"
|
||||
"CREATE TABLE folio_property (folio_uuid TEXT NOT NULL REFERENCES folio, ord INTEGER NOT NULL,"
|
||||
" name TEXT, value TEXT, attrs TEXT, PRIMARY KEY (folio_uuid, ord));"
|
||||
" name TEXT, value TEXT, show INTEGER, attrs TEXT, PRIMARY KEY (folio_uuid, ord));"
|
||||
"CREATE TABLE element (uuid TEXT PRIMARY KEY, folio_uuid TEXT NOT NULL REFERENCES folio, %2,"
|
||||
" info_attrs TEXT, links_attrs TEXT);"
|
||||
"CREATE TABLE element_info (element_uuid TEXT NOT NULL REFERENCES element, ord INTEGER NOT NULL,"
|
||||
@@ -455,6 +455,21 @@ QList<QDomElement> children(const QDomElement &parent, const QString &tag)
|
||||
return list;
|
||||
}
|
||||
|
||||
//A list entry -- a <property>, an <elementInformation> -- as its row:
|
||||
//its name, value, show flag (0 or 1, else left in the JSON) and any
|
||||
//other attribute as JSON, its tag too if it is not @p usual_tag
|
||||
QVariantList entryRow(const QDomElement &e, const QString &usual_tag)
|
||||
{
|
||||
QVariant value;
|
||||
simpleValue(e, &value);
|
||||
const QString show = e.attribute(QStringLiteral("show"));
|
||||
const bool show_stored = show == QLatin1String("0") || show == QLatin1String("1");
|
||||
QStringList kept{QStringLiteral("name")};
|
||||
if (show_stored) kept << QStringLiteral("show");
|
||||
return {e.hasAttribute(QStringLiteral("name")) ? QVariant(e.attribute(QStringLiteral("name"))) : QVariant(),
|
||||
value, show_stored ? QVariant(show.toInt()) : QVariant(), attributesJson(e, kept, usual_tag)};
|
||||
}
|
||||
|
||||
//The key of each of @p items: its uuid, when it has one no other of
|
||||
//@p items has, so the uuid the folio file already holds says which row
|
||||
//is the item's (@p own true). Else (F100: symbols copied with their
|
||||
@@ -510,9 +525,9 @@ QByteArray QetContainerDb::extract(QDomElement project, QString *error)
|
||||
db.exec(QStringLiteral("BEGIN"));
|
||||
|
||||
Statement meta(db.m_db, QStringLiteral("INSERT INTO meta VALUES (?,?)"));
|
||||
Statement project_property(db.m_db, QStringLiteral("INSERT INTO project_property VALUES (?,?,?,?)"));
|
||||
Statement project_property(db.m_db, QStringLiteral("INSERT INTO project_property VALUES (?,?,?,?,?)"));
|
||||
Statement folio(db.m_db, QStringLiteral("INSERT INTO folio VALUES (?,?,%1,?)").arg(placeholders(FolioData.size())));
|
||||
Statement folio_property(db.m_db, QStringLiteral("INSERT INTO folio_property VALUES (?,?,?,?,?)"));
|
||||
Statement folio_property(db.m_db, QStringLiteral("INSERT INTO folio_property VALUES (?,?,?,?,?,?)"));
|
||||
Statement element(db.m_db, QStringLiteral("INSERT INTO element VALUES (?,?,%1,?,?)").arg(placeholders(ElementData.size())));
|
||||
Statement element_info(db.m_db, QStringLiteral("INSERT INTO element_info VALUES (?,?,?,?,?,?)"));
|
||||
Statement link(db.m_db, QStringLiteral("INSERT INTO link VALUES (?,?,?,?)"));
|
||||
@@ -526,27 +541,15 @@ QByteArray QetContainerDb::extract(QDomElement project, QString *error)
|
||||
//<properties> of a block, as rows of @p rows (with @p prefix values)
|
||||
auto moveProperties = [&](QDomElement block, Statement &rows, const QVariantList &prefix) {
|
||||
int ord = 0;
|
||||
for (QDomElement p : children(block, QStringLiteral("property"))) {
|
||||
QVariant value;
|
||||
simpleValue(p, &value);
|
||||
ok = ok && rows.run(QVariantList(prefix) << ord++ << (p.hasAttribute(QStringLiteral("name"))
|
||||
? QVariant(p.attribute(QStringLiteral("name"))) : QVariant())
|
||||
<< value << attributesJson(p, {QStringLiteral("name")}, QStringLiteral("property")));
|
||||
}
|
||||
for (QDomElement p : children(block, QStringLiteral("property")))
|
||||
ok = ok && rows.run(QVariantList(prefix) << ord++ << entryRow(p, QStringLiteral("property")));
|
||||
};
|
||||
|
||||
//Project properties
|
||||
const QDomElement project_props = project.firstChildElement(QStringLiteral("properties"));
|
||||
if (!project_props.isNull() && listBlock(project_props, QStringLiteral("property"))) {
|
||||
ok = ok && meta.run({QStringLiteral("props_attrs"), blockJson(project_props)});
|
||||
int ord = 0;
|
||||
for (QDomElement p : children(project_props, QStringLiteral("property"))) {
|
||||
QVariant value;
|
||||
simpleValue(p, &value);
|
||||
ok = ok && project_property.run({ord++, p.hasAttribute(QStringLiteral("name"))
|
||||
? QVariant(p.attribute(QStringLiteral("name"))) : QVariant(),
|
||||
value, attributesJson(p, {QStringLiteral("name")}, QStringLiteral("property"))});
|
||||
}
|
||||
moveProperties(project_props, project_property, {});
|
||||
leaveMarker(project_props);
|
||||
}
|
||||
|
||||
@@ -597,18 +600,9 @@ QByteArray QetContainerDb::extract(QDomElement project, QString *error)
|
||||
ok = ok && element.run(erow);
|
||||
if (!info.isNull()) {
|
||||
int ord = 0;
|
||||
for (QDomElement i : children(info, QStringLiteral("elementInformation"))) {
|
||||
QVariant value;
|
||||
simpleValue(i, &value);
|
||||
const QString show = i.attribute(QStringLiteral("show"));
|
||||
const bool show_stored = show == QLatin1String("0") || show == QLatin1String("1");
|
||||
QStringList kept{QStringLiteral("name")};
|
||||
if (show_stored) kept << QStringLiteral("show");
|
||||
ok = ok && element_info.run({key, ord++, i.hasAttribute(QStringLiteral("name"))
|
||||
? QVariant(i.attribute(QStringLiteral("name"))) : QVariant(),
|
||||
value, show_stored ? QVariant(show.toInt()) : QVariant(),
|
||||
attributesJson(i, kept, QStringLiteral("elementInformation"))});
|
||||
}
|
||||
for (QDomElement i : children(info, QStringLiteral("elementInformation")))
|
||||
ok = ok && element_info.run(QVariantList{key, ord++}
|
||||
<< entryRow(i, QStringLiteral("elementInformation")));
|
||||
}
|
||||
if (!links.isNull()) {
|
||||
int ord = 0;
|
||||
@@ -755,10 +749,11 @@ bool QetContainerDb::restore(QDomElement project, const QByteArray &database, QS
|
||||
if (hasMarker(project, QStringLiteral("properties"))) {
|
||||
QDomElement props = document.createElement(QStringLiteral("properties"));
|
||||
setAttributesJson(props, meta.value(QStringLiteral("props_attrs")));
|
||||
Statement s(db.m_db, QStringLiteral("SELECT name, value, attrs FROM project_property ORDER BY ord"));
|
||||
Statement s(db.m_db, QStringLiteral("SELECT name, value, attrs, %1 FROM project_property ORDER BY ord")
|
||||
.arg(show_column));
|
||||
while (s.next())
|
||||
props.appendChild(entry(s.value(0), QStringLiteral("name"), s.value(1), s.value(2),
|
||||
QStringLiteral("property")));
|
||||
QStringLiteral("property"), s.value(3)));
|
||||
restoreWhitespace(props, meta.value(QStringLiteral("props_attrs")));
|
||||
if (!replaceMarker(project, props)) {
|
||||
setError(error, QStringLiteral("the project's properties have no place"));
|
||||
@@ -812,11 +807,12 @@ bool QetContainerDb::restore(QDomElement project, const QByteArray &database, QS
|
||||
if (hasMarker(d, QStringLiteral("properties"))) {
|
||||
QDomElement props = document.createElement(QStringLiteral("properties"));
|
||||
setAttributesJson(props, values.at(FolioData.size()));
|
||||
Statement p(db.m_db, QStringLiteral("SELECT name, value, attrs FROM folio_property WHERE %1 = ? ORDER BY ord").arg(folio_ref));
|
||||
Statement p(db.m_db, QStringLiteral("SELECT name, value, attrs, %1 FROM folio_property WHERE %2 = ? ORDER BY ord")
|
||||
.arg(show_column, folio_ref));
|
||||
p.bind({id});
|
||||
while (p.next())
|
||||
props.appendChild(entry(p.value(0), QStringLiteral("name"), p.value(1), p.value(2),
|
||||
QStringLiteral("property")));
|
||||
QStringLiteral("property"), p.value(3)));
|
||||
restoreWhitespace(props, values.at(FolioData.size()));
|
||||
if (!replaceMarker(d, props)) {
|
||||
setError(error, QStringLiteral("folio %1's properties have no place").arg(id));
|
||||
|
||||
@@ -331,6 +331,26 @@ private slots:
|
||||
QCOMPARE(query(database, "SELECT count(*) FROM meta WHERE key = 'props_at'"), QStringLiteral("0"));
|
||||
}
|
||||
|
||||
// A project as QElectroTech saves it needs no JSON: every attribute it
|
||||
// writes has a column, the show flag of a property too
|
||||
void savedProjectNeedsNoJson()
|
||||
{
|
||||
QString error;
|
||||
const QList<QetZip::Entry> entries = QetContainer::split(savedProject(), QString(), &error);
|
||||
QVERIFY2(!entries.isEmpty(), qPrintable(error));
|
||||
const QByteArray database = entry(entries, QStringLiteral("project.sqlite"));
|
||||
QVERIFY(query(database, "SELECT count(*) FROM project_property").toInt() > 0);
|
||||
QCOMPARE(query(database, "SELECT count(*) FROM project_property WHERE show IS NOT NULL"),
|
||||
query(database, "SELECT count(*) FROM project_property"));
|
||||
for (const char *sql : {"SELECT count(*) FROM project_property WHERE attrs IS NOT NULL",
|
||||
"SELECT count(*) FROM folio_property WHERE attrs IS NOT NULL",
|
||||
"SELECT count(*) FROM element_info WHERE attrs IS NOT NULL",
|
||||
"SELECT count(*) FROM link WHERE attrs IS NOT NULL",
|
||||
"SELECT count(*) FROM folio WHERE props_attrs IS NOT NULL",
|
||||
"SELECT count(*) FROM element WHERE info_attrs IS NOT NULL OR links_attrs IS NOT NULL"})
|
||||
QVERIFY2(query(database, sql) == QLatin1String("0"), sql);
|
||||
}
|
||||
|
||||
void laterFormatRefused()
|
||||
{
|
||||
QDomDocument original;
|
||||
|
||||
Reference in New Issue
Block a user