summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/src/object-indexes.qdoc9
-rw-r--r--src/daemon/jsondbindex.cpp13
-rw-r--r--src/daemon/jsondbindex.h7
-rw-r--r--src/daemon/jsondbobjecttable.cpp11
-rw-r--r--src/daemon/jsondbobjecttable.h5
-rw-r--r--src/daemon/jsondbpartition.cpp47
-rw-r--r--src/daemon/jsondbpartition.h6
-rw-r--r--src/daemon/jsondbreducedefinition.cpp3
-rw-r--r--src/daemon/schema/Index.json1
-rw-r--r--tests/auto/client/test-jsondb-client.cpp63
-rw-r--r--tests/auto/daemon/json/map-reduce.json4
11 files changed, 138 insertions, 31 deletions
diff --git a/doc/src/object-indexes.qdoc b/doc/src/object-indexes.qdoc
index ecf92f7..505b0b0 100644
--- a/doc/src/object-indexes.qdoc
+++ b/doc/src/object-indexes.qdoc
@@ -52,6 +52,15 @@ specified, name defaults to propertyName. If propertyFunction is
specified, then name must be specified.
\row
+\li objectType
+\li An optional string or array of strings, naming the object types to
+be indexed. If not specified, all objects in the main object table of
+a partition will be indexed.
+
+If specified for non-view types, the index should have a name that is
+distinct from its propertyName.
+
+\row
\li propertyName
\li A string or array of strings, naming the properties to be
indexed. Mutually exclusive with propertyFunction.
diff --git a/src/daemon/jsondbindex.cpp b/src/daemon/jsondbindex.cpp
index 586fd00..6c95015 100644
--- a/src/daemon/jsondbindex.cpp
+++ b/src/daemon/jsondbindex.cpp
@@ -100,10 +100,12 @@ JsonDbCollator::CasePreference _q_correctCasePreferenceString(const QString &s)
#else
int _q_correctCollationString(const QString &s)
{
+ Q_UNUSED(s);
return 0;
}
int _q_correctCasePreferenceString(const QString &s)
{
+ Q_UNUSED(s);
return 0;
}
#endif //NO_COLLATION_SUPPORT
@@ -130,13 +132,15 @@ QString _q_bytesToHexString(const QByteArray &ba)
}
JsonDbIndex::JsonDbIndex(const QString &fileName, const QString &indexName, const QString &propertyName,
- const QString &propertyType, const QString &locale, const QString &collation,
+ const QString &propertyType, const QStringList &objectType, const QString &locale, const QString &collation,
const QString &casePreference, Qt::CaseSensitivity caseSensitivity, JsonDbObjectTable *objectTable)
: QObject(objectTable)
, mObjectTable(objectTable)
+ , mIndexName(indexName)
, mPropertyName(propertyName)
, mPath(propertyName.split('.'))
, mPropertyType(propertyType)
+ , mObjectType(objectType)
, mLocale(locale)
, mCollation(collation)
, mCasePreference(casePreference)
@@ -239,7 +243,7 @@ bool JsonDbIndex::validateIndex(const JsonDbObject &newIndex, const JsonDbObject
message = QString("Changing old index propertyType from '%1' to '%2' not supported")
.arg(oldIndex.value(JsonDbString::kPropertyTypeStr).toString())
.arg(newIndex.value(JsonDbString::kPropertyTypeStr).toString());
- else if (oldIndex.value(JsonDbString::kObjectTypeStr).toString() != newIndex.value(JsonDbString::kObjectTypeStr).toString())
+ else if (oldIndex.value(JsonDbString::kObjectTypeStr) != newIndex.value(JsonDbString::kObjectTypeStr))
message = QString("Changing old index objectType from '%1' to '%2' not supported")
.arg(oldIndex.value(JsonDbString::kObjectTypeStr).toString())
.arg(newIndex.value(JsonDbString::kObjectTypeStr).toString());
@@ -330,6 +334,9 @@ void JsonDbIndex::indexObject(const ObjectKey &objectKey, JsonDbObject &object,
if (mPropertyName == JsonDbString::kUuidStr)
return;
+ if (!mObjectType.isEmpty() && !mObjectType.contains(object.value(JsonDbString::kTypeStr).toString()))
+ return;
+
Q_ASSERT(!object.contains(JsonDbString::kDeletedStr)
&& !object.value(JsonDbString::kDeletedStr).toBool());
QList<QJsonValue> fieldValues = indexValues(object);
@@ -371,6 +378,8 @@ void JsonDbIndex::deindexObject(const ObjectKey &objectKey, JsonDbObject &object
{
if (mPropertyName == JsonDbString::kUuidStr)
return;
+ if (!mObjectType.isEmpty() && !mObjectType.contains(object.value(JsonDbString::kTypeStr).toString()))
+ return;
if (!mBdb)
open();
QList<QJsonValue> fieldValues = indexValues(object);
diff --git a/src/daemon/jsondbindex.h b/src/daemon/jsondbindex.h
index 2cc9bcf..05569aa 100644
--- a/src/daemon/jsondbindex.h
+++ b/src/daemon/jsondbindex.h
@@ -73,7 +73,7 @@ class JsonDbIndex : public QObject
Q_OBJECT
public:
JsonDbIndex(const QString &fileName, const QString &indexName, const QString &propertyName,
- const QString &propertyType, const QString &locale, const QString &collation,
+ const QString &propertyType, const QStringList &objectType, const QString &locale, const QString &collation,
const QString &casePreference, Qt::CaseSensitivity caseSensitivity,
JsonDbObjectTable *objectTable);
~JsonDbIndex();
@@ -81,6 +81,7 @@ public:
QString propertyName() const { return mPropertyName; }
QStringList fieldPath() const { return mPath; }
QString propertyType() const { return mPropertyType; }
+ QStringList objectType() const { return mObjectType; }
JsonDbManagedBtree *bdb();
@@ -114,9 +115,11 @@ private slots:
private:
JsonDbObjectTable *mObjectTable;
QString mFileName;
+ QString mIndexName;
QString mPropertyName;
QStringList mPath;
QString mPropertyType;
+ QStringList mObjectType;
QString mLocale;
QString mCollation;
QString mCasePreference;
@@ -167,7 +170,7 @@ public:
QString collation;
QString casePreference;
Qt::CaseSensitivity caseSensitivity;
- QString objectType;
+ QStringList objectType;
bool lazy;
QPointer<JsonDbIndex> index;
};
diff --git a/src/daemon/jsondbobjecttable.cpp b/src/daemon/jsondbobjecttable.cpp
index 0b6a094..7557783 100644
--- a/src/daemon/jsondbobjecttable.cpp
+++ b/src/daemon/jsondbobjecttable.cpp
@@ -250,7 +250,7 @@ QHash<QString, IndexSpec> JsonDbObjectTable::indexSpecs() const
}
bool JsonDbObjectTable::addIndex(const QString &indexName, const QString &propertyName,
- const QString &propertyType, const QString &objectType, const QString &propertyFunction,
+ const QString &propertyType, const QStringList &objectTypes, const QString &propertyFunction,
const QString &locale, const QString &collation, const QString &casePreference,
Qt::CaseSensitivity caseSensitivity)
{
@@ -274,9 +274,9 @@ bool JsonDbObjectTable::addIndex(const QString &indexName, const QString &proper
indexSpec.collation = collation;
indexSpec.casePreference = casePreference;
indexSpec.caseSensitivity = caseSensitivity;
- indexSpec.objectType = objectType;
+ indexSpec.objectType = objectTypes;
indexSpec.lazy = false; //lazy;
- indexSpec.index = new JsonDbIndex(mFilename, name, propertyName, propertyType, locale, collation, casePreference, caseSensitivity, this);
+ indexSpec.index = new JsonDbIndex(mFilename, name, propertyName, propertyType, objectTypes, locale, collation, casePreference, caseSensitivity, this);
if (!propertyFunction.isEmpty() && propertyName.isEmpty()) // propertyName takes precedence
indexSpec.index->setPropertyFunction(propertyFunction);
indexSpec.index->setCacheSize(jsondbSettings->cacheSize());
@@ -292,7 +292,10 @@ bool JsonDbObjectTable::addIndex(const QString &indexName, const QString &proper
indexObject.insert(JsonDbString::kCollationStr, collation);
indexObject.insert(JsonDbString::kCaseSensitiveStr, (bool)caseSensitivity);
indexObject.insert(JsonDbString::kCasePreferenceStr, casePreference);
- indexObject.insert(JsonDbString::kObjectTypeStr, objectType);
+ QJsonArray objectTypeList;
+ foreach (const QString objectType, objectTypes)
+ objectTypeList.append(objectType);
+ indexObject.insert(JsonDbString::kObjectTypeStr, objectTypeList);
indexObject.insert("lazy", false);
indexObject.insert(JsonDbString::kPropertyFunctionStr, propertyFunction);
Q_ASSERT(!name.isEmpty());
diff --git a/src/daemon/jsondbobjecttable.h b/src/daemon/jsondbobjecttable.h
index 78ba241..f122006 100644
--- a/src/daemon/jsondbobjecttable.h
+++ b/src/daemon/jsondbobjecttable.h
@@ -141,7 +141,7 @@ public:
bool addIndex(const QString &indexName,
const QString &propertyName = QString(),
const QString &propertyType = QString("string"),
- const QString &objectType = QString(),
+ const QStringList &objectTypes = QStringList(),
const QString &propertyFunction = QString(),
const QString &locale = QString(),
const QString &collation = QString(),
@@ -150,7 +150,8 @@ public:
bool addIndexOnProperty(const QString &propertyName,
const QString &propertyType = QString("string"),
const QString &objectType = QString())
- { return addIndex(propertyName, propertyName, propertyType, objectType); }
+ { return addIndex(propertyName, propertyName, propertyType,
+ objectType.isEmpty() ? QStringList() : (QStringList() << objectType)); }
bool removeIndex(const QString &indexName);
void reindexObjects(const QString &indexName, const QStringList &path, quint32 stateNumber);
void indexObject(const ObjectKey &objectKey, JsonDbObject object, quint32 stateNumber);
diff --git a/src/daemon/jsondbpartition.cpp b/src/daemon/jsondbpartition.cpp
index df9f8e5..310157a 100644
--- a/src/daemon/jsondbpartition.cpp
+++ b/src/daemon/jsondbpartition.cpp
@@ -684,33 +684,52 @@ void JsonDbPartition::initIndexes()
QString indexName = JsonDbIndex::determineName(indexObject);
QString propertyName = indexObject.value(JsonDbString::kPropertyNameStr).toString();
QString propertyType = indexObject.value(JsonDbString::kPropertyTypeStr).toString();
- QString objectType = indexObject.value(JsonDbString::kObjectTypeStr).toString();
QString propertyFunction = indexObject.value(JsonDbString::kPropertyFunctionStr).toString();
QString locale = indexObject.value(JsonDbString::kLocaleStr).toString();
QString collation = indexObject.value(JsonDbString::kCollationStr).toString();
QString casePreference = indexObject.value(JsonDbString::kCasePreferenceStr).toString();
+ QStringList objectTypes;
+ QJsonValue objectTypeValue = indexObject.value(JsonDbString::kObjectTypeStr);
+ if (objectTypeValue.isString()) {
+ objectTypes.append(objectTypeValue.toString());
+ } else if (objectTypeValue.isArray()) {
+ foreach (const QJsonValue objectType, objectTypeValue.toArray())
+ objectTypes.append(objectType.toString());
+ }
+
Qt::CaseSensitivity caseSensitivity = Qt::CaseSensitive;
if (indexObject.contains(JsonDbString::kCaseSensitiveStr))
caseSensitivity = (indexObject.value(JsonDbString::kCaseSensitiveStr).toBool() == true ? Qt::CaseSensitive : Qt::CaseInsensitive);
- addIndex(indexName, propertyName, propertyType, objectType, propertyFunction, locale, collation, casePreference, caseSensitivity);
+ addIndex(indexName, propertyName, propertyType, objectTypes, propertyFunction, locale, collation, casePreference, caseSensitivity);
}
}
}
bool JsonDbPartition::addIndex(const QString &indexName, const QString &propertyName,
- const QString &propertyType, const QString &objectType, const QString &propertyFunction,
+ const QString &propertyType, const QStringList &objectTypes, const QString &propertyFunction,
const QString &locale, const QString &collation, const QString &casePreference,
Qt::CaseSensitivity caseSensitivity)
{
Q_ASSERT(!indexName.isEmpty());
//qDebug() << "JsonDbBtreePartition::addIndex" << propertyName << objectType;
- JsonDbObjectTable *table = findObjectTable(objectType);
+ JsonDbObjectTable *table = 0;
+ if (objectTypes.isEmpty())
+ table = mainObjectTable();
+ else
+ foreach (const QString &objectType, objectTypes) {
+ JsonDbObjectTable *t = findObjectTable(objectType);
+ if (table && (t != table)) {
+ qDebug() << "addIndex" << "index on multiple tables" << objectTypes;
+ return false;
+ }
+ table = t;
+ }
const IndexSpec *indexSpec = table->indexSpec(indexName);
if (indexSpec)
return true;
//if (gVerbose) qDebug() << "JsonDbBtreePartition::addIndex" << propertyName << objectType;
- return table->addIndex(indexName, propertyName, propertyType, objectType, propertyFunction, locale, collation, casePreference, caseSensitivity);
+ return table->addIndex(indexName, propertyName, propertyType, objectTypes, propertyFunction, locale, collation, casePreference, caseSensitivity);
}
bool JsonDbPartition::removeIndex(const QString &indexName, const QString &objectType)
@@ -1654,10 +1673,20 @@ void JsonDbPartition::updateBuiltInTypes(const JsonDbObject &object, const JsonD
if (object.contains(JsonDbString::kCaseSensitiveStr))
caseSensitivity = object.value(JsonDbString::kCaseSensitiveStr).toBool();
+ QStringList objectTypes;
+ QJsonValue v = object.value(JsonDbString::kObjectTypeStr);
+ if (v.isString()) {
+ objectTypes = (QStringList() << v.toString());
+ } else if (v.isArray()) {
+ QJsonArray array = v.toArray();
+ foreach (const QJsonValue objectType, array)
+ objectTypes.append(objectType.toString());
+ }
+
addIndex(indexName,
object.value(JsonDbString::kPropertyNameStr).toString(),
object.value(JsonDbString::kPropertyTypeStr).toString(),
- object.value(JsonDbString::kObjectTypeStr).toString(),
+ objectTypes,
object.value(JsonDbString::kPropertyFunctionStr).toString(),
object.value(JsonDbString::kLocaleStr).toString(),
object.value(JsonDbString::kCollationStr).toString(),
@@ -1750,7 +1779,8 @@ void JsonDbPartition::updateSchemaIndexes(const QString &schemaName, QJsonObject
QString propertyType = (propertyInfo.contains("type") ? propertyInfo.value("type").toString() : "string");
QStringList kpath = path;
kpath << k;
- addIndexOnProperty(kpath.join("."), propertyType, schemaName);
+ QString propertyName = kpath.join(".");
+ addIndex(propertyName, propertyName, propertyType);
}
if (propertyInfo.contains("properties"))
updateSchemaIndexes(schemaName, propertyInfo, path + (QStringList() << k));
@@ -1850,6 +1880,7 @@ void JsonDbPartition::initSchemas()
{
JsonDbObject nameIndex;
nameIndex.insert(JsonDbString::kTypeStr, JsonDbString::kIndexTypeStr);
+ nameIndex.insert(JsonDbString::kNameStr, QLatin1String("capabilityName"));
nameIndex.insert(JsonDbString::kPropertyNameStr, QLatin1String("name"));
nameIndex.insert(JsonDbString::kPropertyTypeStr, QLatin1String("string"));
nameIndex.insert(JsonDbString::kObjectTypeStr, QLatin1String("Capability"));
@@ -1866,7 +1897,7 @@ void JsonDbPartition::initSchemas()
}
JsonDbObject capability = QJsonObject::fromVariantMap(parser.result().toMap());
QString name = capability.value("name").toString();
- GetObjectsResult getObjectResponse = getObjects("name", name, "Capability");
+ GetObjectsResult getObjectResponse = getObjects("capabilityName", name, "Capability");
int count = getObjectResponse.data.size();
if (!count) {
if (jsondbSettings->verbose())
diff --git a/src/daemon/jsondbpartition.h b/src/daemon/jsondbpartition.h
index e4c06a3..f58c8ec 100644
--- a/src/daemon/jsondbpartition.h
+++ b/src/daemon/jsondbpartition.h
@@ -116,16 +116,12 @@ public:
bool addIndex(const QString &indexName,
const QString &propertyName,
const QString &propertyType = QString("string"),
- const QString &objectType = QString(),
+ const QStringList &objectTypes = QStringList(),
const QString &propertyFunction = QString(),
const QString &locale = QString(),
const QString &collation = QString(),
const QString &casePreference = QString(),
Qt::CaseSensitivity caseSensitive = Qt::CaseSensitive);
- bool addIndexOnProperty(const QString &propertyName,
- const QString &propertyType = QString("string"),
- const QString &objectType = QString())
- { return addIndex(propertyName, propertyName, propertyType, objectType); }
bool removeIndex(const QString &indexName, const QString &objectType = QString());
bool checkQuota(const JsonDbOwner *owner, int size) const;
diff --git a/src/daemon/jsondbreducedefinition.cpp b/src/daemon/jsondbreducedefinition.cpp
index 1bc4c71..6de9f43 100644
--- a/src/daemon/jsondbreducedefinition.cpp
+++ b/src/daemon/jsondbreducedefinition.cpp
@@ -136,9 +136,6 @@ void JsonDbReduceDefinition::releaseScriptEngine()
void JsonDbReduceDefinition::initIndexes()
{
- // TODO: this index should not be automatic
- mTargetTable->addIndexOnProperty(mSourceKeyName, QLatin1String("string"), mSourceType);
- // TODO: this index should not be automatic
mTargetTable->addIndexOnProperty(mTargetKeyName, QLatin1String("string"), mTargetType);
mTargetTable->addIndexOnProperty(QLatin1String("_reduceUuid"), QLatin1String("string"), mTargetType);
}
diff --git a/src/daemon/schema/Index.json b/src/daemon/schema/Index.json
index d98cd5b..7c60d15 100644
--- a/src/daemon/schema/Index.json
+++ b/src/daemon/schema/Index.json
@@ -18,7 +18,6 @@
"description": "Type of values stored in that property."
},
"objectType": {
- "type": "string",
"description": "Object type to index. Optional."
}
}
diff --git a/tests/auto/client/test-jsondb-client.cpp b/tests/auto/client/test-jsondb-client.cpp
index 39c8a46..eb138d1 100644
--- a/tests/auto/client/test-jsondb-client.cpp
+++ b/tests/auto/client/test-jsondb-client.cpp
@@ -98,6 +98,7 @@ private slots:
void update();
void find();
void index();
+ void multiTypeIndex();
void registerNotification();
void notify_data();
@@ -692,6 +693,15 @@ void TestJsonDbClient::find()
int id = 0;
int count;
+ // create an index on the name property of com.test.NameIndex objects
+ QVariantMap index;
+ index.insert(JsonDbString::kTypeStr, JsonDbString::kIndexTypeStr);
+ index.insert(JsonDbString::kNameStr, QLatin1String("com.test.NameIndex"));
+ index.insert(JsonDbString::kPropertyNameStr, QLatin1String("name"));
+ index.insert(JsonDbString::kObjectTypeStr, QLatin1String("com.test.find-test"));
+ id = mClient->create(index);
+ waitForResponse1(id);
+
QStringList nameList;
// Create a few items
for (count = 0 ; names[count] ; count++ ) {
@@ -724,7 +734,7 @@ void TestJsonDbClient::find()
// Find one, sorted in reverse alphabetical order
query = QVariantMap();
- query.insert("query", "[?_type=\"com.test.find-test\"][\\name]");
+ query.insert("query", "[?_type=\"com.test.find-test\"][\\com.test.NameIndex]");
id = mClient->find(query);
waitForResponse1(id);
answer = mData.toMap().value("data").toList();
@@ -752,7 +762,7 @@ void TestJsonDbClient::find()
// Read should fail
query = QVariantMap();
- query.insert("query", "[?_type=\"com.test.find-test\"][\\name]");
+ query.insert("query", "[?_type=\"com.test.find-test\"][\\com.test.NameIndex]");
id = mClient->find(query);
waitForResponse1(id);
answer = mData.toMap().value("data").toList();
@@ -823,6 +833,55 @@ void TestJsonDbClient::index()
waitForResponse1(id);
}
+void TestJsonDbClient::multiTypeIndex()
+{
+ QVERIFY(mClient);
+
+ QVariantMap query;
+ int id = 0;
+ int count;
+
+ QStringList indexedTypes = (QStringList()
+ << QLatin1String("com.test.find-test1")
+ << QLatin1String("com.test.find-test2"));
+ // create an index on the name property of com.test.NameIndex objects
+ QVariantMap index;
+ index.insert(JsonDbString::kTypeStr, JsonDbString::kIndexTypeStr);
+ index.insert(JsonDbString::kNameStr, QLatin1String("com.test.MultiTypeIndex"));
+ index.insert(JsonDbString::kPropertyNameStr, QLatin1String("name"));
+ index.insert(JsonDbString::kObjectTypeStr, indexedTypes);
+ id = mClient->create(index);
+ waitForResponse1(id);
+
+ QStringList objectTypes = (QStringList()
+ << QLatin1String("com.test.find-test1")
+ << QLatin1String("com.test.find-test2")
+ << QLatin1String("com.test.find-test3"));
+ QStringList nameList;
+ // Create a few items
+ for (count = 0 ; names[count] ; count++ ) {
+ nameList << names[count];
+ foreach (const QString objectType, objectTypes) {
+ QVariantMap item;
+ item.insert("_type", objectType);
+ item.insert("name", names[count]);
+ id = mClient->create(item);
+ waitForResponse1(id);
+ }
+ }
+
+ // Find all in the index
+ query = QVariantMap();
+ query.insert("query", "[?name exists][/com.test.MultiTypeIndex]");
+ id = mClient->find(query);
+ waitForResponse1(id);
+ QVariantList answer = mData.toMap().value("data").toList();
+ //qDebug() << "answer" << mData.toMap();
+ QCOMPARE(answer.size(), nameList.size() * 2);
+ foreach (QVariant v, answer)
+ QVERIFY(indexedTypes.contains(v.toMap().value(JsonDbString::kTypeStr).toString()));
+}
+
void TestJsonDbClient::notify_data()
{
QTest::addColumn<QString>("partition");
diff --git a/tests/auto/daemon/json/map-reduce.json b/tests/auto/daemon/json/map-reduce.json
index a04ef1c..2736a9c 100644
--- a/tests/auto/daemon/json/map-reduce.json
+++ b/tests/auto/daemon/json/map-reduce.json
@@ -46,7 +46,7 @@
"name": "Phone",
"schema": {
"type": "object",
- "extends": "View"
+ "extends": {"$ref": "View"}
}
},
{
@@ -54,7 +54,7 @@
"name": "PhoneCount",
"schema": {
"type": "object",
- "extends": "View"
+ "extends": {"$ref": "View"}
}
},
{