25 #include <QApplication>
30 #include <QDataStream>
31 #include <QMessageBox>
33 #include <QSqlDatabase>
92 buf.open(QIODevice::WriteOnly);
93 img.
save(&buf, format);
145 bool accessshared =
false;
157 if (url.
scheme() ==
"klf+sqlite") {
161 accessshared =
false;
166 tr(
"Database file <b>%1</b> does not exist.").arg(path));
176 tr(
"Unable to open library file \"%1\" (engine: \"%2\").\nError: %3")
182 qWarning(
"KLFLibDBEngine::openUrl: bad url scheme in URL\n\t%s",
195 klfDbgSt(
"fileName="<<fileName<<
", sresname="<<sresname<<
", srestitle="<<srestitle) ;
198 QString subrestitle = srestitle;
219 tr(
"Unable to create library file %1 (SQLITE database):\n"
221 .arg(path, db.
lastError().text()), QMessageBox::Ok);
227 subresname =
"table1";
229 subrestitle =
"Table 1";
233 subrestitle = subresname;
238 qWarning()<<
KLF_FUNC_NAME<<
"\" character is not allowed in SQLITE database tables (<-> library sub-resources).";
242 r = initFreshDatabase(db);
245 r = createFreshDataTable(db, subresname);
249 tr(
"Unable to initialize the SQLITE database file %1!").arg(url.
path()));
257 qWarning()<<
"Failed to create table named "<<subresname<<
"!";
266 KLFLibDBEngine::KLFLibDBEngine(
const QSqlDatabase& db,
bool autodisconnect,
267 const QUrl& url,
bool accessshared,
QObject *parent)
269 |FeatureSubResourceProps, parent)
277 readResourceProperty(-1);
282 for (k = 0; k < subres.size(); ++k)
283 readAvailColumns(subres[k]);
287 this, SLOT(resourcePropertyUpdate(
int)));
289 this, SLOT(subResourcePropertyUpdate(
const QString&,
int)));
307 bool KLFLibDBEngine::tableExists(
const QString& subResource)
const
309 return pDB.
tables().contains(dataTableName(subResource), Qt::CaseInsensitive);
315 return "t_"+subResource.
toLower();
318 QString KLFLibDBEngine::quotedDataTableName(
const QString& subResource)
320 QString dtname = dataTableName(subResource);
322 return '"' + dtname +
'"';
377 if ( propName.isEmpty() )
385 q.
prepare(
"DELETE FROM klf_properties WHERE name = ?");
389 qWarning()<<
"KLFLibDBEngine::setRes.Property("<<propId<<
","<<value<<
"): can't DELETE!\n\t"
396 q.
prepare(
"INSERT INTO klf_properties (name,value) VALUES (?,?)");
398 q.
bindValue(1, convertVariantToDBData(value));
400 qWarning()<<
"KLFLibDBEngine::setRes.Property("<<propId<<
","<<value<<
"): can't INSERT!\n\t"
406 dbPropertyNotifierInstance(pDB.connectionName())->notifyResourcePropertyChanged(propId);
412 void KLFLibDBEngine::resourcePropertyUpdate(
int propId)
414 readResourceProperty(propId);
417 void KLFLibDBEngine::subResourcePropertyUpdate(
const QString& subResource,
int propId)
422 void KLFLibDBEngine::readResourceProperty(
int propId)
427 QString sqlstr =
"SELECT name,value FROM klf_properties";
431 qWarning()<<
"Can't read un-registered resource property "<<propId<<
" !";
434 sqlstr +=
" WHERE name = ?";
439 q.
prepare(
"SELECT name,value FROM klf_properties");
450 klfDbg(
"Setting property `"<<propname<<
"' (id #"<<propId<<
") to "<<propvalue<<
"" ) ;
456 void KLFLibDBEngine::readDbMetaInfo()
459 q.
prepare(
"SELECT name,value FROM klf_dbmetainfo");
469 pDBVersion = version.
toInt();
473 void KLFLibDBEngine::readAvailColumns(
const QString& subResource)
478 for (k = 0; k < rec.
count(); ++k)
481 pDBAvailColumns[subResource] = columns;
493 for (k = 0; k < entryPropList.
size(); ++k) {
495 if (pDBAvailColumns[subResource].contains(col))
500 if (entryPropList.
size() == 0) {
503 if (wantIdFirst && (!cols.size() || cols[0] !=
"id") )
515 for (k = 0; k < rec.
count(); ++k) {
518 if (propId < 0 && propName !=
"id") {
519 klfDbg(
"Registering property "<<propName ) ;
532 for (k = 0; k < cols.size(); ++k) {
537 QVariant value = dbReadEntryPropertyValue(q.
value(k), propId);
547 klfDbg(
": missing or incorrect preview size set to "<<entry.
preview().
size() ) ;
561 q.
prepare(
QString(
"SELECT id FROM %1").arg(quotedDataTableName(subResource)));
565 qWarning(
"KLFLibDBEngine::allIds: Error fetching IDs!\n"
566 "SQL Error: %s", qPrintable(q.
lastError().text()));
571 idlist << q.
value(0).toInt();
581 q.
prepare(
QString(
"SELECT id FROM %1 WHERE id = ?").arg(quotedDataTableName(subResource)));
585 qWarning(
"KLFLibDBEngine::hasEntry: Error!\n"
586 "SQL Error: %s", qPrintable(q.
lastError().text()));
603 QStringList cols = columnNameList(subResource, wantedEntryProperties,
true);
607 << pDBAvailColumns[subResource];
612 quotedDataTableName(subResource)));
621 for (k = 0; k < idList.
size(); ++k) {
623 progr.doReportProgress(k);
629 qWarning(
"KLFLibDBEngine::entries: Error\n"
630 "SQL Error (?): %s", qPrintable(q.
lastError().text()));
634 klfDbg(
": id="<<idList[k]<<
" does not exist in DB." ) ;
641 e.
entry = readEntry(q, cols);
646 progr.doReportProgress(idList.
size());
655 return "'" + s +
"'";
680 return field+
" LIKE '"+val+
"' ESCAPE '\\' ";
691 *haspostsqlcondition =
false;
703 switch ( f & 0xFF ) {
704 case Qt::MatchExactly:
705 condition += field+
" = ?";
706 if ((f & Qt::CaseSensitive) == 0)
707 condition +=
" COLLATE NOCASE";
708 if (f & Qt::MatchFixedString)
713 condition +=
" OR "+field+
" IS NULL";
715 case Qt::MatchContains:
718 case Qt::MatchStartsWith:
721 case Qt::MatchEndsWith:
724 case Qt::MatchRegExp:
726 *haspostsqlcondition =
true;
727 *postsqlcondition = m;
730 case Qt::MatchWildcard:
731 if (f & Qt::CaseSensitive) {
732 condition += field+
" GLOB ? ";
734 condition +=
" lower("+field+
") GLOB lower(?) ";
739 qWarning()<<
KLF_FUNC_NAME<<
": unknown property match type flags: "<<f ;
747 qWarning()<<
KLF_FUNC_NAME<<
": condition list is empty for NOT match type!";
752 haspostsqlcondition, &postm) ;
753 if (*haspostsqlcondition) {
760 static const char *w_and =
" AND ";
761 static const char *w_or =
" OR ";
769 for (k = 0; k < clist.
size(); ++k) {
776 &thishaspostsql, &thispostm) ;
777 if (thishaspostsql) {
778 postconditionlist.
append(thispostm);
782 if (postconditionlist.
size()) {
783 *haspostsqlcondition =
true;
797 klfDbg(
"\t: subResource="<<subResource<<
"; query="<<query ) ;
806 sql =
QString(
"SELECT %1 FROM %2 ").arg(cols.
join(
","), quotedDataTableName(subResource));
807 QVariantList placeholders;
808 bool haspostsqlcondition =
false;
812 sql +=
" WHERE "+wherecond;
815 if (haspostsqlcondition) {
817 klfDbg(
"You are using a feature that is not natively implemented in KLFLibDBEngine: falling back to "
818 "rudimentary and slow implementation!");
827 if (query.
limit != -1) {
831 klfDbg(
"Built query: SQL="<<sql<<
"; placeholders="<<placeholders) ;
837 for (k = 0; k < placeholders.size(); ++k)
844 <<
"\nSql was="<<sql<<
"; bound values="<<q.
boundValues();
850 cols = detectEntryColumns(q);
864 while (skipped < query.
skip && (ok = q.
next()))
866 klfDbg(
"skipped "<<skipped<<
" entries.") ;
871 while (ok && q.
next()) {
872 if (count % 10 == 0 && count < N) {
879 e.
entry = readEntry(q, cols);
891 klfDbg(
"got "<<count<<
" entries.") ;
897 klfDbg(
"\t: subResource="<<subResource<<
"; entryPropId="<<entryPropId ) ;
903 qWarning()<<
KLF_FUNC_NAME<<
": bad sub-resource: "<<subResource;
904 return QVariantList();
910 qWarning()<<
KLF_FUNC_NAME<<
": Invalid property ID "<<entryPropId;
911 return QVariantList();
914 if (!pDBAvailColumns[subResource].contains(pname)) {
915 qWarning()<<
KLF_FUNC_NAME<<
": property "<<pname<<
" is not available in tables for sub-res "<<subResource
916 <<
" (avail are "<<pDBAvailColumns[subResource]<<
")";
917 return QVariantList();
920 QString sql =
"SELECT DISTINCT "+pname+
" FROM "+quotedDataTableName(subResource);
928 <<
"\nSQL was: "<<sql;
929 return QVariantList();
934 list << dbReadEntryPropertyValue(q.
value(0), entryPropId);
935 klfDbg(
"adding value "<<list.last().toString()) ;
949 q.
prepare(
QString(
"SELECT * FROM %1 WHERE id = ?").arg(quotedDataTableName(subResource)));
954 qWarning(
"KLFLibDBEngine::entry: id=%d cannot be found!\n"
955 "SQL Error (?): %s",
id, qPrintable(q.
lastError().text()));
963 qWarning(
"KLFLibDBEngine::entry(): no entry available!\n"
964 "SQL=\"%s\" (?=%d)", qPrintable(q.
lastQuery()),
id);
969 KLFLibEntry e = readEntry(q, detectEntryColumns(q));
981 QStringList cols = columnNameList(subResource, wantedEntryProperties,
true);
984 q.
prepare(
QString(
"SELECT %1 FROM %2 ORDER BY id ASC").arg(cols.
join(
","), quotedDataTableName(subResource)));
995 cols = detectEntryColumns(q);
997 int count = q.
size();
1009 e.
entry = readEntry(q, cols);
1045 q.
prepare(
"SELECT pvalue FROM klf_subresprops WHERE lower(subresource) = lower(?) AND pid = ?");
1046 q.
addBindValue(QVariant::fromValue<QString>(subResource));
1050 qWarning()<<
"KLFLibDBEngine::subResourceProperty("<<subResource<<
","<<propId<<
"): SQL Error: "
1052 klfDbg(
"DB: "<<pDB.connectionName());
1067 return convertVariantFromDBData(q.
value(0));
1073 return tableExists(subRes);
1084 for (k = 0; k < allTables.size(); ++k) {
1085 if (allTables[k].startsWith(
"t_"))
1086 subreslist << allTables[k].mid(2);
1104 klfDbg(
": setting sub-resource property "<<propId<<
" to "<<value<<
" in sub-res "
1108 klfDbg(
"property already has the requested value "<<value<<
".");
1114 q.
prepare(
"DELETE FROM klf_subresprops WHERE lower(subresource) = lower(?) and pid = ?");
1119 qWarning()<<
"KLFLibDBEngine::setSubRes.Prop.("<<subResource<<
","<<propId<<
","<<value<<
"):"
1126 q.
prepare(
"INSERT INTO klf_subresprops (subresource,pid,pvalue) VALUES (?,?,?)");
1129 q.
bindValue(2, convertVariantToDBData(value));
1131 qWarning()<<
"KLFLibDBEngine::setSubRes.Prop.("<<subResource<<
","<<propId<<
","<<value<<
"):"
1137 dbPropertyNotifierInstance(pDB.connectionName())
1138 ->notifySubResourcePropertyChanged(subResource, propId);
1148 QVariant KLFLibDBEngine::dbMakeEntryPropertyValue(
const QVariant& entryval,
int propertyId)
1151 return QVariant::fromValue<QString>(entryval.
toString());
1153 return QVariant::fromValue<qulonglong>(entryval.
toDateTime().toTime_t());
1157 return QVariant::fromValue<QString>(entryval.
toString());
1159 return QVariant::fromValue<QString>(entryval.
toString());
1162 return QVariant::fromValue<qulonglong>( (((qulonglong)s.
width()) << 32) |
1163 (((qulonglong)s.
height()) & 0xFFFFFFFF) );
1166 return convertVariantToDBData(entryval);
1168 QVariant KLFLibDBEngine::dbReadEntryPropertyValue(
const QVariant& dbdata,
int propertyId)
1177 return QVariant::fromValue<QImage>(img);
1185 int w = (int)((val>>32) & 0xFFFFFFFF) ;
1186 int h = (int)(val & 0xFFFFFFFF) ;
1187 return QVariant::fromValue<QSize>(
QSize(w, h));
1190 return convertVariantFromDBData(dbdata);
1198 QVariant KLFLibDBEngine::convertVariantToDBData(
const QVariant& value)
const
1205 int t = value.
type();
1207 if (t == QVariant::Int || t == QVariant::UInt || t == QVariant::LongLong || t == QVariant::ULongLong ||
1208 t == QVariant::Double || t == QVariant::Bool)
1212 if (t == QVariant::String)
1213 return encaps(ts, value.
toString());
1216 if (t == QVariant::ByteArray)
1218 if (t == QVariant::DateTime)
1220 if (t == QVariant::Image)
1225 {
QDataStream stream(&valuedata, QIODevice::WriteOnly);
1226 stream.setVersion(QDataStream::Qt_4_4);
1228 return encaps(ts, valuedata);
1231 QVariant KLFLibDBEngine::encaps(
const char *ts,
const QString& data)
const
1233 return QVariant::fromValue<QString>(
QString(
"[")+ts+
"]"+data);
1242 return QVariant::fromValue<QByteArray>(edata);
1244 QVariant KLFLibDBEngine::convertVariantFromDBData(
const QVariant& dbdata)
const
1249 int t = dbdata.
type();
1250 if (t == QVariant::Int || t == QVariant::UInt || t == QVariant::LongLong || t == QVariant::ULongLong ||
1251 t == QVariant::Double || t == QVariant::Bool)
1254 if (t == QVariant::String)
1256 if (t == QVariant::ByteArray)
1259 qWarning()<<
"Unexpected DB data variant found: "<<dbdata;
1264 return decaps(sdata.
toUtf8());
1274 for (k = 1; k < data.
size() && data[k] !=
']'; ++k) ;
1275 if (k >= data.
size()) {
1276 qWarning()<<
"KLFLibDBEngine::decaps(QB.A.): bad data:"<<data;
1282 if (typenam ==
"bool") {
1284 return QVariant::fromValue<bool>(svaluedata[0] !=
'0' ||
1285 (svaluedata !=
"1" && (svaluedata[0].
toLower() ==
't' ||
1286 svaluedata[0].
toLower() ==
'y' ||
1287 svaluedata.
toInt() != 0)) );
1289 if (typenam ==
"QString")
1291 if (typenam ==
"QByteArray")
1292 return QVariant::fromValue<QByteArray>(valuedata);
1293 if (typenam ==
"QDateTime")
1295 if (typenam ==
"QImage") {
1298 return QVariant::fromValue<QImage>(img);
1305 stream.setVersion(QDataStream::Qt_4_4);
1310 bool KLFLibDBEngine::ensureDataTableColumnsExist(
const QString& subResource,
const QStringList& columnList)
1314 bool failed =
false;
1315 for (k = 0; k < columnList.size(); ++k) {
1316 if (columnList[k] ==
"*")
1321 sql.
prepare(
"ALTER TABLE "+quotedDataTableName(subResource)+
" ADD COLUMN "+columnList[k]+
" BLOB");
1322 bool r = sql.
exec();
1324 qWarning()<<
"KLFLibDBEngine::ensureDataTableColumnsExist("<<subResource<<
"): Can't add column "
1330 readAvailColumns(subResource);
1334 bool KLFLibDBEngine::ensureDataTableColumnsExist(
const QString& subResource)
1339 return ensureDataTableColumnsExist(subResource, propNameList);
1355 q.
prepare(
QString(
"DROP TABLE %1").arg(quotedDataTableName(subResource)));
1358 qWarning()<<
KLF_FUNC_NAME<<
"("<<subResource<<
"): SQL Error: "
1367 QString newDefaultSubResource;
1371 newDefaultSubResource =
QString();
1389 qWarning()<<
"KLFLibDBEngine::createSubResource: Sub-Resource "<<subResource<<
" already exists!";
1393 bool r = createFreshDataTable(pDB, subResource);
1398 title = subResource;
1418 klfDbg(
"subres="<<subres<<
"; entrylist="<<entrylist) ;
1420 if ( entrylist.
size() == 0 ) {
1425 klfDbg(
"can't modify data.") ;
1429 if ( !tableExists(subres) ) {
1430 qWarning()<<
KLF_FUNC_NAME<<
": Sub-Resource "<<subres<<
" does not exist.";
1438 for (k = 0; k < propids.
size(); ++k) {
1440 questionmarks <<
"?";
1445 ensureDataTableColumnsExist(subres);
1452 q.
prepare(
"INSERT INTO " + quotedDataTableName(subres) +
" (" + props.
join(
",") +
") "
1453 " VALUES (" + questionmarks.
join(
",") +
")");
1456 for (j = 0; j < entrylist.
size(); ++j) {
1458 progr.doReportProgress(j);
1460 for (k = 0; k < propids.
size(); ++k) {
1461 QVariant data = dbMakeEntryPropertyValue(entrylist[j].
property(propids[k]), propids[k]);
1463 klfDbg(
"Binding value "<<k<<
": "<<data ) ;
1469 qWarning()<<
"INSERT failed! SQL Error: "<<q.
lastError().text()<<
"\n\tSQL="<<q.
lastQuery();
1476 insertedIds << v_id.
toInt();
1482 progr.doReportProgress(entrylist.
size());
1497 if ( !tableExists(subResource) ) {
1498 qWarning()<<
KLF_FUNC_NAME<<
": Sub-Resource "<<subResource<<
" does not exist.";
1502 if ( properties.
size() != values.
size() ) {
1503 qWarning(
"KLFLibDBEngine::changeEntry(): properties' and values' sizes mismatch!");
1507 if ( idlist.
size() == 0 )
1510 klfDbg(
"KLFLibDBEngine::changeEntries: funcional tests passed; idlist="<<idlist<<
" props="
1511 <<properties<<
" vals="<<values ) ;
1513 ensureDataTableColumnsExist(subResource);
1518 for (k = 0; k < properties.
size(); ++k) {
1524 .arg(quotedDataTableName(subResource), updatepairs.
join(
",")));
1525 for (k = 0; k < properties.
size(); ++k) {
1526 q.
bindValue(k, dbMakeEntryPropertyValue(values[k], properties[k]));
1528 const int idBindValueNum = k;
1534 bool failed =
false;
1535 for (k = 0; k < idlist.
size(); ++k) {
1537 progr.doReportProgress(k);
1542 qWarning() <<
"SQL UPDATE Error: "<<q.
lastError().text()<<
"\nWith SQL="<<q.
lastQuery()
1548 progr.doReportProgress(idlist.
size());
1559 if (idlist.
size() == 0)
1564 if ( !tableExists(subResource) ) {
1565 qWarning()<<
KLF_FUNC_NAME<<
": Sub-Resource "<<subResource<<
" does not exist.";
1570 bool failed =
false;
1572 QString sql =
QString(
"DELETE FROM %1 WHERE id = ?").arg(quotedDataTableName(subResource));
1574 klfDbg(
"sql is "<<sql<<
", idlist is "<<idlist) ;
1583 for (k = 0; k < idlist.
size(); ++k) {
1585 progr.doReportProgress(k);
1596 progr.doReportProgress(idlist.
size());
1606 if (!newPath.
host().isEmpty()) {
1607 qWarning()<<
"KLFLibDBEngine::saveTo("<<newPath<<
"): Expected empty host!";
1612 qWarning()<<
"KLFLibDBEngine::saveTo("<<newPath<<
"): Bad scheme!";
1617 bool KLFLibDBEngine::initFreshDatabase(
QSqlDatabase db)
1625 sql <<
"CREATE TABLE klf_properties (id INTEGER PRIMARY KEY, name TEXT, value BLOB)";
1626 sql <<
"INSERT INTO klf_properties (name, value) VALUES ('Title', 'New Resource')";
1627 sql <<
"INSERT INTO klf_properties (name, value) VALUES ('Locked', 'false')";
1628 sql <<
"CREATE TABLE klf_dbmetainfo (id INTEGER PRIMARY KEY, name TEXT, value BLOB)";
1629 sql <<
"INSERT INTO klf_dbmetainfo (name, value) VALUES ('klf_version', '" KLF_VERSION_STRING
"')";
1630 sql <<
"INSERT INTO klf_dbmetainfo (name, value) VALUES ('klf_dbversion', '"+
1632 sql <<
"CREATE TABLE klf_subresprops (id INTEGER PRIMARY KEY, pid INTEGER, subresource TEXT, pvalue BLOB)";
1635 for (k = 0; k < sql.size(); ++k) {
1637 query.prepare(sql[k]);
1638 bool r =
query.exec();
1639 if ( !r ||
query.lastError().isValid() ) {
1640 qWarning()<<
"KLFLibDBEngine::initFreshDatabase(): SQL Error: "<<
query.lastError().text()<<
"\n"
1651 qDebug(
"KLFLibDBEngine::createFreshDataTable(.., '%s')", qPrintable(subres));
1652 QString datatablename = dataTableName(subres);
1654 qWarning(
"KLFLibDBEngine::createFreshDataTable(..,%s): DB is not open!", qPrintable(subres));
1658 if ( db.
tables().contains(datatablename) ) {
1659 qWarning(
"KLFLibDBEngine::createFreshDataTable(..,%s): table %s exists!", qPrintable(subres),
1660 qPrintable(datatablename));
1663 QString qdtname = quotedDataTableName(subres);
1668 "CREATE TABLE "+qdtname+
" (id INTEGER PRIMARY KEY, Latex TEXT, DateTime TEXT, "
1669 " Preview BLOB, PreviewSize TEXT, Category TEXT, Tags TEXT, Style BLOB)");
1670 bool r =
query.exec();
1671 if ( !r ||
query.lastError().isValid() ) {
1672 qWarning()<<
"createFreshDataTable(): SQL Error: "<<
query.lastError().text()<<
"\n"
1673 <<
"SQL="<<
query.lastQuery();
1705 if (!pDBPropertyNotifiers.
contains(dbname))
1707 return pDBPropertyNotifiers[dbname];
1712 #define MAGIC_SQLITE_HEADER_LEN 16
1718 = { 0x53, 0x51, 0x4c, 0x69, 0x74, 0x65, 0x20, 0x66,
1719 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x33, 0x00 };
1722 klfDbg(
"guessing scheme of "<<fileName) ;
1728 if ( ! f.
open(QIODevice::ReadOnly) ) {
1729 klfDbg(
"Yikes, can't read file "<<fileName);
1736 klfDbg(
"Nope-can't read header.");
1741 klfDbg(
"Yep, it's klf-sqlite!");
1745 klfDbg(
"Nope-bad header.");
1771 return tr(
"Local Library Database File");
1780 qWarning()<<
"KLFLibDBEngineFactory::schemeFunctions: Bad scheme: "<<scheme;
1801 QString defsubres = parameters[
"klfDefaultSubResource"].toString();
1802 QString defsubrestitle = parameters[
"klfDefaultSubResourceTitle"].toString();
1804 defsubres =
"entries";
1806 defsubrestitle =
tr(
"Default Table",
"[[default sub-resource title]]");
1811 if ( !parameters.
contains(
"Filename") ) {
1813 <<
"KLFLibLegacyEngineFactory::createResource: bad parameters. They do not contain `Filename': "
1819 defsubrestitle, parent);
1820 qWarning()<<
"KLFLibDBEngineFactory::createResource("<<scheme<<
","<<parameters<<
","<<parent<<
"):"
virtual int query(const QString &subResource, const Query &query, QueryResult *result)
void doReportProgress(int value)
virtual void setDefaultSubResource(const QString &subResource)
Set the default sub-resource.
virtual bool changeEntries(const QString &subRes, const QList< entryId > &idlist, const QList< int > &properties, const QList< QVariant > &values)
loadFromData(const uchar *data, int len, const char *format=0)
append(const QByteArray &ba)
virtual KLFLibResourceEngine * openResource(const QUrl &location, QObject *parent=NULL)
toString(const QString &format)
A structure that describes a query for query()
A cached value of the size of value in Preview.
const Qt::MatchFlags matchFlags() const
int setEntryProperty(const QString &propName, const QVariant &value)
entries have to match with one of a list of conditions
KLF_EXPORT uint klfUrlCompare(const QUrl &url1, const QUrl &url2, uint interestFlags, const QStringList &interestQueryItems)
virtual QString schemeTitle(const QString &scheme) const
save(const QString &fileName, const char *format=0, int quality=-1)
static T metatype_from_data(const QByteArray &data)
exec(const QString &query)
contains(const QString &name)
database(const QString &connectionName=QLatin1String(defaultConnection)
contains(const QString &str, Qt::CaseSensitivity cs=Qt::CaseSensitive)
static QString escape_sql_data_string(QString s)
virtual void setProperty(const QString &propname, const QVariant &value)
#define klfDbg(streamableItems)
addDatabase(const QString &type, const QString &connectionName=QLatin1String(defaultConnection)
#define KLF_DEBUG_BLOCK(msg)
Qt::SortOrder orderDirection
virtual bool hasSubResource(const QString &subRes) const
QString guessScheme(const QString &fileName) const
Matches entries that don't match a condition.
virtual uint compareUrlTo(const QUrl &other, uint interestFlags=0xfffffff) const
virtual QString correspondingWidgetType(const QString &scheme) const
prepend(const QString &str)
QList< int > registeredPropertyIdList() const
virtual QList< entryId > insertEntries(const QString &subRes, const KLFLibEntryList &entries)
record(const QString &tablename)
join(const QString &separator)
hasQueryItem(const QString &key)
QString pDBConnectionName
static EntryMatchCondition mkMatchAll()
toString(FormattingOptions options=None)
static KLFLibDBEngine * openUrl(const QUrl &url, QObject *parent=NULL)
tr(const char *sourceText, const char *comment=0, int n=-1)
virtual bool setSubResourceProperty(const QString &subResource, int propId, const QVariant &value)
virtual bool canCreateSubResource() const
QList< KLFLibEntryWithId > entryWithIdList
copy(const QString &newName)
replace(int position, int n, const QString &after)
The Latex Code of the equation.
virtual bool deleteEntries(const QString &subRes, const QList< entryId > &idlist)
int registerProperty(const QString &propertyName) const
number(long n, int base=10)
append(const QString &str)
prepare(const QString &query)
void dataChanged(const QString &subResource, int modificationType, const QList< KLFLib::entryId > &entryIdList)
Emitted when data has changed.
bool propertyIdRegistered(int propId) const
bool thisOperationProgressBlocked() const
static EntryMatchCondition mkOrMatch(QList< EntryMatchCondition > conditions)
removeDatabase(const QString &connectionName)
fromUtf8(const char *str, int size=-1)
virtual bool hasEntry(const QString &, entryId id)
void subResourceCreated(const QString &newSubResource)
Emitted when a sub-resource is created.
virtual bool compareDefaultSubResourceEquals(const QString &subResourceName) const
property(const char *name)
It's possible to modify that something.
KLF_EXPORT QString klfUrlLocalFilePath(const QUrl &url)
void subResourceDeleted(const QString &subResource)
Emitted when a sub-resource is deleted.
virtual QList< KLFLib::entryId > allIds()
Returns all IDs in this resource (and the default sub-resource)
QList< KLFLib::entryId > entryIdList
virtual QList< QVariant > queryValues(const QString &subResource, int entryPropId)
bindValue(const QString &placeholder, const QVariant &val, QSql::ParamType paramType=QSql::In)
const QString matchValueString() const
void resourcePropertyChanged(int propId)
Emitted when a resource property changes.
removeAllQueryItems(const QString &key)
toInt(bool *ok=0, int base=10)
virtual bool createSubResource(const QString &subResource, const QString &subResourceTitle)
setScheme(const QString &scheme)
KLFLibEntryList rawEntryList
endsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive)
compare(const QString &s1, const QString &s2, Qt::CaseSensitivity cs)
static QByteArray metatype_to_data(const T &object)
int propertyIdForName(const QString &propertyName) const
virtual KLFLibEntry entry(const QString &subRes, entryId id)
The Category to which eq. belongs (path-style string)
virtual void setDatabase(const QSqlDatabase &db_connection)
setForwardOnly(bool forward)
virtual QList< KLFLibEntryWithId > entries(const QString &, const QList< KLFLib::entryId > &idList, const QList< int > &wantedEntryProperties=QList< int >())
void subResourcePropertyChanged(const QString &subResource, int propId)
Emitted when a sub-resource property changes.
virtual QList< KLFLibEntryWithId > allEntries(const QString &subRes, const QList< int > &wantedEntryProperties=QList< int >())
static QString makeSubResInternalName(const QString &title)
virtual QString defaultSubResource() const
#define KLF_DEBUG_TIME_BLOCK(msg)
void setPreviewSize(const QSize &sz)
static QByteArray image_data(const QImage &img, const char *format)
virtual bool canModifyData(const QString &subResource, ModifyType modifytype) const
virtual ~KLFLibDBEngine()
contains(const QString &str, Qt::CaseSensitivity cs=Qt::CaseSensitive)
Tags about the equation (string)
virtual bool canModifyProp(int propid) const
fromString(const QString &string, Qt::DateFormat format=Qt::TextDate)
virtual QString title() const
The human-set title of this resource.
QStringList registeredPropertyNameList() const
static KLFLibDBEngine * createSqlite(const QString &fileName, const QString &subresourcename, const QString &subresourcetitle, QObject *parent=NULL)
virtual uint schemeFunctions(const QString &scheme) const
bool propertyNameRegistered(const QString &propertyName) const
entries have to match with all given conditions
A structure that will hold the result of a query() query.
static QString make_like_condition(QString field, QString val, bool wildbefore, bool wildafter, bool casesensitive)
static EntryMatchCondition mkNegateMatch(const EntryMatchCondition &condition)
static int queryImpl(KLFLibResourceEngine *resource, const QString &subResource, const Query &query, QueryResult *result)
An entry (single formula) in the library.
virtual QStringList supportedTypes() const
void defaultSubResourceChanged(const QString &newDefaultSubResource)
Emitted when the default sub-resource changes.
QList< int > wantedEntryProperties
#define klfDbgSt(streamableItems)
An Image Preview of equation (scaled down QImage)
#define MAGIC_SQLITE_HEADER_LEN
critical(QWidget *parent, const QString &title, const QString &text, StandardButtons buttons=Ok, StandardButton defaultButton=NoButton)
Matches a property ID with a string (with a StringMatch)
virtual bool validDatabase() const
tables(QSql::TableType type=QSql::Tables)
fromLatin1(const char *str, int size=-1)
virtual bool canRegisterProperty(const QString &propName) const
virtual KLFLibResourceEngine * createResource(const QString &scheme, const Parameters ¶meters, QObject *parent=NULL)
addQueryItem(const QString &key, const QString &value)
virtual bool saveResourceProperty(int propId, const QVariant &value)
virtual QVariant property(const QString &propName) const
A KLFLibEntry in combination with a KLFLib::entryId.
virtual QStringList subResourceList() const
setDatabaseName(const QString &name)
virtual ~KLFLibDBConnectionClassUser()
virtual ModifyStatus baseCanModifyStatus(bool inSubResource, const QString &subResource=QString()) const
can modify data in resource (base common tests only)
virtual QUrl url(uint flags=0x0) const
query URL
virtual bool saveTo(const QUrl &newPath)
#define KLF_ASSERT_CONDITION(expr, msg, failaction)
Type type() const
Get which type of condition this is.
An abstract resource engine.
addBindValue(const QVariant &val, QSql::ParamType paramType=QSql::In)
QString propertyNameForId(int propId) const
The Date/Time at which the equation was evaluated.
connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type=Qt::AutoCompatConnection)
bool deRef()
Returns TRUE if the object needs to be deleted.
KLFLib::EntryMatchCondition matchCondition
virtual bool canDeleteSubResource(const QString &subResource) const
KLFLibDBEngineFactory(QObject *parent=NULL)
virtual bool canModifyProp(int propId) const
static QString make_sql_condition(const KLFLib::EntryMatchCondition m, QVariantList *placeholders, bool *haspostsqlcondition, KLFLib::EntryMatchCondition *postsqlcondition)
virtual bool canModifyData(const QString &subRes, ModifyType modifytype) const
queryItemValue(const QString &key)
void operationStartReportingProgress(KLFProgressReporter *progressReporter, const QString &descriptiveText)
virtual QVariant subResourceProperty(const QString &subResource, int propId) const
KLFLibDBConnectionClassUser()
fromLocalFile(const QString &localFile)
PropertyMatch propertyMatch() const
Relevant for type PropertyMatchType.
virtual bool deleteSubResource(const QString &subResource)
QList< EntryMatchCondition > conditionList() const
Relevant for types OrMatchType and AndMatchType.