summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDenis Dzyubenko <denis.dzyubenko@nokia.com>2012-04-11 15:59:00 +0200
committerDenis Dzyubenko <denis.dzyubenko@nokia.com>2012-04-11 16:54:46 +0200
commit6b7df60a752422b1f6ff07bb2682c21e18a43985 (patch)
tree3e56bd3f4ee34a228777d00ff328ef1c53cb1df1
parent20549eedb5b5e852c0e384cd76bfbff14168dbda (diff)
parent7ef36e3c5a88560eb4e3a81c2c9f14059739108b (diff)
Merge remote-tracking branch 'gerrit/master' into hbtreehbtree
Conflicts: src/daemon/daemon.pri src/daemon/jsondbview.cpp src/partition/jsondbindex.cpp src/partition/jsondbindex.h src/partition/jsondbindexquery.h src/partition/jsondbmanagedbtree.cpp src/partition/jsondbmanagedbtree.h src/partition/jsondbmanagedbtreetxn.cpp src/partition/jsondbmanagedbtreetxn.h src/partition/jsondbobjecttable.cpp src/partition/jsondbobjecttable.h src/partition/jsondbpartition.cpp src/partition/jsondbpartition.h tests/auto/auto.pro tests/auto/partition/testpartition.cpp tests/benchmarks/benchmarks.pro Change-Id: I963adefd6d32fca9b3537981306b67538c759034
-rw-r--r--config.tests/icu/icu.pro3
-rw-r--r--config.tests/icu/main.cpp (renamed from src/common/jsondb-error.h)9
-rw-r--r--doc/src/partitions.qdoc57
-rw-r--r--examples/declarative/cachingmodel/cachingmodel.qml42
-rw-r--r--modules/qt_jsondbpartition.pri18
-rw-r--r--src/3rdparty/qjson/README18
-rw-r--r--src/3rdparty/qjson/TODO2
-rw-r--r--src/3rdparty/qjson/benchmark/benchmark.pro6
-rw-r--r--src/3rdparty/qjson/benchmark/main.cpp75
-rw-r--r--src/3rdparty/qjson/benchmark/numbers.json19
-rw-r--r--src/3rdparty/qjson/benchmark/test.json66
-rw-r--r--src/3rdparty/qjson/json.pro4
-rw-r--r--src/3rdparty/qjson/qjson.pri1
-rw-r--r--src/3rdparty/qjson/src/json.cpp432
-rw-r--r--src/3rdparty/qjson/src/json.g420
-rw-r--r--src/3rdparty/qjson/src/json.h58
-rw-r--r--src/3rdparty/qjson/src/json.pri4
-rw-r--r--src/3rdparty/qjson/src/jsonparser.cpp527
-rw-r--r--src/3rdparty/qjson/tests/data/non-latin1.json4
-rw-r--r--src/3rdparty/qjson/tests/data/non-latin1.json.ref4
-rw-r--r--src/3rdparty/qjson/tests/data/test.html72
-rw-r--r--src/3rdparty/qjson/tests/data/test.json60
-rw-r--r--src/3rdparty/qjson/tests/data/test.json.ref57
-rw-r--r--src/3rdparty/qjson/tests/data/test_utf-16le-nobom.jsonbin2894 -> 0 bytes
-rw-r--r--src/3rdparty/qjson/tests/data/test_utf-16le-nobom.json.refbin2808 -> 0 bytes
-rw-r--r--src/3rdparty/qjson/tests/data/test_utf-16le.jsonbin2896 -> 0 bytes
-rw-r--r--src/3rdparty/qjson/tests/data/test_utf-16le.json.refbin2808 -> 0 bytes
-rw-r--r--src/3rdparty/qjson/tests/data/test_utf-32le.jsonbin5792 -> 0 bytes
-rw-r--r--src/3rdparty/qjson/tests/data/test_utf-32le.json.refbin5616 -> 0 bytes
-rw-r--r--src/3rdparty/qjson/tests/tests.pro13
-rw-r--r--src/3rdparty/qjson/tests/tst_json.cpp202
-rw-r--r--src/client/qjsondbconnection.cpp24
-rw-r--r--src/client/qjsondbconnection_p.h2
-rw-r--r--src/client/qjsondbreadrequest.h5
-rw-r--r--src/client/qjsondbrequest.cpp18
-rw-r--r--src/client/qjsondbrequest.h43
-rw-r--r--src/client/qjsondbwatcher.cpp23
-rw-r--r--src/client/qjsondbwatcher.h14
-rw-r--r--src/client/qjsondbwatcher_p.h4
-rw-r--r--src/client/qjsondbwriterequest.h17
-rw-r--r--src/clientcompat/clientcompat.pro5
-rw-r--r--src/clientcompat/jsondb-client.cpp4
-rw-r--r--src/clientcompat/jsondb-connection.cpp3
-rw-r--r--src/clientcompat/jsondb-connection_p_p.h4
-rw-r--r--src/clientcompat/jsondb-error.h47
-rw-r--r--src/clientcompat/jsondb-strings.cpp (renamed from src/common/jsondb-strings.cpp)4
-rw-r--r--src/clientcompat/jsondb-strings_p.h3
-rw-r--r--src/common/common.pri24
-rw-r--r--src/common/jsondb-global.h42
-rw-r--r--src/common/jsondb-strings.h42
-rw-r--r--src/common/jsonstream.cpp141
-rw-r--r--src/daemon/daemon.pri56
-rw-r--r--src/daemon/daemon.pro16
-rw-r--r--src/daemon/dbserver.cpp587
-rw-r--r--src/daemon/dbserver.h35
-rw-r--r--src/daemon/jsondbephemeralpartition.cpp10
-rw-r--r--src/daemon/jsondbephemeralpartition.h8
-rw-r--r--src/daemon/jsondbresponse.cpp117
-rw-r--r--src/daemon/jsondbsignals.cpp2
-rw-r--r--src/daemon/jsondbsignals.h2
-rw-r--r--src/daemon/main.cpp31
-rw-r--r--src/imports/jsondb-listmodel/jsondb-listmodel.pro7
-rw-r--r--src/imports/jsondb-listmodel/jsondb.json1
-rw-r--r--src/imports/jsondb-listmodel/plugin.cpp3
-rw-r--r--src/imports/jsondb-listmodel/plugin.h10
-rw-r--r--src/imports/jsondb/jsondatabase.cpp80
-rw-r--r--src/imports/jsondb/jsondatabase.h13
-rw-r--r--src/imports/jsondb/jsondb.json1
-rw-r--r--src/imports/jsondb/jsondb.pro37
-rw-r--r--src/imports/jsondb/jsondbcachinglistmodel.cpp589
-rw-r--r--src/imports/jsondb/jsondbcachinglistmodel.h14
-rw-r--r--src/imports/jsondb/jsondbcachinglistmodel_p.h47
-rw-r--r--src/imports/jsondb/jsondbchangessinceobject.cpp404
-rw-r--r--src/imports/jsondb/jsondbchangessinceobject.h131
-rw-r--r--src/imports/jsondb/jsondblistmodel.cpp539
-rw-r--r--src/imports/jsondb/jsondblistmodel.h39
-rw-r--r--src/imports/jsondb/jsondblistmodel_p.h53
-rw-r--r--src/imports/jsondb/jsondbmodelcache.cpp21
-rw-r--r--src/imports/jsondb/jsondbmodelcache.h16
-rw-r--r--src/imports/jsondb/jsondbmodelutils.cpp56
-rw-r--r--src/imports/jsondb/jsondbmodelutils.h54
-rw-r--r--src/imports/jsondb/jsondbnotification.cpp76
-rw-r--r--src/imports/jsondb/jsondbnotification.h10
-rw-r--r--src/imports/jsondb/jsondbpartition.cpp245
-rw-r--r--src/imports/jsondb/jsondbpartition.h24
-rw-r--r--src/imports/jsondb/jsondbqueryobject.cpp60
-rw-r--r--src/imports/jsondb/jsondbqueryobject.h6
-rw-r--r--src/imports/jsondb/jsondbsortinglistmodel.cpp226
-rw-r--r--src/imports/jsondb/jsondbsortinglistmodel.h15
-rw-r--r--src/imports/jsondb/jsondbsortinglistmodel_p.h27
-rw-r--r--src/imports/jsondb/plugin.cpp11
-rw-r--r--src/imports/jsondb/plugin.h1
-rw-r--r--src/jsonstream/jsonstream.cpp28
-rw-r--r--src/jsonstream/jsonstream.h15
-rw-r--r--src/jsonstream/jsonstream.pri3
-rw-r--r--src/jsonstream/jsonstream.pro3
-rw-r--r--src/partition/jsondb.qrc (renamed from src/daemon/jsondb.qrc)0
-rw-r--r--src/partition/jsondbbtree.cpp (renamed from src/daemon/jsondbbtree.cpp)6
-rw-r--r--src/partition/jsondbbtree.h (renamed from src/daemon/jsondbbtree.h)14
-rw-r--r--src/partition/jsondbcollator.cpp (renamed from src/common/jsondbcollator.cpp)4
-rw-r--r--src/partition/jsondbcollator.h (renamed from src/common/jsondbcollator.h)8
-rw-r--r--src/partition/jsondbcollator_p.h (renamed from src/common/jsondbcollator_p.h)4
-rw-r--r--src/partition/jsondberrors.cpp98
-rw-r--r--src/partition/jsondberrors.h (renamed from src/daemon/jsondbresponse.h)54
-rw-r--r--src/partition/jsondbindex.cpp (renamed from src/daemon/jsondbindex.cpp)66
-rw-r--r--src/partition/jsondbindex.h (renamed from src/daemon/jsondbindex.h)38
-rw-r--r--src/partition/jsondbindexquery.cpp (renamed from src/daemon/jsondbindexquery.cpp)64
-rw-r--r--src/partition/jsondbindexquery.h (renamed from src/daemon/jsondbindexquery.h)15
-rw-r--r--src/partition/jsondbmapdefinition.cpp (renamed from src/daemon/jsondbmapdefinition.cpp)121
-rw-r--r--src/partition/jsondbmapdefinition.h (renamed from src/daemon/jsondbmapdefinition.h)11
-rw-r--r--src/partition/jsondbnotification.cpp (renamed from src/daemon/jsondbnotification.cpp)8
-rw-r--r--src/partition/jsondbnotification.h (renamed from src/daemon/jsondbnotification.h)13
-rw-r--r--src/partition/jsondbobject.cpp (renamed from src/daemon/jsondbobject.cpp)73
-rw-r--r--src/partition/jsondbobject.h (renamed from src/daemon/jsondbobject.h)13
-rw-r--r--src/partition/jsondbobjectkey.h (renamed from src/daemon/jsondbobjectkey.h)14
-rw-r--r--src/partition/jsondbobjecttable.cpp (renamed from src/daemon/jsondbobjecttable.cpp)166
-rw-r--r--src/partition/jsondbobjecttable.h (renamed from src/daemon/jsondbobjecttable.h)54
-rw-r--r--src/partition/jsondbobjecttypes_impl_p.h (renamed from src/daemon/jsondbobjecttypes_impl_p.h)6
-rw-r--r--src/partition/jsondbobjecttypes_p.h (renamed from src/daemon/jsondbobjecttypes_p.h)8
-rw-r--r--src/partition/jsondbowner.cpp (renamed from src/daemon/jsondbowner.cpp)22
-rw-r--r--src/partition/jsondbowner.h (renamed from src/daemon/jsondbowner.h)14
-rw-r--r--src/partition/jsondbpartition.cpp (renamed from src/daemon/jsondbpartition.cpp)237
-rw-r--r--src/partition/jsondbpartition.h (renamed from src/daemon/jsondbpartition.h)23
-rw-r--r--src/partition/jsondbpartitionglobal.h71
-rw-r--r--src/partition/jsondbproxy.cpp (renamed from src/daemon/jsondbproxy.cpp)27
-rw-r--r--src/partition/jsondbproxy.h (renamed from src/daemon/jsondbproxy.h)13
-rw-r--r--src/partition/jsondbquery.cpp (renamed from src/daemon/jsondbquery.cpp)167
-rw-r--r--src/partition/jsondbquery.h (renamed from src/daemon/jsondbquery.h)31
-rw-r--r--src/partition/jsondbreducedefinition.cpp (renamed from src/daemon/jsondbreducedefinition.cpp)58
-rw-r--r--src/partition/jsondbreducedefinition.h (renamed from src/daemon/jsondbreducedefinition.h)11
-rw-r--r--src/partition/jsondbschemamanager_impl_p.h (renamed from src/daemon/jsondbschemamanager_impl_p.h)4
-rw-r--r--src/partition/jsondbschemamanager_p.h (renamed from src/daemon/jsondbschemamanager_p.h)6
-rw-r--r--src/partition/jsondbscriptengine.cpp136
-rw-r--r--src/partition/jsondbscriptengine.h (renamed from src/common/jsonstream.h)50
-rw-r--r--src/partition/jsondbsettings.cpp (renamed from src/daemon/jsondbsettings.cpp)10
-rw-r--r--src/partition/jsondbsettings.h (renamed from src/daemon/jsondbsettings.h)14
-rw-r--r--src/partition/jsondbstat.h (renamed from src/daemon/jsondbstat.h)8
-rw-r--r--src/partition/jsondbstrings.cpp118
-rw-r--r--src/partition/jsondbstrings.h126
-rw-r--r--src/partition/jsondbview.cpp (renamed from src/daemon/jsondbview.cpp)200
-rw-r--r--src/partition/jsondbview.h (renamed from src/daemon/jsondbview.h)17
-rw-r--r--src/partition/partition.pro78
-rw-r--r--src/partition/schema-validation/checkpoints.h (renamed from src/daemon/schema-validation/checkpoints.h)0
-rw-r--r--src/partition/schema-validation/object.h (renamed from src/daemon/schema-validation/object.h)0
-rw-r--r--src/partition/schema/Capability.json (renamed from src/daemon/schema/Capability.json)0
-rw-r--r--src/partition/schema/Index.json (renamed from src/daemon/schema/Index.json)0
-rw-r--r--src/partition/schema/RootCapability.json (renamed from src/daemon/schema/RootCapability.json)0
-rw-r--r--src/partition/schema/View.json (renamed from src/daemon/schema/View.json)0
-rw-r--r--src/partition/schema/notification.json (renamed from src/daemon/schema/notification.json)0
-rw-r--r--src/src.pro2
-rw-r--r--sync.profile5
-rw-r--r--tests/auto/accesscontrol/accesscontrol.pro4
-rw-r--r--tests/auto/accesscontrol/json/capabilities-indexes.json24
-rw-r--r--tests/auto/accesscontrol/json/index-test.json25
-rw-r--r--tests/auto/accesscontrol/testjsondb.cpp162
-rw-r--r--tests/auto/auto.pro5
-rw-r--r--tests/auto/client/client.pro4
-rw-r--r--tests/auto/client/json/index-test.json2
-rw-r--r--tests/auto/client/partitions.json5
-rw-r--r--tests/auto/client/test-jsondb-client.cpp91
-rw-r--r--tests/auto/daemon/daemon.pro17
-rw-r--r--tests/auto/jsondb-listmodel/jsondb-listmodel.pro1
-rw-r--r--tests/auto/jsondb-listmodel/test-jsondb-listmodel.cpp28
-rw-r--r--tests/auto/jsondb-listmodel/test-jsondb-listmodel.h1
-rw-r--r--tests/auto/jsondbcachinglistmodel/jsondbcachinglistmodel.pro11
-rw-r--r--tests/auto/jsondbcachinglistmodel/partitions.json4
-rw-r--r--tests/auto/jsondbcachinglistmodel/testjsondbcachinglistmodel.cpp945
-rw-r--r--tests/auto/jsondbcachinglistmodel/testjsondbcachinglistmodel.h64
-rw-r--r--tests/auto/jsondbchangessinceobject/jsondbchangessinceobject.pro17
-rw-r--r--tests/auto/jsondbchangessinceobject/testjsondbchangessinceobject.cpp332
-rw-r--r--tests/auto/jsondbchangessinceobject/testjsondbchangessinceobject.h108
-rw-r--r--tests/auto/jsondblistmodel/jsondblistmodel.pro11
-rw-r--r--tests/auto/jsondblistmodel/partitions.json3
-rw-r--r--tests/auto/jsondblistmodel/testjsondblistmodel.cpp342
-rw-r--r--tests/auto/jsondblistmodel/testjsondblistmodel.h39
-rw-r--r--tests/auto/jsondbnotification/jsondbnotification.pro11
-rw-r--r--tests/auto/jsondbnotification/partitions.json3
-rw-r--r--tests/auto/jsondbnotification/testjsondbnotification.cpp156
-rw-r--r--tests/auto/jsondbnotification/testjsondbnotification.h31
-rw-r--r--tests/auto/jsondbpartition/jsondbpartition.pro11
-rw-r--r--tests/auto/jsondbpartition/partitions.json3
-rw-r--r--tests/auto/jsondbpartition/testjsondbpartition.cpp95
-rw-r--r--tests/auto/jsondbpartition/testjsondbpartition.h27
-rw-r--r--tests/auto/jsondbqueryobject/jsondbqueryobject.pro11
-rw-r--r--tests/auto/jsondbqueryobject/partitions.json3
-rw-r--r--tests/auto/jsondbqueryobject/testjsondbqueryobject.cpp101
-rw-r--r--tests/auto/jsondbqueryobject/testjsondbqueryobject.h31
-rw-r--r--tests/auto/jsondbsortinglistmodel/jsondbsortinglistmodel.pro11
-rw-r--r--tests/auto/jsondbsortinglistmodel/partitions.json4
-rw-r--r--tests/auto/jsondbsortinglistmodel/testjsondbsortinglistmodel.cpp542
-rw-r--r--tests/auto/jsondbsortinglistmodel/testjsondbsortinglistmodel.h52
-rw-r--r--tests/auto/jsonstream/jsonstream.pro2
-rw-r--r--tests/auto/jsonstream/test-jsonstream.cpp15
-rw-r--r--tests/auto/partition/json-validation.qrc (renamed from tests/auto/daemon/json-validation.qrc)0
-rw-r--r--tests/auto/partition/json-validation/array-boundaries-schema.json (renamed from tests/auto/daemon/json-validation/array-boundaries-schema.json)0
-rw-r--r--tests/auto/partition/json-validation/array-boundaries-twoOrLess-empty-valid.json (renamed from tests/auto/daemon/json-validation/array-boundaries-twoOrLess-empty-valid.json)0
-rw-r--r--tests/auto/partition/json-validation/array-boundaries-twoOrLess-five-invalid.json (renamed from tests/auto/daemon/json-validation/array-boundaries-twoOrLess-five-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/array-boundaries-twoOrLess-two-valid.json (renamed from tests/auto/daemon/json-validation/array-boundaries-twoOrLess-two-valid.json)0
-rw-r--r--tests/auto/partition/json-validation/array-boundaries-twoOrMore-empty-invalid.json (renamed from tests/auto/daemon/json-validation/array-boundaries-twoOrMore-empty-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/array-boundaries-twoOrMore-five-valid.json (renamed from tests/auto/daemon/json-validation/array-boundaries-twoOrMore-five-valid.json)0
-rw-r--r--tests/auto/partition/json-validation/array-boundaries-twoOrMore-one-invalid.json (renamed from tests/auto/daemon/json-validation/array-boundaries-twoOrMore-one-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/array-boundaries-twoOrMore-two-valid.json (renamed from tests/auto/daemon/json-validation/array-boundaries-twoOrMore-two-valid.json)0
-rw-r--r--tests/auto/partition/json-validation/array-items-empty-empty-valid.json (renamed from tests/auto/daemon/json-validation/array-items-empty-empty-valid.json)0
-rw-r--r--tests/auto/partition/json-validation/array-items-empty-mixed-valid.json (renamed from tests/auto/daemon/json-validation/array-items-empty-mixed-valid.json)0
-rw-r--r--tests/auto/partition/json-validation/array-items-empty-numbers-valid.json (renamed from tests/auto/daemon/json-validation/array-items-empty-numbers-valid.json)0
-rw-r--r--tests/auto/partition/json-validation/array-items-number-empty-valid.json (renamed from tests/auto/daemon/json-validation/array-items-number-empty-valid.json)0
-rw-r--r--tests/auto/partition/json-validation/array-items-number-highnumbers-invalid.json (renamed from tests/auto/daemon/json-validation/array-items-number-highnumbers-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/array-items-number-mixed-invalid.json (renamed from tests/auto/daemon/json-validation/array-items-number-mixed-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/array-items-number-numbers-valid.json (renamed from tests/auto/daemon/json-validation/array-items-number-numbers-valid.json)0
-rw-r--r--tests/auto/partition/json-validation/array-items-number-object-invalid.json (renamed from tests/auto/daemon/json-validation/array-items-number-object-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/array-items-number-string-invalid.json (renamed from tests/auto/daemon/json-validation/array-items-number-string-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/array-items-object-empty-valid.json (renamed from tests/auto/daemon/json-validation/array-items-object-empty-valid.json)0
-rw-r--r--tests/auto/partition/json-validation/array-items-object-missingfoo-valid.json (renamed from tests/auto/daemon/json-validation/array-items-object-missingfoo-valid.json)0
-rw-r--r--tests/auto/partition/json-validation/array-items-object-missingid-invalid.json (renamed from tests/auto/daemon/json-validation/array-items-object-missingid-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/array-items-object-numbers-invalid.json (renamed from tests/auto/daemon/json-validation/array-items-object-numbers-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/array-items-object-std-valid.json (renamed from tests/auto/daemon/json-validation/array-items-object-std-valid.json)0
-rw-r--r--tests/auto/partition/json-validation/array-items-object-strings-invalid.json (renamed from tests/auto/daemon/json-validation/array-items-object-strings-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/array-items-schema.json (renamed from tests/auto/daemon/json-validation/array-items-schema.json)0
-rw-r--r--tests/auto/partition/json-validation/integer-boundaries-lessThenOne-one-invalid.json (renamed from tests/auto/daemon/json-validation/integer-boundaries-lessThenOne-one-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/integer-boundaries-lessThenOne-two-invalid.json (renamed from tests/auto/daemon/json-validation/integer-boundaries-lessThenOne-two-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/integer-boundaries-lessThenOne-zero-valid.json (renamed from tests/auto/daemon/json-validation/integer-boundaries-lessThenOne-zero-valid.json)0
-rw-r--r--tests/auto/partition/json-validation/integer-boundaries-moreThenOne-one-invalid.json (renamed from tests/auto/daemon/json-validation/integer-boundaries-moreThenOne-one-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/integer-boundaries-moreThenOne-two-valid.json (renamed from tests/auto/daemon/json-validation/integer-boundaries-moreThenOne-two-valid.json)0
-rw-r--r--tests/auto/partition/json-validation/integer-boundaries-moreThenOne-zero-invalid.json (renamed from tests/auto/daemon/json-validation/integer-boundaries-moreThenOne-zero-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/integer-boundaries-oneOrLess-one-valid.json (renamed from tests/auto/daemon/json-validation/integer-boundaries-oneOrLess-one-valid.json)0
-rw-r--r--tests/auto/partition/json-validation/integer-boundaries-oneOrLess-two-invalid.json (renamed from tests/auto/daemon/json-validation/integer-boundaries-oneOrLess-two-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/integer-boundaries-oneOrMore-one-valid.json (renamed from tests/auto/daemon/json-validation/integer-boundaries-oneOrMore-one-valid.json)0
-rw-r--r--tests/auto/partition/json-validation/integer-boundaries-oneOrMore-two-valid.json (renamed from tests/auto/daemon/json-validation/integer-boundaries-oneOrMore-two-valid.json)0
-rw-r--r--tests/auto/partition/json-validation/integer-boundaries-oneOrMore-zero-invalid.json (renamed from tests/auto/daemon/json-validation/integer-boundaries-oneOrMore-zero-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/integer-boundaries-schema.json (renamed from tests/auto/daemon/json-validation/integer-boundaries-schema.json)0
-rw-r--r--tests/auto/partition/json-validation/numbers-boundaries-lessThenOne-one-invalid.json (renamed from tests/auto/daemon/json-validation/numbers-boundaries-lessThenOne-one-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/numbers-boundaries-lessThenOne-two-invalid.json (renamed from tests/auto/daemon/json-validation/numbers-boundaries-lessThenOne-two-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/numbers-boundaries-lessThenOne-zero-valid.json (renamed from tests/auto/daemon/json-validation/numbers-boundaries-lessThenOne-zero-valid.json)0
-rw-r--r--tests/auto/partition/json-validation/numbers-boundaries-moreThenOne-one-invalid.json (renamed from tests/auto/daemon/json-validation/numbers-boundaries-moreThenOne-one-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/numbers-boundaries-moreThenOne-two-valid.json (renamed from tests/auto/daemon/json-validation/numbers-boundaries-moreThenOne-two-valid.json)0
-rw-r--r--tests/auto/partition/json-validation/numbers-boundaries-moreThenOne-zero-invalid.json (renamed from tests/auto/daemon/json-validation/numbers-boundaries-moreThenOne-zero-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/numbers-boundaries-oneOrLess-one-valid.json (renamed from tests/auto/daemon/json-validation/numbers-boundaries-oneOrLess-one-valid.json)0
-rw-r--r--tests/auto/partition/json-validation/numbers-boundaries-oneOrLess-two-invalid.json (renamed from tests/auto/daemon/json-validation/numbers-boundaries-oneOrLess-two-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/numbers-boundaries-oneOrLess-zero-valid.json (renamed from tests/auto/daemon/json-validation/numbers-boundaries-oneOrLess-zero-valid.json)0
-rw-r--r--tests/auto/partition/json-validation/numbers-boundaries-oneOrMore-one-valid.json (renamed from tests/auto/daemon/json-validation/numbers-boundaries-oneOrMore-one-valid.json)0
-rw-r--r--tests/auto/partition/json-validation/numbers-boundaries-oneOrMore-two-valid.json (renamed from tests/auto/daemon/json-validation/numbers-boundaries-oneOrMore-two-valid.json)0
-rw-r--r--tests/auto/partition/json-validation/numbers-boundaries-oneOrMore-zero-invalid.json (renamed from tests/auto/daemon/json-validation/numbers-boundaries-oneOrMore-zero-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/numbers-boundaries-schema.json (renamed from tests/auto/daemon/json-validation/numbers-boundaries-schema.json)0
-rw-r--r--tests/auto/partition/json-validation/required-missing-invalid.json (renamed from tests/auto/daemon/json-validation/required-missing-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/required-nested-valid.json (renamed from tests/auto/daemon/json-validation/required-nested-valid.json)0
-rw-r--r--tests/auto/partition/json-validation/required-notimportent-number-invalid.json (renamed from tests/auto/daemon/json-validation/required-notimportent-number-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/required-number-valid.json (renamed from tests/auto/daemon/json-validation/required-number-valid.json)0
-rw-r--r--tests/auto/partition/json-validation/required-object-valid.json (renamed from tests/auto/daemon/json-validation/required-object-valid.json)0
-rw-r--r--tests/auto/partition/json-validation/required-schema.json (renamed from tests/auto/daemon/json-validation/required-schema.json)0
-rw-r--r--tests/auto/partition/json-validation/string-boundaries-max5chars-silo-valid.json (renamed from tests/auto/daemon/json-validation/string-boundaries-max5chars-silo-valid.json)0
-rw-r--r--tests/auto/partition/json-validation/string-boundaries-max5chars-silos-valid.json (renamed from tests/auto/daemon/json-validation/string-boundaries-max5chars-silos-valid.json)0
-rw-r--r--tests/auto/partition/json-validation/string-boundaries-max5chars-toolong-invalid.json (renamed from tests/auto/daemon/json-validation/string-boundaries-max5chars-toolong-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/string-boundaries-min5chars-silo-invalid.json (renamed from tests/auto/daemon/json-validation/string-boundaries-min5chars-silo-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/string-boundaries-min5chars-silos-valid.json (renamed from tests/auto/daemon/json-validation/string-boundaries-min5chars-silos-valid.json)0
-rw-r--r--tests/auto/partition/json-validation/string-boundaries-min5chars-toolong-valid.json (renamed from tests/auto/daemon/json-validation/string-boundaries-min5chars-toolong-valid.json)0
-rw-r--r--tests/auto/partition/json-validation/string-boundaries-pattern-a-valid.json (renamed from tests/auto/daemon/json-validation/string-boundaries-pattern-a-valid.json)0
-rw-r--r--tests/auto/partition/json-validation/string-boundaries-pattern-aaa-valid.json (renamed from tests/auto/daemon/json-validation/string-boundaries-pattern-aaa-valid.json)0
-rw-r--r--tests/auto/partition/json-validation/string-boundaries-pattern-ab-invalid.json (renamed from tests/auto/daemon/json-validation/string-boundaries-pattern-ab-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/string-boundaries-schema.json (renamed from tests/auto/daemon/json-validation/string-boundaries-schema.json)0
-rw-r--r--tests/auto/partition/json-validation/type-array-array-valid.json (renamed from tests/auto/daemon/json-validation/type-array-array-valid.json)0
-rw-r--r--tests/auto/partition/json-validation/type-array-bool-invalid.json (renamed from tests/auto/daemon/json-validation/type-array-bool-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/type-array-integer-invalid.json (renamed from tests/auto/daemon/json-validation/type-array-integer-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/type-array-number-invalid.json (renamed from tests/auto/daemon/json-validation/type-array-number-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/type-array-object-invalid.json (renamed from tests/auto/daemon/json-validation/type-array-object-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/type-array-string-invalid.json (renamed from tests/auto/daemon/json-validation/type-array-string-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/type-bool-array-invalid.json (renamed from tests/auto/daemon/json-validation/type-bool-array-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/type-bool-false-valid.json (renamed from tests/auto/daemon/json-validation/type-bool-false-valid.json)0
-rw-r--r--tests/auto/partition/json-validation/type-bool-integer-invalid.json (renamed from tests/auto/daemon/json-validation/type-bool-integer-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/type-bool-number-invalid.json (renamed from tests/auto/daemon/json-validation/type-bool-number-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/type-bool-object-invalid.json (renamed from tests/auto/daemon/json-validation/type-bool-object-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/type-bool-string-invalid.json (renamed from tests/auto/daemon/json-validation/type-bool-string-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/type-bool-true-valid.json (renamed from tests/auto/daemon/json-validation/type-bool-true-valid.json)0
-rw-r--r--tests/auto/partition/json-validation/type-integer-array-invalid.json (renamed from tests/auto/daemon/json-validation/type-integer-array-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/type-integer-bool-invalid.json (renamed from tests/auto/daemon/json-validation/type-integer-bool-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/type-integer-double-invalid.json (renamed from tests/auto/daemon/json-validation/type-integer-double-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/type-integer-integer-valid.json (renamed from tests/auto/daemon/json-validation/type-integer-integer-valid.json)0
-rw-r--r--tests/auto/partition/json-validation/type-integer-object-invalid.json (renamed from tests/auto/daemon/json-validation/type-integer-object-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/type-integer-string-invalid.json (renamed from tests/auto/daemon/json-validation/type-integer-string-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/type-mixed-array-invalid.json (renamed from tests/auto/daemon/json-validation/type-mixed-array-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/type-mixed-double-invalid.json (renamed from tests/auto/daemon/json-validation/type-mixed-double-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/type-mixed-number-valid.json (renamed from tests/auto/daemon/json-validation/type-mixed-number-valid.json)0
-rw-r--r--tests/auto/partition/json-validation/type-mixed-object-invalid.json (renamed from tests/auto/daemon/json-validation/type-mixed-object-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/type-mixed-string-valid.json (renamed from tests/auto/daemon/json-validation/type-mixed-string-valid.json)0
-rw-r--r--tests/auto/partition/json-validation/type-number-array-invalid.json (renamed from tests/auto/daemon/json-validation/type-number-array-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/type-number-bool-invalid.json (renamed from tests/auto/daemon/json-validation/type-number-bool-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/type-number-double-valid.json (renamed from tests/auto/daemon/json-validation/type-number-double-valid.json)0
-rw-r--r--tests/auto/partition/json-validation/type-number-number-valid.json (renamed from tests/auto/daemon/json-validation/type-number-number-valid.json)0
-rw-r--r--tests/auto/partition/json-validation/type-number-object-invalid.json (renamed from tests/auto/daemon/json-validation/type-number-object-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/type-number-string-invalid.json (renamed from tests/auto/daemon/json-validation/type-number-string-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/type-object-array-invalid.json (renamed from tests/auto/daemon/json-validation/type-object-array-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/type-object-bool-invalid.json (renamed from tests/auto/daemon/json-validation/type-object-bool-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/type-object-double-invalid.json (renamed from tests/auto/daemon/json-validation/type-object-double-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/type-object-number-invalid.json (renamed from tests/auto/daemon/json-validation/type-object-number-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/type-object-object-valid.json (renamed from tests/auto/daemon/json-validation/type-object-object-valid.json)0
-rw-r--r--tests/auto/partition/json-validation/type-object-string-invalid.json (renamed from tests/auto/daemon/json-validation/type-object-string-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/type-schema.json (renamed from tests/auto/daemon/json-validation/type-schema.json)0
-rw-r--r--tests/auto/partition/json-validation/type-string-array-invalid.json (renamed from tests/auto/daemon/json-validation/type-string-array-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/type-string-bool-invalid.json (renamed from tests/auto/daemon/json-validation/type-string-bool-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/type-string-double-invalid.json (renamed from tests/auto/daemon/json-validation/type-string-double-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/type-string-integer-invalid.json (renamed from tests/auto/daemon/json-validation/type-string-integer-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/type-string-object-invalid.json (renamed from tests/auto/daemon/json-validation/type-string-object-invalid.json)0
-rw-r--r--tests/auto/partition/json-validation/type-string-string-valid.json (renamed from tests/auto/daemon/json-validation/type-string-string-valid.json)0
-rw-r--r--tests/auto/partition/json/array.json (renamed from tests/auto/daemon/json/array.json)0
-rw-r--r--tests/auto/partition/json/index-casepreference.json (renamed from tests/auto/daemon/json/index-casepreference.json)0
-rw-r--r--tests/auto/partition/json/index-casesensitive.json (renamed from tests/auto/daemon/json/index-casesensitive.json)0
-rw-r--r--tests/auto/partition/json/largeContactsTest.json (renamed from tests/auto/daemon/json/largeContactsTest.json)0
-rw-r--r--tests/auto/partition/json/largeContactsTest10k.json (renamed from tests/auto/daemon/json/largeContactsTest10k.json)0
-rw-r--r--tests/auto/partition/json/largeContactsTest1k.json (renamed from tests/auto/daemon/json/largeContactsTest1k.json)0
-rw-r--r--tests/auto/partition/json/largeContactsTest33k.json (renamed from tests/auto/daemon/json/largeContactsTest33k.json)0
-rw-r--r--tests/auto/partition/json/map-array-conversion.json (renamed from tests/auto/daemon/json/map-array-conversion.json)0
-rw-r--r--tests/auto/partition/json/map-join-sourceuuids.json (renamed from tests/auto/daemon/json/map-join-sourceuuids.json)0
-rw-r--r--tests/auto/partition/json/map-join.json (renamed from tests/auto/daemon/json/map-join.json)0
-rw-r--r--tests/auto/partition/json/map-reduce-schema.json (renamed from tests/auto/daemon/json/map-reduce-schema.json)0
-rw-r--r--tests/auto/partition/json/map-reduce.json (renamed from tests/auto/daemon/json/map-reduce.json)0
-rw-r--r--tests/auto/partition/json/map-sametarget.json (renamed from tests/auto/daemon/json/map-sametarget.json)0
-rw-r--r--tests/auto/partition/json/pk-capability.json (renamed from tests/auto/daemon/json/pk-capability.json)0
-rw-r--r--tests/auto/partition/json/reduce-array.json (renamed from tests/auto/daemon/json/reduce-array.json)0
-rw-r--r--tests/auto/partition/json/reduce-data.json (renamed from tests/auto/daemon/json/reduce-data.json)0
-rw-r--r--tests/auto/partition/json/reduce-subprop.json (renamed from tests/auto/daemon/json/reduce-subprop.json)0
-rw-r--r--tests/auto/partition/json/reduce.json (renamed from tests/auto/daemon/json/reduce.json)0
-rw-r--r--tests/auto/partition/partition.pro32
-rw-r--r--tests/auto/partition/partition.qrc (renamed from tests/auto/daemon/daemon.qrc)2
-rw-r--r--tests/auto/partition/schemas/TestView.json (renamed from tests/auto/daemon/schemas/TestView.json)0
-rw-r--r--tests/auto/partition/schemas/address.json (renamed from tests/auto/daemon/schemas/address.json)0
-rw-r--r--tests/auto/partition/schemas/contact.json (renamed from tests/auto/daemon/schemas/contact.json)0
-rw-r--r--tests/auto/partition/schemas/ephemeral.json (renamed from tests/auto/daemon/schemas/ephemeral.json)0
-rw-r--r--tests/auto/partition/testpartition.cpp (renamed from tests/auto/daemon/testjsondb.cpp)943
-rw-r--r--tests/auto/qjsondbflushrequest/qjsondbflushrequest.pro13
-rw-r--r--tests/auto/qjsondbflushrequest/testqjsondbflushrequest.cpp88
-rw-r--r--tests/auto/qjsondbrequest/partitions.json3
-rw-r--r--tests/auto/qjsondbrequest/qjsondbrequest.pro17
-rw-r--r--tests/auto/qjsondbrequest/testqjsondbrequest.cpp197
-rw-r--r--tests/auto/qjsondbwatcher/qjsondbwatcher.pro2
-rw-r--r--tests/auto/qjsondbwatcher/testqjsondbwatcher.cpp597
-rw-r--r--tests/auto/queries/queries.pro5
-rw-r--r--tests/auto/queries/testjsondbqueries.cpp56
-rw-r--r--tests/auto/tests.xml20
-rw-r--r--tests/benchmarks/benchmarks.pro2
-rw-r--r--tests/benchmarks/client/client-benchmark.cpp9
-rw-r--r--tests/benchmarks/client/client.pro4
-rw-r--r--tests/benchmarks/daemon/daemon.pro14
-rw-r--r--tests/benchmarks/daemon/daemon.qrc6
-rw-r--r--tests/benchmarks/jsondb-listmodel/jsondb-listmodel.pro17
-rw-r--r--tests/benchmarks/jsondb-listmodel/listmodel-benchmark.cpp564
-rw-r--r--tests/benchmarks/jsondb-listmodel/listmodel-benchmark.h123
-rw-r--r--tests/benchmarks/jsondbcachinglistmodel/jsondbcachinglistmodel-bench.cpp351
-rw-r--r--tests/benchmarks/jsondbcachinglistmodel/jsondbcachinglistmodel-bench.h54
-rw-r--r--tests/benchmarks/jsondbcachinglistmodel/jsondbcachinglistmodel.pro6
-rw-r--r--tests/benchmarks/jsondbcachinglistmodel/partitions.json4
-rw-r--r--tests/benchmarks/jsondbsortinglistmodel/jsondbsortinglistmodel-bench.cpp271
-rw-r--r--tests/benchmarks/jsondbsortinglistmodel/jsondbsortinglistmodel-bench.h52
-rw-r--r--tests/benchmarks/jsondbsortinglistmodel/jsondbsortinglistmodel.pro6
-rw-r--r--tests/benchmarks/jsondbsortinglistmodel/partitions.json4
-rw-r--r--tests/benchmarks/partition/bench_partition.cpp (renamed from tests/benchmarks/daemon/bench_daemon.cpp)276
-rw-r--r--tests/benchmarks/partition/partition.pro18
-rw-r--r--tests/benchmarks/partition/partition.qrc6
-rw-r--r--tests/benchmarks/tests.xml8
-rw-r--r--tests/json.qrc2
-rw-r--r--tests/shared/clientwrapper.h23
-rw-r--r--tests/shared/qmltestutil.h17
-rw-r--r--tests/shared/requestwrapper.h290
-rw-r--r--tests/shared/shared.pri10
-rw-r--r--tests/shared/testhelper.cpp419
-rw-r--r--tests/shared/testhelper.h123
-rw-r--r--tests/shared/util.h22
-rw-r--r--tools/jsondb-client/client.cpp3
366 files changed, 8242 insertions, 8468 deletions
diff --git a/config.tests/icu/icu.pro b/config.tests/icu/icu.pro
new file mode 100644
index 00000000..e2346c1f
--- /dev/null
+++ b/config.tests/icu/icu.pro
@@ -0,0 +1,3 @@
+TEMPLATE = app
+TARGET = icu
+SOURCES += main.cpp
diff --git a/src/common/jsondb-error.h b/config.tests/icu/main.cpp
index 3a4989e6..e67e76de 100644
--- a/src/common/jsondb-error.h
+++ b/config.tests/icu/main.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
+** This file is part of the QtJsonDb module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
@@ -39,4 +39,9 @@
**
****************************************************************************/
-#include "../clientcompat/jsondb-error.h"
+#include <unicode/ucol.h>
+
+int main()
+{
+ return 0;
+}
diff --git a/doc/src/partitions.qdoc b/doc/src/partitions.qdoc
index 64911c2a..f1c52b50 100644
--- a/doc/src/partitions.qdoc
+++ b/doc/src/partitions.qdoc
@@ -41,6 +41,63 @@ The various partitions in a set are accessed via the \l {Partition} element in Q
C++, the partition is selected by \c setPartition() on a
\l {QJsonDbReadRequest}, \l {QJsonDbWriteRequest} or \l {QJsonDbWatcher}.
+\section1 Defining Partitions
+
+Partitions in JSON DB are defined via .json files. The filenames must be of the
+form \c partitions*.json. JSON DB searches a series of directories looking for
+such files and the search order is defined as follows:
+
+\list
+\li If a directory is passed as the final argument to the JSON DB binary (jsondb)
+then this location is searched first. If no argument is specified, the current
+working directory is searched.
+\li If the JSONDB_CONFIG_SEARCH_PATH environment variable points to a colon-separated
+list of directories, these are searched next.
+\li Finally, /etc/jsondb is searched.
+\endlist
+
+The partition definition files consist of an array of objects which define the
+partitions:
+\code
+[
+ {
+ "name" : "com.qt-project.partition1",
+ "default" : true
+ },
+ {
+ "name" : "com.qt-project.partition2",
+ "path" : "/var/run/jsondb/partition2"
+ }
+]
+\endcode
+
+The allowed properties:
+
+\table
+\row
+
+\row
+\li name
+\li The name of the partition, specified on all requests to the database.
+If more than one partition specifies the same \c name property, JSON DB
+only loads the first one it finds. See \l {Partition::name} and
+\l {QJsonDbRequest::partition}.
+
+\row
+\li path
+\li The path where the partition files should be stored. If not specified, it
+defaults to the current working directory.
+
+\row
+\li default
+\li If this boolean property is \c true, then requests which do not specify
+a partition will default this partition. If more than one partition is marked
+as default, JSON DB chooses one arbitrarily.
+\endtable
+
+If no partitions.json files are created, then the database defaults to a single
+partition with the name "default".
+
\section1 The Ephemeral Partition
JSON DB offers a partition called \c Ephemeral. Objects written to this
diff --git a/examples/declarative/cachingmodel/cachingmodel.qml b/examples/declarative/cachingmodel/cachingmodel.qml
index 375edf4b..15b6c6d5 100644
--- a/examples/declarative/cachingmodel/cachingmodel.qml
+++ b/examples/declarative/cachingmodel/cachingmodel.qml
@@ -60,22 +60,35 @@ Item {
sortOrder:"[/firstName]"
cacheSize:150
}
+
+ function indexCreateCallback(error, response) {
+ console.log("Index Create callback #############");
+ if (error) {
+ console.log("Failed to create Index "+JSON.stringify(error));
+ return;
+ }
+ console.log("Index created");
+ }
+
function createIndex()
{
+ console.log("createIndex ***************");
var indexDefinition = {
"_type": "Index",
"name": "firstName",
"propertyName": "firstName",
"propertyType": "string"
};
- nokiaPartition.create(indexDefinition);
- nokiaPartition2.create(indexDefinition);
+ nokiaPartition.create(indexDefinition, indexCreateCallback);
+ nokiaPartition2.create(indexDefinition, indexCreateCallback);
+ console.log("createIndex ***************");
}
function partitionCreateCallback(error, response) {
if (error) {
- console.log("Failed to create Partitions");
+ console.log("Failed to create Partitions :"+JSON.stringify(error));
return;
}
+ console.log("Partition Create callback #############");
nokiaPartition = JsonDb.partition("com.nokia.shared", topLevelItem);
nokiaPartition2 = JsonDb.partition("com.nokia.shared2", topLevelItem);
createIndex();
@@ -83,6 +96,7 @@ Item {
}
function checkForPartitions(error, result) {
+ console.log("checkForPartitions");
if (error) {
console.log("Failed to list Partitions");
} else {
@@ -114,9 +128,29 @@ Item {
}
}
}
+ // Logs notifications of type "MyContacts" in partition "com.nokia.shared"
+ JsonDb.Partition {
+ name: "com.nokia.shared"
+ JsonDb.Notification {
+ query: '[?_type="MyContacts"]'
+ onNotification: {
+ switch (action) {
+ case JsonDb.Notification.Create :
+ console.log("{_uuid :" + result._uuid + "} created");
+ break;
+ case JsonDb.Notification.Update :
+ console.log("{_uuid :" + result._uuid + "} was updated");
+ break;
+ case JsonDb.Notification.Remove :
+ console.log("{_uuid :" + result._uuid + "} was removed");
+ break;
+ }
+ }
+ }
+ }
Component.onCompleted: {
- JsonDb.listPartitions(checkForPartitions, topLevelItem);
+ JsonDb.listPartitions(checkForPartitions);
}
Button {
diff --git a/modules/qt_jsondbpartition.pri b/modules/qt_jsondbpartition.pri
new file mode 100644
index 00000000..f68597a1
--- /dev/null
+++ b/modules/qt_jsondbpartition.pri
@@ -0,0 +1,18 @@
+!win32 {
+QT.jsondbpartition.VERSION = 1.0.0
+QT.jsondbpartition.MAJOR_VERSION = 1
+QT.jsondbpartition.MINOR_VERSION = 0
+QT.jsondbpartition.PATCH_VERSION = 0
+
+QT.jsondbpartition.name = QtJsonDbPartition
+QT.jsondbpartition.bins = $$QT_MODULE_BIN_BASE
+QT.jsondbpartition.includes = $$QT_MODULE_INCLUDE_BASE $$QT_MODULE_INCLUDE_BASE/QtJsonDbPartition
+QT.jsondbpartition.private_includes = $$QT_MODULE_INCLUDE_BASE/QtJsonDbPartition/$$QT.jsondbpartition.VERSION
+QT.jsondbpartition.sources = $$QT_MODULE_BASE/src
+QT.jsondbpartition.libs = $$QT_MODULE_LIB_BASE
+QT.jsondbpartition.plugins = $$QT_MODULE_PLUGIN_BASE
+QT.jsondbpartition.imports = $$QT_MODULE_IMPORT_BASE
+QT.jsondbpartition.depends = core network qml
+
+QT_CONFIG += jsondbpartition
+}
diff --git a/src/3rdparty/qjson/README b/src/3rdparty/qjson/README
deleted file mode 100644
index 450e97ee..00000000
--- a/src/3rdparty/qjson/README
+++ /dev/null
@@ -1,18 +0,0 @@
-This is a Qt JSON Parser and serializer.
-
-The API is trivial:
- QVariant Json::parse(jsonString)
- QByteArray Json::stringize(QVariant)
-
-Compilation:
- The code uses QLALR (in Qt respository. $QTDIR/util/qlalr). Just,
- 'qlalr json.g' produces the parser 'jsonparser.cpp'. This generated file is
- checked into the respository for convenience, so that the user does
- not need to build qlalr.
-
-Using in external projects:
- Just drop 3 files - src/json.cpp src/json.h src/jsonparser.cpp into your code.
- Add json.cpp to SOURCES and you are good to go. jsonparser.cpp is included by
- json.cpp so you should not add it to SOURCES. You may add json.h to HEADERS but
- it's not necessary since it does not contains any mocable content.
-
diff --git a/src/3rdparty/qjson/TODO b/src/3rdparty/qjson/TODO
deleted file mode 100644
index e41f2ebe..00000000
--- a/src/3rdparty/qjson/TODO
+++ /dev/null
@@ -1,2 +0,0 @@
-What's needed before MR
-1. Docs
diff --git a/src/3rdparty/qjson/benchmark/benchmark.pro b/src/3rdparty/qjson/benchmark/benchmark.pro
deleted file mode 100644
index d1e6c6e0..00000000
--- a/src/3rdparty/qjson/benchmark/benchmark.pro
+++ /dev/null
@@ -1,6 +0,0 @@
-QT += testlib
-QT -= gui
-
-include(../src/json.pri)
-
-SOURCES += main.cpp
diff --git a/src/3rdparty/qjson/benchmark/main.cpp b/src/3rdparty/qjson/benchmark/main.cpp
deleted file mode 100644
index af82c991..00000000
--- a/src/3rdparty/qjson/benchmark/main.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2011 Denis Dzyubenko <shadone@gmail.com>
-**
-** Use, modification and distribution is allowed without limitation,
-** warranty, liability or support of any kind.
-**
-****************************************************************************/
-
-#include <QtCore>
-#include <QTest>
-
-#include "json.h"
-
-class tst_Json : public QObject
-{
- Q_OBJECT
-private slots:
- void testByteArray();
- void testString();
- void testNumbers();
-};
-
-void tst_Json::testNumbers()
-{
- QFile file(QLatin1String("numbers.json"));
- file.open(QFile::ReadOnly);
- QByteArray ba = file.readAll();
- QString data = QString::fromLocal8Bit(ba.constData(), ba.size());
-
- QBENCHMARK {
- JsonReader reader;
- if (!reader.parse(data)) {
- qDebug() << "Failed to parse: " << reader.errorString();
- return;
- }
- QVariant result = reader.result();
- }
-}
-
-void tst_Json::testString()
-{
- QFile file(QLatin1String("test.json"));
- file.open(QFile::ReadOnly);
- QByteArray ba = file.readAll();
- QString data = QString::fromLocal8Bit(ba.constData(), ba.size());
-
- QBENCHMARK {
- JsonReader reader;
- if (!reader.parse(data)) {
- qDebug() << "Failed to parse: " << reader.errorString();
- return;
- }
- QVariant result = reader.result();
- }
-}
-
-void tst_Json::testByteArray()
-{
- QFile file(QLatin1String("test.json"));
- file.open(QFile::ReadOnly);
- QByteArray testJson = file.readAll();
-
- QBENCHMARK {
- JsonReader reader;
- if (!reader.parse(testJson)) {
- qDebug() << "Failed to parse: " << reader.errorString();
- return;
- }
- QVariant result = reader.result();
- }
-}
-
-QTEST_MAIN(tst_Json)
-#include "main.moc"
diff --git a/src/3rdparty/qjson/benchmark/numbers.json b/src/3rdparty/qjson/benchmark/numbers.json
deleted file mode 100644
index 469156a7..00000000
--- a/src/3rdparty/qjson/benchmark/numbers.json
+++ /dev/null
@@ -1,19 +0,0 @@
-[
- {
- "integer": 1234567890,
- "real": -9876.543210,
- "e": 0.123456789e-12,
- "E": 1.234567890E+34,
- "": 23456789012E66,
- "zero": 0,
- "one": 1
- },
- [
- -1234567890,
- -1234567890,
- -1234567890,
- 1234567890,
- 1234567890,
- 1234567890
- ]
-]
diff --git a/src/3rdparty/qjson/benchmark/test.json b/src/3rdparty/qjson/benchmark/test.json
deleted file mode 100644
index 7c935fff..00000000
--- a/src/3rdparty/qjson/benchmark/test.json
+++ /dev/null
@@ -1,66 +0,0 @@
-[
- "JSON Test Pattern pass1",
- {"object with 1 member":["array with 1 element"]},
- {},
- [],
- -42,
- true,
- false,
- null,
- {
- "integer": 1234567890,
- "real": -9876.543210,
- "e": 0.123456789e-12,
- "E": 1.234567890E+34,
- "": 23456789012E66,
- "zero": 0,
- "one": 1,
- "space": " ",
- "quote": "\"",
- "backslash": "\\",
- "controls": "\b\f\n\r\t",
- "slash": "/ & \/",
- "alpha": "abcdefghijklmnopqrstuvwxyz",
- "ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
- "digit": "0123456789",
- "0123456789": "digit",
- "special": "`1~!@#$%^&*()_+-={\':[,]}|;.</>?",
- "hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A",
- "true": true,
- "false": false,
- "null": null,
- "array":[ ],
- "object":{ },
- "address": "50 St. James Street",
- "url": "http://www.JSON.org/",
- "comment": "// /* <!-- --",
- "# -- --> */": " ",
- " s p a c e d " :[1,2 , 3
-
-,
-
-4 , 5 , 6 ,7 ],"compact":[1,2,3,4,5,6,7],
- "jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}",
- "quotes": "&#34; \u0022 %22 0x22 034 &#x22;",
- "\/\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:\',./<>?" : "A key can be any string"
- },
- 0.5 ,98.6
-,
-99.44
-,
-
-1066,
-1e1,
-0.1e1,
-1e-1,
-1e00,
-2e+00,
-2e-00,
-"rosebud",
-{"foo": "bar"},
-{"classification":{"relevancyScore":1000,"searchUrl":{"value":"http://www.bizrate.com/iphone-cases/index__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"}},"products":{"priceSet":{"minPrice":{"value":"$0.01","integral":1},"maxPrice":{"value":"$4,833.99","integral":483399}},"product":[{"type":"PRODUCT","title":"Silicone case for iPhone 3G/ 3GS","description":"Elite Horizontal Leather Pouch for Apple iPhone 3G/3Gs - Premium quality horizontal case for your Apple iPhone 3G/3Gs. This pouch is ideal for the style conscious on the go. This great looking case is made from high-quality leather with classic black...","manufacturer":"Apple","url":{"value":"http://www.bizrate.com/silicone-case-for-iphone-3g-3gs--pid1968262863/compareprices__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"},"images":{"image":[{"value":"http://image10.bizrate-images.com/resize?sq=60&uid=1968262863","xsize":60,"ysize":60},{"value":"http://image10.bizrate-images.com/resize?sq=100&uid=1968262863","xsize":100,"ysize":100},{"value":"http://image10.bizrate-images.com/resize?sq=160&uid=1968262863","xsize":160,"ysize":160},{"value":"http://image10.bizrate-images.com/resize?sq=400&uid=1968262863","xsize":400,"ysize":400}]},"relevancy":310711221747712.000000,"priceSet":{"minPrice":{"value":"$1.56","integral":156},"maxPrice":{"value":"$29.99","integral":2999},"stores":14},"id":1968262863,"categoryId":8515},{"type":"PRODUCT","title":"Nonslip Checkered Silicone Skin Soft Case for iPhone 4 4G","description":"Specification:Product Name Silicone Skin Case Model for Apple iPhone 4 Color Black Material Soft Silicone Skin Weight 26g Package 1 x Case for Apple iPhone 4 Description:This is a non-OEM product.Accessory Only, Phone is not included.","manufacturer":"H&B","url":{"value":"http://www.bizrate.com/nonslip-checkered-silicone-skin-soft-case-for-iphone-4-4g--pid2534935499/compareprices__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"},"images":{"image":[{"value":"http://image10.bizrate-images.com/resize?sq=60&uid=2534935499","xsize":60,"ysize":60},{"value":"http://image10.bizrate-images.com/resize?sq=100&uid=2534935499","xsize":100,"ysize":100},{"value":"http://image10.bizrate-images.com/resize?sq=160&uid=2534935499","xsize":160,"ysize":160},{"value":"http://image10.bizrate-images.com/resize?sq=400&uid=2534935499","xsize":400,"ysize":400}]},"relevancy":175580930637824.000000,"priceSet":{"minPrice":{"value":"$0.45","integral":45},"maxPrice":{"value":"$194.95","integral":19495},"stores":34},"id":2534935499,"categoryId":8515},{"type":"PRODUCT","title":"Plastic Case for iPhone 4 - Black","description":"Description:Detachable Windmill Type Matte Hard Plastic Case Cover for iPhone 4 (Black / Magenta)Customised your iPhone with this wonderful Plastic Case which is a accessory for your iPhone 4 which is made of high quality and durable plastic, protect","manufacturer":"Griffin","url":{"value":"http://www.bizrate.com/plastic-case-for-iphone-4-black--pid2305624670/compareprices__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"},"images":{"image":[{"value":"http://image10.bizrate-images.com/resize?sq=60&uid=2305624670","xsize":60,"ysize":60},{"value":"http://image10.bizrate-images.com/resize?sq=100&uid=2305624670","xsize":100,"ysize":100},{"value":"http://image10.bizrate-images.com/resize?sq=160&uid=2305624670","xsize":160,"ysize":160},{"value":"http://image10.bizrate-images.com/resize?sq=400&uid=2305624670","xsize":400,"ysize":400}]},"relevancy":132488642953216.000000,"priceSet":{"minPrice":{"value":"$0.99","integral":99},"maxPrice":{"value":"$303.68","integral":30368},"stores":33},"id":2305624670,"categoryId":8515},{"type":"PRODUCT","title":"Protective Silicone Case for iPhone 4","description":"Made of high quality PVC material Protects your iPhone 4 from any scratch and dirt Easy to install and remove, no any tool needed Cut-out design allows user can access all keypad / button and slot without having to remove the case","manufacturer":"Griffin","url":{"value":"http://www.bizrate.com/protective-silicone-case-for-iphone-4--pid2120981405/compareprices__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"},"images":{"image":[{"value":"http://image10.bizrate-images.com/resize?sq=60&uid=2120981405","xsize":60,"ysize":60},{"value":"http://image10.bizrate-images.com/resize?sq=100&uid=2120981405","xsize":100,"ysize":100},{"value":"http://image10.bizrate-images.com/resize?sq=160&uid=2120981405","xsize":160,"ysize":160},{"value":"http://image10.bizrate-images.com/resize?sq=400&uid=2120981405","xsize":400,"ysize":400}]},"relevancy":108614681362432.000000,"priceSet":{"minPrice":{"value":"$1.70","integral":170},"maxPrice":{"value":"$99.99","integral":9999},"stores":11},"id":2120981405,"categoryId":8515},{"type":"PRODUCT","title":"Iphone® 4 Aerosport Case","description":"Do more than just protect your iPhone 4 with this case bundle from rooCASE. This 3 in 1 bundle include a snap-on case, screen protector and a Nike+ sensor shoe pouch that can be use on most running shoes. Color: Purple Design: Love Provides protection...","manufacturer":"Luxmo","url":{"value":"http://www.bizrate.com/iphone-4-aerosport-case--pid2203798762/compareprices__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"},"images":{"image":[{"value":"http://image10.bizrate-images.com/resize?sq=60&uid=2203798762","xsize":60,"ysize":60},{"value":"http://image10.bizrate-images.com/resize?sq=100&uid=2203798762","xsize":100,"ysize":100},{"value":"http://image10.bizrate-images.com/resize?sq=160&uid=2203798762","xsize":160,"ysize":160},{"value":"http://image10.bizrate-images.com/resize?sq=400&uid=2203798762","xsize":400,"ysize":400}]},"relevancy":96203484168192.000000,"priceSet":{"minPrice":{"value":"$2.49","integral":249},"maxPrice":{"value":"$79.95","integral":7995},"stores":16},"id":2203798762,"categoryId":8515},{"type":"PRODUCT","title":"Case Reflect For Iphone 3G","description":"NCAA iPhone 3G faceplate features the schools primary logo silk screened on the front of the case.","manufacturer":"Griffin","url":{"value":"http://www.bizrate.com/case-reflect-for-iphone-3g--pid1114627445/compareprices__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"},"images":{"image":[{"value":"http://image10.bizrate-images.com/resize?sq=60&uid=1114627445","xsize":60,"ysize":60},{"value":"http://image10.bizrate-images.com/resize?sq=100&uid=1114627445","xsize":100,"ysize":100},{"value":"http://image10.bizrate-images.com/resize?sq=160&uid=1114627445","xsize":160,"ysize":160},{"value":"http://image10.bizrate-images.com/resize?sq=400&uid=1114627445","xsize":400,"ysize":400}]},"relevancy":84727583211520.000000,"priceSet":{"minPrice":{"value":"$0.69","integral":69},"maxPrice":{"value":"$75.52","integral":7552},"stores":59},"id":1114627445,"categoryId":8515},{"type":"PRODUCT","title":"Infuse Protector Case for iPhone 4 Black","description":"Protect and personalize your iPhone 4 with this front and back image design Protector Case. Form-fitting front and back hard plastic covers Protects your cell phone without adding a lot of bulk Smooth glossy finish Snaps on to the front edges, sides...","manufacturer":"Luxmo","url":{"value":"http://www.bizrate.com/infuse-protector-case-for-iphone-4-black--pid2557462717/compareprices__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"},"images":{"image":[{"value":"http://image10.bizrate-images.com/resize?sq=60&uid=2557462717","xsize":60,"ysize":60},{"value":"http://image10.bizrate-images.com/resize?sq=100&uid=2557462717","xsize":100,"ysize":100},{"value":"http://image10.bizrate-images.com/resize?sq=160&uid=2557462717","xsize":160,"ysize":160},{"value":"http://image10.bizrate-images.com/resize?sq=400&uid=2557462717","xsize":400,"ysize":400}]},"relevancy":80831066406912.000000,"priceSet":{"minPrice":{"value":"$0.59","integral":59},"maxPrice":{"value":"$79.00","integral":7900},"stores":24},"id":2557462717,"categoryId":8515},{"type":"PRODUCT","title":"Dragonfly iPhone 4 Kream Case - Black","description":"DF-0030219 - White, Kream Case for iPhone 4 by Dragon-Fly","url":{"value":"http://www.bizrate.com/dragonfly-iphone-4-kream-case-black--pid2442061740/compareprices__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"},"images":{"image":[{"value":"http://image10.bizrate-images.com/resize?sq=60&uid=2442061740","xsize":60,"ysize":60},{"value":"http://image10.bizrate-images.com/resize?sq=100&uid=2442061740","xsize":100,"ysize":100},{"value":"http://image10.bizrate-images.com/resize?sq=160&uid=2442061740","xsize":160,"ysize":160},{"value":"http://image10.bizrate-images.com/resize?sq=400&uid=2442061740","xsize":400,"ysize":400}]},"relevancy":70900229603328.000000,"priceSet":{"minPrice":{"value":"$1.05","integral":105},"maxPrice":{"value":"$94.49","integral":9449},"stores":30},"id":2442061740,"categoryId":8515},{"type":"PRODUCT","title":"Apple iPhone 3G/3GS Silicone Case (Black)","description":"Snap on Apple iPhone 3G 3GS Synthetic Leather Hardshell Case! Premium Qualtiy Synthetic Leather cover provides style, comfort, and protection to your iPhone 3G & 3GS. It also adds a sophisticated elegance and cool to your fashion. The case allows Quick...","manufacturer":"Luxmo","url":{"value":"http://www.bizrate.com/apple-iphone-3g3gs-silicone-case-black--pid2004746863/compareprices__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"},"images":{"image":[{"value":"http://image10.bizrate-images.com/resize?sq=60&uid=2004746863","xsize":60,"ysize":60},{"value":"http://image10.bizrate-images.com/resize?sq=100&uid=2004746863","xsize":100,"ysize":100},{"value":"http://image10.bizrate-images.com/resize?sq=160&uid=2004746863","xsize":160,"ysize":160},{"value":"http://image10.bizrate-images.com/resize?sq=400&uid=2004746863","xsize":400,"ysize":400}]},"relevancy":65194915004416.000000,"priceSet":{"minPrice":{"value":"$0.01","integral":1},"maxPrice":{"value":"$414.99","integral":41499},"stores":39},"id":2004746863,"categoryId":8515},{"type":"PRODUCT","title":"Otterbox iPhone 4 Defender Case - Black","description":"Your iPhone 4 has become a big part of your life. With FaceTime video, retina display, multitasking, HD video recording and more - you've got a lot to lose. You won't find a tougher case than the OtterBox Defender Series for iPhone 4. This three-layer...","manufacturer":"Universal","url":{"value":"http://www.bizrate.com/otterbox-iphone-4-defender-case-black--pid2584611575/compareprices__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"},"images":{"image":[{"value":"http://image10.bizrate-images.com/resize?sq=60&uid=2584611575","xsize":60,"ysize":60},{"value":"http://image10.bizrate-images.com/resize?sq=100&uid=2584611575","xsize":100,"ysize":100},{"value":"http://image10.bizrate-images.com/resize?sq=160&uid=2584611575","xsize":160,"ysize":160},{"value":"http://image10.bizrate-images.com/resize?sq=400&uid=2584611575","xsize":400,"ysize":400}]},"relevancy":61515478597632.000000,"priceSet":{"minPrice":{"value":"$3.28","integral":328},"maxPrice":{"value":"$110.65","integral":11065},"stores":25},"id":2584611575,"categoryId":8515}],"includedResults":10,"totalResults":2000}},
-{"classification":{"relevancyScore":1000,"searchUrl":{"value":"http://www.bizrate.com/iphone-cases/index__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"}},"products":{"priceSet":{"minPrice":{"value":"$0.01","integral":1},"maxPrice":{"value":"$4,833.99","integral":483399}},"product":[{"type":"PRODUCT","title":"Silicone case for iPhone 3G/ 3GS","description":"Elite Horizontal Leather Pouch for Apple iPhone 3G/3Gs - Premium quality horizontal case for your Apple iPhone 3G/3Gs. This pouch is ideal for the style conscious on the go. This great looking case is made from high-quality leather with classic black...","manufacturer":"Apple","url":{"value":"http://www.bizrate.com/silicone-case-for-iphone-3g-3gs--pid1968262863/compareprices__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"},"images":{"image":[{"value":"http://image10.bizrate-images.com/resize?sq=60&uid=1968262863","xsize":60,"ysize":60},{"value":"http://image10.bizrate-images.com/resize?sq=100&uid=1968262863","xsize":100,"ysize":100},{"value":"http://image10.bizrate-images.com/resize?sq=160&uid=1968262863","xsize":160,"ysize":160},{"value":"http://image10.bizrate-images.com/resize?sq=400&uid=1968262863","xsize":400,"ysize":400}]},"relevancy":310711221747712.000000,"priceSet":{"minPrice":{"value":"$1.56","integral":156},"maxPrice":{"value":"$29.99","integral":2999},"stores":14},"id":1968262863,"categoryId":8515},{"type":"PRODUCT","title":"Nonslip Checkered Silicone Skin Soft Case for iPhone 4 4G","description":"Specification:Product Name Silicone Skin Case Model for Apple iPhone 4 Color Black Material Soft Silicone Skin Weight 26g Package 1 x Case for Apple iPhone 4 Description:This is a non-OEM product.Accessory Only, Phone is not included.","manufacturer":"H&B","url":{"value":"http://www.bizrate.com/nonslip-checkered-silicone-skin-soft-case-for-iphone-4-4g--pid2534935499/compareprices__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"},"images":{"image":[{"value":"http://image10.bizrate-images.com/resize?sq=60&uid=2534935499","xsize":60,"ysize":60},{"value":"http://image10.bizrate-images.com/resize?sq=100&uid=2534935499","xsize":100,"ysize":100},{"value":"http://image10.bizrate-images.com/resize?sq=160&uid=2534935499","xsize":160,"ysize":160},{"value":"http://image10.bizrate-images.com/resize?sq=400&uid=2534935499","xsize":400,"ysize":400}]},"relevancy":175580930637824.000000,"priceSet":{"minPrice":{"value":"$0.45","integral":45},"maxPrice":{"value":"$194.95","integral":19495},"stores":34},"id":2534935499,"categoryId":8515},{"type":"PRODUCT","title":"Plastic Case for iPhone 4 - Black","description":"Description:Detachable Windmill Type Matte Hard Plastic Case Cover for iPhone 4 (Black / Magenta)Customised your iPhone with this wonderful Plastic Case which is a accessory for your iPhone 4 which is made of high quality and durable plastic, protect","manufacturer":"Griffin","url":{"value":"http://www.bizrate.com/plastic-case-for-iphone-4-black--pid2305624670/compareprices__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"},"images":{"image":[{"value":"http://image10.bizrate-images.com/resize?sq=60&uid=2305624670","xsize":60,"ysize":60},{"value":"http://image10.bizrate-images.com/resize?sq=100&uid=2305624670","xsize":100,"ysize":100},{"value":"http://image10.bizrate-images.com/resize?sq=160&uid=2305624670","xsize":160,"ysize":160},{"value":"http://image10.bizrate-images.com/resize?sq=400&uid=2305624670","xsize":400,"ysize":400}]},"relevancy":132488642953216.000000,"priceSet":{"minPrice":{"value":"$0.99","integral":99},"maxPrice":{"value":"$303.68","integral":30368},"stores":33},"id":2305624670,"categoryId":8515},{"type":"PRODUCT","title":"Protective Silicone Case for iPhone 4","description":"Made of high quality PVC material Protects your iPhone 4 from any scratch and dirt Easy to install and remove, no any tool needed Cut-out design allows user can access all keypad / button and slot without having to remove the case","manufacturer":"Griffin","url":{"value":"http://www.bizrate.com/protective-silicone-case-for-iphone-4--pid2120981405/compareprices__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"},"images":{"image":[{"value":"http://image10.bizrate-images.com/resize?sq=60&uid=2120981405","xsize":60,"ysize":60},{"value":"http://image10.bizrate-images.com/resize?sq=100&uid=2120981405","xsize":100,"ysize":100},{"value":"http://image10.bizrate-images.com/resize?sq=160&uid=2120981405","xsize":160,"ysize":160},{"value":"http://image10.bizrate-images.com/resize?sq=400&uid=2120981405","xsize":400,"ysize":400}]},"relevancy":108614681362432.000000,"priceSet":{"minPrice":{"value":"$1.70","integral":170},"maxPrice":{"value":"$99.99","integral":9999},"stores":11},"id":2120981405,"categoryId":8515},{"type":"PRODUCT","title":"Iphone® 4 Aerosport Case","description":"Do more than just protect your iPhone 4 with this case bundle from rooCASE. This 3 in 1 bundle include a snap-on case, screen protector and a Nike+ sensor shoe pouch that can be use on most running shoes. Color: Purple Design: Love Provides protection...","manufacturer":"Luxmo","url":{"value":"http://www.bizrate.com/iphone-4-aerosport-case--pid2203798762/compareprices__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"},"images":{"image":[{"value":"http://image10.bizrate-images.com/resize?sq=60&uid=2203798762","xsize":60,"ysize":60},{"value":"http://image10.bizrate-images.com/resize?sq=100&uid=2203798762","xsize":100,"ysize":100},{"value":"http://image10.bizrate-images.com/resize?sq=160&uid=2203798762","xsize":160,"ysize":160},{"value":"http://image10.bizrate-images.com/resize?sq=400&uid=2203798762","xsize":400,"ysize":400}]},"relevancy":96203484168192.000000,"priceSet":{"minPrice":{"value":"$2.49","integral":249},"maxPrice":{"value":"$79.95","integral":7995},"stores":16},"id":2203798762,"categoryId":8515},{"type":"PRODUCT","title":"Case Reflect For Iphone 3G","description":"NCAA iPhone 3G faceplate features the schools primary logo silk screened on the front of the case.","manufacturer":"Griffin","url":{"value":"http://www.bizrate.com/case-reflect-for-iphone-3g--pid1114627445/compareprices__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"},"images":{"image":[{"value":"http://image10.bizrate-images.com/resize?sq=60&uid=1114627445","xsize":60,"ysize":60},{"value":"http://image10.bizrate-images.com/resize?sq=100&uid=1114627445","xsize":100,"ysize":100},{"value":"http://image10.bizrate-images.com/resize?sq=160&uid=1114627445","xsize":160,"ysize":160},{"value":"http://image10.bizrate-images.com/resize?sq=400&uid=1114627445","xsize":400,"ysize":400}]},"relevancy":84727583211520.000000,"priceSet":{"minPrice":{"value":"$0.69","integral":69},"maxPrice":{"value":"$75.52","integral":7552},"stores":59},"id":1114627445,"categoryId":8515},{"type":"PRODUCT","title":"Infuse Protector Case for iPhone 4 Black","description":"Protect and personalize your iPhone 4 with this front and back image design Protector Case. Form-fitting front and back hard plastic covers Protects your cell phone without adding a lot of bulk Smooth glossy finish Snaps on to the front edges, sides...","manufacturer":"Luxmo","url":{"value":"http://www.bizrate.com/infuse-protector-case-for-iphone-4-black--pid2557462717/compareprices__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"},"images":{"image":[{"value":"http://image10.bizrate-images.com/resize?sq=60&uid=2557462717","xsize":60,"ysize":60},{"value":"http://image10.bizrate-images.com/resize?sq=100&uid=2557462717","xsize":100,"ysize":100},{"value":"http://image10.bizrate-images.com/resize?sq=160&uid=2557462717","xsize":160,"ysize":160},{"value":"http://image10.bizrate-images.com/resize?sq=400&uid=2557462717","xsize":400,"ysize":400}]},"relevancy":80831066406912.000000,"priceSet":{"minPrice":{"value":"$0.59","integral":59},"maxPrice":{"value":"$79.00","integral":7900},"stores":24},"id":2557462717,"categoryId":8515},{"type":"PRODUCT","title":"Dragonfly iPhone 4 Kream Case - Black","description":"DF-0030219 - White, Kream Case for iPhone 4 by Dragon-Fly","url":{"value":"http://www.bizrate.com/dragonfly-iphone-4-kream-case-black--pid2442061740/compareprices__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"},"images":{"image":[{"value":"http://image10.bizrate-images.com/resize?sq=60&uid=2442061740","xsize":60,"ysize":60},{"value":"http://image10.bizrate-images.com/resize?sq=100&uid=2442061740","xsize":100,"ysize":100},{"value":"http://image10.bizrate-images.com/resize?sq=160&uid=2442061740","xsize":160,"ysize":160},{"value":"http://image10.bizrate-images.com/resize?sq=400&uid=2442061740","xsize":400,"ysize":400}]},"relevancy":70900229603328.000000,"priceSet":{"minPrice":{"value":"$1.05","integral":105},"maxPrice":{"value":"$94.49","integral":9449},"stores":30},"id":2442061740,"categoryId":8515},{"type":"PRODUCT","title":"Apple iPhone 3G/3GS Silicone Case (Black)","description":"Snap on Apple iPhone 3G 3GS Synthetic Leather Hardshell Case! Premium Qualtiy Synthetic Leather cover provides style, comfort, and protection to your iPhone 3G & 3GS. It also adds a sophisticated elegance and cool to your fashion. The case allows Quick...","manufacturer":"Luxmo","url":{"value":"http://www.bizrate.com/apple-iphone-3g3gs-silicone-case-black--pid2004746863/compareprices__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"},"images":{"image":[{"value":"http://image10.bizrate-images.com/resize?sq=60&uid=2004746863","xsize":60,"ysize":60},{"value":"http://image10.bizrate-images.com/resize?sq=100&uid=2004746863","xsize":100,"ysize":100},{"value":"http://image10.bizrate-images.com/resize?sq=160&uid=2004746863","xsize":160,"ysize":160},{"value":"http://image10.bizrate-images.com/resize?sq=400&uid=2004746863","xsize":400,"ysize":400}]},"relevancy":65194915004416.000000,"priceSet":{"minPrice":{"value":"$0.01","integral":1},"maxPrice":{"value":"$414.99","integral":41499},"stores":39},"id":2004746863,"categoryId":8515},{"type":"PRODUCT","title":"Otterbox iPhone 4 Defender Case - Black","description":"Your iPhone 4 has become a big part of your life. With FaceTime video, retina display, multitasking, HD video recording and more - you've got a lot to lose. You won't find a tougher case than the OtterBox Defender Series for iPhone 4. This three-layer...","manufacturer":"Universal","url":{"value":"http://www.bizrate.com/otterbox-iphone-4-defender-case-black--pid2584611575/compareprices__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"},"images":{"image":[{"value":"http://image10.bizrate-images.com/resize?sq=60&uid=2584611575","xsize":60,"ysize":60},{"value":"http://image10.bizrate-images.com/resize?sq=100&uid=2584611575","xsize":100,"ysize":100},{"value":"http://image10.bizrate-images.com/resize?sq=160&uid=2584611575","xsize":160,"ysize":160},{"value":"http://image10.bizrate-images.com/resize?sq=400&uid=2584611575","xsize":400,"ysize":400}]},"relevancy":61515478597632.000000,"priceSet":{"minPrice":{"value":"$3.28","integral":328},"maxPrice":{"value":"$110.65","integral":11065},"stores":25},"id":2584611575,"categoryId":8515}],"includedResults":10,"totalResults":2000}},
-{"classification":{"relevancyScore":1000,"searchUrl":{"value":"http://www.bizrate.com/iphone-cases/index__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"}},"products":{"priceSet":{"minPrice":{"value":"$0.01","integral":1},"maxPrice":{"value":"$4,833.99","integral":483399}},"product":[{"type":"PRODUCT","title":"Silicone case for iPhone 3G/ 3GS","description":"Elite Horizontal Leather Pouch for Apple iPhone 3G/3Gs - Premium quality horizontal case for your Apple iPhone 3G/3Gs. This pouch is ideal for the style conscious on the go. This great looking case is made from high-quality leather with classic black...","manufacturer":"Apple","url":{"value":"http://www.bizrate.com/silicone-case-for-iphone-3g-3gs--pid1968262863/compareprices__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"},"images":{"image":[{"value":"http://image10.bizrate-images.com/resize?sq=60&uid=1968262863","xsize":60,"ysize":60},{"value":"http://image10.bizrate-images.com/resize?sq=100&uid=1968262863","xsize":100,"ysize":100},{"value":"http://image10.bizrate-images.com/resize?sq=160&uid=1968262863","xsize":160,"ysize":160},{"value":"http://image10.bizrate-images.com/resize?sq=400&uid=1968262863","xsize":400,"ysize":400}]},"relevancy":310711221747712.000000,"priceSet":{"minPrice":{"value":"$1.56","integral":156},"maxPrice":{"value":"$29.99","integral":2999},"stores":14},"id":1968262863,"categoryId":8515},{"type":"PRODUCT","title":"Nonslip Checkered Silicone Skin Soft Case for iPhone 4 4G","description":"Specification:Product Name Silicone Skin Case Model for Apple iPhone 4 Color Black Material Soft Silicone Skin Weight 26g Package 1 x Case for Apple iPhone 4 Description:This is a non-OEM product.Accessory Only, Phone is not included.","manufacturer":"H&B","url":{"value":"http://www.bizrate.com/nonslip-checkered-silicone-skin-soft-case-for-iphone-4-4g--pid2534935499/compareprices__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"},"images":{"image":[{"value":"http://image10.bizrate-images.com/resize?sq=60&uid=2534935499","xsize":60,"ysize":60},{"value":"http://image10.bizrate-images.com/resize?sq=100&uid=2534935499","xsize":100,"ysize":100},{"value":"http://image10.bizrate-images.com/resize?sq=160&uid=2534935499","xsize":160,"ysize":160},{"value":"http://image10.bizrate-images.com/resize?sq=400&uid=2534935499","xsize":400,"ysize":400}]},"relevancy":175580930637824.000000,"priceSet":{"minPrice":{"value":"$0.45","integral":45},"maxPrice":{"value":"$194.95","integral":19495},"stores":34},"id":2534935499,"categoryId":8515},{"type":"PRODUCT","title":"Plastic Case for iPhone 4 - Black","description":"Description:Detachable Windmill Type Matte Hard Plastic Case Cover for iPhone 4 (Black / Magenta)Customised your iPhone with this wonderful Plastic Case which is a accessory for your iPhone 4 which is made of high quality and durable plastic, protect","manufacturer":"Griffin","url":{"value":"http://www.bizrate.com/plastic-case-for-iphone-4-black--pid2305624670/compareprices__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"},"images":{"image":[{"value":"http://image10.bizrate-images.com/resize?sq=60&uid=2305624670","xsize":60,"ysize":60},{"value":"http://image10.bizrate-images.com/resize?sq=100&uid=2305624670","xsize":100,"ysize":100},{"value":"http://image10.bizrate-images.com/resize?sq=160&uid=2305624670","xsize":160,"ysize":160},{"value":"http://image10.bizrate-images.com/resize?sq=400&uid=2305624670","xsize":400,"ysize":400}]},"relevancy":132488642953216.000000,"priceSet":{"minPrice":{"value":"$0.99","integral":99},"maxPrice":{"value":"$303.68","integral":30368},"stores":33},"id":2305624670,"categoryId":8515},{"type":"PRODUCT","title":"Protective Silicone Case for iPhone 4","description":"Made of high quality PVC material Protects your iPhone 4 from any scratch and dirt Easy to install and remove, no any tool needed Cut-out design allows user can access all keypad / button and slot without having to remove the case","manufacturer":"Griffin","url":{"value":"http://www.bizrate.com/protective-silicone-case-for-iphone-4--pid2120981405/compareprices__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"},"images":{"image":[{"value":"http://image10.bizrate-images.com/resize?sq=60&uid=2120981405","xsize":60,"ysize":60},{"value":"http://image10.bizrate-images.com/resize?sq=100&uid=2120981405","xsize":100,"ysize":100},{"value":"http://image10.bizrate-images.com/resize?sq=160&uid=2120981405","xsize":160,"ysize":160},{"value":"http://image10.bizrate-images.com/resize?sq=400&uid=2120981405","xsize":400,"ysize":400}]},"relevancy":108614681362432.000000,"priceSet":{"minPrice":{"value":"$1.70","integral":170},"maxPrice":{"value":"$99.99","integral":9999},"stores":11},"id":2120981405,"categoryId":8515},{"type":"PRODUCT","title":"Iphone® 4 Aerosport Case","description":"Do more than just protect your iPhone 4 with this case bundle from rooCASE. This 3 in 1 bundle include a snap-on case, screen protector and a Nike+ sensor shoe pouch that can be use on most running shoes. Color: Purple Design: Love Provides protection...","manufacturer":"Luxmo","url":{"value":"http://www.bizrate.com/iphone-4-aerosport-case--pid2203798762/compareprices__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"},"images":{"image":[{"value":"http://image10.bizrate-images.com/resize?sq=60&uid=2203798762","xsize":60,"ysize":60},{"value":"http://image10.bizrate-images.com/resize?sq=100&uid=2203798762","xsize":100,"ysize":100},{"value":"http://image10.bizrate-images.com/resize?sq=160&uid=2203798762","xsize":160,"ysize":160},{"value":"http://image10.bizrate-images.com/resize?sq=400&uid=2203798762","xsize":400,"ysize":400}]},"relevancy":96203484168192.000000,"priceSet":{"minPrice":{"value":"$2.49","integral":249},"maxPrice":{"value":"$79.95","integral":7995},"stores":16},"id":2203798762,"categoryId":8515},{"type":"PRODUCT","title":"Case Reflect For Iphone 3G","description":"NCAA iPhone 3G faceplate features the schools primary logo silk screened on the front of the case.","manufacturer":"Griffin","url":{"value":"http://www.bizrate.com/case-reflect-for-iphone-3g--pid1114627445/compareprices__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"},"images":{"image":[{"value":"http://image10.bizrate-images.com/resize?sq=60&uid=1114627445","xsize":60,"ysize":60},{"value":"http://image10.bizrate-images.com/resize?sq=100&uid=1114627445","xsize":100,"ysize":100},{"value":"http://image10.bizrate-images.com/resize?sq=160&uid=1114627445","xsize":160,"ysize":160},{"value":"http://image10.bizrate-images.com/resize?sq=400&uid=1114627445","xsize":400,"ysize":400}]},"relevancy":84727583211520.000000,"priceSet":{"minPrice":{"value":"$0.69","integral":69},"maxPrice":{"value":"$75.52","integral":7552},"stores":59},"id":1114627445,"categoryId":8515},{"type":"PRODUCT","title":"Infuse Protector Case for iPhone 4 Black","description":"Protect and personalize your iPhone 4 with this front and back image design Protector Case. Form-fitting front and back hard plastic covers Protects your cell phone without adding a lot of bulk Smooth glossy finish Snaps on to the front edges, sides...","manufacturer":"Luxmo","url":{"value":"http://www.bizrate.com/infuse-protector-case-for-iphone-4-black--pid2557462717/compareprices__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"},"images":{"image":[{"value":"http://image10.bizrate-images.com/resize?sq=60&uid=2557462717","xsize":60,"ysize":60},{"value":"http://image10.bizrate-images.com/resize?sq=100&uid=2557462717","xsize":100,"ysize":100},{"value":"http://image10.bizrate-images.com/resize?sq=160&uid=2557462717","xsize":160,"ysize":160},{"value":"http://image10.bizrate-images.com/resize?sq=400&uid=2557462717","xsize":400,"ysize":400}]},"relevancy":80831066406912.000000,"priceSet":{"minPrice":{"value":"$0.59","integral":59},"maxPrice":{"value":"$79.00","integral":7900},"stores":24},"id":2557462717,"categoryId":8515},{"type":"PRODUCT","title":"Dragonfly iPhone 4 Kream Case - Black","description":"DF-0030219 - White, Kream Case for iPhone 4 by Dragon-Fly","url":{"value":"http://www.bizrate.com/dragonfly-iphone-4-kream-case-black--pid2442061740/compareprices__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"},"images":{"image":[{"value":"http://image10.bizrate-images.com/resize?sq=60&uid=2442061740","xsize":60,"ysize":60},{"value":"http://image10.bizrate-images.com/resize?sq=100&uid=2442061740","xsize":100,"ysize":100},{"value":"http://image10.bizrate-images.com/resize?sq=160&uid=2442061740","xsize":160,"ysize":160},{"value":"http://image10.bizrate-images.com/resize?sq=400&uid=2442061740","xsize":400,"ysize":400}]},"relevancy":70900229603328.000000,"priceSet":{"minPrice":{"value":"$1.05","integral":105},"maxPrice":{"value":"$94.49","integral":9449},"stores":30},"id":2442061740,"categoryId":8515},{"type":"PRODUCT","title":"Apple iPhone 3G/3GS Silicone Case (Black)","description":"Snap on Apple iPhone 3G 3GS Synthetic Leather Hardshell Case! Premium Qualtiy Synthetic Leather cover provides style, comfort, and protection to your iPhone 3G & 3GS. It also adds a sophisticated elegance and cool to your fashion. The case allows Quick...","manufacturer":"Luxmo","url":{"value":"http://www.bizrate.com/apple-iphone-3g3gs-silicone-case-black--pid2004746863/compareprices__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"},"images":{"image":[{"value":"http://image10.bizrate-images.com/resize?sq=60&uid=2004746863","xsize":60,"ysize":60},{"value":"http://image10.bizrate-images.com/resize?sq=100&uid=2004746863","xsize":100,"ysize":100},{"value":"http://image10.bizrate-images.com/resize?sq=160&uid=2004746863","xsize":160,"ysize":160},{"value":"http://image10.bizrate-images.com/resize?sq=400&uid=2004746863","xsize":400,"ysize":400}]},"relevancy":65194915004416.000000,"priceSet":{"minPrice":{"value":"$0.01","integral":1},"maxPrice":{"value":"$414.99","integral":41499},"stores":39},"id":2004746863,"categoryId":8515},{"type":"PRODUCT","title":"Otterbox iPhone 4 Defender Case - Black","description":"Your iPhone 4 has become a big part of your life. With FaceTime video, retina display, multitasking, HD video recording and more - you've got a lot to lose. You won't find a tougher case than the OtterBox Defender Series for iPhone 4. This three-layer...","manufacturer":"Universal","url":{"value":"http://www.bizrate.com/otterbox-iphone-4-defender-case-black--pid2584611575/compareprices__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"},"images":{"image":[{"value":"http://image10.bizrate-images.com/resize?sq=60&uid=2584611575","xsize":60,"ysize":60},{"value":"http://image10.bizrate-images.com/resize?sq=100&uid=2584611575","xsize":100,"ysize":100},{"value":"http://image10.bizrate-images.com/resize?sq=160&uid=2584611575","xsize":160,"ysize":160},{"value":"http://image10.bizrate-images.com/resize?sq=400&uid=2584611575","xsize":400,"ysize":400}]},"relevancy":61515478597632.000000,"priceSet":{"minPrice":{"value":"$3.28","integral":328},"maxPrice":{"value":"$110.65","integral":11065},"stores":25},"id":2584611575,"categoryId":8515}],"includedResults":10,"totalResults":2000}},
-{"classification":{"relevancyScore":1000,"searchUrl":{"value":"http://www.bizrate.com/iphone-cases/index__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"}},"products":{"priceSet":{"minPrice":{"value":"$0.01","integral":1},"maxPrice":{"value":"$4,833.99","integral":483399}},"product":[{"type":"PRODUCT","title":"Silicone case for iPhone 3G/ 3GS","description":"Elite Horizontal Leather Pouch for Apple iPhone 3G/3Gs - Premium quality horizontal case for your Apple iPhone 3G/3Gs. This pouch is ideal for the style conscious on the go. This great looking case is made from high-quality leather with classic black...","manufacturer":"Apple","url":{"value":"http://www.bizrate.com/silicone-case-for-iphone-3g-3gs--pid1968262863/compareprices__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"},"images":{"image":[{"value":"http://image10.bizrate-images.com/resize?sq=60&uid=1968262863","xsize":60,"ysize":60},{"value":"http://image10.bizrate-images.com/resize?sq=100&uid=1968262863","xsize":100,"ysize":100},{"value":"http://image10.bizrate-images.com/resize?sq=160&uid=1968262863","xsize":160,"ysize":160},{"value":"http://image10.bizrate-images.com/resize?sq=400&uid=1968262863","xsize":400,"ysize":400}]},"relevancy":310711221747712.000000,"priceSet":{"minPrice":{"value":"$1.56","integral":156},"maxPrice":{"value":"$29.99","integral":2999},"stores":14},"id":1968262863,"categoryId":8515},{"type":"PRODUCT","title":"Nonslip Checkered Silicone Skin Soft Case for iPhone 4 4G","description":"Specification:Product Name Silicone Skin Case Model for Apple iPhone 4 Color Black Material Soft Silicone Skin Weight 26g Package 1 x Case for Apple iPhone 4 Description:This is a non-OEM product.Accessory Only, Phone is not included.","manufacturer":"H&B","url":{"value":"http://www.bizrate.com/nonslip-checkered-silicone-skin-soft-case-for-iphone-4-4g--pid2534935499/compareprices__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"},"images":{"image":[{"value":"http://image10.bizrate-images.com/resize?sq=60&uid=2534935499","xsize":60,"ysize":60},{"value":"http://image10.bizrate-images.com/resize?sq=100&uid=2534935499","xsize":100,"ysize":100},{"value":"http://image10.bizrate-images.com/resize?sq=160&uid=2534935499","xsize":160,"ysize":160},{"value":"http://image10.bizrate-images.com/resize?sq=400&uid=2534935499","xsize":400,"ysize":400}]},"relevancy":175580930637824.000000,"priceSet":{"minPrice":{"value":"$0.45","integral":45},"maxPrice":{"value":"$194.95","integral":19495},"stores":34},"id":2534935499,"categoryId":8515},{"type":"PRODUCT","title":"Plastic Case for iPhone 4 - Black","description":"Description:Detachable Windmill Type Matte Hard Plastic Case Cover for iPhone 4 (Black / Magenta)Customised your iPhone with this wonderful Plastic Case which is a accessory for your iPhone 4 which is made of high quality and durable plastic, protect","manufacturer":"Griffin","url":{"value":"http://www.bizrate.com/plastic-case-for-iphone-4-black--pid2305624670/compareprices__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"},"images":{"image":[{"value":"http://image10.bizrate-images.com/resize?sq=60&uid=2305624670","xsize":60,"ysize":60},{"value":"http://image10.bizrate-images.com/resize?sq=100&uid=2305624670","xsize":100,"ysize":100},{"value":"http://image10.bizrate-images.com/resize?sq=160&uid=2305624670","xsize":160,"ysize":160},{"value":"http://image10.bizrate-images.com/resize?sq=400&uid=2305624670","xsize":400,"ysize":400}]},"relevancy":132488642953216.000000,"priceSet":{"minPrice":{"value":"$0.99","integral":99},"maxPrice":{"value":"$303.68","integral":30368},"stores":33},"id":2305624670,"categoryId":8515},{"type":"PRODUCT","title":"Protective Silicone Case for iPhone 4","description":"Made of high quality PVC material Protects your iPhone 4 from any scratch and dirt Easy to install and remove, no any tool needed Cut-out design allows user can access all keypad / button and slot without having to remove the case","manufacturer":"Griffin","url":{"value":"http://www.bizrate.com/protective-silicone-case-for-iphone-4--pid2120981405/compareprices__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"},"images":{"image":[{"value":"http://image10.bizrate-images.com/resize?sq=60&uid=2120981405","xsize":60,"ysize":60},{"value":"http://image10.bizrate-images.com/resize?sq=100&uid=2120981405","xsize":100,"ysize":100},{"value":"http://image10.bizrate-images.com/resize?sq=160&uid=2120981405","xsize":160,"ysize":160},{"value":"http://image10.bizrate-images.com/resize?sq=400&uid=2120981405","xsize":400,"ysize":400}]},"relevancy":108614681362432.000000,"priceSet":{"minPrice":{"value":"$1.70","integral":170},"maxPrice":{"value":"$99.99","integral":9999},"stores":11},"id":2120981405,"categoryId":8515},{"type":"PRODUCT","title":"Iphone® 4 Aerosport Case","description":"Do more than just protect your iPhone 4 with this case bundle from rooCASE. This 3 in 1 bundle include a snap-on case, screen protector and a Nike+ sensor shoe pouch that can be use on most running shoes. Color: Purple Design: Love Provides protection...","manufacturer":"Luxmo","url":{"value":"http://www.bizrate.com/iphone-4-aerosport-case--pid2203798762/compareprices__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"},"images":{"image":[{"value":"http://image10.bizrate-images.com/resize?sq=60&uid=2203798762","xsize":60,"ysize":60},{"value":"http://image10.bizrate-images.com/resize?sq=100&uid=2203798762","xsize":100,"ysize":100},{"value":"http://image10.bizrate-images.com/resize?sq=160&uid=2203798762","xsize":160,"ysize":160},{"value":"http://image10.bizrate-images.com/resize?sq=400&uid=2203798762","xsize":400,"ysize":400}]},"relevancy":96203484168192.000000,"priceSet":{"minPrice":{"value":"$2.49","integral":249},"maxPrice":{"value":"$79.95","integral":7995},"stores":16},"id":2203798762,"categoryId":8515},{"type":"PRODUCT","title":"Case Reflect For Iphone 3G","description":"NCAA iPhone 3G faceplate features the schools primary logo silk screened on the front of the case.","manufacturer":"Griffin","url":{"value":"http://www.bizrate.com/case-reflect-for-iphone-3g--pid1114627445/compareprices__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"},"images":{"image":[{"value":"http://image10.bizrate-images.com/resize?sq=60&uid=1114627445","xsize":60,"ysize":60},{"value":"http://image10.bizrate-images.com/resize?sq=100&uid=1114627445","xsize":100,"ysize":100},{"value":"http://image10.bizrate-images.com/resize?sq=160&uid=1114627445","xsize":160,"ysize":160},{"value":"http://image10.bizrate-images.com/resize?sq=400&uid=1114627445","xsize":400,"ysize":400}]},"relevancy":84727583211520.000000,"priceSet":{"minPrice":{"value":"$0.69","integral":69},"maxPrice":{"value":"$75.52","integral":7552},"stores":59},"id":1114627445,"categoryId":8515},{"type":"PRODUCT","title":"Infuse Protector Case for iPhone 4 Black","description":"Protect and personalize your iPhone 4 with this front and back image design Protector Case. Form-fitting front and back hard plastic covers Protects your cell phone without adding a lot of bulk Smooth glossy finish Snaps on to the front edges, sides...","manufacturer":"Luxmo","url":{"value":"http://www.bizrate.com/infuse-protector-case-for-iphone-4-black--pid2557462717/compareprices__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"},"images":{"image":[{"value":"http://image10.bizrate-images.com/resize?sq=60&uid=2557462717","xsize":60,"ysize":60},{"value":"http://image10.bizrate-images.com/resize?sq=100&uid=2557462717","xsize":100,"ysize":100},{"value":"http://image10.bizrate-images.com/resize?sq=160&uid=2557462717","xsize":160,"ysize":160},{"value":"http://image10.bizrate-images.com/resize?sq=400&uid=2557462717","xsize":400,"ysize":400}]},"relevancy":80831066406912.000000,"priceSet":{"minPrice":{"value":"$0.59","integral":59},"maxPrice":{"value":"$79.00","integral":7900},"stores":24},"id":2557462717,"categoryId":8515},{"type":"PRODUCT","title":"Dragonfly iPhone 4 Kream Case - Black","description":"DF-0030219 - White, Kream Case for iPhone 4 by Dragon-Fly","url":{"value":"http://www.bizrate.com/dragonfly-iphone-4-kream-case-black--pid2442061740/compareprices__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"},"images":{"image":[{"value":"http://image10.bizrate-images.com/resize?sq=60&uid=2442061740","xsize":60,"ysize":60},{"value":"http://image10.bizrate-images.com/resize?sq=100&uid=2442061740","xsize":100,"ysize":100},{"value":"http://image10.bizrate-images.com/resize?sq=160&uid=2442061740","xsize":160,"ysize":160},{"value":"http://image10.bizrate-images.com/resize?sq=400&uid=2442061740","xsize":400,"ysize":400}]},"relevancy":70900229603328.000000,"priceSet":{"minPrice":{"value":"$1.05","integral":105},"maxPrice":{"value":"$94.49","integral":9449},"stores":30},"id":2442061740,"categoryId":8515},{"type":"PRODUCT","title":"Apple iPhone 3G/3GS Silicone Case (Black)","description":"Snap on Apple iPhone 3G 3GS Synthetic Leather Hardshell Case! Premium Qualtiy Synthetic Leather cover provides style, comfort, and protection to your iPhone 3G & 3GS. It also adds a sophisticated elegance and cool to your fashion. The case allows Quick...","manufacturer":"Luxmo","url":{"value":"http://www.bizrate.com/apple-iphone-3g3gs-silicone-case-black--pid2004746863/compareprices__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"},"images":{"image":[{"value":"http://image10.bizrate-images.com/resize?sq=60&uid=2004746863","xsize":60,"ysize":60},{"value":"http://image10.bizrate-images.com/resize?sq=100&uid=2004746863","xsize":100,"ysize":100},{"value":"http://image10.bizrate-images.com/resize?sq=160&uid=2004746863","xsize":160,"ysize":160},{"value":"http://image10.bizrate-images.com/resize?sq=400&uid=2004746863","xsize":400,"ysize":400}]},"relevancy":65194915004416.000000,"priceSet":{"minPrice":{"value":"$0.01","integral":1},"maxPrice":{"value":"$414.99","integral":41499},"stores":39},"id":2004746863,"categoryId":8515},{"type":"PRODUCT","title":"Otterbox iPhone 4 Defender Case - Black","description":"Your iPhone 4 has become a big part of your life. With FaceTime video, retina display, multitasking, HD video recording and more - you've got a lot to lose. You won't find a tougher case than the OtterBox Defender Series for iPhone 4. This three-layer...","manufacturer":"Universal","url":{"value":"http://www.bizrate.com/otterbox-iphone-4-defender-case-black--pid2584611575/compareprices__rf--af1__af_assettype_id--10__af_creative_id--6__af_id--50085__af_placement_id--1.html"},"images":{"image":[{"value":"http://image10.bizrate-images.com/resize?sq=60&uid=2584611575","xsize":60,"ysize":60},{"value":"http://image10.bizrate-images.com/resize?sq=100&uid=2584611575","xsize":100,"ysize":100},{"value":"http://image10.bizrate-images.com/resize?sq=160&uid=2584611575","xsize":160,"ysize":160},{"value":"http://image10.bizrate-images.com/resize?sq=400&uid=2584611575","xsize":400,"ysize":400}]},"relevancy":61515478597632.000000,"priceSet":{"minPrice":{"value":"$3.28","integral":328},"maxPrice":{"value":"$110.65","integral":11065},"stores":25},"id":2584611575,"categoryId":8515}],"includedResults":10,"totalResults":2000}}
-]
-
diff --git a/src/3rdparty/qjson/json.pro b/src/3rdparty/qjson/json.pro
deleted file mode 100644
index ffb1ce99..00000000
--- a/src/3rdparty/qjson/json.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-TEMPLATE = subdirs
-CONFIG += ordered
-
-SUBDIRS = tests benchmark
diff --git a/src/3rdparty/qjson/qjson.pri b/src/3rdparty/qjson/qjson.pri
deleted file mode 100644
index 680b5818..00000000
--- a/src/3rdparty/qjson/qjson.pri
+++ /dev/null
@@ -1 +0,0 @@
-include(src/json.pri)
diff --git a/src/3rdparty/qjson/src/json.cpp b/src/3rdparty/qjson/src/json.cpp
deleted file mode 100644
index dba77799..00000000
--- a/src/3rdparty/qjson/src/json.cpp
+++ /dev/null
@@ -1,432 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2010 Girish Ramakrishnan <girish@forwardbias.in>
-**
-** Use, modification and distribution is allowed without limitation,
-** warranty, liability or support of any kind.
-**
-****************************************************************************/
-
-#include "json.h"
-#include "jsonparser.cpp"
-
-#include <QTextCodec>
-#include <qnumeric.h>
-
-/*!
- \class JsonReader
- \internal
- \reentrant
-
- \brief The JsonReader class provides a fast parser for reading
- well-formed JSON into a QVariant.
-
- The parser converts JSON types into QVariant types. For example, JSON
- arrays are translated into QVariantList and JSON objects are translated
- into QVariantMap. For example,
- \code
- JsonReader reader;
- if (reader.parse("{ \"id\": 123, \"company\": \"Nokia\", \"authors\": [\"Denis\",\"Ettrich\",\"Girish\"])) {
- QVariant result = reader.result();
- QVariantMap map = result.toMap(); // the JSON object
- qDebug() << map.count(); // 3
- qDebug() << map["id"].toInt(); // 123
- qDebug() << map["company"].toString(); // "Nokia"
- QVariantList list = map["authors"].toList();
- qDebug() << list[1].toString(); // "Girish"
- } else {
- qDebug() << reader.errorString();
- }
- \endcode
-
- As seen above, the reader converts the JSON into a QVariant with arbitrary nesting.
- A complete listing of JSON to QVariant conversion is documented at parse().
-
- JsonWriter can be used to convert a QVariant into JSON string.
-*/
-
-/*!
- Constructs a JSON reader.
- */
-JsonReader::JsonReader()
-{
-}
-
-/*!
- Destructor
- */
-JsonReader::~JsonReader()
-{
-}
-
-/*!
- Parses the JSON \a ba as a QVariant.
-
- If the parse succeeds, this function returns true and the QVariant can
- be accessed using result(). If the parse fails, this function returns
- false and the error message can be accessed using errorMessage().
-
- The encoding of \ba is auto-detected based on the pattern of nulls in the
- initial 4 octets as described in "Section 3. Encoding" of RFC 2647. If an
- encoding could not be auto-detected, this function assumes UTF-8.
-
- The conversion from JSON type into QVariant type is as listed below:
- \table
- \row
- \li false
- \li QVariant::Bool with the value false.
- \row
- \li true
- \li QVariant::Bool with the value true.
- \row
- \li null
- \li QVariant::Invalid i.e QVariant()
- \row
- \li object
- \li QVariant::Map i.e QVariantMap
- \row
- \li array
- \li QVariant::List i.e QVariantList
- \row
- \li string
- \li QVariant::String i.e QString
- \row
- \li number
- \li QVariant::Double or QVariant::LongLong. If the JSON number contains a '.' or 'e'
- or 'E', QVariant::Double is used.
- \endtable
-
- The byte array \ba may or may not contain a BOM.
- */
-bool JsonReader::parse(const QByteArray &ba)
-{
- int mib = 106; // utf-8
-
- QTextCodec *codec = QTextCodec::codecForUtfText(ba, 0); // try BOM detection
- if (!codec) {
- if (ba.length() > 3) { // auto-detect
- const char *data = ba.constData();
- if (data[0] != 0) {
- if (data[1] != 0)
- mib = 106; // utf-8
- else if (data[2] != 0)
- mib = 1014; // utf16 le
- else
- mib = 1019; // utf32 le
- } else if (data[1] != 0)
- mib = 1013; // utf16 be
- else
- mib = 1018; // utf32 be
- }
- codec = QTextCodec::codecForMib(mib);
- }
- QString str = codec->toUnicode(ba);
- return parse(str);
-}
-
-/*!
- Parses the JSON string \a str as a QVariant.
-
- If the parse succeeds, this function returns true and the QVariant can
- be accessed using result(). If the parse fails, this function returns
- false and the error message can be accessed using errorMessage().
- */
-bool JsonReader::parse(const QString &str)
-{
- JsonLexer lexer(str);
- JsonParser parser;
- if (!parser.parse(&lexer)) {
- m_errorString = parser.errorMessage();
- m_result = QVariant();
- return false;
- }
- m_errorString.clear();
- m_result = parser.result();
- return true;
-}
-
-/*!
- Returns the result of the last parse() call.
-
- If parse() failed, this function returns an invalid QVariant.
- */
-QVariant JsonReader::result() const
-{
- return m_result;
-}
-
-/*!
- Returns the error message for the last parse() call.
-
- If parse() succeeded, this functions return an empty string. The error message
- should be used for debugging purposes only.
- */
-QString JsonReader::errorString() const
-{
- return m_errorString;
-}
-
-/*!
- \class JsonWriter
- \internal
- \reentrant
-
- \brief The JsonWriter class converts a QVariant into a JSON string.
-
- The writer converts specific supported types stored in a QVariant into JSON.
- For example,
- \code
- QVariant v;
- QVariantMap map;
- map["id"] = 123;
- map["company"] = "Nokia";
- QVariantList list;
- list << "Denis" << "Ettrich" << "Girish";
- map["authors"] = list;
-
- JsonWriter writer;
- QString json = writer.toString(v);
- qDebug() << json; // {"authors": ["Denis", "Ettrich", "Girish"], "company": "Nokia", "id": 123 }
- \endcode
-
- The list of QVariant types that the writer supports is listed in toString(). Note that
- custom C++ types registered using Q_DECLARE_METATYPE are not supported.
-*/
-
-/*!
- Creates a JsonWriter.
- */
-JsonWriter::JsonWriter()
- : m_autoFormatting(false), m_autoFormattingIndent(4, QLatin1Char(' '))
-{
-}
-
-/*!
- Destructor.
- */
-JsonWriter::~JsonWriter()
-{
-}
-
-/*!
- Enables auto formatting if \a enable is \c true, otherwise
- disables it.
-
- When auto formatting is enabled, the writer automatically inserts
- spaces and new lines to make the output more human readable.
-
- The default value is \c false.
- */
-void JsonWriter::setAutoFormatting(bool enable)
-{
- m_autoFormatting = enable;
-}
-
-/*!
- Returns \c true if auto formattting is enabled, otherwise \c false.
- */
-bool JsonWriter::autoFormatting() const
-{
- return m_autoFormatting;
-}
-
-/*!
- Sets the number of spaces or tabs used for indentation when
- auto-formatting is enabled. Positive numbers indicate spaces,
- negative numbers tabs.
-
- The default indentation is 4.
-
- \sa setAutoFormatting()
-*/
-void JsonWriter::setAutoFormattingIndent(int spacesOrTabs)
-{
- m_autoFormattingIndent = QString(qAbs(spacesOrTabs), QLatin1Char(spacesOrTabs >= 0 ? ' ' : '\t'));
-}
-
-/*!
- Retuns the numbers of spaces or tabs used for indentation when
- auto-formatting is enabled. Positive numbers indicate spaces,
- negative numbers tabs.
-
- The default indentation is 4.
-
- \sa setAutoFormatting()
-*/
-int JsonWriter::autoFormattingIndent() const
-{
- return m_autoFormattingIndent.count(QLatin1Char(' ')) - m_autoFormattingIndent.count(QLatin1Char('\t'));
-}
-
-/*! \internal
- Inserts escape character \ for characters in string as described in JSON specification.
- */
-static QString escape(const QVariant &variant)
-{
- QString str = variant.toString();
- QString res;
- res.reserve(str.length());
- for (int i = 0; i < str.length(); i++) {
- if (str[i] == QLatin1Char('\b')) {
- res += QLatin1String("\\b");
- } else if (str[i] == QLatin1Char('\f')) {
- res += QLatin1String("\\f");
- } else if (str[i] == QLatin1Char('\n')) {
- res += QLatin1String("\\n");
- } else if (str[i] == QLatin1Char('\r')) {
- res += QLatin1String("\\r");
- } else if (str[i] == QLatin1Char('\t')) {
- res += QLatin1String("\\t");
- } else if (str[i] == QLatin1Char('\"')) {
- res += QLatin1String("\\\"");
- } else if (str[i] == QLatin1Char('\\')) {
- res += QLatin1String("\\\\");
- } else if (str[i] == QLatin1Char('/')) {
- res += QLatin1String("\\/");
- } else if (str[i].unicode() > 127) {
- res += QLatin1String("\\u") + QString::number(str[i].unicode(), 16).rightJustified(4, QLatin1Char('0'));
- } else {
- res += str[i];
- }
- }
- return res;
-}
-
-/*! \internal
- Stringifies \a variant.
- */
-QString JsonWriter::stringify(const QVariant &variant, int depth)
-{
- QString result;
- if (variant.type() == QVariant::List || variant.type() == QVariant::StringList) {
- result += QLatin1Char('[');
- QVariantList list = variant.toList();
- for (int i = 0; i < list.count(); i++) {
- if (i != 0) {
- result += QLatin1Char(',');
- if (m_autoFormatting)
- result += QLatin1Char(' ');
- }
- result += stringify(list[i], depth+1);
- }
- result += QLatin1Char(']');
- } else if (variant.type() == QVariant::Map) {
- QString indent = m_autoFormattingIndent.repeated(depth);
- QVariantMap map = variant.toMap();
- if (m_autoFormatting && depth != 0) {
- result += QLatin1Char('\n');
- result += indent;
- result += QLatin1String("{\n");
- } else {
- result += QLatin1Char('{');
- }
- for (QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it) {
- if (it != map.constBegin()) {
- result += QLatin1Char(',');
- if (m_autoFormatting)
- result += QLatin1Char('\n');
- }
- if (m_autoFormatting)
- result += indent + QLatin1Char(' ');
- result += QLatin1Char('\"') + escape(it.key()) + QLatin1String("\":");
- result += stringify(it.value(), depth+1);
- }
- if (m_autoFormatting) {
- result += QLatin1Char('\n');
- result += indent;
- }
- result += QLatin1Char('}');
- } else if (variant.type() == QVariant::String || variant.type() == QVariant::ByteArray) {
- result = QLatin1Char('\"') + escape(variant) + QLatin1Char('\"');
- } else if (variant.type() == QVariant::Double || (int)variant.type() == (int)QMetaType::Float) {
- double d = variant.toDouble();
- if (qIsFinite(d))
- result.setNum(variant.toDouble(), 'g', 15);
- else
- result = QLatin1String("null");
- } else if (variant.type() == QVariant::Bool) {
- result = variant.toBool() ? QLatin1String("true") : QLatin1String("false");
- } else if (variant.type() == QVariant::Invalid) {
- result = QLatin1String("null");
- } else if (variant.type() == QVariant::ULongLong) {
- result = QString::number(variant.toULongLong());
- } else if (variant.type() == QVariant::LongLong) {
- result = QString::number(variant.toLongLong());
- } else if (variant.type() == QVariant::Int) {
- result = QString::number(variant.toInt());
- } else if (variant.type() == QVariant::UInt) {
- result = QString::number(variant.toUInt());
- } else if (variant.type() == QVariant::Char) {
- QChar c = variant.toChar();
- if (c.unicode() > 127)
- result = QLatin1String("\"\\u") + QString::number(c.unicode(), 16).rightJustified(4, QLatin1Char('0')) + QLatin1Char('\"');
- else
- result = QLatin1Char('\"') + c + QLatin1Char('\"');
- } else if (variant.canConvert<qlonglong>()) {
- result = QString::number(variant.toLongLong());
- } else if (variant.canConvert<QString>()) {
- result = QLatin1Char('\"') + escape(variant) + QLatin1Char('\"');
- } else {
- result = QLatin1String("null");
- }
-
- return result;
-}
-
-/*!
- Converts the variant \a var into a JSON string.
-
- The stringizer converts \a var into JSON based on the type of it's contents. The supported
- types and their conversion into JSON is as listed below:
-
- \table
- \row
- \li QVariant::List, QVariant::StringList
- \li JSON array []
- \row
- \li QVariant::Map
- \li JSON object {}
- \row
- \li QVariant::String, QVariant::ByteArray
- \li JSON string encapsulated in double quotes. String contents are escaped using '\' if necessary.
- \row
- \li QVariant::Double, QMetaType::Float
- \li JSON number with a precision 15. Infinity and NaN are converted into null.
- \row
- \li QVariant::Bool
- \li JSON boolean true and false
- \row
- \li QVariant::Invalid
- \li JSON null
- \row
- \li QVariant::ULongLong, QVariant::LongLong, QVariant::Int, QVariant::UInt,
- \li JSON number
- \row
- \li QVariant::Char
- \li JSON string. Non-ASCII characters are converted into the \uXXXX notation.
- \endtable
-
- As a fallback, the writer attempts to convert a type not listed above into a long long or a
- QString using QVariant::canConvert. See the QVariant documentation for possible conversions.
-
- JsonWriter does not support stringizing custom user types stored in the QVariant. Any such
- value would be converted into JSON null.
- */
-QString JsonWriter::toString(const QVariant &var)
-{
- return stringify(var);
-}
-
-/*!
- Converts the variant \a var into a JSON string.
-
- The returned QByteArray is UTF-8 encoded and does not contain a BOM. The list of supported
- C++ types is documented in toString().
-
- \sa toString()
- */
-QByteArray JsonWriter::toByteArray(const QVariant &var)
-{
- return stringify(var).toUtf8();
-}
-
diff --git a/src/3rdparty/qjson/src/json.g b/src/3rdparty/qjson/src/json.g
deleted file mode 100644
index d1f9e17f..00000000
--- a/src/3rdparty/qjson/src/json.g
+++ /dev/null
@@ -1,420 +0,0 @@
--- ***************************************************************************
---
--- Copyright (c) 2010 Girish Ramakrishnan <girish@forwardbias.in>
--- Copyright (c) 2011 Denis Dzyubenko <shadone@gmail.com>
---
--- Use, modification and distribution is allowed without limitation,
--- warranty, liability or support of any kind.
---
--- **************************************************************************
-
-%parser JsonGrammar
-%merged_output jsonparser.cpp
-
-%token T_STRING "string"
-%token T_NUMBER "number"
-%token T_LCURLYBRACKET "{"
-%token T_RCURLYBRACKET "}"
-%token T_LSQUAREBRACKET "["
-%token T_RSQUAREBRACKET "]"
-%token T_COLON ":"
-%token T_COMMA ","
-%token T_FALSE "false"
-%token T_TRUE "true"
-%token T_NULL "null"
-%token ERROR "error"
-
-%start Root
-
-/:
-/****************************************************************************
-**
-** Copyright (c) 2010 Girish Ramakrishnan <girish@forwardbias.in>
-** Copyright (c) 2011 Denis Dzyubenko <shadone@gmail.com>
-**
-** Use, modification and distribution is allowed without limitation,
-** warranty, liability or support of any kind.
-**
-****************************************************************************/
-
-#ifndef JSONPARSER_P_H
-#define JSONPARSER_P_H
-
-#include <QString>
-#include <QVariant>
-#include <QVector>
-
-class JsonLexer
-{
-public:
- JsonLexer(const QString &string);
- ~JsonLexer();
-
- int lex();
- QVariant symbol() const { return m_symbol; }
- int lineNumber() const { return m_lineNumber; }
- int pos() const { return m_pos; }
-
-private:
- int parseNumber();
- int parseString();
- int parseKeyword();
-
- QString m_strdata;
- int m_lineNumber;
- int m_pos;
- QVariant m_symbol;
-};
-
-class JsonParser : protected $table
-{
-public:
- JsonParser();
- ~JsonParser();
-
- bool parse(JsonLexer *lex);
- QVariant result() const { return m_result; }
- QString errorMessage() const { return QString::fromLatin1("%1 at line %2 pos %3").arg(m_errorMessage).arg(m_errorLineNumber).arg(m_errorPos); }
-
-private:
- void reallocateStack();
-
- inline QVariant &sym(int index)
- { return m_symStack[m_tos + index - 1]; }
- inline QVariantMap &map(int index)
- { return m_mapStack[m_tos + index - 1]; }
- inline QVariantList &list(int index)
- { return m_listStack[m_tos + index - 1]; }
-
- int m_tos;
- QVector<int> m_stateStack;
- QVector<QVariant> m_symStack;
- QVector<QVariantMap> m_mapStack;
- QVector<QVariantList> m_listStack;
- QString m_errorMessage;
- int m_errorLineNumber;
- int m_errorPos;
- QVariant m_result;
-};
-
-#endif // JSONPARSER_P_H
-:/
-
-/.
-/****************************************************************************
-**
-** Copyright (c) 2010 Girish Ramakrishnan <girish@forwardbias.in>
-** Copyright (c) 2011 Denis Dzyubenko <shadone@gmail.com>
-**
-** Use, modification and distribution is allowed without limitation,
-** warranty, liability or support of any kind.
-**
-****************************************************************************/
-
-#include <QtDebug>
-
-#define L1C(c) ushort(uchar(c))
-
-JsonLexer::JsonLexer(const QString &str)
- : m_strdata(str), m_lineNumber(1), m_pos(0)
-{
-}
-
-
-
-JsonLexer::~JsonLexer()
-{
-}
-
-int JsonLexer::parseString()
-{
- bool esc = false;
- ++m_pos; // skip initial "
- int start = m_pos;
-
- const ushort *uc = m_strdata.utf16();
- const int remaining = m_strdata.length() - m_pos;
- int i;
- for (i = 0; i < remaining; ++i) {
- const ushort c = uc[m_pos + i];
- if (c == L1C('\"')) {
- m_symbol = QString((QChar *)uc + m_pos, i);
- m_pos += i;
- ++m_pos; // eat quote
- return JsonGrammar::T_STRING;
- } else if (c == L1C('\\')) {
- ++m_pos; // eat backslash
- esc = true;
- break;
- }
- }
-
- QString str;
- if (i) {
- str.resize(i);
- memcpy((char *)str.utf16(), uc + start, i * 2);
- m_pos += i;
- }
-
- for (; m_pos < m_strdata.length(); ++m_pos) {
- const ushort c = uc[m_pos];
- if (esc) {
- if (c == L1C('b')) str += QLatin1Char('\b');
- else if (c == L1C('f')) str += QLatin1Char('\f');
- else if (c == L1C('n')) str += QLatin1Char('\n');
- else if (c == L1C('r')) str += QLatin1Char('\r');
- else if (c == L1C('t')) str += QLatin1Char('\t');
- else if (c == L1C('\\')) str += QLatin1Char('\\');
- else if (c == L1C('\"')) str += QLatin1Char('\"');
- else if (c == L1C('u') && m_pos+4<m_strdata.length()-1) {
- QString u = m_strdata.mid(m_pos+1, 4);
- str += QChar(u.toUShort(0, 16));
- m_pos += 4;
- } else {
- str += QChar(c);
- }
- esc = false;
- } else if (c == L1C('\\')) {
- esc = true;
- } else if (c == L1C('\"')) {
- m_symbol = str;
- ++m_pos;
- return JsonGrammar::T_STRING;
- } else {
- str += QChar(c);
- }
- }
- return JsonGrammar::ERROR;
-}
-
-int JsonLexer::parseNumber()
-{
- int start = m_pos;
- bool isDouble = false;
- const ushort *uc = m_strdata.utf16();
- const int l = m_strdata.length();
- const int negative = (uc[m_pos] == L1C('-') ? ++m_pos, -1 : (uc[m_pos] == L1C('+') ? ++m_pos, 1 : 1));
- qlonglong value = 0;
- for (; m_pos < l; ++m_pos) {
- const ushort &c = uc[m_pos];
- if (c == L1C('+') || c == L1C('-'))
- continue;
- if (c == L1C('.') || c == L1C('e') || c == L1C('E')) {
- isDouble = true;
- continue;
- }
- if (c >= L1C('0') && c <= L1C('9')) {
- if (!isDouble) {
- value *= 10;
- value += c - L1C('0');
- }
- continue;
- }
- break;
- }
- if (!isDouble) {
- m_symbol = value * negative;
- } else {
- QString number = QString::fromRawData((QChar *)uc+start, m_pos-start);
- m_symbol = number.toDouble();
- }
- return JsonGrammar::T_NUMBER;
-}
-
-int JsonLexer::parseKeyword()
-{
- int start = m_pos;
- for (; m_pos < m_strdata.length(); ++m_pos) {
- const ushort c = m_strdata.at(m_pos).unicode();
- if (c >= L1C('a') && c <= L1C('z'))
- continue;
- break;
- }
- const ushort *k = (const ushort *)m_strdata.constData() + start;
- const int l = m_pos-start;
- if (l == 4) {
- static const ushort true_data[] = { 't', 'r', 'u', 'e' };
- static const ushort null_data[] = { 'n', 'u', 'l', 'l' };
- if (!memcmp(k, true_data, 4))
- return JsonGrammar::T_TRUE;
- if (!memcmp(k, null_data, 4))
- return JsonGrammar::T_NULL;
- } else if (l == 5) {
- static const ushort false_data[] = { 'f', 'a', 'l', 's', 'e' };
- if (!memcmp(k, false_data, 5))
- return JsonGrammar::T_FALSE;
- }
- return JsonGrammar::ERROR;
-}
-
-int JsonLexer::lex()
-{
- m_symbol.clear();
-
- const ushort *uc = m_strdata.utf16();
- const int len = m_strdata.length();
- while (m_pos < len) {
- const ushort c = uc[m_pos];
- switch (c) {
- case L1C('['): ++m_pos; return JsonGrammar::T_LSQUAREBRACKET;
- case L1C(']'): ++m_pos; return JsonGrammar::T_RSQUAREBRACKET;
- case L1C('{'): ++m_pos; return JsonGrammar::T_LCURLYBRACKET;
- case L1C('}'): ++m_pos; return JsonGrammar::T_RCURLYBRACKET;
- case L1C(':'): ++m_pos; return JsonGrammar::T_COLON;
- case L1C(','): ++m_pos; return JsonGrammar::T_COMMA;
- case L1C(' '): case L1C('\r'): case L1C('\t'): ++m_pos; break;
- case L1C('\n'): ++m_pos; ++m_lineNumber; break;
- case L1C('"'): return parseString();
- default:
- if (c == L1C('+') || c == L1C('-') || (c >= L1C('0') && c <= L1C('9'))) {
- return parseNumber();
- }
- if (c >= L1C('a') && c <= L1C('z')) {
- return parseKeyword();
- }
- return JsonGrammar::ERROR;
- }
- }
- return JsonGrammar::EOF_SYMBOL;
-}
-#undef L1C
-
-JsonParser::JsonParser()
-{
-}
-
-JsonParser::~JsonParser()
-{
-}
-
-void JsonParser::reallocateStack()
-{
- int size = m_stateStack.size();
- if (size == 0)
- size = 128;
- else
- size <<= 1;
-
- m_symStack.resize(size);
- m_mapStack.resize(size);
- m_listStack.resize(size);
- m_stateStack.resize(size);
-}
-
-bool JsonParser::parse(JsonLexer *lexer)
-{
- const int INITIAL_STATE = 0;
- int yytoken = -1;
- reallocateStack();
- m_tos = 0;
- m_stateStack[++m_tos] = INITIAL_STATE;
-
- while (true) {
- const int state = m_stateStack[m_tos];
- if (yytoken == -1 && -TERMINAL_COUNT != action_index[state]) {
- yytoken = lexer->lex();
- }
- int act = t_action(state, yytoken);
- if (act == ACCEPT_STATE)
- return true;
- else if (act > 0) {
- if (++m_tos == m_stateStack.size())
- reallocateStack();
- m_stateStack[m_tos] = act;
- m_symStack[m_tos] = lexer->symbol();
- yytoken = -1;
- } else if (act < 0) {
- int r = -act-1;
- m_tos -= rhs[r];
- act = m_stateStack.at(m_tos++);
- switch (r) {
-./
-
-Root ::= Value;
-/. case $rule_number: { m_result = sym(1); break; } ./
-
-Object ::= T_LCURLYBRACKET Members T_RCURLYBRACKET;
-/. case $rule_number: { sym(1) = map(2); break; } ./
-
-Members ::= T_STRING T_COLON Value;
-/. case $rule_number: { QVariantMap m; m.insert(sym(1).toString(), sym(3)); map(1) = m; break; } ./
-
-Members ::= Members T_COMMA T_STRING T_COLON Value;
-/. case $rule_number: { map(1).insert(sym(3).toString(), sym(5)); break; } ./
-
-Members ::= ;
-/. case $rule_number: { map(1) = QVariantMap(); break; } ./
-
-Value ::= T_FALSE;
-/. case $rule_number: { sym(1) = QVariant(false); break; } ./
-
-Value ::= T_TRUE;
-/. case $rule_number: { sym(1) = QVariant(true); break; } ./
-
-Value ::= T_NULL;
-Value ::= Object;
-Value ::= Array;
-Value ::= T_NUMBER;
-Value ::= T_STRING;
-
-Array ::= T_LSQUAREBRACKET Values T_RSQUAREBRACKET;
-/. case $rule_number: { sym(1) = list(2); break; } ./
-
-Values ::= Value;
-/. case $rule_number: { QVariantList l; l.append(sym(1)); list(1) = l; break; } ./
-
-Values ::= Values T_COMMA Value;
-/. case $rule_number: { list(1).append(sym(3)); break; } ./
-
-Values ::= ;
-/. case $rule_number: { list(1) = QVariantList(); break; } ./
-
-/.
- } // switch
- m_stateStack[m_tos] = nt_action(act, lhs[r] - TERMINAL_COUNT);
- } else {
- int ers = state;
- int shifts = 0;
- int reduces = 0;
- int expected_tokens[3];
- for (int tk = 0; tk < TERMINAL_COUNT; ++tk) {
- int k = t_action(ers, tk);
-
- if (! k)
- continue;
- else if (k < 0)
- ++reduces;
- else if (spell[tk]) {
- if (shifts < 3)
- expected_tokens[shifts] = tk;
- ++shifts;
- }
- }
-
- m_errorLineNumber = lexer->lineNumber();
- m_errorPos = lexer->pos();
- m_errorMessage.clear();
- if (shifts && shifts < 3) {
- bool first = true;
-
- for (int s = 0; s < shifts; ++s) {
- if (first)
- m_errorMessage += QLatin1String("Expected ");
- else
- m_errorMessage += QLatin1String(", ");
-
- first = false;
- m_errorMessage += QLatin1String("'");
- m_errorMessage += QLatin1String(spell[expected_tokens[s]]);
- m_errorMessage += QLatin1String("'");
- }
- }
- return false;
- }
- }
-
- return false;
-}
-
-./
-
diff --git a/src/3rdparty/qjson/src/json.h b/src/3rdparty/qjson/src/json.h
deleted file mode 100644
index 62f33a40..00000000
--- a/src/3rdparty/qjson/src/json.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2010 Girish Ramakrishnan <girish@forwardbias.in>
-**
-** Use, modification and distribution is allowed without limitation,
-** warranty, liability or support of any kind.
-**
-****************************************************************************/
-
-#ifndef JSON_H
-#define JSON_H
-
-#include <QByteArray>
-#include <QVariant>
-
-class JsonReader
-{
-public:
- JsonReader();
- ~JsonReader();
-
- bool parse(const QByteArray &ba);
- bool parse(const QString &str);
-
- QVariant result() const;
-
- QString errorString() const;
-
-private:
- QVariant m_result;
- QString m_errorString;
- void *reserved;
-};
-
-class JsonWriter
-{
-public:
- JsonWriter();
- ~JsonWriter();
-
- QString toString(const QVariant &variant);
- QByteArray toByteArray(const QVariant &variant);
-
- void setAutoFormatting(bool autoFormat);
- bool autoFormatting() const;
-
- void setAutoFormattingIndent(int spaceOrTabs);
- int autoFormattingIndent() const;
-
-private:
- QString stringify(const QVariant &variant, int depth = 0);
- bool m_autoFormatting;
- QString m_autoFormattingIndent;
- void *reserved;
-};
-
-#endif // JSON_H
-
diff --git a/src/3rdparty/qjson/src/json.pri b/src/3rdparty/qjson/src/json.pri
deleted file mode 100644
index 0244a158..00000000
--- a/src/3rdparty/qjson/src/json.pri
+++ /dev/null
@@ -1,4 +0,0 @@
-INCLUDEPATH += $$PWD
-SOURCES += $$PWD/json.cpp
-
-#DEFINES += QT_NO_CAST_FROM_ASCII QT_NO_CAST_TO_ASCII QT_NO_CAST_FROM_BYTEARRAY
diff --git a/src/3rdparty/qjson/src/jsonparser.cpp b/src/3rdparty/qjson/src/jsonparser.cpp
deleted file mode 100644
index 899103f9..00000000
--- a/src/3rdparty/qjson/src/jsonparser.cpp
+++ /dev/null
@@ -1,527 +0,0 @@
-// This file was generated by qlalr - DO NOT EDIT!
-#ifndef JSONPARSER_CPP
-#define JSONPARSER_CPP
-
-class JsonGrammar
-{
-public:
- enum VariousConstants {
- EOF_SYMBOL = 0,
- ERROR = 12,
- T_COLON = 7,
- T_COMMA = 8,
- T_FALSE = 9,
- T_LCURLYBRACKET = 3,
- T_LSQUAREBRACKET = 5,
- T_NULL = 11,
- T_NUMBER = 2,
- T_RCURLYBRACKET = 4,
- T_RSQUAREBRACKET = 6,
- T_STRING = 1,
- T_TRUE = 10,
-
- ACCEPT_STATE = 12,
- RULE_COUNT = 17,
- STATE_COUNT = 27,
- TERMINAL_COUNT = 13,
- NON_TERMINAL_COUNT = 7,
-
- GOTO_INDEX_OFFSET = 27,
- GOTO_INFO_OFFSET = 37,
- GOTO_CHECK_OFFSET = 37
- };
-
- static const char *const spell [];
- static const short lhs [];
- static const short rhs [];
-
-#ifndef QLALR_NO_JSONGRAMMAR_DEBUG_INFO
- static const int rule_index [];
- static const int rule_info [];
-#endif // QLALR_NO_JSONGRAMMAR_DEBUG_INFO
-
- static const short goto_default [];
- static const short action_default [];
- static const short action_index [];
- static const short action_info [];
- static const short action_check [];
-
- static inline int nt_action (int state, int nt)
- {
- const int yyn = action_index [GOTO_INDEX_OFFSET + state] + nt;
- if (yyn < 0 || action_check [GOTO_CHECK_OFFSET + yyn] != nt)
- return goto_default [nt];
-
- return action_info [GOTO_INFO_OFFSET + yyn];
- }
-
- static inline int t_action (int state, int token)
- {
- const int yyn = action_index [state] + token;
-
- if (yyn < 0 || action_check [yyn] != token)
- return - action_default [state];
-
- return action_info [yyn];
- }
-};
-
-
-const char *const JsonGrammar::spell [] = {
- "end of file", "string", "number", "{", "}", "[", "]", ":", ",", "false",
- "true", "null", "error",
-#ifndef QLALR_NO_JSONGRAMMAR_DEBUG_INFO
-"Root", "Value", "Object", "Members", "Array", "Values", "$accept"
-#endif // QLALR_NO_JSONGRAMMAR_DEBUG_INFO
-};
-
-const short JsonGrammar::lhs [] = {
- 13, 15, 16, 16, 16, 14, 14, 14, 14, 14,
- 14, 14, 17, 18, 18, 18, 19};
-
-const short JsonGrammar::rhs [] = {
- 1, 3, 3, 5, 0, 1, 1, 1, 1, 1,
- 1, 1, 3, 1, 3, 0, 2};
-
-
-#ifndef QLALR_NO_JSONGRAMMAR_DEBUG_INFO
-const int JsonGrammar::rule_info [] = {
- 13, 14
- , 15, 3, 16, 4
- , 16, 1, 7, 14
- , 16, 16, 8, 1, 7, 14
- , 16
- , 14, 9
- , 14, 10
- , 14, 11
- , 14, 15
- , 14, 17
- , 14, 2
- , 14, 1
- , 17, 5, 18, 6
- , 18, 14
- , 18, 18, 8, 14
- , 18
- , 19, 13, 0};
-
-const int JsonGrammar::rule_index [] = {
- 0, 2, 6, 10, 16, 17, 19, 21, 23, 25,
- 27, 29, 31, 35, 37, 41, 42};
-#endif // QLALR_NO_JSONGRAMMAR_DEBUG_INFO
-
-const short JsonGrammar::action_default [] = {
- 0, 10, 9, 0, 6, 5, 16, 8, 11, 12,
- 7, 1, 17, 0, 0, 0, 2, 0, 0, 4,
- 0, 3, 14, 0, 0, 13, 15};
-
-const short JsonGrammar::goto_default [] = {
- 3, 11, 2, 13, 1, 23, 0};
-
-const short JsonGrammar::action_index [] = {
- 24, -13, -13, 12, -13, -1, 24, -13, -13, -13,
- -13, -13, -13, 1, -5, 2, -13, -6, 24, -13,
- 24, -13, -13, -2, 24, -13, -13,
-
- -7, -7, -7, -7, -7, -7, 1, -7, -7, -7,
- -7, -7, -7, -7, -7, -7, -7, -7, 0, -7,
- -1, -7, -7, -7, 5, -7, -7};
-
-const short JsonGrammar::action_info [] = {
- 14, 18, 20, 17, 25, 16, 24, 0, 0, 15,
- 0, 0, 12, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 9, 8, 5, 0, 6,
- 0, 0, 0, 4, 10, 7, 0,
-
- 21, 19, 22, 0, 0, 0, 26, 0, 0, 0,
- 0, 0};
-
-const short JsonGrammar::action_check [] = {
- 1, 7, 7, 1, 6, 4, 8, -1, -1, 8,
- -1, -1, 0, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 1, 2, 3, -1, 5,
- -1, -1, -1, 9, 10, 11, -1,
-
- 1, 1, 1, -1, -1, -1, 1, -1, -1, -1,
- -1, -1};
-
-
-#line 29 "json.g"
-
-/****************************************************************************
-**
-** Copyright (c) 2010 Girish Ramakrishnan <girish@forwardbias.in>
-** Copyright (c) 2011 Denis Dzyubenko <shadone@gmail.com>
-**
-** Use, modification and distribution is allowed without limitation,
-** warranty, liability or support of any kind.
-**
-****************************************************************************/
-
-#ifndef JSONPARSER_P_H
-#define JSONPARSER_P_H
-
-#include <QString>
-#include <QVariant>
-#include <QVector>
-
-class JsonLexer
-{
-public:
- JsonLexer(const QString &string);
- ~JsonLexer();
-
- int lex();
- QVariant symbol() const { return m_symbol; }
- int lineNumber() const { return m_lineNumber; }
- int pos() const { return m_pos; }
-
-private:
- int parseNumber();
- int parseString();
- int parseKeyword();
-
- QString m_strdata;
- int m_lineNumber;
- int m_pos;
- QVariant m_symbol;
-};
-
-class JsonParser : protected JsonGrammar
-{
-public:
- JsonParser();
- ~JsonParser();
-
- bool parse(JsonLexer *lex);
- QVariant result() const { return m_result; }
- QString errorMessage() const { return QString::fromLatin1("%1 at line %2 pos %3").arg(m_errorMessage).arg(m_errorLineNumber).arg(m_errorPos); }
-
-private:
- void reallocateStack();
-
- inline QVariant &sym(int index)
- { return m_symStack[m_tos + index - 1]; }
- inline QVariantMap &map(int index)
- { return m_mapStack[m_tos + index - 1]; }
- inline QVariantList &list(int index)
- { return m_listStack[m_tos + index - 1]; }
-
- int m_tos;
- QVector<int> m_stateStack;
- QVector<QVariant> m_symStack;
- QVector<QVariantMap> m_mapStack;
- QVector<QVariantList> m_listStack;
- QString m_errorMessage;
- int m_errorLineNumber;
- int m_errorPos;
- QVariant m_result;
-};
-
-#endif // JSONPARSER_P_H
-
-#line 103 "json.g"
-
-/****************************************************************************
-**
-** Copyright (c) 2010 Girish Ramakrishnan <girish@forwardbias.in>
-** Copyright (c) 2011 Denis Dzyubenko <shadone@gmail.com>
-**
-** Use, modification and distribution is allowed without limitation,
-** warranty, liability or support of any kind.
-**
-****************************************************************************/
-
-#include <QtDebug>
-
-#define L1C(c) ushort(uchar(c))
-
-JsonLexer::JsonLexer(const QString &str)
- : m_strdata(str), m_lineNumber(1), m_pos(0)
-{
-}
-
-
-
-JsonLexer::~JsonLexer()
-{
-}
-
-int JsonLexer::parseString()
-{
- bool esc = false;
- ++m_pos; // skip initial "
- int start = m_pos;
-
- const ushort *uc = m_strdata.utf16();
- const int remaining = m_strdata.length() - m_pos;
- int i;
- for (i = 0; i < remaining; ++i) {
- const ushort c = uc[m_pos + i];
- if (c == L1C('\"')) {
- m_symbol = QString((QChar *)uc + m_pos, i);
- m_pos += i;
- ++m_pos; // eat quote
- return JsonGrammar::T_STRING;
- } else if (c == L1C('\\')) {
- ++m_pos; // eat backslash
- esc = true;
- break;
- }
- }
-
- QString str;
- if (i) {
- str.resize(i);
- memcpy((char *)str.utf16(), uc + start, i * 2);
- m_pos += i;
- }
-
- for (; m_pos < m_strdata.length(); ++m_pos) {
- const ushort c = uc[m_pos];
- if (esc) {
- if (c == L1C('b')) str += QLatin1Char('\b');
- else if (c == L1C('f')) str += QLatin1Char('\f');
- else if (c == L1C('n')) str += QLatin1Char('\n');
- else if (c == L1C('r')) str += QLatin1Char('\r');
- else if (c == L1C('t')) str += QLatin1Char('\t');
- else if (c == L1C('\\')) str += QLatin1Char('\\');
- else if (c == L1C('\"')) str += QLatin1Char('\"');
- else if (c == L1C('u') && m_pos+4<m_strdata.length()-1) {
- // FIXME: This code is wrong
- QString u1 = m_strdata.mid(m_pos+1, 2); // TODO: QStringRef please
- QString u2 = m_strdata.mid(m_pos+3, 2);
- bool ok;
- str += QChar(u2.toInt(&ok, 16), u1.toInt(&ok, 16));
- m_pos += 4;
- } else {
- str += QChar(c);
- }
- esc = false;
- } else if (c == L1C('\\')) {
- esc = true;
- } else if (c == L1C('\"')) {
- m_symbol = str;
- ++m_pos;
- return JsonGrammar::T_STRING;
- } else {
- str += QChar(c);
- }
- }
- return JsonGrammar::ERROR;
-}
-
-int JsonLexer::parseNumber()
-{
- int start = m_pos;
- bool isDouble = false;
- const ushort *uc = m_strdata.utf16();
- const int l = m_strdata.length();
- const int negative = (uc[m_pos] == L1C('-') ? ++m_pos, -1 : (uc[m_pos] == L1C('+') ? ++m_pos, 1 : 1));
- qlonglong value = 0;
- for (; m_pos < l; ++m_pos) {
- const ushort &c = uc[m_pos];
- if (c == L1C('+') || c == L1C('-'))
- continue;
- if (c == L1C('.') || c == L1C('e') || c == L1C('E')) {
- isDouble = true;
- continue;
- }
- if (c >= L1C('0') && c <= L1C('9')) {
- if (!isDouble) {
- value *= 10;
- value += c - L1C('0');
- }
- continue;
- }
- break;
- }
- if (!isDouble) {
- m_symbol = value * negative;
- } else {
- QString number = QString::fromRawData((QChar *)uc+start, m_pos-start);
- m_symbol = number.toDouble();
- }
- return JsonGrammar::T_NUMBER;
-}
-
-int JsonLexer::parseKeyword()
-{
- int start = m_pos;
- for (; m_pos < m_strdata.length(); ++m_pos) {
- const ushort c = m_strdata.at(m_pos).unicode();
- if (c >= L1C('a') && c <= L1C('z'))
- continue;
- break;
- }
- const ushort *k = (const ushort *)m_strdata.constData() + start;
- const int l = m_pos-start;
- if (l == 4) {
- static const ushort true_data[] = { 't', 'r', 'u', 'e' };
- static const ushort null_data[] = { 'n', 'u', 'l', 'l' };
- if (!memcmp(k, true_data, 4))
- return JsonGrammar::T_TRUE;
- if (!memcmp(k, null_data, 4))
- return JsonGrammar::T_NULL;
- } else if (l == 5) {
- static const ushort false_data[] = { 'f', 'a', 'l', 's', 'e' };
- if (!memcmp(k, false_data, 5))
- return JsonGrammar::T_FALSE;
- }
- return JsonGrammar::ERROR;
-}
-
-int JsonLexer::lex()
-{
- m_symbol.clear();
-
- const ushort *uc = m_strdata.utf16();
- const int len = m_strdata.length();
- while (m_pos < len) {
- const ushort c = uc[m_pos];
- switch (c) {
- case L1C('['): ++m_pos; return JsonGrammar::T_LSQUAREBRACKET;
- case L1C(']'): ++m_pos; return JsonGrammar::T_RSQUAREBRACKET;
- case L1C('{'): ++m_pos; return JsonGrammar::T_LCURLYBRACKET;
- case L1C('}'): ++m_pos; return JsonGrammar::T_RCURLYBRACKET;
- case L1C(':'): ++m_pos; return JsonGrammar::T_COLON;
- case L1C(','): ++m_pos; return JsonGrammar::T_COMMA;
- case L1C(' '): case L1C('\r'): case L1C('\t'): ++m_pos; break;
- case L1C('\n'): ++m_pos; ++m_lineNumber; break;
- case L1C('"'): return parseString();
- default:
- if (c == L1C('+') || c == L1C('-') || (c >= L1C('0') && c <= L1C('9'))) {
- return parseNumber();
- }
- if (c >= L1C('a') && c <= L1C('z')) {
- return parseKeyword();
- }
- return JsonGrammar::ERROR;
- }
- }
- return JsonGrammar::EOF_SYMBOL;
-}
-#undef L1C
-
-JsonParser::JsonParser()
-{
-}
-
-JsonParser::~JsonParser()
-{
-}
-
-void JsonParser::reallocateStack()
-{
- int size = m_stateStack.size();
- if (size == 0)
- size = 128;
- else
- size <<= 1;
-
- m_symStack.resize(size);
- m_mapStack.resize(size);
- m_listStack.resize(size);
- m_stateStack.resize(size);
-}
-
-bool JsonParser::parse(JsonLexer *lexer)
-{
- const int INITIAL_STATE = 0;
- int yytoken = -1;
- reallocateStack();
- m_tos = 0;
- m_stateStack[++m_tos] = INITIAL_STATE;
-
- while (true) {
- const int state = m_stateStack[m_tos];
- if (yytoken == -1 && -TERMINAL_COUNT != action_index[state]) {
- yytoken = lexer->lex();
- }
- int act = t_action(state, yytoken);
- if (act == ACCEPT_STATE)
- return true;
- else if (act > 0) {
- if (++m_tos == m_stateStack.size())
- reallocateStack();
- m_stateStack[m_tos] = act;
- m_symStack[m_tos] = lexer->symbol();
- yytoken = -1;
- } else if (act < 0) {
- int r = -act-1;
- m_tos -= rhs[r];
- act = m_stateStack.at(m_tos++);
- switch (r) {
-
-#line 337 "json.g"
- case 0: { m_result = sym(1); break; }
-#line 340 "json.g"
- case 1: { sym(1) = map(2); break; }
-#line 343 "json.g"
- case 2: { QVariantMap m; m.insert(sym(1).toString(), sym(3)); map(1) = m; break; }
-#line 346 "json.g"
- case 3: { map(1).insert(sym(3).toString(), sym(5)); break; }
-#line 349 "json.g"
- case 4: { map(1) = QVariantMap(); break; }
-#line 352 "json.g"
- case 5: { sym(1) = QVariant(false); break; }
-#line 355 "json.g"
- case 6: { sym(1) = QVariant(true); break; }
-#line 364 "json.g"
- case 12: { sym(1) = list(2); break; }
-#line 367 "json.g"
- case 13: { QVariantList l; l.append(sym(1)); list(1) = l; break; }
-#line 370 "json.g"
- case 14: { list(1).append(sym(3)); break; }
-#line 373 "json.g"
- case 15: { list(1) = QVariantList(); break; }
-#line 375 "json.g"
-
- } // switch
- m_stateStack[m_tos] = nt_action(act, lhs[r] - TERMINAL_COUNT);
- } else {
- int ers = state;
- int shifts = 0;
- int reduces = 0;
- int expected_tokens[3];
- for (int tk = 0; tk < TERMINAL_COUNT; ++tk) {
- int k = t_action(ers, tk);
-
- if (! k)
- continue;
- else if (k < 0)
- ++reduces;
- else if (spell[tk]) {
- if (shifts < 3)
- expected_tokens[shifts] = tk;
- ++shifts;
- }
- }
-
- m_errorLineNumber = lexer->lineNumber();
- m_errorPos = lexer->pos();
- m_errorMessage.clear();
- if (shifts && shifts < 3) {
- bool first = true;
-
- for (int s = 0; s < shifts; ++s) {
- if (first)
- m_errorMessage += QLatin1String("Expected ");
- else
- m_errorMessage += QLatin1String(", ");
-
- first = false;
- m_errorMessage += QLatin1String("'");
- m_errorMessage += QLatin1String(spell[expected_tokens[s]]);
- m_errorMessage += QLatin1String("'");
- }
- }
- return false;
- }
- }
-
- return false;
-}
-
-
-#endif // JSONPARSER_CPP
-
diff --git a/src/3rdparty/qjson/tests/data/non-latin1.json b/src/3rdparty/qjson/tests/data/non-latin1.json
deleted file mode 100644
index 4adddef3..00000000
--- a/src/3rdparty/qjson/tests/data/non-latin1.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "name": "தஹெரா"
-}
-
diff --git a/src/3rdparty/qjson/tests/data/non-latin1.json.ref b/src/3rdparty/qjson/tests/data/non-latin1.json.ref
deleted file mode 100644
index 42f0b7fe..00000000
--- a/src/3rdparty/qjson/tests/data/non-latin1.json.ref
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "name": "\u0ba4\u0bb9\u0bc6\u0bb0\u0bbe"
-}
-
diff --git a/src/3rdparty/qjson/tests/data/test.html b/src/3rdparty/qjson/tests/data/test.html
deleted file mode 100644
index bb3b40c5..00000000
--- a/src/3rdparty/qjson/tests/data/test.html
+++ /dev/null
@@ -1,72 +0,0 @@
-<html>
-<script>
- JSON_STRING = '[\
- "JSON Test Pattern pass1",\
- {"object with 1 member":["array with 1 element"]},\
- {},\
- [],\
- -42,\
- true,\
- false,\
- null,\
- {\
- "integer": 1234567890,\
- "real": -9876.543210,\
- "e": 0.123456789e-12,\
- "E": 1.234567890E+34,\
- "": 23456789012E66,\
- "zero": 0,\
- "one": 1,\
- "space": " ",\
- "quote": "\\"",\
- "backslash": "\\\\",\
- "controls": "\\b\\f\\n\\r\\t",\
- "slash": "/ & \\/",\
- "alpha": "abcdefghijklmnopqrstuvwxyz",\
- "ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWXYZ",\
- "digit": "0123456789",\
- "0123456789": "digit",\
- "special": "`1~!@#$%^&*()_+-={\':[,]}|;.</>?",\
- "hex": "\\u0123\\u4567\\u89AB\\uCDEF\\uabcd\\uef4A",\
- "true": true,\
- "false": false,\
- "null": null,\
- "array":[ ],\
- "object":{ },\
- "address": "50 St. James Street",\
- "url": "http://www.JSON.org/",\
- "comment": "// /* <!-- --",\
- "# -- --> */": " ",\
- " s p a c e d " :[1,2 , 3\
-\
-,\
-\
-4 , 5 , 6 ,7 ],"compact":[1,2,3,4,5,6,7],\
- "jsontext": "{\\\"object with 1 member\\\":[\\\"array with 1 element\\\"]}",\
- "quotes": "&#34; \\u0022 %22 0x22 034 &#x22;",\
- "\\/\\\\\\"\\uCAFE\\uBABE\\uAB98\\uFCDE\\ubcda\\uef4A\\b\\f\\n\\r\\t`1~!@#$%^&*()_+-=[]{}|;:\',./<>?" : "A key can be any string"\
- },\
- 0.5 ,98.6\
-,\
-99.44\
-,\
-\
-1066,\
-1e1,\
-0.1e1,\
-1e-1,\
-1e00,\
-2e+00,\
-2e-00,\
-"rosebud"]';
-
- function testJson() {
- var obj = JSON.parse(JSON_STRING);
- document.write(JSON.stringify(obj))
- }
-</script>
-
-<body onload="testJson()">
- Hello
-</body>
-</html> \ No newline at end of file
diff --git a/src/3rdparty/qjson/tests/data/test.json b/src/3rdparty/qjson/tests/data/test.json
deleted file mode 100644
index c5b8e211..00000000
--- a/src/3rdparty/qjson/tests/data/test.json
+++ /dev/null
@@ -1,60 +0,0 @@
-[
- "JSON Test Pattern pass1",
- {"object with 1 member":["array with 1 element"]},
- {},
- [],
- -42,
- true,
- false,
- null,
- {
- "integer": 1234567890,
- "real": -9876.543210,
- "e": 0.123456789e-12,
- "E": 1.234567890E+34,
- "": 23456789012E66,
- "zero": 0,
- "one": 1,
- "space": " ",
- "quote": "\"",
- "backslash": "\\",
- "controls": "\b\f\n\r\t",
- "slash": "/ & \/",
- "alpha": "abcdefghijklmnopqrstuvwxyz",
- "ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
- "digit": "0123456789",
- "0123456789": "digit",
- "special": "`1~!@#$%^&*()_+-={\':[,]}|;.</>?",
- "hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A",
- "true": true,
- "false": false,
- "null": null,
- "array":[ ],
- "object":{ },
- "address": "50 St. James Street",
- "url": "http://www.JSON.org/",
- "comment": "// /* <!-- --",
- "# -- --> */": " ",
- " s p a c e d " :[1,2 , 3
-
-,
-
-4 , 5 , 6 ,7 ],"compact":[1,2,3,4,5,6,7],
- "jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}",
- "quotes": "&#34; \u0022 %22 0x22 034 &#x22;",
- "\/\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:\',./<>?" : "A key can be any string"
- },
- 0.5 ,98.6
-,
-99.44
-,
-
-1066,
-1e1,
-0.1e1,
-1e-1,
-1e00,
-2e+00,
-2e-00,
-"rosebud"]
-
diff --git a/src/3rdparty/qjson/tests/data/test.json.ref b/src/3rdparty/qjson/tests/data/test.json.ref
deleted file mode 100644
index b4206236..00000000
--- a/src/3rdparty/qjson/tests/data/test.json.ref
+++ /dev/null
@@ -1,57 +0,0 @@
-[
- "JSON Test Pattern pass1",
- {"object with 1 member":["array with 1 element"]},
- {},
- [],
- -42,
- true,
- false,
- null,
- {
- "": 2.3456789012e+76,
- " s p a c e d " :[1,2 , 3,4 , 5, 6 ,7],
- "# -- --> *\/": " ",
- "\/\"\ucafe\ubabe\uab98\ufcde\ubcda\uef4a\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',.\/<>?" : "A key can be any string",
- "0123456789": "digit",
- "ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
- "E": 1.23456789e+34,
- "address": "50 St. James Street",
- "alpha": "abcdefghijklmnopqrstuvwxyz",
- "array":[ ],
- "backslash": "\\",
- "comment": "\/\/ \/* <!-- --",
- "compact":[1,2,3,4,5,6,7],
- "controls": "\b\f\n\r\t",
- "digit": "0123456789",
- "e": 1.23456789e-13,
- "false": false,
- "hex": "\u0123\u4567\u89ab\ucdef\uabcd\uef4a",
- "integer": 1234567890,
- "jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}",
- "null": null,
- "object":{ },
- "one": 1,
- "quote": "\"",
- "quotes": "&#34; \" %22 0x22 034 &#x22;",
- "real": -9876.54321,
- "slash": "\/ & \/",
- "space": " ",
- "special": "`1~!@#$%^&*()_+-={':[,]}|;.<\/>?",
- "true": true,
- "url": "http:\/\/www.JSON.org\/",
- "zero": 0
- },
- 0.5 ,98.6
-,
-99.44
-,
-
-1066,
-10,
-1,
-0.1,
-1,
-2,
-2,
-"rosebud"]
-
diff --git a/src/3rdparty/qjson/tests/data/test_utf-16le-nobom.json b/src/3rdparty/qjson/tests/data/test_utf-16le-nobom.json
deleted file mode 100644
index aed8eb32..00000000
--- a/src/3rdparty/qjson/tests/data/test_utf-16le-nobom.json
+++ /dev/null
Binary files differ
diff --git a/src/3rdparty/qjson/tests/data/test_utf-16le-nobom.json.ref b/src/3rdparty/qjson/tests/data/test_utf-16le-nobom.json.ref
deleted file mode 100644
index 8b9d9b91..00000000
--- a/src/3rdparty/qjson/tests/data/test_utf-16le-nobom.json.ref
+++ /dev/null
Binary files differ
diff --git a/src/3rdparty/qjson/tests/data/test_utf-16le.json b/src/3rdparty/qjson/tests/data/test_utf-16le.json
deleted file mode 100644
index 277dc529..00000000
--- a/src/3rdparty/qjson/tests/data/test_utf-16le.json
+++ /dev/null
Binary files differ
diff --git a/src/3rdparty/qjson/tests/data/test_utf-16le.json.ref b/src/3rdparty/qjson/tests/data/test_utf-16le.json.ref
deleted file mode 100644
index 8b9d9b91..00000000
--- a/src/3rdparty/qjson/tests/data/test_utf-16le.json.ref
+++ /dev/null
Binary files differ
diff --git a/src/3rdparty/qjson/tests/data/test_utf-32le.json b/src/3rdparty/qjson/tests/data/test_utf-32le.json
deleted file mode 100644
index 7345dafb..00000000
--- a/src/3rdparty/qjson/tests/data/test_utf-32le.json
+++ /dev/null
Binary files differ
diff --git a/src/3rdparty/qjson/tests/data/test_utf-32le.json.ref b/src/3rdparty/qjson/tests/data/test_utf-32le.json.ref
deleted file mode 100644
index 2624ef36..00000000
--- a/src/3rdparty/qjson/tests/data/test_utf-32le.json.ref
+++ /dev/null
Binary files differ
diff --git a/src/3rdparty/qjson/tests/tests.pro b/src/3rdparty/qjson/tests/tests.pro
deleted file mode 100644
index 1f0de7ae..00000000
--- a/src/3rdparty/qjson/tests/tests.pro
+++ /dev/null
@@ -1,13 +0,0 @@
-QT += testlib
-
-include(../src/json.pri)
-SOURCES += tst_json.cpp
-
-TARGET = tst_json
-
-wince {
- DEFINES += SRCDIR=\\\"\\\"
-} else {
- DEFINES += SRCDIR=\\\"$$PWD/\\\"
-}
-
diff --git a/src/3rdparty/qjson/tests/tst_json.cpp b/src/3rdparty/qjson/tests/tst_json.cpp
deleted file mode 100644
index 1dceea73..00000000
--- a/src/3rdparty/qjson/tests/tst_json.cpp
+++ /dev/null
@@ -1,202 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2011 Girish Ramakrishnan <girish@forwardbias.in>
-**
-** Use, modification and distribution is allowed without limitation,
-** warranty, liability or support of any kind.
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-#include "json.h"
-
-class tst_Json : public QObject
-{
- Q_OBJECT
-
-private slots:
- void parseAndStringify_data();
- void parseAndStringify();
-
- void stringify_data();
- void stringify();
-
- void parseError_data();
- void parseError();
-};
-
-static QByteArray unformat(const QByteArray &input)
-{
- QByteArray output;
- bool inQuote = false, escape = false;
- for (int i = 0; i < input.count(); i++) {
- char c = input[i];
- if (escape) {
- escape = false;
- } else if (c == '\\') {
- escape = true;
- } else {
- if (c == '\"')
- inQuote = !inQuote;
- if (!inQuote && (c == ' ' || c == '\r' || c == '\n' || c == '\t'))
- continue;
- }
- output += c;
- }
- return output;
-}
-
-void tst_Json::parseAndStringify_data()
-{
- QTest::addColumn<QByteArray>("json");
- QTest::addColumn<QByteArray>("reference"); // always UTF-8
- QDir dir;
- dir.cd(QLatin1String(SRCDIR "data/"));
- foreach(QString filename , dir.entryList(QStringList() << QLatin1String("*.json"))) {
- QFile jsonFile(dir.filePath(filename));
- jsonFile.open(QFile::ReadOnly);
- QByteArray json = jsonFile.readAll();
- QFile refFile(dir.filePath(filename + QLatin1String(".ref")));
- QByteArray reference;
- if (refFile.open(QFile::ReadOnly)) {
- reference = refFile.readAll();
- } else {
- reference = json;
- }
- if (filename.contains(QLatin1String("utf-16"))) {
- reference = QTextCodec::codecForName("UTF-16LE")->toUnicode(reference).toUtf8();
- } else if (filename.contains(QLatin1String("utf-32"))) {
- reference = QTextCodec::codecForName("UTF-32LE")->toUnicode(reference).toUtf8();
- }
- reference = unformat(reference);
- QTest::newRow(dir.filePath(filename).toLatin1().data()) << json << reference;
- }
-}
-
-void tst_Json::parseAndStringify()
-{
- QFETCH(QByteArray, json);
- QFETCH(QByteArray, reference);
-
- JsonReader reader;
- QVERIFY2(reader.parse(json), reader.errorString().toLocal8Bit().constData());
- QVariant result = reader.result();
-
- JsonWriter writer;
- QByteArray jsonAgain = writer.toByteArray(result);
- QVERIFY(jsonAgain == reference);
-
- // test pretty writing
- writer.setAutoFormatting(true);
- jsonAgain = writer.toByteArray(result);
- QVERIFY(unformat(jsonAgain) == reference);
-}
-
-struct CustomType {
- int x;
-};
-Q_DECLARE_METATYPE(CustomType)
-
-void tst_Json::stringify_data()
-{
- QTest::addColumn<QVariant>("input");
- QTest::addColumn<QString>("output");
-
- QTest::newRow("null_variant") << QVariant() << "null";
-
- // bool
- QTest::newRow("true") << QVariant(true) << "true";
- QTest::newRow("false") << QVariant(false) << "false";
-
- // lists
- QTest::newRow("empty list") << QVariant(QVariantList()) << "[]";
-
- // objects
- QTest::newRow("empty object") << QVariant(QVariantMap()) << "{}";
-
- // numbers
- QTest::newRow("number") << QVariant(42) << "42";
- QTest::newRow("nan") << QVariant(double(NAN)) << "null";
- QTest::newRow("inf") << QVariant(double(INFINITY)) << "null";
- QTest::newRow("-inf") << QVariant(double(-INFINITY)) << "null";
-
- // unicode
- QTest::newRow("non-ascii/latin1") << QVariant(QChar(0xFB)) << "\"\\u00fb\"";
-
- const char utf8[] = {0xE0, 0xAE, 0x9F, 0xE0, 0xAE, 0xBF, 0x00 };
- QTest::newRow("tamil tee") << QVariant(QString::fromUtf8(utf8)) << "\"\\u0b9f\\u0bbf\"";
-
- // various QVariant types
- QVariantList vlist;
- vlist = QVariantList() << QVariant(float(1)) << QVariant(qlonglong(13))
- << QVariant(qulonglong(14)) << QVariant(quint32(15))
- << QVariant(char('x')) << QVariant(QChar(QLatin1Char('X')));
- QTest::newRow("various types") << QVariant(vlist) << "[1,13,14,15,120,\"X\"]";
-
- // custom types
- // It is out of the scope of the standard to specify what happens when
- // a custom type that cannot be stringized is present. We generate a null
- // for unsupported types
- CustomType c;
- QTest::newRow("unpresentable object") << qVariantFromValue(c) << "null";
-
- vlist = QVariantList() << 1 << qVariantFromValue(c) << 2;
- QTest::newRow("unpresentable object[]") << QVariant(vlist) << "[1,null,2]";
-
- QVariantMap map;
- map[QLatin1String("one")] = 1;
- map[QLatin1String("two")] = 2;
- map[QLatin1String("custom")] = qVariantFromValue(c);
- QTest::newRow("unpresentable object{}") << QVariant(map) << "{\"custom\":null,\"one\":1,\"two\":2}";
-}
-
-void tst_Json::stringify()
-{
- QFETCH(QVariant, input);
- QFETCH(QString, output);
-
- JsonWriter writer;
- QCOMPARE(writer.toString(input), output);
-
- // just check if it parses, just in case
- JsonReader reader;
- QVERIFY(reader.parse(writer.toString(input)));
-}
-
-void tst_Json::parseError_data()
-{
- QTest::addColumn<QString>("input");
- QTest::addColumn<int>("line");
- QTest::addColumn<int>("pos");
- QTest::addColumn<QString>("expect");
-
- // Most of the time the error message itself is not useful. These tests exist
- // primarily to make sure that parsing fails
- QTest::newRow("error 1") << "!" << 1 << 0 << "";
- QTest::newRow("error 2") << "[1,2," << 1 << 5 << "";
- QTest::newRow("error 3") << "[1,2" << 1 << 4 << "Expected ']', ','";
- QTest::newRow("error 4") << "[1,2p" << 1 << 5 << "Expected ']', ','";
- QTest::newRow("error 5") << "[1,2] {" << 1 << 7 << "Expected 'end of file'";
- QTest::newRow("error 6") << "{ foo: bar }" << 1 << 5 << "Expected '}', ','";
- QTest::newRow("error 7") << "\n\n{ \"cat\" : \"pillar\"" << 3 << 20 << "Expected '}', ','";
- QTest::newRow("success") << "true" << -1 << -1 << "";
-}
-
-void tst_Json::parseError()
-{
- QFETCH(QString, input);
- QFETCH(int, line);
- QFETCH(int, pos);
- QFETCH(QString, expect);
-
- JsonReader reader;
- QVERIFY(!reader.parse(input) || line == -1);
-
- if (line != -1)
- QCOMPARE(reader.errorString(), QString::fromUtf8("%1 at line %2 pos %3").arg(expect).arg(line).arg(pos));
-}
-
-QTEST_MAIN(tst_Json)
-
-#include "tst_json.moc"
-
diff --git a/src/client/qjsondbconnection.cpp b/src/client/qjsondbconnection.cpp
index f7f10b12..6c76bbcf 100644
--- a/src/client/qjsondbconnection.cpp
+++ b/src/client/qjsondbconnection.cpp
@@ -162,7 +162,7 @@ QJsonDbConnectionPrivate::QJsonDbConnectionPrivate(QJsonDbConnection *q)
QObject::connect(socket, SIGNAL(connected()), q_ptr, SLOT(_q_onConnected()));
QObject::connect(socket, SIGNAL(error(QLocalSocket::LocalSocketError)),
q_ptr, SLOT(_q_onError(QLocalSocket::LocalSocketError)));
- stream = new JsonStream::JsonStream(q);
+ stream = new QtJsonDbJsonStream::JsonStream(q);
stream->setDevice(socket);
QObject::connect(stream, SIGNAL(receive(QJsonObject)),
q_ptr, SLOT(_q_onReceivedObject(QJsonObject)));
@@ -300,6 +300,7 @@ void QJsonDbConnectionPrivate::_q_onReceivedObject(const QJsonObject &object)
}
// initialize actionType to silence compiler warnings.
QJsonDbWatcher::Action actionType = QJsonDbWatcher::All;
+ bool stateChanged = false;
if (action == JsonDbStrings::Notification::actionCreate())
actionType = QJsonDbWatcher::Created;
else if (action == JsonDbStrings::Notification::actionUpdate())
@@ -307,10 +308,13 @@ void QJsonDbConnectionPrivate::_q_onReceivedObject(const QJsonObject &object)
else if (action == JsonDbStrings::Notification::actionRemove())
actionType = QJsonDbWatcher::Removed;
else if (action == JsonDbStrings::Notification::actionStateChange())
- actionType = QJsonDbWatcher::StateChanged;
+ stateChanged = true;
else
qWarning() << "Unknown action" << action << "received for notification" << notifyUuid;
- if (actionType != QJsonDbWatcher::All)
+
+ if (stateChanged)
+ watcher->d_func()->handleStateChange(stateNumber);
+ else if (actionType != QJsonDbWatcher::All)
watcher->d_func()->handleNotification(stateNumber, actionType, object);
} else {
// received notification for unknown watcher, just ignore it.
@@ -581,9 +585,15 @@ void QJsonDbConnectionPrivate::initWatcher(QJsonDbWatcher *watcher)
QJsonDbObject object;
object.insert(JsonDbStrings::Property::type(), QJsonValue(JsonDbStrings::Types::notification()));
object.insert(JsonDbStrings::Property::query(), QJsonValue(dwatcher->query));
- // ### TODO: in the future pass initialStateNumber to the server
- object.insert(JsonDbStrings::Property::initialStateNumber(),
- static_cast<int>(qMax(dwatcher->lastStateNumber, dwatcher->initialStateNumber)));
+ bool initialStateNumberSpecified = (dwatcher->initialStateNumber != static_cast<quint32>(QJsonDbWatcherPrivate::UnspecifiedInitialStateNumber));
+ if (dwatcher->lastStateNumber != 0 || initialStateNumberSpecified) {
+ quint32 initialStateNumber;
+ if (initialStateNumberSpecified)
+ initialStateNumber = qMax(dwatcher->lastStateNumber, dwatcher->initialStateNumber);
+ else
+ initialStateNumber = dwatcher->lastStateNumber;
+ object.insert(JsonDbStrings::Property::initialStateNumber(), static_cast<int>(initialStateNumber));
+ }
QJsonArray actions;
if (dwatcher->actions & QJsonDbWatcher::Created)
actions.append(JsonDbStrings::Notification::actionCreate());
@@ -591,8 +601,6 @@ void QJsonDbConnectionPrivate::initWatcher(QJsonDbWatcher *watcher)
actions.append(JsonDbStrings::Notification::actionUpdate());
if (dwatcher->actions & QJsonDbWatcher::Removed)
actions.append(JsonDbStrings::Notification::actionRemove());
- if (dwatcher->actions & QJsonDbWatcher::StateChanged)
- actions.append(JsonDbStrings::Notification::actionStateChange());
object.insert(JsonDbStrings::Property::actions(), actions);
object.insert(JsonDbStrings::Protocol::partition(), QJsonValue(dwatcher->partition));
object.insert(JsonDbStrings::Property::uuid(), QJsonValue(dwatcher->uuid));
diff --git a/src/client/qjsondbconnection_p.h b/src/client/qjsondbconnection_p.h
index bf65e6b3..11199fd1 100644
--- a/src/client/qjsondbconnection_p.h
+++ b/src/client/qjsondbconnection_p.h
@@ -103,7 +103,7 @@ public:
QTimer timeoutTimer;
QLocalSocket *socket;
- JsonStream::JsonStream *stream;
+ QtJsonDbJsonStream::JsonStream *stream;
int lastRequestId;
QWeakPointer<QJsonDbRequest> currentRequest;
diff --git a/src/client/qjsondbreadrequest.h b/src/client/qjsondbreadrequest.h
index 8fb14ab1..9da0bc77 100644
--- a/src/client/qjsondbreadrequest.h
+++ b/src/client/qjsondbreadrequest.h
@@ -69,9 +69,12 @@ public:
enum ErrorCode {
NoError = QJsonDbRequest::NoError,
+ InvalidRequest = QJsonDbRequest::InvalidRequest,
+ OperationNotPermitted = QJsonDbRequest::OperationNotPermitted,
InvalidPartition = QJsonDbRequest::InvalidPartition,
+ DatabaseConnectionError = QJsonDbRequest::DatabaseConnectionError,
MissingQuery = QJsonDbRequest::MissingQuery,
- MissingType = QJsonDbRequest::MissingType,
+ InvalidMessage= QJsonDbRequest::InvalidMessage,
InvalidLimit = QJsonDbRequest::InvalidLimit
};
diff --git a/src/client/qjsondbrequest.cpp b/src/client/qjsondbrequest.cpp
index f94853d0..2dabc640 100644
--- a/src/client/qjsondbrequest.cpp
+++ b/src/client/qjsondbrequest.cpp
@@ -167,13 +167,27 @@ QList<QJsonObject> QJsonDbRequest::takeResults(int amount)
}
/*!
- \fn bool QJsonDbRequest::isActive() const
-
Returns true if the request is active, i.e. in either QJsonDbRequest::Queued
or QJsonDbRequest::Sent or QJsonDbRequest::Receiving state.
\sa status
*/
+bool QJsonDbRequest::isActive() const
+{
+ switch (status()) {
+ case QJsonDbRequest::Queued:
+ case QJsonDbRequest::Sent:
+ case QJsonDbRequest::Receiving:
+ return true;
+ case QJsonDbRequest::Inactive:
+ case QJsonDbRequest::Canceled:
+ case QJsonDbRequest::Finished:
+ case QJsonDbRequest::Error:
+ return false;
+ }
+ return false;
+}
+
/*!
\fn void QJsonDbRequest::started()
diff --git a/src/client/qjsondbrequest.h b/src/client/qjsondbrequest.h
index 1b7fe17b..d0ff2ba9 100644
--- a/src/client/qjsondbrequest.h
+++ b/src/client/qjsondbrequest.h
@@ -63,28 +63,27 @@ public:
enum ErrorCode {
NoError = 0,
-// ### TODO: clean me up and move me to ReadRequest and WriteRequest
-// InvalidMessage = 1,
-// InvalidRequest = 2,
- MissingObject = 3,
-// DatabaseError = 4,
-// MissingUUID = 5,
- MissingType = 6,
- MissingQuery = 7,
- InvalidLimit = 8,
-// InvalidOffset = 9,
-// MismatchedNotifyId = 10,
-// InvalidActions = 11,
-// UpdatingStaleVersion = 12,
-// OperationNotPermitted = 13,
-// QuotaExceeded = 14,
-// FailedSchemaValidation = 15,
-// InvalidMap = 16,
-// InvalidReduce = 17,
-// InvalidSchemaOperation = 18,
- InvalidPartition = 19,
-// InvalidIndexOperation = 20
- DatabaseConnectionError = 21
+ InvalidRequest = 1,
+ OperationNotPermitted = 2,
+ InvalidPartition = 3,
+ DatabaseConnectionError = 4,
+ MissingQuery = 5,
+ InvalidMessage= 6,
+ InvalidLimit = 7,
+ InvalidOffset = 8,
+ InvalidStateNumber = 9,
+ MissingObject = 10,
+ DatabaseError = 11,
+ MissingUUID = 12,
+ MissingType = 13,
+ UpdatingStaleVersion = 14,
+ QuotaExceeded = 15,
+ FailedSchemaValidation = 16,
+ InvalidMap = 17,
+ InvalidReduce = 18,
+ InvalidSchemaOperation = 19,
+ InvalidIndexOperation = 20,
+ InvalidType = 21
};
enum Status {
diff --git a/src/client/qjsondbwatcher.cpp b/src/client/qjsondbwatcher.cpp
index e99f7bd6..2d39abd5 100644
--- a/src/client/qjsondbwatcher.cpp
+++ b/src/client/qjsondbwatcher.cpp
@@ -44,7 +44,6 @@
#include "qjsondbconnection_p.h"
#include <QUuid>
-#include <QDebug>
QT_BEGIN_NAMESPACE_JSONDB
@@ -84,8 +83,6 @@ QJsonDbNotification::QJsonDbNotification(const QJsonObject &object, QJsonDbWatch
longer matches the watcher query string, and the object contains
the property \c{_deleted} with value \c{true}.
- \li If the action() is QJsonDbWatcher::StateChanged, the object is empty.
-
\endlist
\sa QJsonDbObject
@@ -115,7 +112,7 @@ quint32 QJsonDbNotification::stateNumber() const
QJsonDbWatcherPrivate::QJsonDbWatcherPrivate(QJsonDbWatcher *q)
: q_ptr(q), status(QJsonDbWatcher::Inactive),
- actions(QJsonDbWatcher::All), initialStateNumber(0), lastStateNumber(0)
+ actions(QJsonDbWatcher::All), initialStateNumber(QJsonDbWatcherPrivate::UnspecifiedInitialStateNumber), lastStateNumber(0)
{
uuid = QUuid::createUuid().toString();
}
@@ -176,7 +173,6 @@ QJsonDbWatcherPrivate::QJsonDbWatcherPrivate(QJsonDbWatcher *q)
\value Created Watches for objects to start matching the given query string.
\value Updated Watches for modifications of objects matching the given query.
\value Removed Watches for objects that stop matching the given query string.
- \value StateChanged Watches for database state changes.
\value All A convenience value that specifies to watch for all possible actions.
*/
/*!
@@ -339,6 +335,8 @@ quint32 QJsonDbWatcher::initialStateNumber() const
This property contains valid data only after watcher was successfully
activated (i.e. the watcher state was changed to QJsonDbWatcher::Active).
+ The lastStateNumber will be changed after receiving all notifications for that state number.
+
\sa lastStateNumberChanged(), status
*/
quint32 QJsonDbWatcher::lastStateNumber() const
@@ -400,7 +398,7 @@ void QJsonDbWatcherPrivate::_q_onError(QtJsonDb::QJsonDbRequest::ErrorCode code,
{
Q_Q(QJsonDbWatcher);
Q_UNUSED(code);
- QJsonDbWatcher::ErrorCode error = QJsonDbWatcher::InvalidQuery; // ### TODO:
+ QJsonDbWatcher::ErrorCode error = static_cast<QJsonDbWatcher::ErrorCode>(code);
emit q->error(error, message);
}
@@ -410,13 +408,20 @@ void QJsonDbWatcherPrivate::handleNotification(quint32 stateNumber, QJsonDbWatch
if (!actions.testFlag(action))
return;
Q_ASSERT(!object.isEmpty());
+ if (initialStateNumber == static_cast<quint32>(QJsonDbWatcherPrivate::UnspecifiedInitialStateNumber))
+ initialStateNumber = stateNumber;
+ QJsonDbNotification n(object, action, stateNumber);
+ notifications.append(n);
+ emit q->notificationsAvailable(notifications.size());
+}
+
+void QJsonDbWatcherPrivate::handleStateChange(quint32 stateNumber)
+{
+ Q_Q(QJsonDbWatcher);
if (stateNumber != lastStateNumber) {
lastStateNumber = stateNumber;
emit q->lastStateNumberChanged(stateNumber);
}
- QJsonDbNotification n(object, action, stateNumber);
- notifications.append(n);
- emit q->notificationsAvailable(notifications.size());
}
/*!
diff --git a/src/client/qjsondbwatcher.h b/src/client/qjsondbwatcher.h
index d647fdfc..0e283418 100644
--- a/src/client/qjsondbwatcher.h
+++ b/src/client/qjsondbwatcher.h
@@ -47,6 +47,7 @@
#include <QtCore/QUuid>
#include <QtJsonDb/qjsondbglobal.h>
+#include <QtJsonDb/qjsondbrequest.h>
QT_BEGIN_HEADER
@@ -69,7 +70,6 @@ public:
Created = 0x01, // ### TODO: rename me to StartsMatching ?
Updated = 0x02,
Removed = 0x04,
- StateChanged = 0x08,
All = 0xFF
};
@@ -86,11 +86,13 @@ public:
inline bool isActive() const { return status() == QJsonDbWatcher::Active; }
enum ErrorCode {
- NoError = 0,
- InvalidActions = 1,
- InvalidQuery = 2,
- InvalidPartition = 3,
- InvalidStateNumber = 4
+ NoError = QJsonDbRequest::NoError,
+ InvalidRequest = QJsonDbRequest::InvalidRequest,
+ OperationNotPermitted = QJsonDbRequest::OperationNotPermitted,
+ InvalidPartition = QJsonDbRequest::InvalidPartition,
+ DatabaseConnectionError = QJsonDbRequest::DatabaseConnectionError,
+ MissingQuery = QJsonDbRequest::MissingQuery,
+ InvalidStateNumber = QJsonDbRequest::InvalidStateNumber
};
QJsonDbWatcher(QObject *parent = 0);
diff --git a/src/client/qjsondbwatcher_p.h b/src/client/qjsondbwatcher_p.h
index c439591e..e156117f 100644
--- a/src/client/qjsondbwatcher_p.h
+++ b/src/client/qjsondbwatcher_p.h
@@ -73,6 +73,7 @@ public:
void _q_onError(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString &message);
void handleNotification(quint32 stateNumber, QJsonDbWatcher::Action action, const QJsonObject &object);
+ void handleStateChange(quint32 stateNumber);
void setStatus(QJsonDbWatcher::Status newStatus);
QJsonDbWatcher *q_ptr;
@@ -81,6 +82,9 @@ public:
QJsonDbWatcher::Actions actions;
QString query;
QString partition;
+ enum {
+ UnspecifiedInitialStateNumber = -1
+ };
quint32 initialStateNumber;
quint32 lastStateNumber;
diff --git a/src/client/qjsondbwriterequest.h b/src/client/qjsondbwriterequest.h
index 41e27fe6..8249c282 100644
--- a/src/client/qjsondbwriterequest.h
+++ b/src/client/qjsondbwriterequest.h
@@ -66,7 +66,22 @@ public:
enum ErrorCode {
NoError = QJsonDbRequest::NoError,
- MissingObject = QJsonDbRequest::MissingObject
+ InvalidRequest = QJsonDbRequest::InvalidRequest,
+ OperationNotPermitted = QJsonDbRequest::OperationNotPermitted,
+ InvalidPartition = QJsonDbRequest::InvalidPartition,
+ DatabaseConnectionError = QJsonDbRequest::DatabaseConnectionError,
+ MissingObject = QJsonDbRequest::MissingObject,
+ DatabaseError = QJsonDbRequest::DatabaseError,
+ MissingUUID = QJsonDbRequest::MissingUUID,
+ MissingType = QJsonDbRequest::MissingType,
+ UpdatingStaleVersion = QJsonDbRequest::UpdatingStaleVersion,
+ QuotaExceeded = QJsonDbRequest::QuotaExceeded,
+ FailedSchemaValidation = QJsonDbRequest::FailedSchemaValidation,
+ InvalidMap = QJsonDbRequest::InvalidMap,
+ InvalidReduce = QJsonDbRequest::InvalidReduce,
+ InvalidSchemaOperation = QJsonDbRequest::InvalidSchemaOperation,
+ InvalidIndexOperation = QJsonDbRequest::InvalidIndexOperation,
+ InvalidType = QJsonDbRequest::InvalidType
};
enum ConflictResolutionMode {
diff --git a/src/clientcompat/clientcompat.pro b/src/clientcompat/clientcompat.pro
index 38b03f88..911c2b0a 100644
--- a/src/clientcompat/clientcompat.pro
+++ b/src/clientcompat/clientcompat.pro
@@ -14,7 +14,7 @@ QT = core network
CONFIG += module create_prl
MODULE_PRI = ../../modules/qt_jsondbcompat.pri
-include(../common/common.pri)
+include(../jsonstream/jsonstream.pri)
HEADERS += qtjsondbcompatversion.h
@@ -37,6 +37,7 @@ SOURCES += \
jsondb-connection.cpp \
jsondb-query.cpp \
jsondb-oneshot.cpp \
- jsondb-notification.cpp
+ jsondb-notification.cpp \
+ jsondb-strings.cpp
mac:QMAKE_FRAMEWORK_BUNDLE_NAME = $$QT.jsondbcompat.name
diff --git a/src/clientcompat/jsondb-client.cpp b/src/clientcompat/jsondb-client.cpp
index 82a117ba..4a9e69ac 100644
--- a/src/clientcompat/jsondb-client.cpp
+++ b/src/clientcompat/jsondb-client.cpp
@@ -41,7 +41,7 @@
#include "jsondb-client.h"
#include "jsondb-client_p.h"
-#include "jsondb-strings.h"
+#include "jsondb-strings_p.h"
#include "jsondb-connection_p.h"
@@ -359,6 +359,8 @@ void JsonDbClientPrivate::_q_handleNotified(const QString &notifyUuid, const QVa
type = JsonDbClient::NotifyUpdate;
} else if (action == JsonDbString::kRemoveStr) {
type = JsonDbClient::NotifyRemove;
+ } else if (action == QLatin1String("stateChange")) {
+ return;
} else {
Q_ASSERT(false);
return;
diff --git a/src/clientcompat/jsondb-connection.cpp b/src/clientcompat/jsondb-connection.cpp
index 9e1d0f1b..8d72f22a 100644
--- a/src/clientcompat/jsondb-connection.cpp
+++ b/src/clientcompat/jsondb-connection.cpp
@@ -39,13 +39,14 @@
**
****************************************************************************/
-#include "jsondb-strings.h"
+#include "jsondb-strings_p.h"
#include "jsondb-error.h"
#include "jsondb-oneshot_p.h"
#include "jsondb-connection_p.h"
#include "jsondb-connection_p_p.h"
#include "qjsonobject.h"
+#include "qjsonarray.h"
QT_BEGIN_NAMESPACE_JSONDB
diff --git a/src/clientcompat/jsondb-connection_p_p.h b/src/clientcompat/jsondb-connection_p_p.h
index 3eb06cdb..ab426a6f 100644
--- a/src/clientcompat/jsondb-connection_p_p.h
+++ b/src/clientcompat/jsondb-connection_p_p.h
@@ -64,7 +64,7 @@ class JsonDbConnectionPrivate
Q_DECLARE_PUBLIC(JsonDbConnection)
public:
JsonDbConnectionPrivate(JsonDbConnection *q)
- : q_ptr(q), socket(0), tcpSocket(0), mStream(0, q), mId(1), status(JsonDbConnection::Null)
+ : q_ptr(q), socket(0), tcpSocket(0), mStream(q), mId(1), status(JsonDbConnection::Null)
{ }
~JsonDbConnectionPrivate()
{ }
@@ -77,7 +77,7 @@ public:
JsonDbConnection *q_ptr;
QLocalSocket *socket;
QTcpSocket *tcpSocket;
- JsonStream mStream;
+ QtJsonDbJsonStream::JsonStream mStream;
int mId;
JsonDbConnection::Status status;
QString errorString;
diff --git a/src/clientcompat/jsondb-error.h b/src/clientcompat/jsondb-error.h
index 9a577b00..6eb78694 100644
--- a/src/clientcompat/jsondb-error.h
+++ b/src/clientcompat/jsondb-error.h
@@ -51,28 +51,33 @@ QT_BEGIN_NAMESPACE_JSONDB
class JsonDbError {
public:
enum ErrorCode {
+ // common errors
NoError = 0,
- InvalidMessage = 1, // Unable to parse the query message
- InvalidRequest = 2, // Request object doesn't contain correct elements
- MissingObject = 3, // Invalid or missing "object" field
- DatabaseError = 4, // Error directly from the database
- MissingUUID = 5, // Missing id field
- MissingType = 6, // Missing _type field
- MissingQuery = 7, // Missing query field
- InvalidLimit = 8, // Invalid limit field
- InvalidOffset = 9, // Invalid offset field
- MismatchedNotifyId = 10, // Request to delete notify doesn't match existing notification
- InvalidActions = 11, // List of actions supplied to setNotification is invalid
- UpdatingStaleVersion = 12, // Updating stale version of object
- OperationNotPermitted = 13,
- QuotaExceeded = 14,
- FailedSchemaValidation = 15, // Invalid according to the schema
- InvalidMap = 16, // The Map definition is invalid
- InvalidReduce = 17, // The Reduce definition is invalid
- InvalidSchemaOperation = 18,
- InvalidPartition = 19,
- InvalidIndexOperation = 20,
- InvalidType = 21
+ InvalidRequest = 1,
+ OperationNotPermitted = 2,
+ InvalidPartition = 3,
+ DatabaseConnectionError = 4,
+
+ // read / notify errors
+ MissingQuery = 5,
+ InvalidMessage= 6,
+ InvalidLimit = 7,
+ InvalidOffset = 8,
+ InvalidStateNumber = 9,
+
+ // write errors
+ MissingObject = 10,
+ DatabaseError = 11,
+ MissingUUID = 12,
+ MissingType = 13,
+ UpdatingStaleVersion = 14,
+ QuotaExceeded = 15,
+ FailedSchemaValidation = 16,
+ InvalidMap = 17,
+ InvalidReduce = 18,
+ InvalidSchemaOperation = 19,
+ InvalidIndexOperation = 20,
+ InvalidType = 21
};
};
diff --git a/src/common/jsondb-strings.cpp b/src/clientcompat/jsondb-strings.cpp
index fa4e424b..322b31db 100644
--- a/src/common/jsondb-strings.cpp
+++ b/src/clientcompat/jsondb-strings.cpp
@@ -39,7 +39,7 @@
**
****************************************************************************/
-#include "jsondb-strings.h"
+#include "jsondb-strings_p.h"
QT_BEGIN_NAMESPACE_JSONDB
@@ -111,5 +111,7 @@ const QString JsonDbString::kCollationStr = QString::fromLatin1("collation");
const QString JsonDbString::kCaseSensitiveStr = QString::fromLatin1("caseSensitive");
const QString JsonDbString::kCasePreferenceStr = QString::fromLatin1("casePreference");
const QString JsonDbString::kDatabaseSchemaVersionStr = QString::fromLatin1("databaseSchemaVersion");
+const QString JsonDbString::kPathStr = QString::fromLatin1("path");
+const QString JsonDbString::kDefaultStr = QString::fromLatin1("default");
QT_END_NAMESPACE_JSONDB
diff --git a/src/clientcompat/jsondb-strings_p.h b/src/clientcompat/jsondb-strings_p.h
index 77d0792e..88152d63 100644
--- a/src/clientcompat/jsondb-strings_p.h
+++ b/src/clientcompat/jsondb-strings_p.h
@@ -70,6 +70,7 @@ public:
static const QString kFindStr;
static const QString kNameStr;
static const QString kIdStr;
+ static const QString kIndexValueStr;
static const QString kLengthStr;
static const QString kLimitStr;
static const QString kMapTypeStr;
@@ -116,6 +117,8 @@ public:
static const QString kCaseSensitiveStr;
static const QString kCasePreferenceStr;
static const QString kDatabaseSchemaVersionStr;
+ static const QString kPathStr;
+ static const QString kDefaultStr;
};
QT_END_NAMESPACE_JSONDB
diff --git a/src/common/common.pri b/src/common/common.pri
deleted file mode 100644
index 01e012ca..00000000
--- a/src/common/common.pri
+++ /dev/null
@@ -1,24 +0,0 @@
-INCLUDEPATH += $$PWD
-
-include(../3rdparty/qjson/qjson.pri)
-
-unix {
- contains(QT_CONFIG,icu) {
- LIBS += -licuuc -licui18n
- } else {
- DEFINES += NO_COLLATION_SUPPORT
- }
-}
-
-HEADERS += \
- $$PWD/jsondb-global.h \
- $$PWD/jsondb-error.h \
- $$PWD/jsondb-strings.h \
- $$PWD/jsondbcollator.h \
- $$PWD/jsondbcollator_p.h \
- $$PWD/jsonstream.h
-
-SOURCES += \
- $$PWD/jsondb-strings.cpp \
- $$PWD/jsondbcollator.cpp \
- $$PWD/jsonstream.cpp
diff --git a/src/common/jsondb-global.h b/src/common/jsondb-global.h
deleted file mode 100644
index 1ad585a8..00000000
--- a/src/common/jsondb-global.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "../clientcompat/jsondb-global.h"
diff --git a/src/common/jsondb-strings.h b/src/common/jsondb-strings.h
deleted file mode 100644
index dc0295b8..00000000
--- a/src/common/jsondb-strings.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "../clientcompat/jsondb-strings_p.h"
diff --git a/src/common/jsonstream.cpp b/src/common/jsonstream.cpp
deleted file mode 100644
index c2500eff..00000000
--- a/src/common/jsonstream.cpp
+++ /dev/null
@@ -1,141 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "jsonstream.h"
-#include <QDebug>
-#include <QDataStream>
-#include <QLocalSocket>
-#include <QAbstractSocket>
-#include <QtEndian>
-
-#ifdef QT_DEBUG
-#include <QUdpSocket>
-#include <QDateTime>
-#include <QCoreApplication>
-#endif
-
-QT_BEGIN_NAMESPACE_JSONDB
-
-JsonStream::JsonStream(QIODevice *device, QObject *parent) :
- QObject(parent),
- mDevice(0)
-{
- setDevice(device);
-}
-
-QIODevice *JsonStream::device() const
-{
- return mDevice;
-}
-
-/** Set the device used by the JsonStream.
- The stream does not take ownership of the device.
-*/
-void JsonStream::setDevice(QIODevice *device)
-{
- if (mDevice) {
- disconnect(mDevice, SIGNAL(readyRead()), this, SLOT(deviceReadyRead()));
- disconnect(mDevice, SIGNAL(bytesWritten(qint64)), this, SLOT(deviceBytesWritten(qint64)));
- disconnect(mDevice, SIGNAL(aboutToClose()), this, SIGNAL(aboutToClose()));
- }
- mDevice = device;
- if (mDevice) {
- connect(mDevice, SIGNAL(readyRead()), this, SLOT(deviceReadyRead()));
- connect(mDevice, SIGNAL(bytesWritten(qint64)), this, SLOT(deviceBytesWritten(qint64)));
- connect(mDevice, SIGNAL(aboutToClose()), this, SIGNAL(aboutToClose()));
- }
-}
-
-bool JsonStream::send(const QJsonObject &object)
-{
- QByteArray data = QJsonDocument(object).toBinaryData();
- int shouldWrite = data.size();
- if (mWriteBuffer.isEmpty()) {
- int didWrite = mDevice->write(data);
- if (didWrite < 0) {
- qWarning() << "Error writing to socket" << mDevice->errorString();
- } else if (didWrite < shouldWrite) {
- mWriteBuffer = data.mid(didWrite);
- }
- QLocalSocket *s = qobject_cast<QLocalSocket *>(mDevice);
- if (s)
- s->flush();
- } else {
- qWarning() << "Buffering, slow down your writes";
- mWriteBuffer.append(data);
- }
- return true;
-}
-
-void JsonStream::deviceReadyRead()
-{
- while (!mDevice->atEnd()) {
- int bytesAvailable = mDevice->bytesAvailable();
- int offset = mReadBuffer.size();
- mReadBuffer.resize(offset + bytesAvailable);
- int bytesRead = mDevice->read(mReadBuffer.data()+offset, bytesAvailable);
- if (bytesRead < 0) {
- qWarning() << "Error reading from socket" << mDevice->errorString();
- continue;
- }
- while (mReadBuffer.size()) {
- QJsonDocument doc(QJsonDocument::fromBinaryData(mReadBuffer, QJsonDocument::Validate));
- if (doc.isEmpty())
- break;
- receive(doc.object());
- mReadBuffer = mReadBuffer.mid(doc.toBinaryData().size());
- }
- }
-}
-
-void JsonStream::deviceBytesWritten(qint64 bytes)
-{
- Q_UNUSED(bytes);
- if (!mWriteBuffer.isEmpty()) {
- int didWrite = mDevice->write(mWriteBuffer);
- mWriteBuffer = mWriteBuffer.mid(didWrite);
- }
-}
-
-
-#include "moc_jsonstream.cpp"
-
-QT_END_NAMESPACE_JSONDB
diff --git a/src/daemon/daemon.pri b/src/daemon/daemon.pri
deleted file mode 100644
index 1deaa06f..00000000
--- a/src/daemon/daemon.pri
+++ /dev/null
@@ -1,56 +0,0 @@
-include($$PWD/../3rdparty/btree/btree.pri)
-include($$PWD/../hbtree/hbtree.pri)
-include($$PWD/../common/common.pri)
-
-DEFINES += $$quote(QT_BEGIN_MOC_NAMESPACE=\"QT_USE_NAMESPACE QT_USE_NAMESPACE_JSONDB\")
-
-RESOURCES = $$PWD/jsondb.qrc
-HEADERS += \
- $$PWD/jsondbowner.h \
- $$PWD/jsondbproxy.h \
- $$PWD/jsondbresponse.h \
- $$PWD/jsondbephemeralpartition.h \
- $$PWD/jsondbindex.h \
- $$PWD/jsondbobject.h \
- $$PWD/jsondbpartition.h \
- $$PWD/jsondbquery.h \
- $$PWD/jsondbstat.h \
- $$PWD/jsondbview.h \
- $$PWD/jsondbmapdefinition.h \
- $$PWD/jsondbnotification.h \
- $$PWD/jsondbobjectkey.h \
- $$PWD/jsondbobjecttable.h \
- $$PWD/jsondbbtree.h \
- $$PWD/jsondbobjecttypes_impl_p.h \
- $$PWD/jsondbobjecttypes_p.h \
- $$PWD/jsondbreducedefinition.h \
- $$PWD/schema-validation/checkpoints.h \
- $$PWD/schema-validation/object.h \
- $$PWD/jsondbschemamanager_impl_p.h \
- $$PWD/jsondbschemamanager_p.h \
- $$PWD/jsondbsignals.h \
- $$PWD/jsondbsettings.h \
- $$PWD/jsondbindexquery.h
-
-HEADERS += $$QSONCONVERSION_HEADERS
-
-SOURCES += \
- $$PWD/jsondbowner.cpp \
- $$PWD/jsondbproxy.cpp \
- $$PWD/jsondbresponse.cpp \
- $$PWD/jsondbephemeralpartition.cpp \
- $$PWD/jsondbindex.cpp \
- $$PWD/jsondbobject.cpp \
- $$PWD/jsondbpartition.cpp \
- $$PWD/jsondbquery.cpp \
- $$PWD/jsondbview.cpp \
- $$PWD/jsondbmapdefinition.cpp \
- $$PWD/jsondbnotification.cpp \
- $$PWD/jsondbobjecttable.cpp \
- $$PWD/jsondbbtree.cpp \
- $$PWD/jsondbreducedefinition.cpp \
- $$PWD/jsondbsignals.cpp \
- $$PWD/jsondbsettings.cpp \
- $$PWD/jsondbindexquery.cpp
-
-SOURCES += $$QSONCONVERSION_SOURCES
diff --git a/src/daemon/daemon.pro b/src/daemon/daemon.pro
index 00bcc114..42173231 100644
--- a/src/daemon/daemon.pro
+++ b/src/daemon/daemon.pro
@@ -3,20 +3,28 @@ DESTDIR = $$QT.jsondb.bins
target.path = $$[QT_INSTALL_PREFIX]/bin
INSTALLS += target
+include($$PWD/../jsonstream/jsonstream.pri)
+
LIBS += -L$$QT.jsondb.libs
-QT = core network qml
+QT = core network qml jsondbpartition
mac:CONFIG -= app_bundle
-include(daemon.pri)
+# HACK, remove when jsondbpartition separates private api from public api
+include(../3rdparty/btree/btree.pri)
+include(../hbtree/hbtree.pri)
HEADERS += \
- $$PWD/dbserver.h
+ $$PWD/dbserver.h \
+ $$PWD/jsondbephemeralpartition.h \
+ $$PWD/jsondbsignals.h
SOURCES += \
$$PWD/main.cpp \
- $$PWD/dbserver.cpp
+ $$PWD/dbserver.cpp \
+ $$PWD/jsondbephemeralpartition.cpp \
+ $$PWD/jsondbsignals.cpp
systemd {
DEFINES += USE_SYSTEMD
diff --git a/src/daemon/dbserver.cpp b/src/daemon/dbserver.cpp
index 29b050c0..845100a0 100644
--- a/src/daemon/dbserver.cpp
+++ b/src/daemon/dbserver.cpp
@@ -39,14 +39,12 @@
**
****************************************************************************/
-#include <QtCore>
#include <QtNetwork>
+#include <QDir>
#include <QElapsedTimer>
-#include <json.h>
-
-#include "jsondb-strings.h"
-#include "jsondb-error.h"
+#include "jsondbstrings.h"
+#include "jsondberrors.h"
#include "jsondbephemeralpartition.h"
#include "jsondbindexquery.h"
@@ -61,7 +59,7 @@
#include <errno.h>
#endif
-QT_BEGIN_NAMESPACE_JSONDB
+QT_USE_NAMESPACE_JSONDB_PARTITION
static const int gReadBufferSize = 65536;
@@ -92,45 +90,58 @@ static void sendError( JsonStream *stream, JsonDbError::ErrorCode code,
stream->send(map);
}
-DBServer::DBServer(const QString &filePath, const QString &baseName, QObject *parent)
- : QObject(parent),
- mDefaultPartition(0),
- mEphemeralPartition(0),
- mTcpServerPort(0),
- mServer(0),
- mTcpServer(0),
- mOwner(new JsonDbOwner(this)),
- mFilePath(filePath),
- mBaseName(baseName)
+DBServer::DBServer(const QString &searchPath, QObject *parent) :
+ QObject(parent)
+ , mDefaultPartition(0)
+ , mEphemeralPartition(0)
+ , mTcpServerPort(0)
+ , mServer(0)
+ , mTcpServer(0)
+ , mOwner(new JsonDbOwner(this))
{
// for queued connection handling
qRegisterMetaType<JsonDbPartition*>("JsonDbPartition*");
qRegisterMetaType<QSet<QString> >("QSet<QString>");
+ qRegisterMetaType<JsonDbUpdateList>("JsonDbUpdateList");
- QFileInfo info(filePath);
+ // make the user-specified path (or PWD) the first in the search path, then and
+ // the /etc one the last
+ QStringList searchPaths = jsondbSettings->configSearchPath();
+ if (searchPath.isEmpty())
+ searchPaths.prepend(QDir::currentPath());
+ else if (!searchPaths.contains(searchPath))
+ searchPaths.prepend(searchPath);
- if (QString::compare(info.suffix(), QLatin1String("db"), Qt::CaseInsensitive) == 0) {
- mFilePath = info.absolutePath();
- if (mBaseName.isEmpty())
- mBaseName = info.baseName();
- }
+ if (!searchPaths.contains(QLatin1String("/etc/jsondb")))
+ searchPaths.append(QLatin1String("/etc/jsondb"));
+ jsondbSettings->setConfigSearchPath(searchPaths);
- if (mFilePath.isEmpty())
- mFilePath = QDir::currentPath();
- if (mBaseName.isEmpty())
- mBaseName = QLatin1String("default.System");
- if (!mBaseName.endsWith(QLatin1String(".System")))
- mBaseName += QLatin1String(".System");
+ mOwner->setAllowAll(true);
+}
- QDir(mFilePath).mkpath(QString("."));
+DBServer::~DBServer()
+{
+ close();
+}
- mOwner->setAllowAll(true);
+void DBServer::clearNotifications()
+{
+ QMapIterator<QString,JsonDbNotification*> mi(mNotificationMap);
+ while (mi.hasNext()) {
+ delete mi.value();
+ mi.next();
+ }
+ delete mi.value();
+ mNotificationMap.clear();
+ mNotifications.clear();
+ mKeyedNotifications.clear();
}
void DBServer::sigHUP()
{
if (jsondbSettings->debug())
qDebug() << "SIGHUP received";
+ loadPartitions();
reduceMemoryUsage();
}
@@ -220,7 +231,7 @@ void DBServer::close()
partition->compact();
partition->close();
}
-
+ clearNotifications();
QCoreApplication::exit();
}
@@ -232,54 +243,87 @@ bool DBServer::loadPartitions()
this, SLOT(objectsUpdated(JsonDbUpdateList)));
}
- QHash<QString, JsonDbPartition*> oldPartitions = mPartitions;
- oldPartitions.remove(mBaseName);
-
- if (!mDefaultPartition) {
- mDefaultPartition = new JsonDbPartition(QDir(mFilePath).absoluteFilePath(mBaseName + QLatin1String(".db")),
- mBaseName, mOwner, this);
- connect(mDefaultPartition, SIGNAL(objectsUpdated(JsonDbUpdateList)),
- this, SLOT(objectsUpdated(JsonDbUpdateList)));
- connect(mDefaultPartition, SIGNAL(viewUpdated(QString)),
- this, SLOT(viewUpdated(QString)),
- Qt::QueuedConnection);
+ QHash<QString, JsonDbPartition*> partitions;
+ QList<QJsonObject> definitions = findPartitionDefinitions();
+ QString defaultPartitionName;
- if (!mDefaultPartition->open())
- return false;
+ foreach (const QJsonObject &definition, definitions) {
+ QString name = definition.value(JsonDbString::kNameStr).toString();
- mPartitions[mBaseName] = mDefaultPartition;
- }
+ if (definition.value(JsonDbString::kDefaultStr).toBool() && defaultPartitionName.isEmpty())
+ defaultPartitionName = name;
- JsonDbQueryResult partitions = mDefaultPartition->queryObjects(mOwner, JsonDbQuery::parse(QLatin1String("[?_type=\"Partition\"]")));
+ if (mPartitions.contains(name)) {
+ partitions[name] = mPartitions.take(name);
+ } else {
- foreach (const JsonDbObject &partition, partitions.data) {
- if (partition.contains(JsonDbString::kNameStr)) {
- QString name = partition.value(JsonDbString::kNameStr).toString();
+ if (partitions.contains(name)) {
+ qWarning() << "Duplicate partition name:" << name;
+ continue;
+ }
- if (!mPartitions.contains(name)) {
- QString filename = partition.contains(QLatin1String("file")) ?
- partition.value(QLatin1String("file")).toString() :
- QDir(mFilePath).absoluteFilePath(name + QLatin1String(".db"));
- JsonDbPartition *p = new JsonDbPartition(filename, name, mOwner, this);
- connect(p, SIGNAL(objectsUpdated(JsonDbUpdateList)),
- this, SLOT(objectsUpdated(JsonDbUpdateList)));
- connect(p, SIGNAL(viewUpdated(QString)),
- this, SLOT(viewUpdated(QString)),
- Qt::QueuedConnection);
+ QString path = definition.value(JsonDbString::kPathStr).toString();
+ QDir pathDir(path);
+ pathDir.mkpath(QLatin1String("."));
- if (!p->open())
- return false;
+ JsonDbPartition *partition = new JsonDbPartition(pathDir.absoluteFilePath(name), name, mOwner, this);
+ partitions[name] = partition;
+ connect(partition, SIGNAL(objectsUpdated(JsonDbUpdateList)), this, SLOT(objectsUpdated(JsonDbUpdateList)));
- mPartitions[name] = p;
+ // TODO: for removable partitions, this shouldn't cause a total failure
+ if (!partition->open()) {
+ close();
+ return false;
}
- oldPartitions.remove(name);
+ // create an object in the Ephemeral partition to reflect this partition
+ JsonDbObject partitionRecord(definition);
+ partitionRecord.insert(JsonDbString::kUuidStr, JsonDbObject::createUuidFromString(name).toString());
+ partitionRecord.insert(JsonDbString::kTypeStr, JsonDbString::kPartitionTypeStr);
+ mEphemeralPartition->updateObjects(mOwner, JsonDbObjectList() << partitionRecord, JsonDbPartition::ForcedWrite);
}
}
// close any partitions that were declared previously but are no longer present
- foreach (JsonDbPartition *p, oldPartitions.values())
- p->close();
+ foreach (JsonDbPartition *partition, mPartitions.values()) {
+
+ if (mDefaultPartition == partition)
+ mDefaultPartition = 0;
+
+ QList<JsonDbObject> toRemove;
+
+ // remove the ephemeral object representing this partition
+ JsonDbObject partitionRecord;
+ partitionRecord.insert(JsonDbString::kUuidStr, JsonDbObject::createUuidFromString(partition->name()).toString());
+ partitionRecord.insert(JsonDbString::kTypeStr, JsonDbString::kPartitionTypeStr);
+ partitionRecord.markDeleted();
+ toRemove.append(partitionRecord);
+
+ // remove any notifications for the partition being closed
+ QJsonObject bindings;
+ bindings.insert(QLatin1String("notification"), JsonDbString::kNotificationTypeStr);
+ bindings.insert(QLatin1String("partition"), partition->name());
+
+ QScopedPointer<JsonDbQuery> query(JsonDbQuery::parse(QLatin1String("[?_type=%notification][?partition=%partition]"),
+ bindings));
+ JsonDbQueryResult results = mEphemeralPartition->queryObjects(mOwner, query.data());
+ foreach (const JsonDbObject &result, results.data) {
+ JsonDbObject notification = result;
+ notification.markDeleted();
+ toRemove.append(notification);
+ }
+
+ mEphemeralPartition->updateObjects(mOwner, toRemove, JsonDbPartition::ForcedWrite);
+
+ disconnect(partition, SIGNAL(objectsUpdated(JsonDbUpdateList)), this, SLOT(objectsUpdated(JsonDbUpdateList)));
+ partition->close();
+ delete partition;
+ }
+
+ mPartitions = partitions;
+
+ if (!mDefaultPartition)
+ mDefaultPartition = mPartitions[defaultPartitionName];
return true;
}
@@ -305,7 +349,8 @@ void DBServer::handleConnection()
if (jsondbSettings->debug())
qDebug() << "client connected to jsondb server" << connection;
connect(connection, SIGNAL(disconnected()), this, SLOT(removeConnection()));
- JsonStream *stream = new JsonStream(connection, this);
+ JsonStream *stream = new JsonStream(this);
+ stream->setDevice(connection);
connect(stream, SIGNAL(receive(QJsonObject)), this,
SLOT(receiveMessage(QJsonObject)));
mConnections.insert(connection, stream);
@@ -318,7 +363,8 @@ void DBServer::handleTcpConnection()
if (jsondbSettings->debug())
qDebug() << "remote client connected to jsondb server" << connection;
connect(connection, SIGNAL(disconnected()), this, SLOT(removeConnection()));
- JsonStream *stream = new JsonStream(connection, this);
+ JsonStream *stream = new JsonStream(this);
+ stream->setDevice(connection);
connect(stream, SIGNAL(receive(QJsonObject)), this,
SLOT(receiveMessage(QJsonObject)));
mConnections.insert(connection, stream);
@@ -431,6 +477,9 @@ void DBServer::objectsUpdated(const QList<JsonDbUpdate> &objects)
{
QString partitionName;
JsonDbPartition *partition = 0;
+ QList<JsonDbUpdate> updatesToEagerViews;
+ QSet<QString> eagerViewTypes;
+ bool isViewUpdate = false;
if (sender() == mEphemeralPartition) {
partitionName = mEphemeralPartition->name();
@@ -441,8 +490,14 @@ void DBServer::objectsUpdated(const QList<JsonDbUpdate> &objects)
else
return;
}
+ quint32 partitionStateNumber = 0;
+ if (partition)
+ partition->mainObjectTable()->stateNumber();
+ else if (mDefaultPartition)
+ partitionStateNumber = mDefaultPartition->mainObjectTable()->stateNumber();
- QSet<QString> eagerViewUpdates;
+ if (jsondbSettings->debug())
+ qDebug() << "objectsUpdated" << partitionName << partitionStateNumber;
// FIXME: pretty good place to batch notifications
foreach (const JsonDbUpdate &updated, objects) {
@@ -455,12 +510,13 @@ void DBServer::objectsUpdated(const QList<JsonDbUpdate> &objects)
if (object.type() == JsonDbString::kNotificationTypeStr)
continue;
+ QString oldObjectType = oldObject.value(JsonDbString::kTypeStr).toString();
QString objectType = object.value(JsonDbString::kTypeStr).toString();
quint32 stateNumber;
if (partition) {
JsonDbObjectTable *objectTable = partition->findObjectTable(objectType);
stateNumber = objectTable->stateNumber();
- } else
+ } else if (partitionName != mEphemeralPartition->name())
stateNumber = mDefaultPartition->mainObjectTable()->stateNumber();
QStringList notificationKeys;
@@ -468,9 +524,37 @@ void DBServer::objectsUpdated(const QList<JsonDbUpdate> &objects)
notificationKeys << objectType;
// eagerly update views if this object that was created isn't a view type itself
- if (mEagerViewSourceTypes.contains(objectType) && partition
- && !partition->findView(objectType))
- eagerViewUpdates.insert(objectType);
+ if (partition) {
+ WeightedSourceViewGraph &sourceViewGraph = mEagerViewSourceGraph[partitionName];
+ if (jsondbSettings->verbose()) qDebug() << "objectType" << objectType << sourceViewGraph.contains(oldObjectType) << sourceViewGraph.contains(objectType);
+ if (partition->findView(objectType)) {
+ if (jsondbSettings->verbose()) qDebug() << "isViewUpdate" << objectType;
+ isViewUpdate = true;
+ } else if ((sourceViewGraph.contains(oldObjectType))
+ || (sourceViewGraph.contains(objectType))) {
+ JsonDbUpdateList updateList;
+ if (oldObjectType == objectType) {
+ updateList.append(updated);
+ } else {
+ JsonDbObject tombstone(oldObject);
+ tombstone.insert(QLatin1String("_deleted"), true);
+ updateList.append(JsonDbUpdate(oldObject, tombstone, JsonDbNotification::Delete));
+ updateList.append(JsonDbUpdate(JsonDbObject(), object, JsonDbNotification::Create));
+ }
+ foreach (const JsonDbUpdate &splitUpdate, updateList) {
+ const QString updatedObjectType = splitUpdate.newObject.type();
+ const ViewEdgeWeights &edgeWeights = sourceViewGraph[updatedObjectType];
+ for (ViewEdgeWeights::const_iterator it = edgeWeights.begin(); it != edgeWeights.end(); ++it) {
+ if (jsondbSettings->verbose()) qDebug() << "edge weight" << updatedObjectType << it.key() << it.value().count;
+ if (it.value() > 0) {
+ eagerViewTypes.insert(it.key());
+ if (sourceViewGraph.contains(updatedObjectType))
+ updatesToEagerViews.append(splitUpdate);
+ }
+ }
+ }
+ }
+ }
}
if (object.contains(JsonDbString::kUuidStr))
@@ -491,31 +575,119 @@ void DBServer::objectsUpdated(const QList<JsonDbUpdate> &objects)
}
}
- if (!eagerViewUpdates.isEmpty())
+ if (isViewUpdate)
+ return;
+ if (updatesToEagerViews.isEmpty()) {
+ updateEagerViewStateNumbers(partition ? partition : mDefaultPartition, partitionStateNumber);
+ emitStateChanged(partition);
+ } else {
QMetaObject::invokeMethod(this, "updateEagerViews", Qt::QueuedConnection,
Q_ARG(JsonDbPartition*, partition),
- Q_ARG(QSet<QString>, eagerViewUpdates));
+ Q_ARG(QSet<QString>, eagerViewTypes),
+ Q_ARG(JsonDbUpdateList, updatesToEagerViews));
+ }
}
-void DBServer::viewUpdated(const QString &type)
+// Updates the in-memory state numbers on each view so that we know it
+// has seen all relevant updates from this transaction
+void DBServer::updateEagerViewStateNumbers(JsonDbPartition *partition, quint32 partitionStateNumber)
{
- JsonDbPartition *partition = qobject_cast<JsonDbPartition*>(sender());
if (!partition)
return;
+ if (jsondbSettings->verbose())
+ qDebug() << "updateEagerViewStateNumbers" << (partition ? partition->name() : "no partition") << partitionStateNumber << "{";
+ const QString &partitionName = partition->name();
+ WeightedSourceViewGraph &sourceViewGraph = mEagerViewSourceGraph[partitionName];
+ foreach (const ViewEdgeWeights &edgeWeights, sourceViewGraph) {
+ for (ViewEdgeWeights::const_iterator jt = edgeWeights.begin(); jt != edgeWeights.end(); ++jt) {
+ const QString &viewType = jt.key();
+ if (jt.value() == 0)
+ continue;
+ JsonDbView *view = partition->findView(viewType);
+ if (view)
+ view->updateViewStateNumber(partitionStateNumber);
+ else
+ if (jsondbSettings->debug())
+ qCritical() << "no view for" << viewType << partition->name();
+ }
+ }
+ if (jsondbSettings->verbose())
+ qDebug() << "updateEagerViewStateNumbers" << (partition ? partition->name() : "no partition") << partitionStateNumber << "}";
+}
- if (mEagerViewSourceTypes.contains(type))
- updateEagerViews(partition, QSet<QString>() << type);
+void DBServer::emitStateChanged(JsonDbPartition *partition)
+{
+ if (!partition)
+ return;
+ quint32 lastStateNumber = partition->mainObjectTable()->stateNumber();
+ QJsonObject stateChange;
+ stateChange.insert("_state", static_cast<int>(lastStateNumber));
+ foreach (const JsonDbNotification *n, mNotificationMap) {
+ if (n->lastStateNumber() == lastStateNumber
+ && n->partition() == partition->name())
+ emit notified(n->uuid(), lastStateNumber, stateChange, "stateChange");
+ }
}
-void DBServer::updateEagerViews(JsonDbPartition *partition, const QSet<QString> &viewTypes)
+void DBServer::updateEagerViews(JsonDbPartition *partition, QSet<QString> viewTypes, QList<JsonDbUpdate> changeList)
{
- foreach (const QString &type, viewTypes) {
- const QSet<QString> &targetTypes = mEagerViewSourceTypes[type];
- for (QSet<QString>::const_iterator it = targetTypes.begin(); it != targetTypes.end(); ++it) {
- if (partition)
- partition->updateView(*it);
+ QSet<QString> viewsUpdated;
+
+ if (jsondbSettings->verbose())
+ qDebug() << "updateEagerViews {" << partition->mainObjectTable()->stateNumber() << viewTypes;
+ quint32 partitionStateNumber = partition->mainObjectTable()->stateNumber();
+ const QString &partitionName = partition->name();
+ WeightedSourceViewGraph &sourceViewGraph = mEagerViewSourceGraph[partitionName];
+
+ while (!viewTypes.isEmpty()) {
+ bool madeProgress = false;
+ foreach (const QString &targetType, viewTypes) {
+ JsonDbView *view = partition->findView(targetType);
+ if (!view) {
+ if (jsondbSettings->verbose())
+ qWarning() << "non-view viewType?" << targetType << "eager views to update" << viewTypes;
+ viewTypes.remove(targetType);
+ madeProgress = true;
+ continue;
+ }
+ QSet<QString> typesNeeded(view->sourceTypeSet());
+ typesNeeded.intersect(viewTypes);
+ if (!typesNeeded.isEmpty())
+ continue;
+ viewTypes.remove(targetType);
+ QList<JsonDbUpdate> additionalChanges;
+ view->updateEagerView(changeList, &additionalChanges);
+ if (jsondbSettings->verbose())
+ qDebug() << "updated view" << targetType << additionalChanges.size() << additionalChanges;
+ changeList.append(additionalChanges);
+ viewsUpdated.insert(targetType);
+ // if this triggers other eager types, we need to update that also
+ if (sourceViewGraph.contains(targetType)) {
+ const ViewEdgeWeights &edgeWeights = sourceViewGraph[targetType];
+ for (ViewEdgeWeights::const_iterator it = edgeWeights.begin(); it != edgeWeights.end(); ++it) {
+ if (it.value() == 0)
+ continue;
+ const QString &viewType = it.key();
+ if (viewsUpdated.contains(viewType))
+ qWarning() << "View update cycle detected" << targetType << viewType << viewsUpdated;
+ else
+ viewTypes.insert(viewType);
+ }
+ }
+
+ madeProgress = true;
+ }
+ if (!madeProgress) {
+ qCritical() << "Failed to update any views" << viewTypes;
+ break;
}
}
+
+ updateEagerViewStateNumbers(partition, partitionStateNumber);
+ emitStateChanged(partition);
+
+ if (jsondbSettings->verbose())
+ qDebug() << "updateEagerViews }" << partition->mainObjectTable()->stateNumber() << viewsUpdated;
}
void DBServer::objectUpdated(const QString &partitionName, quint32 stateNumber, JsonDbNotification *n,
@@ -549,10 +721,23 @@ void DBServer::objectUpdated(const QString &partitionName, quint32 stateNumber,
r = object;
}
if (!r.isEmpty()&& (n->actions() & effectiveAction)) {
+ JsonDbPartition *partition = findPartition(partitionName);
+ if (partition && !n->parsedQuery()->orderTerms.isEmpty()) {
+ const QString &indexName = n->parsedQuery()->orderTerms[0].propertyName;
+ QString objectType = r.type();
+ JsonDbObjectTable *objectTable = partition->findObjectTable(objectType);
+ IndexSpec *indexSpec = objectTable->indexSpec(indexName);
+ if (indexSpec) {
+ QList<QJsonValue> indexValues = indexSpec->index->indexValues(r);
+ if (!indexValues.isEmpty())
+ r.insert(JsonDbString::kIndexValueStr, indexValues[0]);
+ }
+ }
QString actionStr = (effectiveAction == JsonDbNotification::Create ? JsonDbString::kCreateStr :
(effectiveAction == JsonDbNotification::Update ? JsonDbString::kUpdateStr :
JsonDbString::kRemoveStr));
notified(n->uuid(), stateNumber, r, actionStr);
+ n->setLastStateNumber(stateNumber);
}
}
}
@@ -587,10 +772,6 @@ void DBServer::processWrite(JsonStream *stream, JsonDbOwner *owner, const JsonDb
removeNotification(object);
if (!object.isDeleted())
createNotification(object, stream);
-
- // handle partitions
- } else if (object.type() == JsonDbString::kPartitionTypeStr) {
- loadPartitions();
}
}
@@ -652,18 +833,11 @@ void DBServer::processRead(JsonStream *stream, JsonDbOwner *owner, const QJsonVa
response.insert(JsonDbString::kResultStr, QJsonValue());
} else {
QJsonObject result;
- if (queryResult.values.size()) {
- result.insert(JsonDbString::kDataStr, queryResult.values);
- result.insert(JsonDbString::kLengthStr, queryResult.values.size());
- } else {
- QJsonArray values;
- for (int i = 0; i < queryResult.data.size(); i++) {
- JsonDbObject d = queryResult.data.at(i);
- values.append(d);
- }
- result.insert(JsonDbString::kDataStr, values);
- result.insert(JsonDbString::kLengthStr, values.size());
- }
+ QJsonArray data;
+ for (int i = 0; i < queryResult.data.size(); i++)
+ data.append(queryResult.data.at(i));
+ result.insert(JsonDbString::kDataStr, data);
+ result.insert(JsonDbString::kLengthStr, data.size());
result.insert(JsonDbString::kOffsetStr, queryResult.offset);
result.insert(JsonDbString::kExplanationStr, queryResult.explanation);
result.insert("sortKeys", queryResult.sortKeys);
@@ -678,6 +852,7 @@ void DBServer::processRead(JsonStream *stream, JsonDbOwner *owner, const QJsonVa
void DBServer::processChangesSince(JsonStream *stream, JsonDbOwner *owner, const QJsonValue &object, const QString &partitionName, int id)
{
+ Q_UNUSED(owner);
QJsonObject result;
if (object.type() == QJsonValue::Object) {
@@ -703,6 +878,7 @@ void DBServer::processChangesSince(JsonStream *stream, JsonDbOwner *owner, const
void DBServer::processFlush(JsonStream *stream, JsonDbOwner *owner, const QString &partitionName, int id)
{
+ Q_UNUSED(owner);
JsonDbPartition *partition = mPartitions.value(partitionName, mDefaultPartition);
QJsonObject result = partition->flush();
result.insert(JsonDbString::kIdStr, id);
@@ -715,14 +891,15 @@ void DBServer::debugQuery(JsonDbQuery *query, int limit, int offset, const JsonD
for (int i = 0; i < orQueryTerms.size(); i++) {
const OrQueryTerm &orQueryTerm = orQueryTerms[i];
foreach (const QueryTerm &queryTerm, orQueryTerm.terms()) {
- if (jsondbSettings->verbose())
+ if (jsondbSettings->verbose()) {
qDebug() << __FILE__ << __LINE__
- << QString(" %1%2%3 %4 %5 ")
- .arg(queryTerm.propertyName())
- .arg(queryTerm.joinField().size() ? "->" : "")
- .arg(queryTerm.joinField())
- .arg(queryTerm.op())
- .arg(JsonWriter().toString(queryTerm.value().toVariant()));
+ << QString(" %1%2%3 %4")
+ .arg(queryTerm.propertyName())
+ .arg(queryTerm.joinField().size() ? "->" : "")
+ .arg(queryTerm.joinField())
+ .arg(queryTerm.op())
+ << queryTerm.value();
+ }
}
}
@@ -797,18 +974,20 @@ void DBServer::createNotification(const JsonDbObject &object, JsonStream *stream
QStringList actions = QVariant(object.value(JsonDbString::kActionsStr).toArray().toVariantList()).toStringList();
QString query = object.value(JsonDbString::kQueryStr).toString();
QJsonObject bindings = object.value("bindings").toObject();
- QString partition = object.value(JsonDbString::kPartitionStr).toString();
-
- bool ok;
- quint32 stateNumber = object.value("initialStateNumber").toVariant().toInt(&ok);
- if (!ok)
- stateNumber = 0;
+ QString partitionName = object.value(JsonDbString::kPartitionStr).toString();
+ quint32 stateNumber = 0;
- if (partition.isEmpty())
- partition = mDefaultPartition->name();
+ if (partitionName.isEmpty())
+ partitionName = mDefaultPartition->name();
+ JsonDbPartition *partition = findPartition(partitionName);
- JsonDbNotification *n = new JsonDbNotification(getOwner(stream), uuid, query, actions, partition);
+ JsonDbNotification *n = new JsonDbNotification(getOwner(stream), uuid, query, actions, partitionName);
+ if (object.contains("initialStateNumber") && object.value("initialStateNumber").isDouble())
+ stateNumber = static_cast<quint32>(object.value("initialStateNumber").toDouble());
+ else if (partition)
+ stateNumber = partition->mainObjectTable()->stateNumber();
n->setInitialStateNumber(stateNumber);
+
JsonDbQuery *parsedQuery = JsonDbQuery::parse(query, bindings);
n->setCompiledQuery(parsedQuery);
const QList<OrQueryTerm> &orQueryTerms = parsedQuery->queryTerms;
@@ -840,11 +1019,10 @@ void DBServer::createNotification(const JsonDbObject &object, JsonStream *stream
mNotifications[uuid] = stream;
foreach (const QString &objectType, parsedQuery->matchedTypes())
- updateEagerViewTypes(objectType, mPartitions.value(partition, mDefaultPartition), stateNumber);
+ updateEagerViewTypes(objectType, mPartitions.value(partitionName, mDefaultPartition), stateNumber, 1);
- if (stateNumber)
+ if (partition)
notifyHistoricalChanges(n);
-
}
void DBServer::removeNotification(const JsonDbObject &object)
@@ -873,6 +1051,10 @@ void DBServer::removeNotification(const JsonDbObject &object)
mKeyedNotifications.remove("__generic_notification__", n);
+ const QString &partitionName = n->partition();
+ foreach (const QString &objectType, parsedQuery->matchedTypes())
+ updateEagerViewTypes(objectType, mPartitions.value(partitionName, mDefaultPartition), 0, -1);
+
delete n;
}
}
@@ -885,7 +1067,7 @@ void DBServer::notifyHistoricalChanges(JsonDbNotification *n)
JsonDbQuery *parsedQuery = n->parsedQuery();
QSet<QString> matchedTypes = parsedQuery->matchedTypes();
bool matchAnyType = matchedTypes.isEmpty();
- if (stateNumber == static_cast<quint32>(-1)) {
+ if (stateNumber == 0) {
QString indexName = JsonDbString::kTypeStr;
if (matchAnyType) {
matchedTypes.insert(QString());
@@ -894,62 +1076,96 @@ void DBServer::notifyHistoricalChanges(JsonDbNotification *n)
}
foreach (const QString matchedType, matchedTypes) {
JsonDbObjectTable *objectTable = partition->findObjectTable(matchedType);
+ lastStateNumber = objectTable->stateNumber();
+ if (lastStateNumber == stateNumber)
+ continue;
// views dont have a _type index
if (partition->findView(matchedType))
indexName = JsonDbString::kUuidStr;
lastStateNumber = objectTable->stateNumber();
- JsonDbIndexQuery *indexQuery = JsonDbIndexQuery::indexQuery(partition, objectTable,
+ QScopedPointer<JsonDbIndexQuery> indexQuery(JsonDbIndexQuery::indexQuery(partition, objectTable,
indexName, QString("string"),
- n->owner());
+ n->owner()));
if (!matchAnyType) {
- indexQuery->setMin(matchedType);
- indexQuery->setMax(matchedType);
+ indexQuery.data()->setMin(matchedType);
+ indexQuery.data()->setMax(matchedType);
}
JsonDbObject oldObject;
- for (JsonDbObject o = indexQuery->first(); !o.isEmpty(); o = indexQuery->next()) {
+ int c = 0;
+ for (JsonDbObject o = indexQuery.data()->first(); !o.isEmpty(); o = indexQuery.data()->next()) {
JsonDbNotification::Action action = JsonDbNotification::Create;
- objectUpdated(partition->name(), stateNumber, n, action, oldObject, o);
+ objectUpdated(partition->name(), lastStateNumber, n, action, oldObject, o);
+ c++;
}
}
} else {
- QJsonObject changesSince = partition->changesSince(stateNumber, matchedTypes);
- QJsonObject changes(changesSince.value("result").toObject());
- lastStateNumber = changes.value("currentStateNumber").toDouble();
- QJsonArray changeList(changes.value("changes").toArray());
- quint32 count = changeList.size();
- for (quint32 i = 0; i < count; i++) {
- QJsonObject change = changeList.at(i).toObject();
- QJsonObject before = change.value("before").toObject();
- QJsonObject after = change.value("after").toObject();
-
- JsonDbNotification::Action action = JsonDbNotification::Update;
- if (before.isEmpty())
- action = JsonDbNotification::Create;
- else if (after.contains(JsonDbString::kDeletedStr))
- action = JsonDbNotification::Delete;
- objectUpdated(partition->name(), stateNumber, n, action, before, after);
+ foreach (const QString matchedType, matchedTypes) {
+ JsonDbObjectTable *objectTable = partition->findObjectTable(matchedType);
+ if (objectTable->stateNumber() == stateNumber)
+ continue;
+ QList<JsonDbUpdate> updateList;
+ lastStateNumber = objectTable->changesSince(stateNumber, matchedTypes, &updateList);
+ foreach (const JsonDbUpdate &update, updateList) {
+ QJsonObject before = update.oldObject;
+ QJsonObject after = update.newObject;
+
+ JsonDbNotification::Action action = JsonDbNotification::Update;
+ if (before.isEmpty())
+ action = JsonDbNotification::Create;
+ else if (after.contains(JsonDbString::kDeletedStr))
+ action = JsonDbNotification::Delete;
+ objectUpdated(partition->name(), lastStateNumber, n, action, before, after);
+ }
}
}
QJsonObject stateChange;
stateChange.insert("_state", static_cast<int>(lastStateNumber));
- emit notified(n->uuid(), stateNumber, stateChange, "stateChange");
+ emit notified(n->uuid(), lastStateNumber, stateChange, "stateChange");
}
-void DBServer::updateEagerViewTypes(const QString &objectType, JsonDbPartition *partition, quint32 stateNumber)
+/*!
+ Updates the per-partition information on eager views.
+
+ For each partition, we maintain a graph with weighted edges from
+ source types to \a viewType.
+
+ Adds \a increment weight to the edge from each of the source types
+ of the view to the target type. Call with \a increment of 1 when
+ adding an eager view type, and -1 when removing an eager view type.
+
+ It recursively updates the graph for each source type that is also a
+ view.
+
+ If \a stateNumber is non-zero, do a full update of each the views so
+ that they will be ready for eager updates.
+ */
+void DBServer::updateEagerViewTypes(const QString &viewType, JsonDbPartition *partition, quint32 stateNumber, int increment)
{
- // FIXME: eager view types should be broken down by partition
- JsonDbView *view = partition->findView(objectType);
+ JsonDbView *view = partition->findView(viewType);
if (!view)
return;
+ QString partitionName = partition->name();
+ WeightedSourceViewGraph &sourceViewGraph = mEagerViewSourceGraph[partitionName];
+
+ // An update of the Map/Reduce definition also causes the view to
+ // need to be updated, so we count it as a view source.
+
+ // this is a bit conservative, since we add both Map and Reduce as
+ // sources, but it shortens the code
+ sourceViewGraph[JsonDbString::kMapTypeStr][viewType] += increment;
+ sourceViewGraph[JsonDbString::kReduceTypeStr][viewType] += increment;
foreach (const QString sourceType, view->sourceTypes()) {
- mEagerViewSourceTypes[sourceType].insert(objectType);
+ sourceViewGraph[sourceType][viewType] += increment;
+ if (jsondbSettings->verbose())
+ qDebug() << "SourceView" << sourceType << viewType << sourceViewGraph[sourceType][viewType].count;
// now recurse until we get to a non-view sourceType
- updateEagerViewTypes(sourceType, partition, stateNumber);
+ updateEagerViewTypes(sourceType, partition, stateNumber, increment);
}
- partition->updateView(objectType, stateNumber);
+ if (stateNumber)
+ partition->updateView(viewType, stateNumber);
}
JsonDbPartition *DBServer::findPartition(const QString &partitionName)
@@ -965,6 +1181,67 @@ JsonDbPartition *DBServer::findPartition(const QString &partitionName)
return partition;
}
+QList<QJsonObject> DBServer::findPartitionDefinitions() const
+{
+ QList<QJsonObject> partitions;
+
+ bool defaultSpecified = false;
+
+ foreach (const QString &path, jsondbSettings->configSearchPath()) {
+ QDir searchPath(path);
+ if (!searchPath.exists())
+ continue;
+
+ if (jsondbSettings->debug())
+ qDebug() << QString("Searching %1 for partition definition files").arg(path);
+
+ QStringList files = searchPath.entryList(QStringList() << "partitions*.json",
+ QDir::CaseSensitive | QDir::Files | QDir::Readable);
+ foreach (const QString file, files) {
+ if (jsondbSettings->debug())
+ qDebug() << QString("Loading partition definitions from %1").arg(file);
+
+ QFile partitionFile(searchPath.absoluteFilePath(file));
+ partitionFile.open(QFile::ReadOnly);
+
+ QJsonArray partitionList = QJsonDocument::fromJson(partitionFile.readAll()).array();
+ if (partitionList.isEmpty())
+ continue;
+
+ for (int i = 0; i < partitionList.count(); i++) {
+ QJsonObject def = partitionList[i].toObject();
+ if (def.contains(JsonDbString::kNameStr)) {
+ if (!def.contains(JsonDbString::kPathStr))
+ def.insert(JsonDbString::kPathStr, QDir::currentPath());
+ if (def.contains(JsonDbString::kDefaultStr))
+ defaultSpecified = true;
+ partitions.append(def);
+ }
+ }
+ }
+ }
+
+ // if no partitions are specified just make a partition in the current working
+ // directory and call it "default"
+ if (partitions.isEmpty()) {
+ QJsonObject defaultPartition;
+ defaultPartition.insert(JsonDbString::kNameStr, QLatin1String("default"));
+ defaultPartition.insert(JsonDbString::kPathStr, QDir::currentPath());
+ defaultPartition.insert(JsonDbString::kDefaultStr, true);
+ partitions.append(defaultPartition);
+ defaultSpecified = true;
+ }
+
+ // ensure that at least one partition is marked as default
+ if (!defaultSpecified) {
+ QJsonObject defaultPartition = partitions.takeFirst();
+ defaultPartition.insert(JsonDbString::kDefaultStr, true);
+ partitions.append(defaultPartition);
+ }
+
+ return partitions;
+}
+
void DBServer::receiveMessage(const QJsonObject &message)
{
JsonStream *stream = qobject_cast<JsonStream *>(sender());
@@ -975,7 +1252,7 @@ void DBServer::receiveMessage(const QJsonObject &message)
JsonDbPartition *partition = findPartition(partitionName);
if (!(partitionName.isEmpty() || partition || partitionName == mEphemeralPartition->name())) {
- sendError(stream, JsonDbError::InvalidRequest,
+ sendError(stream, JsonDbError::InvalidPartition,
QString("Invalid partition '%1'").arg(partitionName), id);
return;
}
@@ -1017,12 +1294,12 @@ void DBServer::receiveMessage(const QJsonObject &message)
// TODO: remove at the same time that clientcompat is dropped
if (action == JsonDbString::kRemoveStr && object.toObject().contains(JsonDbString::kQueryStr)) {
- JsonDbQuery *query = JsonDbQuery::parse(object.toObject().value(JsonDbString::kQueryStr).toString());
+ QScopedPointer<JsonDbQuery> parsedQuery(JsonDbQuery::parse(object.toObject().value(JsonDbString::kQueryStr).toString()));
JsonDbQueryResult res;
if (partition)
- res = partition->queryObjects(owner, query);
+ res = partition->queryObjects(owner, parsedQuery.data());
else
- res = mEphemeralPartition->queryObjects(owner, query);
+ res = mEphemeralPartition->queryObjects(owner, parsedQuery.data());
QJsonArray toRemove;
foreach (const QJsonValue &value, res.data)
@@ -1134,5 +1411,3 @@ void DBServer::removeConnection()
}
#include "moc_dbserver.cpp"
-
-QT_END_NAMESPACE_JSONDB
diff --git a/src/daemon/dbserver.h b/src/daemon/dbserver.h
index d4df0cca..e727369c 100644
--- a/src/daemon/dbserver.h
+++ b/src/daemon/dbserver.h
@@ -58,15 +58,18 @@ class QLocalServer;
class QTcpServer;
QT_END_NAMESPACE
-QT_BEGIN_NAMESPACE_JSONDB
-
class JsonDbEphemeralPartition;
+using QtJsonDbJsonStream::JsonStream;
+QT_USE_NAMESPACE_JSONDB_PARTITION
+
class DBServer : public QObject
{
Q_OBJECT
public:
- DBServer(const QString &fileName, const QString &baseName, QObject *parent = 0);
+ DBServer(const QString &searchPath, QObject *parent = 0);
+ ~DBServer();
+
void setTcpServerPort(quint16 port) { mTcpServerPort = port; }
quint16 tcpServerPort() const { return mTcpServerPort; }
@@ -89,11 +92,12 @@ protected slots:
void receiveMessage(const QJsonObject &document);
void handleConnectionError();
void removeConnection();
+ void clearNotifications();
void notified(const QString &id, quint32 stateNumber, const QJsonObject &object, const QString &action);
void objectsUpdated(const JsonDbUpdateList &objects);
- void viewUpdated(const QString &type);
- void updateEagerViews(JsonDbPartition *partition, const QSet<QString> &viewTypes);
+ void updateEagerViews(JsonDbPartition *partition, const QSet<QString> eagerViewTypes, JsonDbUpdateList changeList);
+ void emitStateChanged(JsonDbPartition *partition);
private:
void objectUpdated(const QString &partitionName, quint32 stateNumber, JsonDbNotification *n, JsonDbNotification::Action action, const JsonDbObject &oldObject, const JsonDbObject &object);
@@ -113,19 +117,32 @@ private:
void createNotification(const JsonDbObject &object, JsonStream *stream);
void removeNotification(const JsonDbObject &object);
void notifyHistoricalChanges(JsonDbNotification *n);
- void updateEagerViewTypes(const QString &objectType, JsonDbPartition *partition, quint32 stateNumber);
+ void updateEagerViewTypes(const QString &objectType, JsonDbPartition *partition, quint32 stateNumber, int weight=1);
+ void updateEagerViewStateNumbers(JsonDbPartition *partition, quint32 partitionStateNumber);
JsonDbPartition* findPartition(const QString &partitionName);
+ QList<QJsonObject> findPartitionDefinitions() const;
JsonDbOwner *getOwner( JsonStream *stream);
JsonDbOwner *createDummyOwner( JsonStream *stream);
+
QHash<QString, JsonDbPartition *> mPartitions;
JsonDbPartition *mDefaultPartition;
JsonDbEphemeralPartition *mEphemeralPartition;
QMap<QString, JsonDbNotification *> mNotificationMap;
QMultiMap<QString, JsonDbNotification *> mKeyedNotifications;
- QMap<QString,QSet<QString> > mEagerViewSourceTypes; // set of eager view types dependent on this source type
+ class EdgeCount {
+ public:
+ EdgeCount() : count(0){};
+ int count;
+ bool operator >(int val) const { return count > val; }
+ bool operator ==(int val) const { return count == val; }
+ EdgeCount &operator +=(int delta) { count += delta; if (count < 0) count = 0; return *this; }
+ };
+ typedef QHash<QString, EdgeCount> ViewEdgeWeights;
+ typedef QHash<QString, ViewEdgeWeights> WeightedSourceViewGraph;
+ QHash<QString, WeightedSourceViewGraph> mEagerViewSourceGraph; // per partition graph with weighted edges from source to target types
quint16 mTcpServerPort;
QLocalServer *mServer;
QTcpServer *mTcpServer;
@@ -133,13 +150,9 @@ private:
JsonDbOwner *mOwner;
QMap<QIODevice*,JsonDbOwner*> mOwners;
QMap<QString,JsonStream *> mNotifications; // maps notification Id to socket
- QString mFilePath; // Directory where database files shall be stored
- QString mBaseName; // Prefix to use in database file names
bool mCompactOnClose;
};
-QT_END_NAMESPACE_JSONDB
-
QT_END_HEADER
#endif // DBSERVER_H
diff --git a/src/daemon/jsondbephemeralpartition.cpp b/src/daemon/jsondbephemeralpartition.cpp
index 989748f4..a786394a 100644
--- a/src/daemon/jsondbephemeralpartition.cpp
+++ b/src/daemon/jsondbephemeralpartition.cpp
@@ -43,13 +43,12 @@
#include "jsondbobject.h"
#include "jsondbquery.h"
-#include "jsondbresponse.h"
-#include "jsondb-error.h"
-#include "jsondb-strings.h"
+#include "jsondberrors.h"
+#include "jsondbstrings.h"
#include <qjsonobject.h>
-QT_BEGIN_NAMESPACE_JSONDB
+QT_USE_NAMESPACE_JSONDB_PARTITION
JsonDbEphemeralPartition::JsonDbEphemeralPartition(const QString &name, QObject *parent) :
QObject(parent)
@@ -98,6 +97,7 @@ JsonDbQueryResult JsonDbEphemeralPartition::queryObjects(const JsonDbOwner *owne
JsonDbWriteResult JsonDbEphemeralPartition::updateObjects(const JsonDbOwner *owner, const JsonDbObjectList &objects, JsonDbPartition::WriteMode mode)
{
+ Q_UNUSED(mode);
JsonDbWriteResult result;
QList<JsonDbUpdate> updated;
@@ -149,5 +149,3 @@ JsonDbWriteResult JsonDbEphemeralPartition::updateObjects(const JsonDbOwner *own
emit objectsUpdated(updated);
return result;
}
-
-QT_END_NAMESPACE_JSONDB
diff --git a/src/daemon/jsondbephemeralpartition.h b/src/daemon/jsondbephemeralpartition.h
index 8d68477d..e5ed8083 100644
--- a/src/daemon/jsondbephemeralpartition.h
+++ b/src/daemon/jsondbephemeralpartition.h
@@ -53,9 +53,11 @@
QT_BEGIN_HEADER
-QT_BEGIN_NAMESPACE_JSONDB
-
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
class JsonDbQuery;
+QT_END_NAMESPACE_JSONDB_PARTITION
+
+QT_USE_NAMESPACE_JSONDB_PARTITION
class JsonDbEphemeralPartition : public QObject
{
@@ -79,8 +81,6 @@ private:
QString mName;
};
-QT_END_NAMESPACE_JSONDB
-
QT_END_HEADER
#endif // JSONDB_EPHEMERAL_PARTITION_H
diff --git a/src/daemon/jsondbresponse.cpp b/src/daemon/jsondbresponse.cpp
deleted file mode 100644
index d50280b9..00000000
--- a/src/daemon/jsondbresponse.cpp
+++ /dev/null
@@ -1,117 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QMap>
-#include <QDebug>
-
-#include "jsondbresponse.h"
-#include "jsondbsettings.h"
-#include "jsondb-strings.h"
-#include <qjsonobject.h>
-#include <qjsonvalue.h>
-
-QT_BEGIN_NAMESPACE_JSONDB
-
-void JsonDbResponse::setError(QJsonObject &map, int code, const QString &message)
-{
- map.insert(JsonDbString::kCodeStr, QJsonValue(code));
- map.insert(JsonDbString::kMessageStr, message);
-}
-
-QJsonObject JsonDbResponse::makeError(int code, const QString &message)
-{
- QJsonObject map;
- setError(map, code, message);
- return map;
-}
-
-QJsonObject JsonDbResponse::makeResponse(QJsonObject &resultmap, QJsonObject &errormap, bool silent)
-{
- QJsonObject map;
- if (jsondbSettings->debug() && !silent && !errormap.isEmpty()) {
- qCritical() << errormap;
- }
- if (!resultmap.isEmpty())
- map.insert( JsonDbString::kResultStr, resultmap);
- else
- map.insert( JsonDbString::kResultStr, QJsonValue());
-
- if (!errormap.isEmpty())
- map.insert( JsonDbString::kErrorStr, errormap );
- else
- map.insert( JsonDbString::kErrorStr, QJsonValue());
- return map;
-}
-
-QJsonObject JsonDbResponse::makeResponse(QJsonObject &resultmap)
-{
- QJsonObject map;
- if (!resultmap.isEmpty())
- map.insert( JsonDbString::kResultStr, resultmap);
- else
- map.insert( JsonDbString::kResultStr, QJsonValue());
-
- map.insert( JsonDbString::kErrorStr, QJsonValue());
- return map;
-}
-
-QJsonObject JsonDbResponse::makeErrorResponse(QJsonObject &resultmap,
- int code, const QString &message, bool silent)
-{
- QJsonObject errormap;
- setError(errormap, code, message);
- return makeResponse(resultmap, errormap, silent);
-}
-
-QJsonObject JsonDbResponse::makeErrorResponse(int code, const QString &message, bool silent)
-{
- QJsonObject resultmap, errormap;
- setError(errormap, code, message);
- return makeResponse(resultmap, errormap, silent);
-}
-
-bool JsonDbResponse::responseIsError(QJsonObject responseMap)
-{
- return responseMap.contains(JsonDbString::kErrorStr)
- && (responseMap.value(JsonDbString::kErrorStr).type() == QJsonValue::Object);
-}
-
-QT_END_NAMESPACE_JSONDB
diff --git a/src/daemon/jsondbsignals.cpp b/src/daemon/jsondbsignals.cpp
index c27b5f43..15ef8b1b 100644
--- a/src/daemon/jsondbsignals.cpp
+++ b/src/daemon/jsondbsignals.cpp
@@ -119,5 +119,3 @@ void JsonDbSignals::handleSig()
}
mNotifier->setEnabled(true);
}
-
-
diff --git a/src/daemon/jsondbsignals.h b/src/daemon/jsondbsignals.h
index 95b52ce2..2973cd8f 100644
--- a/src/daemon/jsondbsignals.h
+++ b/src/daemon/jsondbsignals.h
@@ -42,7 +42,6 @@
#ifndef JSONDB_SIGNALS_H
#define JSONDB_SIGNALS_H
-#include "jsondb-global.h"
#include <QObject>
QT_BEGIN_HEADER
@@ -51,6 +50,7 @@ QT_BEGIN_NAMESPACE
class QSocketNotifier;
QT_END_NAMESPACE
+
class JsonDbSignals : public QObject
{
Q_OBJECT
diff --git a/src/daemon/main.cpp b/src/daemon/main.cpp
index a79a2289..4370e123 100644
--- a/src/daemon/main.cpp
+++ b/src/daemon/main.cpp
@@ -50,6 +50,7 @@
#include <stdio.h>
#include <string.h>
+#include "jsondbpartitionglobal.h"
#include "jsondbsettings.h"
#include "jsondbsignals.h"
#include "dbserver.h"
@@ -60,11 +61,7 @@
QString progname;
-QT_BEGIN_NAMESPACE_JSONDB
-
-QT_END_NAMESPACE_JSONDB
-
-QT_USE_NAMESPACE_JSONDB
+QT_USE_NAMESPACE_JSONDB_PARTITION
/***************************************************************************/
@@ -113,8 +110,6 @@ static void usage()
{
cout << "Usage: " << qPrintable(progname) << " [OPTIONS] [FILENAME]" << endl
<< endl
- << " -dbdir Directory to use for database files. $HOME/.jsondb is the default." << endl
- << " -base-name Basename/prefix to be used in database files. Username of the process is the default." << endl
#ifdef Q_OS_LINUX
<< " -daemon Run as a daemon process" << endl
<< " -sigstop Send SIGSTOP to self when ready to notify upstart" << endl
@@ -164,10 +159,8 @@ int main(int argc, char * argv[])
QCoreApplication::setOrganizationDomain("nrcc.noklab.com");
QCoreApplication::setApplicationName("jsondb");
QCoreApplication::setApplicationVersion("1.0");
- QString arguments;
QString pidFileName;
- QString baseName;
- QString filePath;
+ QString searchPath;
quint16 port = 0;
bool clear = false;
rlim_t limit = 0;
@@ -227,9 +220,11 @@ int main(int argc, char * argv[])
} else if (arg == "-clear") {
clear = true;
} else if (arg == "-base-name") {
- baseName = args.takeFirst();
+ args.removeAt(0);
+ qWarning() << QLatin1String("The -base-name argument is no longer supported");
} else if (arg == "-dbdir") {
- filePath = args.takeFirst();
+ args.removeAt(0);
+ qWarning() << QLatin1String("The -dbdir argument is no longer supported");
} else if (arg == "-log-file") {
logFileName = args.takeFirst();
} else {
@@ -252,14 +247,8 @@ int main(int argc, char * argv[])
// FIXME: we should either support passing in the file or not
// missing dbdir and base-name with the file name is just bad
- if (args.size() == 1) {
- if (filePath.isEmpty()) {
- filePath = args.takeFirst();
- } else {
- qCritical() << "Cannot specify the file name in combination with -dbdir";
- usage();
- }
- }
+ if (args.size() == 1)
+ searchPath = args.takeFirst();
if (!args.isEmpty())
usage();
@@ -274,7 +263,7 @@ int main(int argc, char * argv[])
qInstallMsgHandler(logMessageOutput);
}
- DBServer server(filePath, baseName);
+ DBServer server(searchPath);
if (port)
server.setTcpServerPort(port);
JsonDbSignals handler;
diff --git a/src/imports/jsondb-listmodel/jsondb-listmodel.pro b/src/imports/jsondb-listmodel/jsondb-listmodel.pro
index 9e86677c..cfa60add 100644
--- a/src/imports/jsondb-listmodel/jsondb-listmodel.pro
+++ b/src/imports/jsondb-listmodel/jsondb-listmodel.pro
@@ -18,6 +18,7 @@ INSTALLS += target qmldir
qtPrepareTool(QMLPLUGINDUMP, qmlplugindump)
QMLTYPESFILE = $$QT.jsondb.imports/$$TARGETPATH/plugin.qmltypes
mac: !exists($$QMLPLUGINDUMP): QMLPLUGINDUMP = "$${QMLPLUGINDUMP}.app/Contents/MacOS/qmlplugindump"
+ unix:!mac: QMLPLUGINDUMP = "$${QMLPLUGINDUMP} -platform minimal"
QMAKE_POST_LINK += LD_LIBRARY_PATH=$$QT.jsondb.libs $$QMLPLUGINDUMP QtAddOn.JsonDb 1.0 $$QT.jsondb.imports > $$QMLTYPESFILE
qmltypes.files = $$QMLTYPESFILE
@@ -27,19 +28,15 @@ INSTALLS += target qmldir
VERSION = 1.0
-include(../../common/common.pri)
-
HEADERS += \
jsondb-listmodel.h \
jsondb-listmodel_p.h \
jsondb-component.h \
plugin.h
-HEADERS += $$QSONCONVERSION_HEADERS
-
SOURCES += \
jsondb-listmodel.cpp \
jsondb-component.cpp \
plugin.cpp
-SOURCES += $$QSONCONVERSION_SOURCES
+OTHER_FILES += jsondb.json
diff --git a/src/imports/jsondb-listmodel/jsondb.json b/src/imports/jsondb-listmodel/jsondb.json
new file mode 100644
index 00000000..0967ef42
--- /dev/null
+++ b/src/imports/jsondb-listmodel/jsondb.json
@@ -0,0 +1 @@
+{}
diff --git a/src/imports/jsondb-listmodel/plugin.cpp b/src/imports/jsondb-listmodel/plugin.cpp
index 3bd57634..28554c08 100644
--- a/src/imports/jsondb-listmodel/plugin.cpp
+++ b/src/imports/jsondb-listmodel/plugin.cpp
@@ -45,9 +45,6 @@
#include "jsondb-component.h"
#include "jsondb-listmodel.h"
-Q_EXPORT_STATIC_PLUGIN(JsonDbListModelPlugin)
-Q_EXPORT_PLUGIN2(jsondblistmodelplugin, JsonDbListModelPlugin)
-
void JsonDbListModelPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
{
Q_UNUSED(engine);
diff --git a/src/imports/jsondb-listmodel/plugin.h b/src/imports/jsondb-listmodel/plugin.h
index 68b28ab6..e6e88b3f 100644
--- a/src/imports/jsondb-listmodel/plugin.h
+++ b/src/imports/jsondb-listmodel/plugin.h
@@ -47,12 +47,12 @@
class JsonDbListModelPlugin : public QQmlExtensionPlugin
{
- Q_OBJECT
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface" FILE "jsondb.json")
- public:
-
- void initializeEngine(QQmlEngine *engine, const char *uri);
- void registerTypes(const char *uri);
+public:
+ void initializeEngine(QQmlEngine *engine, const char *uri);
+ void registerTypes(const char *uri);
};
#endif
diff --git a/src/imports/jsondb/jsondatabase.cpp b/src/imports/jsondb/jsondatabase.cpp
index 491fe85d..3d784287 100644
--- a/src/imports/jsondb/jsondatabase.cpp
+++ b/src/imports/jsondb/jsondatabase.cpp
@@ -41,22 +41,15 @@
#include "jsondatabase.h"
#include "jsondbpartition.h"
-#include "jsondb-object.h"
#include <QJSEngine>
#include <QQmlEngine>
+#include <qjsondbobject.h>
+#include <qjsondbconnection.h>
#include <qdebug.h>
QT_BEGIN_NAMESPACE_JSONDB
-struct Uuid
-{
- uint data1;
- ushort data2;
- ushort data3;
- uchar data4[8];
-};
-
-static const Uuid JsonDbNamespace = {0x6ba7b810, 0x9dad, 0x11d1, { 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} };
+QPointer<QJsonDbConnection> JsonDatabase::connection(0);
/*!
\qmlclass JsonDatabase
@@ -70,13 +63,6 @@ static const Uuid JsonDbNamespace = {0x6ba7b810, 0x9dad, 0x11d1, { 0x80, 0xb4, 0
JsonDatabase::JsonDatabase(QObject *parent)
:QObject(parent)
{
- connect(&jsonDb, SIGNAL(response(int,const QVariant&)),
- this, SLOT(dbResponse(int,const QVariant&)),
- Qt::QueuedConnection);
- connect(&jsonDb, SIGNAL(error(int,int,QString)),
- this, SLOT(dbErrorResponse(int,int,QString)),
- Qt::QueuedConnection);
-
}
JsonDatabase::~JsonDatabase()
@@ -133,9 +119,18 @@ void JsonDatabase::listPartitions(const QJSValue &listCallback)
qWarning() << "Invalid callback specified.";
return;
}
- QString query(QLatin1String("[?_type=\"Partition\"]"));
- int id = jsonDb.query(query, 0, -1);
- listCallbacks.insert(id, listCallback);
+
+ QJsonDbReadRequest *request = new QJsonDbReadRequest;
+ request->setQuery(QLatin1String("[?_type=\"Partition\"]"));
+ request->setPartition(QLatin1String("Ephemeral"));
+ connect(request, SIGNAL(finished()), this, SLOT(onQueryFinished()));
+ connect(request, SIGNAL(finished()), request, SLOT(deleteLater()));
+ connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ this, SLOT(onQueryError(QtJsonDb::QJsonDbRequest::ErrorCode,QString)));
+ connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ request, SLOT(deleteLater()));
+ sharedConnection().send(request);
+ listCallbacks.insert(request, listCallback);
}
/*!
@@ -156,29 +151,23 @@ void JsonDatabase::listPartitions(const QJSValue &listCallback)
QString JsonDatabase::uuidFromString(const QString &identifier)
{
- const QUuid ns(JsonDbNamespace.data1, JsonDbNamespace.data2, JsonDbNamespace.data3,
- JsonDbNamespace.data4[0], JsonDbNamespace.data4[1], JsonDbNamespace.data4[2],
- JsonDbNamespace.data4[3], JsonDbNamespace.data4[4], JsonDbNamespace.data4[5],
- JsonDbNamespace.data4[6], JsonDbNamespace.data4[7]);
- return QUuid::createUuidV3(ns, identifier).toString();
+ return QJsonDbObject::createUuidFromString(identifier).toString();
}
-void JsonDatabase::dbResponse(int id, const QVariant &result)
+void JsonDatabase::onQueryFinished()
{
- if (listCallbacks.contains(id)) {
- // Make sure that id exists in the map.
- QJSValue callback = listCallbacks[id];
+ QJsonDbReadRequest *request = qobject_cast<QJsonDbReadRequest *>(sender());
+ if (listCallbacks.contains(request)) {
+ QJSValue callback = listCallbacks[request];
QJSEngine *engine = callback.engine();
QJSValueList args;
args << QJSValue(QJSValue::UndefinedValue);
- QVariantMap objectMap = result.toMap();
- if (objectMap.contains(QLatin1String("data"))) {
- QVariantList items = objectMap.value(QLatin1String("data")).toList();
- int count = items.count();
+ QList<QJsonObject> objects = request->takeResults();
+ int count = objects.count();
+ if (count) {
QJSValue response = engine->newArray(count);
for (int i = 0; i < count; ++i) {
- QVariantMap object = items.at(i).toMap();
- QString partitionName = object.value(QLatin1String("name")).toString();
+ QString partitionName = objects[i].value(QLatin1String("name")).toString();
response.setProperty(i, engine->newQObject(partition(partitionName)));
}
args << response;
@@ -186,14 +175,15 @@ void JsonDatabase::dbResponse(int id, const QVariant &result)
args << engine->newArray();
}
callback.call(args);
- listCallbacks.remove(id);
+ listCallbacks.remove(request);
}
}
-void JsonDatabase::dbErrorResponse(int id, int code, const QString &message)
+void JsonDatabase::onQueryError(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString &message)
{
- if (listCallbacks.contains(id)) {
- QJSValue callback = listCallbacks[id];
+ QJsonDbReadRequest *request = qobject_cast<QJsonDbReadRequest *>(sender());
+ if (listCallbacks.contains(request)) {
+ QJSValue callback = listCallbacks[request];
QJSEngine *engine = callback.engine();
QJSValueList args;
@@ -204,9 +194,19 @@ void JsonDatabase::dbErrorResponse(int id, int code, const QString &message)
args << engine->toScriptValue(QVariant(error))<< engine->newArray();
callback.call(args);
- listCallbacks.remove(id);
+ listCallbacks.remove(request);
}
}
+QJsonDbConnection& JsonDatabase::sharedConnection()
+{
+ if (!connection) {
+ connection = QJsonDbConnection::defaultConnection();
+ connection->connectToServer();
+ }
+ return *connection;
+}
+
+
#include "moc_jsondatabase.cpp"
QT_END_NAMESPACE_JSONDB
diff --git a/src/imports/jsondb/jsondatabase.h b/src/imports/jsondb/jsondatabase.h
index a1803a81..19ae5a43 100644
--- a/src/imports/jsondb/jsondatabase.h
+++ b/src/imports/jsondb/jsondatabase.h
@@ -45,7 +45,9 @@
#include <QObject>
#include <QJSValue>
#include <QPointer>
-#include "jsondb-client.h"
+#include <QMap>
+#include <QJsonDbConnection>
+#include <QJsonDbReadRequest>
QT_BEGIN_NAMESPACE_JSONDB
@@ -61,14 +63,15 @@ public:
Q_INVOKABLE JsonDbPartition* partition(const QString &partitionName);
Q_INVOKABLE void listPartitions(const QJSValue &callback);
Q_INVOKABLE QString uuidFromString(const QString &identifier);
+ static QJsonDbConnection& sharedConnection();
private Q_SLOTS:
- void dbResponse(int id, const QVariant &result);
- void dbErrorResponse(int id, int code, const QString &message);
+ void onQueryFinished();
+ void onQueryError(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString &message);
private:
- QMap<int, QJSValue> listCallbacks;
- JsonDbClient jsonDb;
+ QMap<QJsonDbReadRequest*, QJSValue> listCallbacks;
+ static QPointer<QJsonDbConnection> connection;
};
QT_END_NAMESPACE_JSONDB
diff --git a/src/imports/jsondb/jsondb.json b/src/imports/jsondb/jsondb.json
new file mode 100644
index 00000000..0967ef42
--- /dev/null
+++ b/src/imports/jsondb/jsondb.json
@@ -0,0 +1 @@
+{}
diff --git a/src/imports/jsondb/jsondb.pro b/src/imports/jsondb/jsondb.pro
index 781e3d1d..1f6e7f4a 100644
--- a/src/imports/jsondb/jsondb.pro
+++ b/src/imports/jsondb/jsondb.pro
@@ -3,9 +3,9 @@ TARGETPATH = QtJsonDb
include(../qimportbase.pri)
-QT += network qml jsondbcompat-private
+QT += network qml jsondb jsondb-private
-DESTDIR = $$QT.jsondbcompat.imports/$$TARGETPATH
+DESTDIR = $$QT.jsondb.imports/$$TARGETPATH
target.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH
qmldir.files += $$PWD/qmldir
@@ -17,8 +17,9 @@ INSTALLS += target qmldir
!cross_compile {
qtPrepareTool(QMLPLUGINDUMP, qmlplugindump)
mac: !exists($$QMLPLUGINDUMP): QMLPLUGINDUMP = "$${QMLPLUGINDUMP}.app/Contents/MacOS/qmlplugindump"
- QMLTYPESFILE = $$QT.jsondbcompat.imports/$$TARGETPATH/plugin.qmltypes
- QMAKE_POST_LINK += LD_LIBRARY_PATH=$$QT.jsondbcompat.libs $$QMLPLUGINDUMP QtJsonDb 1.0 $$QT.jsondbcompat.imports > $$QMLTYPESFILE
+ unix:!mac: QMLPLUGINDUMP = "$${QMLPLUGINDUMP} -platform minimal"
+ QMLTYPESFILE = $$QT.jsondb.imports/$$TARGETPATH/plugin.qmltypes
+ QMAKE_POST_LINK += LD_LIBRARY_PATH=$$QT.jsondb.libs $$QMLPLUGINDUMP QtJsonDb 1.0 $$QT.jsondb.imports > $$QMLTYPESFILE
qmltypes.files = $$QMLTYPESFILE
qmltypes.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH
@@ -27,37 +28,31 @@ INSTALLS += target qmldir
VERSION = 1.0
-include(../../common/common.pri)
-
HEADERS += \
jsondbpartition.h \
jsondbnotification.h \
- jsondbsortinglistmodel.h \
- jsondbsortinglistmodel_p.h \
- jsondblistmodel.h \
- jsondblistmodel_p.h \
plugin.h \
jsondatabase.h \
jsondbqueryobject.h \
- jsondbchangessinceobject.h \
+ jsondbmodelutils.h \
jsondbmodelcache.h \
+ jsondblistmodel.h \
+ jsondblistmodel_p.h \
+ jsondbsortinglistmodel_p.h \
+ jsondbsortinglistmodel.h \
jsondbcachinglistmodel_p.h \
- jsondbcachinglistmodel.h \
- jsondbmodelutils.h
-
-HEADERS += $$QSONCONVERSION_HEADERS
+ jsondbcachinglistmodel.h
SOURCES += \
jsondbpartition.cpp \
jsondbnotification.cpp \
- jsondbsortinglistmodel.cpp \
- jsondblistmodel.cpp \
plugin.cpp \
jsondatabase.cpp \
jsondbqueryobject.cpp \
- jsondbchangessinceobject.cpp \
- jsondbcachinglistmodel.cpp \
+ jsondbmodelutils.cpp \
jsondbmodelcache.cpp \
- jsondbmodelutils.cpp
+ jsondblistmodel.cpp \
+ jsondbsortinglistmodel.cpp \
+ jsondbcachinglistmodel.cpp
-SOURCES += $$QSONCONVERSION_SOURCES
+OTHER_FILES += jsondb.json
diff --git a/src/imports/jsondb/jsondbcachinglistmodel.cpp b/src/imports/jsondb/jsondbcachinglistmodel.cpp
index c34617c7..afcec554 100644
--- a/src/imports/jsondb/jsondbcachinglistmodel.cpp
+++ b/src/imports/jsondb/jsondbcachinglistmodel.cpp
@@ -40,15 +40,18 @@
****************************************************************************/
//#define JSONDB_LISTMODEL_DEBUG
+//#define JSONDB_LISTMODEL_BENCHMARK
#include "jsondbcachinglistmodel.h"
#include "jsondbcachinglistmodel_p.h"
-#include "private/jsondb-strings_p.h"
#include "plugin.h"
#include <QJSEngine>
#include <QJSValueIterator>
#include <QDebug>
+#ifdef JSONDB_LISTMODEL_BENCHMARK
+#include <QElapsedTimer>
+#endif
/*!
\internal
@@ -70,13 +73,6 @@ JsonDbCachingListModelPrivate::JsonDbCachingListModelPrivate(JsonDbCachingListMo
void JsonDbCachingListModelPrivate::init()
{
- Q_Q(JsonDbCachingListModel);
- q->connect(&dbClient, SIGNAL(response(int,const QVariant&)),
- q, SLOT(_q_jsonDbResponse(int,const QVariant&)),
- Qt::QueuedConnection);
- q->connect(&dbClient, SIGNAL(error(int,int,const QString&)),
- q, SLOT(_q_jsonDbErrorResponse(int,int,const QString&)),
- Qt::QueuedConnection);
}
void JsonDbCachingListModelPrivate::setCacheParams(int maxItems)
@@ -84,18 +80,29 @@ void JsonDbCachingListModelPrivate::setCacheParams(int maxItems)
objectCache.setPageSize(maxItems);
chunkSize = objectCache.chunkSize();
lowWaterMark = objectCache.chunkSize()/4;
- //lowWaterMark = objectCache.pageSize/4;
}
JsonDbCachingListModelPrivate::~JsonDbCachingListModelPrivate()
{
- // Why do we need to do this while destroying the object
clearNotifications();
+ while (!keyRequests.isEmpty()) {
+ delete keyRequests[0];
+ keyRequests.removeFirst();
+ }
+ while (!indexRequests.isEmpty()) {
+ delete indexRequests[0];
+ indexRequests.removeFirst();
+ }
+ while (!valueRequests.isEmpty()) {
+ delete valueRequests[0];
+ valueRequests.removeFirst();
+ }
+
}
// insert item notification handler
// + add items, for chunked read
-void JsonDbCachingListModelPrivate::addItem(const QVariantMap &item, int partitionIndex)
+void JsonDbCachingListModelPrivate::addItem(const QJsonObject &item, int partitionIndex)
{
Q_Q(JsonDbCachingListModel);
const QString &uuid = item.value(QLatin1String("_uuid")).toString();
@@ -103,7 +110,10 @@ void JsonDbCachingListModelPrivate::addItem(const QVariantMap &item, int partiti
if (objectSortValues.contains(uuid))
return;
- SortingKey key(partitionIndex, item, ascendingOrders, orderPaths, partitionIndexDetails[0].spec);
+ QVariantList vl;
+ vl.append(uuid);
+ vl.append(item.value(QLatin1String("_indexValue")).toVariant());
+ SortingKey key(partitionIndex, vl, QList<bool>() << ascendingOrder, partitionIndexDetails[partitionIndex].spec);
QMap<SortingKey, QString>::const_iterator begin = objectUuids.constBegin();
QMap<SortingKey, QString>::const_iterator end = objectUuids.constEnd();
QMap<SortingKey, QString>::const_iterator i = objectUuids.upperBound(key);
@@ -120,7 +130,7 @@ void JsonDbCachingListModelPrivate::addItem(const QVariantMap &item, int partiti
// deleteitem notification handler
-void JsonDbCachingListModelPrivate::deleteItem(const QVariantMap &item, int partitionIndex)
+void JsonDbCachingListModelPrivate::deleteItem(const QJsonObject &item, int partitionIndex)
{
Q_Q(JsonDbCachingListModel);
QString uuid = item.value(QLatin1String("_uuid")).toString();
@@ -144,14 +154,17 @@ void JsonDbCachingListModelPrivate::deleteItem(const QVariantMap &item, int part
}
// updateitem notification handler
-void JsonDbCachingListModelPrivate::updateItem(const QVariantMap &item, int partitionIndex)
+void JsonDbCachingListModelPrivate::updateItem(const QJsonObject &item, int partitionIndex)
{
Q_Q(JsonDbCachingListModel);
QString uuid = item.value(QLatin1String("_uuid")).toString();
QMap<QString, SortingKey>::const_iterator keyIndex = objectSortValues.constFind(uuid);
if (keyIndex != objectSortValues.constEnd()) {
SortingKey key = keyIndex.value();
- SortingKey newKey(partitionIndex, item, ascendingOrders, orderPaths, partitionIndexDetails[0].spec);
+ QVariantList vl;
+ vl.append(uuid);
+ vl.append(item.value(QLatin1String("_indexValue")).toVariant());
+ SortingKey newKey(partitionIndex, vl, QList<bool>() << ascendingOrder, partitionIndexDetails[partitionIndex].spec);
QMap<SortingKey, QString>::const_iterator begin = objectUuids.constBegin();
QMap<SortingKey, QString>::const_iterator end = objectUuids.constEnd();
QMap<SortingKey, QString>::const_iterator oldPos = objectUuids.constFind(key);
@@ -276,55 +289,50 @@ void JsonDbCachingListModelPrivate::createObjectRequests(int startIndex, int max
r.lastOffset = indexNSizes[i].index;
r.lastSize = -1;
r.requestCount = indexNSizes[i].count;
- r.requestId = dbClient.query(query+sortOrder, indexNSizes[i].index,
- qMin(r.requestCount, chunkSize),
- partitionObjects[i]->name());
+ QJsonDbReadRequest *request = valueRequests[i]->newRequest(i);
+ request->setQuery(query+sortOrder);
+ request->setProperty("queryOffset", indexNSizes[i].index);
+ request->setQueryLimit(qMin(r.requestCount, chunkSize));
+ request->setPartition(partitionObjects[i]->name());
+ JsonDatabase::sharedConnection().send(request);
#ifdef JSONDB_LISTMODEL_DEBUG
qDebug()<<"Query"<<query+sortOrder<<partitionObjects[i]->name();
- qDebug()<<"Request "<<r.requestId <<
+ qDebug()<<"Request "<<request->property("requestId") <<
"Total Count "<<r.requestCount <<
"Offset"<<r.lastOffset<<
"Count "<<qMin(r.requestCount,chunkSize);
#endif
} else {
- r.requestId = -1;
r.lastSize = 0;
r.requestCount = 0;
}
}
- delete indexNSizes;
+ delete [] indexNSizes;
}
-void JsonDbCachingListModelPrivate::verifyIndexSpec(const QVariant &v, int partitionIndex)
+void JsonDbCachingListModelPrivate::verifyIndexSpec(const QList<QJsonObject> &items, int partitionIndex)
{
Q_Q(JsonDbCachingListModel);
- QVariantMap m = v.toMap();
- QVariantList items;
- if (m.contains(QLatin1String("data")))
- items = m.value(QLatin1String("data")).toList();
SortIndexSpec &indexSpec = partitionIndexDetails[partitionIndex].spec;
- QString propertyFunction;
- QString indexName;
bool validIndex = false;
- if (orderProperties.count())
- indexName = orderProperties[0];
if (items.count()) {
- QVariantMap spec = items[0].toMap();
- indexSpec.propertyName = spec.value(QLatin1String("propertyName")).toString();
- indexSpec.propertyType = spec.value(QLatin1String("propertyType")).toString();
+ QJsonObject spec = items[0];
+ indexSpec.propertyName = QLatin1String("_indexValue");
+ QString propertyType = spec.value(QLatin1String("propertyType")).toString();
indexSpec.name = spec.value(QLatin1String("name")).toString();
- propertyFunction = spec.value(QLatin1String("propertyFunction")).toString();
+ indexSpec.caseSensitive = true;
if (!indexName.isEmpty()) {
if (indexSpec.name == indexName) {
- validIndex = true;
- if (!indexSpec.propertyType.compare(QLatin1String("string"), Qt::CaseInsensitive)) {
+ if (!propertyType.compare(QLatin1String("string"), Qt::CaseInsensitive)) {
indexSpec.type = SortIndexSpec::String;
- indexSpec.caseSensitive = true;
+ validIndex = true;
+ } else if (!propertyType.compare(QLatin1String("number"), Qt::CaseInsensitive)) {
+ indexSpec.type = SortIndexSpec::Number;
+ validIndex = true;
+ } else if (!propertyType.compare(QLatin1String("UUID"), Qt::CaseInsensitive)) {
+ indexSpec.type = SortIndexSpec::UUID;
+ validIndex = true;
}
- if (indexSpec.propertyName.isEmpty())
- validIndex = false;
- if (!propertyFunction.isEmpty())
- validIndex = false; // Cannot support property functions
}
}
}
@@ -345,7 +353,6 @@ void JsonDbCachingListModelPrivate::verifyIndexSpec(const QVariant &v, int parti
}
if (checkedAll) {
//Start fetching the keys.
- orderProperties[0] = indexSpec.propertyName;
setQueryForSortKeys();
for (int i = 0; i < partitionKeyRequestDetails.count(); i++) {
fetchPartitionKeys(i);
@@ -354,32 +361,17 @@ void JsonDbCachingListModelPrivate::verifyIndexSpec(const QVariant &v, int parti
}
}
-void JsonDbCachingListModelPrivate::fillKeys(const QVariant &v, int partitionIndex)
+void JsonDbCachingListModelPrivate::fillKeys(const QList<QJsonObject> &items, int partitionIndex)
{
- Q_Q(JsonDbCachingListModel);
- QVariantMap m = v.toMap();
- QVariantList items;
- if (m.contains(QLatin1String("data")))
- items = m.value(QLatin1String("data")).toList();
- // Check if the sort key is same as requested.
- // We can only support this model if an index is present
- if (m.contains(QLatin1String("sortKeys"))) {
- const QVariantList &sortKeys = m.value(QLatin1String("sortKeys")).toList();
- if (!(sortKeys.count() && sortKeys[0].toString() == orderProperties[0])) {
- qWarning() << "Error JsonDbCachingListModel requires Index for "<<orderProperties[0]<<" Sort Keys"<<sortKeys;
- reset();
- state = JsonDbCachingListModel::Error;
- emit q->stateChanged(state);
- return;
- }
- }
RequestInfo &r = partitionKeyRequestDetails[partitionIndex];
r.lastSize = items.size();
for (int i = 0; i < r.lastSize; i++) {
- const QVariantList &item = items.at(i).toList();
- const QString &uuid = item.at(0).toString();
-
- SortingKey key(partitionIndex, item, ascendingOrders, partitionIndexDetails[0].spec);
+ const QJsonObject &item = items.at(i);
+ const QString &uuid = item.value(QLatin1String("_uuid")).toString();
+ QVariantList vl;
+ vl.append(uuid);
+ vl.append(item.value(QLatin1String("_indexValue")).toVariant());
+ SortingKey key(partitionIndex, vl, QList<bool>() << ascendingOrder, partitionIndexDetails[partitionIndex].spec);
objectUuids.insert(key, uuid);
partitionObjectUuids[partitionIndex].insert(key, uuid);
objectSortValues.insert(uuid, key);
@@ -389,7 +381,7 @@ void JsonDbCachingListModelPrivate::fillKeys(const QVariant &v, int partitionInd
// all the results
bool allRequestsFinished = true;
for (int i = 0; i < partitionKeyRequestDetails.count(); i++) {
- if (partitionKeyRequestDetails[i].lastSize >= chunkSize*2 || partitionKeyRequestDetails[i].lastSize == -1) {
+ if (partitionKeyRequestDetails[i].lastSize >= chunkSize || partitionKeyRequestDetails[i].lastSize == -1) {
allRequestsFinished = false;
break;
}
@@ -401,12 +393,12 @@ void JsonDbCachingListModelPrivate::fillKeys(const QVariant &v, int partitionInd
#endif
if (!objectUuids.count()) {
for (int i = 0; i<partitionObjectDetails.count(); i++) {
- fillData(QVariant(), i);
+ fillData(QList<QJsonObject>(), i);
}
return;
}
createObjectRequests(0, qMin(objectCache.maxItems(), objectUuids.count()));
- } else if (r.lastSize >= chunkSize*2){
+ } else if (r.lastSize >= chunkSize){
// more items, fetch next chunk of keys
fetchNextKeyChunk(partitionIndex);
}
@@ -420,20 +412,16 @@ void JsonDbCachingListModelPrivate::emitDataChanged(int from, int to)
emit q->dataChanged(modelIndexFrom, modelIndexTo);
}
-void JsonDbCachingListModelPrivate::fillData(const QVariant &v, int partitionIndex)
+void JsonDbCachingListModelPrivate::fillData(const QList<QJsonObject> &items, int partitionIndex)
{
Q_Q(JsonDbCachingListModel);
- QVariantMap m = v.toMap();
- QVariantList items;
- if (m.contains(QLatin1String("data")))
- items = m.value(QLatin1String("data")).toList();
RequestInfo &r = partitionObjectDetails[partitionIndex];
r.lastSize = items.size();
r.requestCount -= r.lastSize;
r.lastOffset += r.lastSize;
for (int i = 0; i < r.lastSize; i++) {
- const QVariantMap &item = items.at(i).toMap();
+ const QJsonObject &item = items.at(i);
const QString &uuid = item.value(QLatin1String("_uuid")).toString();
tmpObjects.insert(uuid, item);
}
@@ -499,11 +487,11 @@ void JsonDbCachingListModelPrivate::fillData(const QVariant &v, int partitionInd
// retrieved all elements
state = JsonDbCachingListModel::Ready;
emit q->stateChanged(state);
- for (int i = 0; i < pendingNotifications.size(); i++) {
- const NotifyItem &pending = pendingNotifications[i];
- sendNotifications(pending.notifyUuid, pendingNotifications[i].item, pendingNotifications[i].action);
+ if (!pendingNotifications.isEmpty()) {
+ foreach (NotificationItem pending, pendingNotifications)
+ sendNotification(pending.partitionIndex, pending.item, pending.action);
+ pendingNotifications.clear();
}
- pendingNotifications.clear();
if (requestQueue.count()) {
QPair<int, int> req = requestQueue.takeFirst();
createObjectRequests(req.first, req.second);
@@ -550,10 +538,7 @@ void JsonDbCachingListModelPrivate::reset()
bool JsonDbCachingListModelPrivate::checkForDefaultIndexTypes(int index)
{
Q_Q(JsonDbCachingListModel);
- if (!orderProperties.count())
- return false;
bool defaultType = false;
- QString indexName = orderProperties[0];
if (!indexName.compare(QLatin1String("_uuid")) || !indexName.compare(QLatin1String("_type"))) {
defaultType = true;
QMetaObject::invokeMethod(q, "_q_verifyDefaultIndexType", Qt::QueuedConnection,
@@ -574,10 +559,12 @@ void JsonDbCachingListModelPrivate::fetchIndexSpec(int index)
state = JsonDbCachingListModel::Querying;
emit q->stateChanged(state);
}
- IndexInfo &r = partitionIndexDetails[index];
QPointer<JsonDbPartition> p = partitionObjects[index];
if (p) {
- r.requestId = dbClient.query(queryForIndexSpec, 0, -1, p->name());
+ QJsonDbReadRequest *request = indexRequests[index]->newRequest(index);
+ request->setQuery(queryForIndexSpec);
+ request->setPartition(p->name());
+ JsonDatabase::sharedConnection().send(request);
}
}
@@ -596,7 +583,11 @@ void JsonDbCachingListModelPrivate::fetchPartitionKeys(int index)
if (p) {
r.lastSize = -1;
r.lastOffset = 0;
- r.requestId = dbClient.query(queryForSortKeys, 0, chunkSize*2, p->name());
+ QJsonDbReadRequest *request = keyRequests[index]->newRequest(index);
+ request->setQuery(queryForSortKeys);
+ request->setQueryLimit(chunkSize);
+ request->setPartition(p->name());
+ JsonDatabase::sharedConnection().send(request);
}
}
@@ -610,6 +601,9 @@ void JsonDbCachingListModelPrivate::initializeModel(bool reset)
for (int i = 0; i < partitionObjectUuids.count(); i++) {
partitionObjectUuids[i].clear();
}
+ for (int i = 0; i < partitionIndexDetails.count(); i++) {
+ partitionIndexDetails[i].clear();
+ }
}
for (int i = 0; i < partitionObjects.count(); i++) {
fetchIndexSpec(i);
@@ -625,17 +619,26 @@ void JsonDbCachingListModelPrivate::fetchModel(bool reset)
void JsonDbCachingListModelPrivate::fetchNextKeyChunk(int partitionIndex)
{
RequestInfo &r = partitionKeyRequestDetails[partitionIndex];
- r.lastOffset += chunkSize*2;
- r.requestId = dbClient.query(queryForSortKeys, r.lastOffset,
- chunkSize*2, partitionObjects[partitionIndex]->name());
+ r.lastOffset += chunkSize;
+ QJsonDbReadRequest *request = keyRequests[partitionIndex]->newRequest(partitionIndex);
+ request->setQuery(queryForSortKeys);
+ request->setProperty("queryOffset", r.lastOffset);
+ request->setQueryLimit(chunkSize);
+ request->setPartition(partitionObjects[partitionIndex]->name());
+ JsonDatabase::sharedConnection().send(request);
+
}
void JsonDbCachingListModelPrivate::fetchNextChunk(int partitionIndex)
{
RequestInfo &r = partitionObjectDetails[partitionIndex];
- r.requestId = dbClient.query(query+sortOrder, r.lastOffset,
- qMin(r.requestCount, chunkSize),
- partitionObjects[partitionIndex]->name());
+ QJsonDbReadRequest *request = valueRequests[partitionIndex]->newRequest(partitionIndex);
+ request->setQuery(query+sortOrder);
+ request->setProperty("queryOffset", r.lastOffset);
+ request->setQueryLimit(qMin(r.requestCount, chunkSize));
+ request->setPartition(partitionObjects[partitionIndex]->name());
+ JsonDatabase::sharedConnection().send(request);
+
}
void JsonDbCachingListModelPrivate::prefetchNearbyPages(int index)
@@ -688,15 +691,14 @@ void JsonDbCachingListModelPrivate::requestPageContaining(int index)
}
-
void JsonDbCachingListModelPrivate::clearNotification(int index)
{
if (index >= partitionObjects.count())
return;
RequestInfo &r = partitionObjectDetails[index];
- if (!r.notifyUuid.isEmpty()) {
- dbClient.unregisterNotification(r.notifyUuid);
+ if (r.watcher) {
+ JsonDatabase::sharedConnection().removeWatcher(r.watcher);
}
r.clear();
}
@@ -713,13 +715,16 @@ void JsonDbCachingListModelPrivate::createOrUpdateNotification(int index)
if (index >= partitionObjects.count())
return;
clearNotification(index);
- JsonDbClient::NotifyTypes notifyActions = JsonDbClient::NotifyCreate
- | JsonDbClient::NotifyUpdate| JsonDbClient::NotifyRemove;
- partitionObjectDetails[index].notifyUuid= dbClient.registerNotification(
- notifyActions , query, partitionObjects[index]->name(),
- q, SLOT(_q_dbNotified(QString,QtAddOn::JsonDb::JsonDbNotification)),
- q, SLOT(_q_dbNotifyReadyResponse(int,QVariant)),
- SLOT(_q_dbNotifyErrorResponse(int,int,QString)));
+ QJsonDbWatcher *watcher = new QJsonDbWatcher();
+ watcher->setQuery(query+sortOrder);
+ watcher->setWatchedActions(QJsonDbWatcher::Created | QJsonDbWatcher::Updated |QJsonDbWatcher::Removed);
+ watcher->setPartition(partitionObjects[index]->name());
+ QObject::connect(watcher, SIGNAL(notificationsAvailable(int)),
+ q, SLOT(_q_notificationsAvailable()));
+ QObject::connect(watcher, SIGNAL(error(QtJsonDb::QJsonDbWatcher::ErrorCode,QString)),
+ q, SLOT(_q_notificationError(QtJsonDb::QJsonDbWatcher::ErrorCode,QString)));
+ JsonDatabase::sharedConnection().addWatcher(watcher);
+ partitionObjectDetails[index].watcher = watcher;
}
void JsonDbCachingListModelPrivate::createOrUpdateNotifications()
@@ -733,23 +738,14 @@ void JsonDbCachingListModelPrivate::parseSortOrder()
{
Q_Q(JsonDbCachingListModel);
QRegExp orderMatch("\\[([/\\\\[\\]])[ ]*([^\\[\\]]+)[ ]*\\]");
- ascendingOrders.clear();
- orderProperties.clear();
- orderPaths.clear();
- int matchIndex = 0, firstMatch = -1;
- while ((matchIndex = orderMatch.indexIn(sortOrder, matchIndex)) >= 0) {
- bool ascendingOrder = false;
+ if (orderMatch.indexIn(sortOrder, 0) >= 0) {
+ ascendingOrder = false;
if (!orderMatch.cap(1).compare(QLatin1String("/")))
ascendingOrder = true;
- ascendingOrders << ascendingOrder;
- orderProperties << orderMatch.cap(2);
- orderPaths << orderMatch.cap(2).split('.');
- if (firstMatch == -1)
- firstMatch = matchIndex;
- matchIndex += orderMatch.matchedLength();
- }
- if (orderProperties.count()) {
- queryForIndexSpec = QString(QLatin1String("[?_type=\"Index\"][?name=\"%1\"]")).arg(orderProperties[0]);
+ indexName = orderMatch.cap(2);
+ }
+ if (!indexName.isEmpty()) {
+ queryForIndexSpec = QString(QLatin1String("[?_type=\"Index\"][?name=\"%1\"]")).arg(indexName);
} else {
// Set default sort order (by _uuid)
q->setSortOrder(QLatin1String("[/_uuid]"));
@@ -760,45 +756,15 @@ void JsonDbCachingListModelPrivate::setQueryForSortKeys()
{
// Query to retrieve the sortKeys
// TODO remove the "[= {}]" from query
- queryForSortKeys = query + QLatin1String("[= [ _uuid");
- for (int i = 0; i < orderProperties.count() ; i++) {
- queryForSortKeys += QLatin1String(", ") + orderProperties[i];
- }
- queryForSortKeys += QLatin1String("]]");
+ queryForSortKeys = query + QLatin1String("[= { _uuid: _uuid");
+ queryForSortKeys += QLatin1String("}]");
queryForSortKeys += sortOrder;
}
-int JsonDbCachingListModelPrivate::indexOfKeyIndexSpecId(int requestId)
-{
- for (int i = 0; i < partitionIndexDetails.count(); i++) {
- if (requestId == partitionIndexDetails[i].requestId)
- return i;
- }
- return -1;
-}
-
-int JsonDbCachingListModelPrivate::indexOfKeyRequestId(int requestId)
-{
- for (int i = 0; i < partitionKeyRequestDetails.count(); i++) {
- if (requestId == partitionKeyRequestDetails[i].requestId)
- return i;
- }
- return -1;
-}
-
-int JsonDbCachingListModelPrivate::indexOfRequestId(int requestId)
-{
- for (int i = 0; i < partitionObjectDetails.count(); i++) {
- if (requestId == partitionObjectDetails[i].requestId)
- return i;
- }
- return -1;
-}
-
-int JsonDbCachingListModelPrivate::indexOfNotifyUUID(const QString& notifyUuid)
+int JsonDbCachingListModelPrivate::indexOfWatcher(QJsonDbWatcher *watcher)
{
for (int i = 0; i < partitionObjectDetails.count(); i++) {
- if (notifyUuid == partitionObjectDetails[i].notifyUuid)
+ if (watcher == partitionObjectDetails[i].watcher)
return i;
}
return -1;
@@ -841,7 +807,7 @@ QVariant JsonDbCachingListModelPrivate::getItem(int index)
}
if (state == JsonDbCachingListModel::Ready) // Pre-fetch only, if in Ready state
prefetchNearbyPages(index);
- return QVariant(objectCache.valueAtPage(page, uuid));
+ return QVariant(objectCache.valueAtPage(page, uuid).toVariantMap());
}
QVariant JsonDbCachingListModelPrivate::getItem(int index, int role)
@@ -909,40 +875,66 @@ int JsonDbCachingListModelPrivate::indexOf(const QString &uuid) const
return iterator_position(begin, end, i);
}
-void JsonDbCachingListModelPrivate::sendNotifications(const QString& currentNotifyUuid, const QVariant &v, JsonDbClient::NotifyType action)
+void JsonDbCachingListModelPrivate::sendNotification(int partitionIndex, const QJsonObject &object, QJsonDbWatcher::Action action)
{
- int idx = indexOfNotifyUUID(currentNotifyUuid);
- if (idx == -1)
- return;
-
- const QVariantMap &item = v.toMap();
- if (action == JsonDbClient::NotifyCreate) {
- addItem(item, idx);
- } else if (action == JsonDbClient::NotifyRemove) {
- deleteItem(item, idx);
- } else if (action == JsonDbClient::NotifyUpdate) {
- updateItem(item, idx);
+ if (action == QJsonDbWatcher::Created) {
+ addItem(object, partitionIndex);
+ } else if (action == QJsonDbWatcher::Removed)
+ deleteItem(object, partitionIndex);
+ else if (action == QJsonDbWatcher::Updated) {
+ updateItem(object, partitionIndex);
}
}
-void JsonDbCachingListModelPrivate::_q_jsonDbResponse(int id, const QVariant &v)
+void JsonDbCachingListModelPrivate::_q_keyResponse(int index, const QList<QJsonObject> &v, const QString &sortKey)
{
- int idx = -1;
- if ((idx = indexOfKeyRequestId(id)) != -1) {
- partitionKeyRequestDetails[idx].requestId = -1;
- partitionObjectDetails[idx].requestId = -1;
- fillKeys(v, idx);
- } else if ((idx = indexOfRequestId(id)) != -1) {
- partitionObjectDetails[idx].requestId = -1;
- fillData(v, idx);
- } else if ((idx = indexOfKeyIndexSpecId(id)) != -1) {
- partitionIndexDetails[idx].requestId = -1;
- verifyIndexSpec(v, idx);
- }
+#ifdef JSONDB_LISTMODEL_BENCHMARK
+ QElapsedTimer elt;
+ elt.start();
+#endif
+ Q_UNUSED(sortKey)
+ fillKeys(v, index);
+#ifdef JSONDB_LISTMODEL_BENCHMARK
+ qint64 elap = elt.elapsed();
+ if (elap > 3)
+ qDebug() << Q_FUNC_INFO << "took more than 3 ms (" << elap << "ms )";
+#endif
+}
+
+void JsonDbCachingListModelPrivate::_q_valueResponse(int index, const QList<QJsonObject> &v)
+{
+#ifdef JSONDB_LISTMODEL_BENCHMARK
+ QElapsedTimer elt;
+ elt.start();
+#endif
+ fillData(v, index);
+#ifdef JSONDB_LISTMODEL_BENCHMARK
+ qint64 elap = elt.elapsed();
+ if (elap > 3)
+ qDebug() << Q_FUNC_INFO << "took more than 3 ms (" << elap << "ms )";
+#endif
}
-void JsonDbCachingListModelPrivate::_q_jsonDbErrorResponse(int, int code, const QString &message)
+void JsonDbCachingListModelPrivate::_q_indexResponse(int index, const QList<QJsonObject> &v)
{
+#ifdef JSONDB_LISTMODEL_BENCHMARK
+ QElapsedTimer elt;
+ elt.start();
+#endif
+ verifyIndexSpec(v, index);
+#ifdef JSONDB_LISTMODEL_BENCHMARK
+ qint64 elap = elt.elapsed();
+ if (elap > 3)
+ qDebug() << Q_FUNC_INFO << "took more than 3 ms (" << elap << "ms )";
+#endif
+}
+
+void JsonDbCachingListModelPrivate::_q_readError(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString & message)
+{
+#ifdef JSONDB_LISTMODEL_BENCHMARK
+ QElapsedTimer elt;
+ elt.start();
+#endif
Q_Q(JsonDbCachingListModel);
qWarning() << QString("JsonDb error: %1 %2").arg(code).arg(message);
int oldErrorCode = errorCode;
@@ -950,28 +942,55 @@ void JsonDbCachingListModelPrivate::_q_jsonDbErrorResponse(int, int code, const
errorString = message;
if (oldErrorCode != errorCode)
emit q->errorChanged(q->error());
+#ifdef JSONDB_LISTMODEL_BENCHMARK
+ qint64 elap = elt.elapsed();
+ if (elap > 3)
+ qDebug() << Q_FUNC_INFO << "took more than 3 ms (" << elap << "ms )";
+#endif
}
-void JsonDbCachingListModelPrivate::_q_dbNotified(const QString &notify_uuid, const QtAddOn::JsonDb::JsonDbNotification &_notification)
+void JsonDbCachingListModelPrivate::_q_notificationsAvailable()
{
- if (state == JsonDbCachingListModel::Querying) {
- NotifyItem pending;
- pending.notifyUuid = notify_uuid;
- pending.item = _notification.object();
- pending.action = _notification.action();
- pendingNotifications.append(pending);
- } else if (state == JsonDbCachingListModel::Ready) {
- sendNotifications(notify_uuid, _notification.object(), _notification.action());
+#ifdef JSONDB_LISTMODEL_BENCHMARK
+ QElapsedTimer elt;
+ elt.start();
+#endif
+ Q_Q(JsonDbCachingListModel);
+ QJsonDbWatcher *watcher = qobject_cast<QJsonDbWatcher *>(q->sender());
+ int partitionIndex = indexOfWatcher(watcher);
+ if (!watcher || partitionIndex == -1)
+ return;
+ QList<QJsonDbNotification> list = watcher->takeNotifications();
+ for (int i = 0; i < list.count(); i++) {
+ const QJsonDbNotification & notification = list[i];
+ QJsonObject object = notification.object();
+ QJsonDbWatcher::Action action = notification.action();
+ if (state == JsonDbCachingListModel::Querying) {
+ NotificationItem pending;
+ pending.partitionIndex = partitionIndex;
+ pending.item = object;
+ pending.action = action;
+ pendingNotifications.append(pending);
+ } else {
+ foreach (NotificationItem pending, pendingNotifications)
+ sendNotification(pending.partitionIndex, pending.item, pending.action);
+ pendingNotifications.clear();
+ sendNotification(partitionIndex, object, action);
+ }
}
+#ifdef JSONDB_LISTMODEL_BENCHMARK
+ qint64 elap = elt.elapsed();
+ if (elap > 3)
+ qDebug() << Q_FUNC_INFO << "took more than 3 ms (" << elap << "ms )";
+#endif
}
-void JsonDbCachingListModelPrivate::_q_dbNotifyReadyResponse(int /* id */, const QVariant &/* result */)
-{
-}
-
-void JsonDbCachingListModelPrivate::_q_dbNotifyErrorResponse(int id, int code, const QString &message)
+void JsonDbCachingListModelPrivate::_q_notificationError(QtJsonDb::QJsonDbWatcher::ErrorCode code, const QString &message)
{
- Q_UNUSED(id);
+#ifdef JSONDB_LISTMODEL_BENCHMARK
+ QElapsedTimer elt;
+ elt.start();
+#endif
Q_Q(JsonDbCachingListModel);
qWarning() << QString("JsonDbCachingListModel Notification error: %1 %2").arg(code).arg(message);
int oldErrorCode = errorCode;
@@ -979,23 +998,27 @@ void JsonDbCachingListModelPrivate::_q_dbNotifyErrorResponse(int id, int code, c
errorString = message;
if (oldErrorCode != errorCode)
emit q->errorChanged(q->error());
+#ifdef JSONDB_LISTMODEL_BENCHMARK
+ qint64 elap = elt.elapsed();
+ if (elap > 3)
+ qDebug() << Q_FUNC_INFO << "took more than 3 ms (" << elap << "ms )";
+#endif
}
void JsonDbCachingListModelPrivate::_q_verifyDefaultIndexType(int index)
{
- if (!orderProperties.count())
- return;
- QString indexName = orderProperties[0];
+#ifdef JSONDB_LISTMODEL_BENCHMARK
+ QElapsedTimer elt;
+ elt.start();
+#endif
SortIndexSpec &indexSpec = partitionIndexDetails[index].spec;
partitionIndexDetails[index].valid = true;
if (!indexName.compare(QLatin1String("_uuid"))) {
- indexSpec.propertyName = QLatin1String("_uuid");
- indexSpec.propertyType = QLatin1String("_uuid");
+ indexSpec.name = QLatin1String("_uuid");
indexSpec.type = SortIndexSpec::UUID;
indexSpec.caseSensitive = false;
} else if (!indexName.compare(QLatin1String("_type"))) {
- indexSpec.propertyName = QLatin1String("_type");
- indexSpec.propertyType = QLatin1String("_type");
+ indexSpec.name = QLatin1String("_type");
indexSpec.type = SortIndexSpec::String;
indexSpec.caseSensitive = true;
}
@@ -1009,12 +1032,56 @@ void JsonDbCachingListModelPrivate::_q_verifyDefaultIndexType(int index)
}
if (checkedAll) {
//Start fetching the keys.
- orderProperties[0] = indexSpec.propertyName;
setQueryForSortKeys();
for (int i = 0; i < partitionKeyRequestDetails.count(); i++) {
fetchPartitionKeys(i);
}
}
+#ifdef JSONDB_LISTMODEL_BENCHMARK
+ qint64 elap = elt.elapsed();
+ if (elap > 3)
+ qDebug() << Q_FUNC_INFO << "took more than 3 ms (" << elap << "ms )";
+#endif
+}
+
+void JsonDbCachingListModelPrivate::appendPartition(JsonDbPartition *v)
+{
+ Q_Q(JsonDbCachingListModel);
+ partitionObjects.append(QPointer<JsonDbPartition>(v));
+
+ partitionObjectDetails.append(RequestInfo());
+ ModelRequest *valueRequest = new ModelRequest();
+ QObject::connect(valueRequest, SIGNAL(finished(int,QList<QJsonObject>,QString)),
+ q, SLOT(_q_valueResponse(int,QList<QJsonObject>)));
+ QObject::connect(valueRequest, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ q, SLOT(_q_readError(QtJsonDb::QJsonDbRequest::ErrorCode,QString)));
+ valueRequests.append(valueRequest);
+
+ partitionKeyRequestDetails.append(RequestInfo());
+ ModelRequest *keyRequest = new ModelRequest();
+ QObject::connect(keyRequest, SIGNAL(finished(int,QList<QJsonObject>,QString)),
+ q, SLOT(_q_keyResponse(int,QList<QJsonObject>,QString)));
+ QObject::connect(keyRequest, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ q, SLOT(_q_readError(QtJsonDb::QJsonDbRequest::ErrorCode,QString)));
+ keyRequests.append(keyRequest);
+
+ partitionObjectUuids.append(JsonDbModelIndexType());
+
+ partitionIndexDetails.append(IndexInfo());
+ ModelRequest *indexRequest = new ModelRequest();
+ QObject::connect(indexRequest, SIGNAL(finished(int,QList<QJsonObject>,QString)),
+ q, SLOT(_q_indexResponse(int,QList<QJsonObject>)));
+ QObject::connect(indexRequest, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ q, SLOT(_q_readError(QtJsonDb::QJsonDbRequest::ErrorCode,QString)));
+ indexRequests.append(indexRequest);
+
+ if (componentComplete && !query.isEmpty()) {
+ parseSortOrder();
+ createOrUpdateNotification(partitionObjects.count()-1);
+ if (state == JsonDbCachingListModel::None)
+ resetModel = true;
+ fetchIndexSpec(partitionObjects.count()-1);
+ }
}
void JsonDbCachingListModelPrivate::partitions_append(QQmlListProperty<JsonDbPartition> *p, JsonDbPartition *v)
@@ -1022,18 +1089,7 @@ void JsonDbCachingListModelPrivate::partitions_append(QQmlListProperty<JsonDbPar
JsonDbCachingListModel *q = qobject_cast<JsonDbCachingListModel *>(p->object);
JsonDbCachingListModelPrivate *pThis = (q) ? q->d_func() : 0;
if (pThis) {
- pThis->partitionObjects.append(QPointer<JsonDbPartition>(v));\
- pThis->partitionObjectDetails.append(RequestInfo());
- pThis->partitionKeyRequestDetails.append(RequestInfo());
- pThis->partitionObjectUuids.append(JsonDbModelIndexType());
- pThis->partitionIndexDetails.append(IndexInfo());
- if (pThis->componentComplete && !pThis->query.isEmpty()) {
- pThis->parseSortOrder();
- pThis->createOrUpdateNotification(pThis->partitionObjects.count()-1);
- if (pThis->state == JsonDbCachingListModel::None)
- pThis->resetModel = true;
- pThis->fetchIndexSpec(pThis->partitionObjects.count()-1);
- }
+ pThis->appendPartition(v);
}
}
@@ -1057,17 +1113,34 @@ JsonDbPartition* JsonDbCachingListModelPrivate::partitions_at(QQmlListProperty<J
return 0;
}
+void JsonDbCachingListModelPrivate::clearPartitions()
+{
+ partitionObjects.clear();
+ partitionObjectDetails.clear();
+ partitionKeyRequestDetails.clear();
+ partitionObjectUuids.clear();
+ partitionIndexDetails.clear();
+ while (!keyRequests.isEmpty()) {
+ delete keyRequests[0];
+ keyRequests.removeFirst();
+ }
+ while (!indexRequests.isEmpty()) {
+ delete indexRequests[0];
+ indexRequests.removeFirst();
+ }
+ while (!valueRequests.isEmpty()) {
+ delete valueRequests[0];
+ valueRequests.removeFirst();
+ }
+ reset();
+}
+
void JsonDbCachingListModelPrivate::partitions_clear(QQmlListProperty<JsonDbPartition> *p)
{
JsonDbCachingListModel *q = qobject_cast<JsonDbCachingListModel *>(p->object);
JsonDbCachingListModelPrivate *pThis = (q) ? q->d_func() : 0;
if (pThis) {
- pThis->partitionObjects.clear();
- pThis->partitionObjectDetails.clear();
- pThis->partitionKeyRequestDetails.clear();
- pThis->partitionObjectUuids.clear();
- pThis->partitionIndexDetails.clear();
- pThis->reset();
+ pThis->clearPartitions();
}
}
@@ -1124,8 +1197,17 @@ JsonDbCachingListModel::JsonDbCachingListModel(QObject *parent)
: QAbstractListModel(parent)
, d_ptr(new JsonDbCachingListModelPrivate(this))
{
+#ifdef JSONDB_LISTMODEL_BENCHMARK
+ QElapsedTimer elt;
+ elt.start();
+#endif
Q_D(JsonDbCachingListModel);
d->init();
+#ifdef JSONDB_LISTMODEL_BENCHMARK
+ qint64 elap = elt.elapsed();
+ if (elap > 3)
+ qDebug() << Q_FUNC_INFO << "took more than 3 ms (" << elap << "ms )";
+#endif
}
JsonDbCachingListModel::~JsonDbCachingListModel()
@@ -1138,12 +1220,21 @@ void JsonDbCachingListModel::classBegin()
void JsonDbCachingListModel::componentComplete()
{
+#ifdef JSONDB_LISTMODEL_BENCHMARK
+ QElapsedTimer elt;
+ elt.start();
+#endif
Q_D(JsonDbCachingListModel);
d->componentComplete = true;
if (!d->query.isEmpty() && d->partitionObjects.count()) {
d->createOrUpdateNotifications();
d->fetchModel();
}
+#ifdef JSONDB_LISTMODEL_BENCHMARK
+ qint64 elap = elt.elapsed();
+ if (elap > 3)
+ qDebug() << Q_FUNC_INFO << "took more than 3 ms (" << elap << "ms )";
+#endif
}
/*!
@@ -1159,8 +1250,18 @@ int JsonDbCachingListModel::rowCount(const QModelIndex &parent) const
QVariant JsonDbCachingListModel::data(const QModelIndex &modelIndex, int role) const
{
+#ifdef JSONDB_LISTMODEL_BENCHMARK
+ QElapsedTimer elt;
+ elt.start();
+#endif
JsonDbCachingListModel *pThis = const_cast<JsonDbCachingListModel *>(this);
- return pThis->d_func()->getItem(modelIndex.row(), role);
+ QVariant ret = pThis->d_func()->getItem(modelIndex.row(), role);
+#ifdef JSONDB_LISTMODEL_BENCHMARK
+ qint64 elap = elt.elapsed();
+ if (elap > 3)
+ qDebug() << Q_FUNC_INFO << "took more than 3 ms (" << elap << "ms )";
+#endif
+ return ret;
}
/*!
@@ -1224,6 +1325,10 @@ QVariant JsonDbCachingListModel::scriptableRoleNames() const
void JsonDbCachingListModel::setScriptableRoleNames(const QVariant &vroles)
{
+#ifdef JSONDB_LISTMODEL_BENCHMARK
+ QElapsedTimer elt;
+ elt.start();
+#endif
Q_D(JsonDbCachingListModel);
d->properties.clear();
d->roleNames.clear();
@@ -1247,6 +1352,11 @@ void JsonDbCachingListModel::setScriptableRoleNames(const QVariant &vroles)
}
}
QAbstractItemModel::setRoleNames(d->roleNames);
+#ifdef JSONDB_LISTMODEL_BENCHMARK
+ qint64 elap = elt.elapsed();
+ if (elap > 3)
+ qDebug() << Q_FUNC_INFO << "took more than 3 ms (" << elap << "ms )";
+#endif
}
/*!
@@ -1277,6 +1387,10 @@ QString JsonDbCachingListModel::query() const
void JsonDbCachingListModel::setQuery(const QString &newQuery)
{
+#ifdef JSONDB_LISTMODEL_BENCHMARK
+ QElapsedTimer elt;
+ elt.start();
+#endif
Q_D(JsonDbCachingListModel);
const QString oldQuery = d->query;
@@ -1292,6 +1406,11 @@ void JsonDbCachingListModel::setQuery(const QString &newQuery)
return;
d->createOrUpdateNotifications();
d->fetchModel();
+#ifdef JSONDB_LISTMODEL_BENCHMARK
+ qint64 elap = elt.elapsed();
+ if (elap > 3)
+ qDebug() << Q_FUNC_INFO << "took more than 3 ms (" << elap << "ms )";
+#endif
}
/*!
@@ -1319,6 +1438,10 @@ int JsonDbCachingListModel::cacheSize() const
void JsonDbCachingListModel::setCacheSize(int newCacheSize)
{
+#ifdef JSONDB_LISTMODEL_BENCHMARK
+ QElapsedTimer elt;
+ elt.start();
+#endif
Q_D(JsonDbCachingListModel);
if (newCacheSize == d->cacheSize)
return;
@@ -1332,10 +1455,19 @@ void JsonDbCachingListModel::setCacheSize(int newCacheSize)
#ifdef JSONDB_LISTMODEL_DEBUG
d->objectCache.dumpCacheDetails();
#endif
+#ifdef JSONDB_LISTMODEL_BENCHMARK
+ qint64 elap = elt.elapsed();
+ if (elap > 3)
+ qDebug() << Q_FUNC_INFO << "took more than 3 ms (" << elap << "ms )";
+#endif
}
void JsonDbCachingListModel::partitionNameChanged(const QString &partitionName)
{
+#ifdef JSONDB_LISTMODEL_BENCHMARK
+ QElapsedTimer elt;
+ elt.start();
+#endif
Q_UNUSED(partitionName);
Q_D(JsonDbCachingListModel);
@@ -1344,6 +1476,11 @@ void JsonDbCachingListModel::partitionNameChanged(const QString &partitionName)
d->createOrUpdateNotifications();
d->fetchModel();
+#ifdef JSONDB_LISTMODEL_BENCHMARK
+ qint64 elap = elt.elapsed();
+ if (elap > 3)
+ qDebug() << Q_FUNC_INFO << "took more than 3 ms (" << elap << "ms )";
+#endif
}
/*!
@@ -1402,6 +1539,10 @@ QString JsonDbCachingListModel::sortOrder() const
void JsonDbCachingListModel::setSortOrder(const QString &newSortOrder)
{
+#ifdef JSONDB_LISTMODEL_BENCHMARK
+ QElapsedTimer elt;
+ elt.start();
+#endif
Q_D(JsonDbCachingListModel);
const QString oldSortOrder = d->sortOrder;
@@ -1413,6 +1554,11 @@ void JsonDbCachingListModel::setSortOrder(const QString &newSortOrder)
d->createOrUpdateNotifications();
d->fetchModel();
}
+#ifdef JSONDB_LISTMODEL_BENCHMARK
+ qint64 elap = elt.elapsed();
+ if (elap > 3)
+ qDebug() << Q_FUNC_INFO << "took more than 3 ms (" << elap << "ms )";
+#endif
}
/*!
@@ -1477,8 +1623,17 @@ int JsonDbCachingListModel::indexOf(const QString &uuid) const
*/
void JsonDbCachingListModel::get(int index, const QJSValue &callback)
{
+#ifdef JSONDB_LISTMODEL_BENCHMARK
+ QElapsedTimer elt;
+ elt.start();
+#endif
Q_D(JsonDbCachingListModel);
d->queueGetCallback(index, callback);
+#ifdef JSONDB_LISTMODEL_BENCHMARK
+ qint64 elap = elt.elapsed();
+ if (elap > 3)
+ qDebug() << Q_FUNC_INFO << "took more than 3 ms (" << elap << "ms )";
+#endif
}
/*!
diff --git a/src/imports/jsondb/jsondbcachinglistmodel.h b/src/imports/jsondb/jsondbcachinglistmodel.h
index 76b0311a..84f66de9 100644
--- a/src/imports/jsondb/jsondbcachinglistmodel.h
+++ b/src/imports/jsondb/jsondbcachinglistmodel.h
@@ -53,7 +53,6 @@
#include <QJSValue>
#include <QScopedPointer>
-#include "jsondb-global.h"
#include "jsondbpartition.h"
QT_BEGIN_NAMESPACE_JSONDB
@@ -121,13 +120,14 @@ private:
Q_DISABLE_COPY(JsonDbCachingListModel)
Q_DECLARE_PRIVATE(JsonDbCachingListModel)
QScopedPointer<JsonDbCachingListModelPrivate> d_ptr;
- Q_PRIVATE_SLOT(d_func(), void _q_jsonDbResponse(int, const QVariant&))
- Q_PRIVATE_SLOT(d_func(), void _q_jsonDbErrorResponse(int, int, const QString&))
- Q_PRIVATE_SLOT(d_func(), void _q_dbNotified(QString, QtAddOn::JsonDb::JsonDbNotification))
- Q_PRIVATE_SLOT(d_func(), void _q_dbNotifyReadyResponse(int, QVariant))
- Q_PRIVATE_SLOT(d_func(), void _q_dbNotifyErrorResponse(int, int, QString))
- Q_PRIVATE_SLOT(d_func(), void _q_verifyDefaultIndexType(int))
+ Q_PRIVATE_SLOT(d_func(), void _q_verifyDefaultIndexType(int))
+ Q_PRIVATE_SLOT(d_func(), void _q_notificationsAvailable())
+ Q_PRIVATE_SLOT(d_func(), void _q_notificationError(QtJsonDb::QJsonDbWatcher::ErrorCode, QString))
+ Q_PRIVATE_SLOT(d_func(), void _q_keyResponse(int, QList<QJsonObject>, QString))
+ Q_PRIVATE_SLOT(d_func(), void _q_valueResponse(int, QList<QJsonObject>))
+ Q_PRIVATE_SLOT(d_func(), void _q_indexResponse(int, QList<QJsonObject>))
+ Q_PRIVATE_SLOT(d_func(), void _q_readError(QtJsonDb::QJsonDbRequest::ErrorCode, QString))
};
QT_END_NAMESPACE_JSONDB
diff --git a/src/imports/jsondb/jsondbcachinglistmodel_p.h b/src/imports/jsondb/jsondbcachinglistmodel_p.h
index bf949dc3..759440e8 100644
--- a/src/imports/jsondb/jsondbcachinglistmodel_p.h
+++ b/src/imports/jsondb/jsondbcachinglistmodel_p.h
@@ -50,8 +50,9 @@
#include <QStringList>
#include <QPointer>
#include <QUuid>
+#include <QJsonObject>
-#include "jsondb-client.h"
+#include "jsondatabase.h"
#include "jsondbmodelutils.h"
#include "jsondbmodelcache.h"
@@ -93,9 +94,8 @@ public:
QList<RequestInfo> partitionKeyRequestDetails;
QList<JsonDbModelIndexType> partitionObjectUuids;
- QList<bool> ascendingOrders;
- QStringList orderProperties;
- QList<QStringList> orderPaths;
+ bool ascendingOrder;
+ QString indexName;
QString query;
QVariant queryOptions;
@@ -110,13 +110,15 @@ public:
QHash<int, QByteArray> roleNames;
QHash<int, QStringList> properties;
- QList<NotifyItem> pendingNotifications;
+ QList<NotificationItem> pendingNotifications;
QList<int> cacheMiss;
QMap<int, QJSValue> getCallbacks;
QList< QPair<int,int> > requestQueue;
+ QList< QPointer<ModelRequest> >keyRequests;
+ QList< QPointer<ModelRequest> >indexRequests;
+ QList< QPointer<ModelRequest> >valueRequests;
JsonDbCachingListModel::State state;
- JsonDbClient dbClient;
QModelIndex parent;
int errorCode;
QString errorString;
@@ -131,11 +133,11 @@ public:
void clearCache();
void removeLastItem();
- void addItem(const QVariantMap &item, int partitionIndex);
- void deleteItem(const QVariantMap &item, int partitionIndex);
- void updateItem(const QVariantMap &item, int partitionIndex);
- void fillKeys(const QVariant &v, int partitionIndex);
- void fillData(const QVariant &v, int partitionIndex);
+ void addItem(const QJsonObject &item, int partitionIndex);
+ void deleteItem(const QJsonObject &item, int partitionIndex);
+ void updateItem(const QJsonObject &item, int partitionIndex);
+ void fillKeys(const QList<QJsonObject> &items, int partitionIndex);
+ void fillData(const QList<QJsonObject> &items, int partitionIndex);
void reset();
void emitDataChanged(int from, int to);
@@ -156,13 +158,12 @@ public:
void createOrUpdateNotifications();
void parseSortOrder();
void setQueryForSortKeys();
- void verifyIndexSpec(const QVariant &v, int partitionIndex);
+ void verifyIndexSpec(const QList<QJsonObject> &items, int partitionIndex);
- int indexOfKeyRequestId(int requestId);
- int indexOfRequestId(int requestId);
- int indexOfNotifyUUID(const QString& notifyUuid);
- int indexOfKeyIndexSpecId(int requestId);
+ int indexOfWatcher(QJsonDbWatcher *watcher);
+ void appendPartition(JsonDbPartition *v);
+ void clearPartitions();
QVariant getItem(int index);
QVariant getItem(int index, int role);
void queueGetCallback(int index, const QJSValue &callback);
@@ -172,14 +173,16 @@ public:
void set(int index, const QJSValue& valuemap,
const QJSValue &successCallback,
const QJSValue &errorCallback);
- void sendNotifications(const QString& currentNotifyUuid, const QVariant &v, JsonDbClient::NotifyType action);
+ void sendNotification(int partitionIndex, const QJsonObject &object, QJsonDbWatcher::Action action);
+
// private slots
- void _q_jsonDbResponse(int , const QVariant &);
- void _q_jsonDbErrorResponse(int , int, const QString&);
- void _q_dbNotified(const QString &notify_uuid, const QtAddOn::JsonDb::JsonDbNotification &_notification);
- void _q_dbNotifyReadyResponse(int id, const QVariant &result);
- void _q_dbNotifyErrorResponse(int id, int code, const QString &message);
void _q_verifyDefaultIndexType(int index);
+ void _q_notificationsAvailable();
+ void _q_notificationError(QtJsonDb::QJsonDbWatcher::ErrorCode code, const QString &message);
+ void _q_readError(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString & message);
+ void _q_keyResponse(int , const QList<QJsonObject>&, const QString&);
+ void _q_valueResponse(int , const QList<QJsonObject>&);
+ void _q_indexResponse(int , const QList<QJsonObject>&);
static void partitions_append(QQmlListProperty<JsonDbPartition> *p, JsonDbPartition *v);
static int partitions_count(QQmlListProperty<JsonDbPartition> *p);
diff --git a/src/imports/jsondb/jsondbchangessinceobject.cpp b/src/imports/jsondb/jsondbchangessinceobject.cpp
deleted file mode 100644
index 0872a469..00000000
--- a/src/imports/jsondb/jsondbchangessinceobject.cpp
+++ /dev/null
@@ -1,404 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#include "jsondb-global.h"
-#include "jsondbchangessinceobject.h"
-#include "jsondbpartition.h"
-#include "private/jsondb-strings_p.h"
-#include <qdebug.h>
-
-QT_BEGIN_NAMESPACE_JSONDB
-
-/*!
- \qmlclass ChangesSince
- \inqmlmodule QtJsonDb
- \since 1.x
-
- This allows to query the list of changes that happened between the current state and a specified
- stateNumber. Users can execute this by calling the start(). To retrieve the results, connect to
- onResultsReady and/or onFinished.
-
- \code
- JsonDb.Partition {
- id: nokiaPartition
- name: "com.nokia.shared"
- }
- JsonDb.ChangesSince {
- id:contactChanges
- partition:nokiaPartition
- types: ["Contact"]
- stateNumber : 10
- onFinished: {
- var results = contactsQuery.takeResults();
- console.log("Results: Count + results.length );
- }
-
- onStatusChanged: {
- if (status === JsonDb.ChangesSince.Error)
- console.log("Failed " + error.code + " "+ error.message);
- }
-
- }
-
- contactChanges.exec();
- \endcode
-
-*/
-
-JsonDbChangesSinceObject::JsonDbChangesSinceObject(QObject *parent)
- : QObject(parent)
- , completed(false)
- , startStateNumber(0)
- , partitionObject(0)
- , defaultPartitionObject(0)
- , jsondbChangesSince(0)
- , errorCode(0)
- , objectStatus(JsonDbChangesSinceObject::Null)
-{
-}
-
-JsonDbChangesSinceObject::~JsonDbChangesSinceObject()
-{
- if (defaultPartitionObject)
- delete defaultPartitionObject;
- if (jsondbChangesSince)
- delete jsondbChangesSince;
-}
-
-
-/*!
- \qmlproperty list QtJsonDb::ChangesSince::types
- Holds the list of object types which will be checked
- while executing the ChangesSince.
-*/
-QStringList JsonDbChangesSinceObject::types() const
-{
- return filterTypes;
-}
-
-void JsonDbChangesSinceObject::setTypes(const QStringList &newTypes)
-{
- filterTypes = newTypes;
- checkForReadyStatus();
-}
-
-/*!
- \qmlproperty object QtJsonDb::ChangesSince::partition
- Holds the partition object for the object.
-*/
-
-JsonDbPartition* JsonDbChangesSinceObject::partition()
-{
- if (!partitionObject) {
- defaultPartitionObject = new JsonDbPartition();
- setPartition(defaultPartitionObject);
- }
- checkForReadyStatus();
- return partitionObject;
-}
-
-void JsonDbChangesSinceObject::setPartition(JsonDbPartition *newPartition)
-{
- if (partitionObject == newPartition)
- return;
- if (partitionObject == defaultPartitionObject)
- delete defaultPartitionObject;
- partitionObject = newPartition;
- checkForReadyStatus();
-}
-
-/*!
- \qmlproperty int QtJsonDb::ChangesSince::stateNumber
- State Number from which the changesSince is computed.
-*/
-quint32 JsonDbChangesSinceObject::stateNumber() const
-{
- return startStateNumber;
-}
-
-void JsonDbChangesSinceObject::setStateNumber(quint32 newStateNumber)
-{
- startStateNumber = newStateNumber;
- checkForReadyStatus();
-}
-
-/*!
- \qmlproperty int QtJsonDb::ChangesSince::startingStateNumber
- State Number from which the changesSince is actually ccomputed. This
- can be different from the QtJsonDb::ChangesSince::stateNumber. Only
- valid after receiving the onResultsReady()
-*/
-quint32 JsonDbChangesSinceObject::startingStateNumber() const
-{
- if (jsondbChangesSince)
- return jsondbChangesSince->startingStateNumber();
- return startStateNumber;
-}
-
-/*!
- \qmlproperty int QtJsonDb::ChangesSince::currentStateNumber
- The current state number when the changesSince was executed. Only
- valid after receiving the onResultsReady()
-*/
-quint32 JsonDbChangesSinceObject::currentStateNumber() const
-{
- if (jsondbChangesSince)
- return jsondbChangesSince->currentStateNumber();
- return startStateNumber;
-}
-
-
-/*!
- \qmlmethod list QtJsonDb::ChangesSince::takeResults()
-
- Retrieves the list of results available in the object. This can be called multiple
- times for a single execution. Call this from onResultsReady or onFinished. This will
- remove the returned results from the query object.
-
- If the request was successful, the response will be an array of objects. Each item in
- the results array will be an object of type {"after" : {} , "before" : {}}. The \a after
- sub-object will be undefined for deleted objects. For newly created objects, the \a before
- sub-object will be undefined. If both sub-objects are valid the change, represents an update.
-
-
- \code
- property var objects : [];
- JsonDb.ChangesSince {
- id:contactChanges
- partition:nokiaPartition
- types: ["Contact"]
- stateNumber : 10
- onResultsReady: {
- objects = objects.concat(contactChanges.takeResults());
- console.log("Length :" + objects.length);
- }
- onFinished: {
- objects = objects.concat(contactChanges.takeResults());
- console.log("Results: Count + objects.length );
- }
-
- onStatusChanged: {
- if (status === JsonDb.ChangesSince.Error)
- console.log("Failed " + error.code + " "+ error.message);
- }
-
- }
- \endcode
-
-*/
-
-QVariantList JsonDbChangesSinceObject::takeResults()
-{
- QVariantList list;
- if (jsondbChangesSince) {
- list = jsondbChangesSince->takeResults();
- }
- return list;
-}
-
-/*!
- \qmlsignal QtJsonDb::ChangesSince::onResultsReady(int resultsAvailable)
-
- This handler is called when the a set of results are avaialable in the object. This
- will be called multiple times for an execution of the changesSince. Results can be
- retrievd here by calling takeResults() of the query object.
-
-*/
-
-/*!
- \qmlsignal QtJsonDb::ChangesSince::onFinished()
-
- This handler is called when the an execution of changesSince is finished. Results can be
- retrievd here by calling takeResults() of the changesSince object. Users can wait for
- onFinished to avoid chunked reading.
-*/
-
-/*!
- \qmlproperty object QtJsonDb::ChangesSince::error
- \readonly
-
- This property holds the current error information for the ChangesSince object. It contains:
- \list
- \li error.code - code for the current error.
- \li error.message - detailed explanation of the error
- \endlist
-*/
-
-QVariantMap JsonDbChangesSinceObject::error() const
-{
- QVariantMap errorMap;
- errorMap.insert(QLatin1String("code"), errorCode);
- errorMap.insert(QLatin1String("message"), errorString);
- return errorMap;
-}
-
-/*!
- \qmlproperty enumeration QtJsonDb::ChangesSince::status
- \readonly
-
- This property holds the current status of the ChangesSince object. It can be one of:
- \list
- \li Query.Null - waiting for component to finish loading or for all the pararamters to be set.
- \li Query.Loading - Executing the changes-since query
- \li Query.Ready - object is ready, users can call start()
- \li Query.Error - an error occurred while executing the query
- \endlist
-
- \sa QtJsonDb::ChangesSince::error
-*/
-
-JsonDbChangesSinceObject::Status JsonDbChangesSinceObject::status() const
-{
- return objectStatus;
-}
-
-void JsonDbChangesSinceObject::componentComplete()
-{
- completed = true;
-}
-
-void JsonDbChangesSinceObject::clearError()
-{
- int oldErrorCode = errorCode;
- errorCode = 0;
- errorString.clear();
- if (oldErrorCode != Error) {
- emit errorChanged(error());
- }
-}
-
-bool JsonDbChangesSinceObject::parametersReady()
-{
- return (completed && partitionObject);
-}
-
-void JsonDbChangesSinceObject::checkForReadyStatus()
-{
- if (objectStatus != JsonDbChangesSinceObject::Null)
- return;
-
- JsonDbChangesSinceObject::Status oldStatus = objectStatus;
-
- if (!partitionObject)
- partitionObject = qobject_cast<JsonDbPartition*>(parent());
- if (!parametersReady()) {
- objectStatus = JsonDbChangesSinceObject::Null;
- if (objectStatus != oldStatus)
- emit statusChanged(objectStatus);
- return;
- } else {
- objectStatus = JsonDbChangesSinceObject::Ready;
- if (objectStatus != oldStatus)
- emit statusChanged(objectStatus);
- }
-}
-
-void JsonDbChangesSinceObject::setReadyStatus()
-{
- JsonDbChangesSinceObject::Status oldStatus = objectStatus;
-
- objectStatus = JsonDbChangesSinceObject::Ready;
- if (objectStatus != oldStatus)
- emit statusChanged(objectStatus);
-}
-
-void JsonDbChangesSinceObject::setError(QtAddOn::JsonDb::JsonDbError::ErrorCode code, const QString& message)
-{
- int oldErrorCode = errorCode;
- errorCode = code;
- errorString = message;
- if (objectStatus != JsonDbChangesSinceObject::Error) {
- objectStatus = JsonDbChangesSinceObject::Error;
- emit statusChanged(objectStatus);
- }
- if (oldErrorCode != JsonDbChangesSinceObject::Error) {
- emit errorChanged(error());
- }
-}
-
-
-/*!
- \qmlmethod object QtJsonDb::ChangesSince::start()
-
- Users should call this method to start the execution of changesSince on this partition.
- Once there are some results ready on the object, the onResultsReady will be triggered. This
- will be called whenever a new chunk of results is ready. Users can call takeResults() on
- this object to retrieve the results at any time. The ChangesSince also emits an onFinished()
- signal when the execution is finished.
-
-*/
-int JsonDbChangesSinceObject::start()
-{
- if (!completed) {
- qWarning("Component not ready");
- return -1;
- }
- checkForReadyStatus();
- if (!parametersReady()) {
- qWarning("Missing properties");
- return -1;
- }
-
- if (jsondbChangesSince) {
- delete jsondbChangesSince;
- }
- jsondbChangesSince = partitionObject->jsonDb.changesSince();
- jsondbChangesSince->setTypes(filterTypes);
- jsondbChangesSince->setStateNumber(startStateNumber);
- jsondbChangesSince->setPartition(partitionObject->name());
- connect(jsondbChangesSince, SIGNAL(resultsReady(int)),
- this, SIGNAL(resultsReady(int)));
- connect(jsondbChangesSince, SIGNAL(finished()),
- this, SLOT(setReadyStatus()));
- connect(jsondbChangesSince, SIGNAL(finished()),
- this, SIGNAL(finished()));
- connect(jsondbChangesSince, SIGNAL(error(QtAddOn::JsonDb::JsonDbError::ErrorCode,QString)),
- this, SLOT(setError(QtAddOn::JsonDb::JsonDbError::ErrorCode,QString)));
-
- jsondbChangesSince->start();
- objectStatus = JsonDbChangesSinceObject::Loading;
- emit statusChanged(objectStatus);
-
- return jsondbChangesSince->requestId();
-
-}
-
-#include "moc_jsondbchangessinceobject.cpp"
-QT_END_NAMESPACE_JSONDB
diff --git a/src/imports/jsondb/jsondbchangessinceobject.h b/src/imports/jsondb/jsondbchangessinceobject.h
deleted file mode 100644
index 22649af4..00000000
--- a/src/imports/jsondb/jsondbchangessinceobject.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef JSONDBCHANGESSINCEOBJECT_H
-#define JSONDBCHANGESSINCEOBJECT_H
-
-#include <QObject>
-#include <QVariant>
-#include <QPointer>
-#include <QJSValue>
-#include <QQmlParserStatus>
-#include <QQmlListProperty>
-#include "jsondb-client.h"
-
-QT_BEGIN_NAMESPACE_JSONDB
-
-class JsonDbPartition;
-class JsonDbPartitionPrivate;
-
-class JsonDbChangesSinceObject : public QObject, public QQmlParserStatus
-{
- Q_OBJECT
- Q_INTERFACES(QQmlParserStatus)
-
-public:
- Q_ENUMS(Status)
- enum Status { Null, Loading, Ready, Error };
-
- Q_PROPERTY(JsonDbPartition* partition READ partition WRITE setPartition)
- Q_PROPERTY(QStringList types READ types WRITE setTypes)
- Q_PROPERTY(quint32 stateNumber READ stateNumber WRITE setStateNumber)
-
- Q_PROPERTY(quint32 startingStateNumber READ startingStateNumber)
- Q_PROPERTY(quint32 currentStateNumber READ currentStateNumber)
- Q_PROPERTY(Status status READ status NOTIFY statusChanged)
- Q_PROPERTY(QVariantMap error READ error NOTIFY errorChanged)
-
- JsonDbChangesSinceObject(QObject *parent = 0);
- ~JsonDbChangesSinceObject();
-
- QStringList types() const;
- void setTypes(const QStringList &newTypes);
-
- JsonDbPartition* partition();
- void setPartition(JsonDbPartition* newPartition);
-
-
- quint32 stateNumber() const;
- void setStateNumber(quint32 stateNumber);
-
- quint32 startingStateNumber() const;
- quint32 currentStateNumber() const;
-
- JsonDbChangesSinceObject::Status status() const;
- QVariantMap error() const;
-
- void classBegin() {}
- void componentComplete();
-
- Q_INVOKABLE int start();
- Q_INVOKABLE QVariantList takeResults();
-
-Q_SIGNALS:
- void resultsReady(int resultsAvailable);
- void finished();
- void statusChanged(JsonDbChangesSinceObject::Status newStatus);
- void errorChanged(const QVariantMap &newError);
-
-private Q_SLOTS:
- void setError(QtAddOn::JsonDb::JsonDbError::ErrorCode code, const QString& message);
- void setReadyStatus();
-
-private:
- bool completed;
- quint32 startStateNumber;
- QStringList filterTypes;
- QPointer<JsonDbPartition> partitionObject;
- QPointer<JsonDbPartition> defaultPartitionObject;
- QPointer<JsonDbChangesSince> jsondbChangesSince;
- int errorCode;
- QString errorString;
- Status objectStatus;
-
- void clearError();
- inline bool parametersReady();
- void checkForReadyStatus();
- friend class JsonDbPartition;
- friend class JsonDbPartitionPrivate;
-};
-
-QT_END_NAMESPACE_JSONDB
-
-#endif //JSONDBCHANGESSINCEOBJECT_H
diff --git a/src/imports/jsondb/jsondblistmodel.cpp b/src/imports/jsondb/jsondblistmodel.cpp
index 7f184d7b..c22a4f88 100644
--- a/src/imports/jsondb/jsondblistmodel.cpp
+++ b/src/imports/jsondb/jsondblistmodel.cpp
@@ -41,10 +41,13 @@
#include "jsondblistmodel.h"
#include "jsondblistmodel_p.h"
-#include "private/jsondb-strings_p.h"
+#include "jsondatabase.h"
#include <QJSEngine>
#include <QJSValueIterator>
+#include <QThread>
+#include <QString>
+#include <qdebug.h>
#undef DEBUG_LIST_MODEL
@@ -70,33 +73,34 @@ JsonDbListModelPrivate::JsonDbListModelPrivate(JsonDbListModel *q)
, cacheStart(0)
, cacheEnd(0)
, newChunkOffset(0)
- , totalCountRequestId(-1)
, lastFetchedIndex(-1)
, requestInProgress(false)
, componentComplete(false)
, resetModel(true)
- , updateRecieved(false)
+ , updateReceived(false)
, totalRowCountRecieved(false)
, state(None)
- , jsonDbConnection(JsonDbConnection::instance())
+ , errorCode(0)
{
}
void JsonDbListModelPrivate::init()
{
Q_Q(JsonDbListModel);
- q->connect(&jsonDb, SIGNAL(response(int,const QVariant&)),
- q, SLOT(_q_jsonDbResponse(int,const QVariant&)));
- q->connect(&jsonDb, SIGNAL(error(int,int,const QString&)),
- q, SLOT(_q_jsonDbErrorResponse(int,int,const QString&)));
+ QObject::connect(&valueRequest, SIGNAL(finished(int,QList<QJsonObject>,QString)),
+ q, SLOT(_q_valueResponse(int,QList<QJsonObject>)));
+ QObject::connect(&valueRequest, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ q, SLOT(_q_readError(QtJsonDb::QJsonDbRequest::ErrorCode,QString)));
+ QObject::connect(&countRequest, SIGNAL(finished(int,QList<QJsonObject>,QString)),
+ q, SLOT(_q_countResponse(int,QList<QJsonObject>)));
+ QObject::connect(&countRequest, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ q, SLOT(_q_readError(QtJsonDb::QJsonDbRequest::ErrorCode,QString)));
+
}
JsonDbListModelPrivate::~JsonDbListModelPrivate()
{
- // Why do we need to do this while destroying the object
- if (!notifyUuid.isEmpty()) {
- jsonDb.unregisterNotification(notifyUuid);
- }
+ clearNotification();
}
void JsonDbListModelPrivate::clearCache(int newStart)
@@ -217,7 +221,6 @@ void JsonDbListModelPrivate::insertItem(const QVariantMap &item, bool emitSignal
// When a new item is added, the position of the item is not known
// to the model. We will clear the cache and notify that an item
// is added at the end + all data is changed.
- QModelIndex parent;
q->beginInsertRows(parent, totalRowCount-1, totalRowCount-1);
q->endInsertRows();
emit q->countChanged();
@@ -239,7 +242,6 @@ void JsonDbListModelPrivate::deleteItem(const QVariantMap &item, bool emitSignal
int index = cachedUuids.indexOf(uuid);
if (index != -1) {
// When item is in the cache emit signals using the exact position.
- QModelIndex parent;
if (emitSignals)
q->beginRemoveRows(parent, cacheStart+index, cacheStart+index);
removeItem(index);
@@ -253,7 +255,6 @@ void JsonDbListModelPrivate::deleteItem(const QVariantMap &item, bool emitSignal
// Model dosen't know the position from where the item is deleted.
// We will clear the cache and notify that an item is removed
// from the end + all data is changed.
- QModelIndex parent;
if (!totalRowCount)
emitSignals = false;
if (emitSignals)
@@ -313,17 +314,68 @@ void JsonDbListModelPrivate::_q_requestAnotherChunk(int offset)
newChunkOffset = cacheEnd;
// now fetch more
resetModel = false;
- int id = jsonDb.query(query, newChunkOffset, maxItemsToFetch, partitionObject->name());
- requestIds.insert(id);
-
+ QJsonDbReadRequest *request = valueRequest.newRequest(0);
+ request->setQuery(query);
+ request->setProperty("queryOffset", newChunkOffset);
+ request->setQueryLimit(maxItemsToFetch);
+ request->setPartition(partitionObject->name());
+ JsonDatabase::sharedConnection().send(request);
requestInProgress = true;
}
+ModelSyncCall::ModelSyncCall(const QString &_query, int _offset, int _maxItems,
+ const QString & _partitionName, QVariantList *_data)
+ : query(_query),
+ offset(_offset),
+ maxItems(_maxItems),
+ partitionName(_partitionName),
+ data(_data)
+{
+
+}
+ModelSyncCall::~ModelSyncCall()
+{
+ if (request)
+ delete request;
+ if (connection)
+ delete connection;
+}
+
+void ModelSyncCall::createSyncRequest()
+{
+ connection = new QJsonDbConnection();
+ connection->connectToServer();
+ request = new QJsonDbReadRequest;
+ connect(request, SIGNAL(finished()), this, SLOT(onQueryFinished()));
+ connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ this, SLOT(onQueryError(QtJsonDb::QJsonDbRequest::ErrorCode,QString)));
+ request->setQuery(query);
+ request->setProperty("queryOffset", offset);
+ request->setQueryLimit(maxItems);
+ request->setPartition(partitionName);
+ connection->send(request);
+ //qDebug()<<"createSyncRequest Query :"<<query<<request->property("requestId");
+}
+
+void ModelSyncCall::onQueryFinished()
+{
+ *data = qjsonobject_list_to_qvariantlist(request->takeResults());
+ //qDebug()<<"onQueryFinished Query :"<<query<<request->property("requestId");
+ QThread::currentThread()->quit();
+}
+
+void ModelSyncCall::onQueryError(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString &message)
+{
+ qWarning() << QString("JsonDbListModel error: %1 %2").arg(code).arg(message);
+ QThread::currentThread()->quit();
+}
+
void JsonDbListModelPrivate::fetchChunkSynchronous(int offset)
{
// Ignore previous reqests
if (requestInProgress) {
- requestIds.clear();
+ //requestIds.clear();
+ valueRequest.resetRequest();
}
Q_ASSERT(!query.isEmpty());
int maxItemsToFetch = chunkSize;
@@ -337,32 +389,49 @@ void JsonDbListModelPrivate::fetchChunkSynchronous(int offset)
// now fetch more
resetModel = false;
requestInProgress = true;
- QVariantMap request = JsonDbConnection::makeQueryRequest(query, newChunkOffset, maxItemsToFetch,
- QMap<QString,QVariant>(), partitionObject->name());
- QVariant v = jsonDbConnection->sync(request);
+ QVariantList resultList;
+ QThread syncThread;
+ ModelSyncCall *call = new ModelSyncCall(query, newChunkOffset, maxItemsToFetch,
+ partitionObject->name(), &resultList);
+ QObject::connect(&syncThread, SIGNAL(started()),
+ call, SLOT(createSyncRequest()));
+ QObject::connect(&syncThread, SIGNAL(finished()),
+ call, SLOT(deleteLater()));
+ call->moveToThread(&syncThread);
+ syncThread.start();
+ syncThread.wait();
+ updateCache(resultList);
requestInProgress = false;
- updateCache(v.toMap());
}
void JsonDbListModelPrivate::populateModel()
{
Q_Q(JsonDbListModel);
clearCache();
- updateRecieved = false;
+ updateReceived = false;
totalRowCountRecieved = false;
totalRowCount = 0;
+ newChunkOffset = 0;
// Request the total count
QString countQuery = query+"[count]";
- totalCountRequestId = jsonDb.query(countQuery, 0, -1, partitionObject->name());
-
+ QJsonDbReadRequest *cRequest = countRequest.newRequest(0);
+ cRequest->setQuery(countQuery);
+ cRequest->setPartition(partitionObject->name());
+ JsonDatabase::sharedConnection().send(cRequest);
+ //qDebug()<<"Count Query :"<<countQuery<<cRequest->property("requestId");
//Request at least 2 chunks of data
int itemsToGet = chunkSize*2;
if (maxCacheSize)
itemsToGet = qMin(itemsToGet, maxCacheSize);
resetModel = true;
-
- int id = jsonDb.query(query, newChunkOffset, itemsToGet, partitionObject->name());
- requestIds.insert(id);
+ QJsonDbReadRequest *request = valueRequest.newRequest(0);
+ request->setQuery(query);
+ request->setProperty("queryOffset", newChunkOffset); //TODO change newChunkOffset to 0
+ request->setQueryLimit(itemsToGet);
+ request->setPartition(partitionObject->name());
+ JsonDatabase::sharedConnection().send(request);
+ //qDebug()<<"Query :"<<query<<request->property("requestId")<<newChunkOffset;
+ createOrUpdateNotification();
requestInProgress = true;
state = JsonDbListModelPrivate::Querying;
emit q->stateChanged();
@@ -515,24 +584,28 @@ void JsonDbListModel::componentComplete()
d->populateModel();
}
-void JsonDbListModelPrivate::createOrUpdateNotification()
+void JsonDbListModelPrivate::clearNotification()
{
- Q_Q(JsonDbListModel);
-
- if (!notifyUuid.isEmpty()) {
- jsonDb.unregisterNotification(notifyUuid);
- notifyUuid.clear();
+ if (watcher) {
+ JsonDatabase::sharedConnection().removeWatcher(watcher);
+ delete watcher;
+ watcher = 0;
}
+}
- JsonDbClient::NotifyTypes notifyActions = JsonDbClient::NotifyCreate
- | JsonDbClient::NotifyUpdate| JsonDbClient::NotifyRemove;
-
- notifyUuid = jsonDb.registerNotification(
- notifyActions , query, partitionObject->name(),
- q, SLOT(_q_dbNotified(QString,QtAddOn::JsonDb::JsonDbNotification)),
- q, SLOT(_q_dbNotifyReadyResponse(int,QVariant)),
- SLOT(_q_dbNotifyErrorResponse(int,int,QString)));
-
+void JsonDbListModelPrivate::createOrUpdateNotification()
+{
+ Q_Q(JsonDbListModel);
+ clearNotification();
+ watcher = new QJsonDbWatcher();
+ watcher->setQuery(query);
+ watcher->setWatchedActions(QJsonDbWatcher::Created | QJsonDbWatcher::Updated |QJsonDbWatcher::Removed);
+ watcher->setPartition(partitionObject->name());
+ QObject::connect(watcher, SIGNAL(notificationsAvailable(int)),
+ q, SLOT(_q_notificationsAvailable()));
+ QObject::connect(watcher, SIGNAL(error(QtJsonDb::QJsonDbWatcher::ErrorCode,QString)),
+ q, SLOT(_q_notificationError(QtJsonDb::QJsonDbWatcher::ErrorCode,QString)));
+ JsonDatabase::sharedConnection().addWatcher(watcher);
}
int JsonDbListModel::sectionIndex(const QString &section,
@@ -540,20 +613,69 @@ int JsonDbListModel::sectionIndex(const QString &section,
const QJSValue &errorCallback)
{
Q_D(JsonDbListModel);
+ if (!successCallback.isCallable()) {
+ qWarning("JsonDbListModel Cannot call sectionIndex without a success callbak function");
+ return -1;
+ }
// Find the count of items "< section"
QString sectionCountQueryLT = d->queryWithoutSort+"[?"+d->orderProperties[0]+"<\""+section+"\"][count]";
- int id = d->jsonDb.query(sectionCountQueryLT, 0, -1, d->partitionObject->name());
- // Register any valid callbacks
+
+ QJsonDbReadRequest *request = new QJsonDbReadRequest();
+ connect(request, SIGNAL(finished()), this, SLOT(_q_sectionIndexResponse()));
+ connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ this, SLOT(_q_sectionIndexError(QtJsonDb::QJsonDbRequest::ErrorCode,QString)));
+ request->setQuery(sectionCountQueryLT);
+ request->setPartition(d->partitionObject->name());
+ JsonDatabase::sharedConnection().send(request);
+ int id = request->property("requestId").toInt();
CallbackInfo info;
- if (successCallback.isCallable()
- || errorCallback.isCallable()) {
- info.successCallback = successCallback;
- info.errorCallback = errorCallback;
- d->sectionIndexRequestIds.insert(id, info);
- }
+ info.successCallback = successCallback;
+ info.errorCallback = errorCallback;
+ d->sectionIndexCallbacks.insert(request, info);
return id;
}
+void JsonDbListModelPrivate::_q_sectionIndexResponse()
+{
+ Q_Q(JsonDbListModel);
+ QJsonDbReadRequest *request = qobject_cast<QJsonDbReadRequest*>(q->sender());
+ if (request) {
+ QList<QJsonObject> v = request->takeResults();
+ if (v.count()) {
+ int id = request->property("requestId").toInt();
+ int count = (int) v[0].value(QStringLiteral("count")).toDouble();
+ CallbackInfo info = sectionIndexCallbacks.value(request);
+ if (info.successCallback.isCallable()) {
+ QJSValueList args;
+ args << info.successCallback.engine()->toScriptValue(id);
+ args << info.successCallback.engine()->toScriptValue(count);
+ info.successCallback.call(args);
+ }
+ }
+ sectionIndexCallbacks.remove(request);
+ request->deleteLater();
+ }
+}
+
+void JsonDbListModelPrivate::_q_sectionIndexError(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString &message)
+{
+ Q_Q(JsonDbListModel);
+ QJsonDbReadRequest *request = qobject_cast<QJsonDbReadRequest*>(q->sender());
+ if (request) {
+ int id = request->property("requestId").toInt();
+ CallbackInfo info = sectionIndexCallbacks.value(request);
+ if (info.errorCallback.isCallable()) {
+ QJSValueList args;
+ args << info.successCallback.engine()->toScriptValue(id);
+ args << info.successCallback.engine()->toScriptValue(int(code));
+ args << info.successCallback.engine()->toScriptValue(message);
+ info.errorCallback.call(args);
+ }
+ sectionIndexCallbacks.remove(request);
+ request->deleteLater();
+ }
+}
+
int JsonDbListModel::count() const
{
Q_D(const JsonDbListModel);
@@ -638,17 +760,7 @@ void JsonDbListModelPrivate::set(int index, const QJSValue& valuemap,
lastFetchedItem.clear();
lastFetchedIndex = -1;
- // Item will be updated through the update notification
- CallbackInfo info;
- info.index = index;
- int id = jsonDb.update(item, partitionObject->name()); // possibly change to variantToQson(item)..
- // Register any valid callbacks
- if (successCallback.isCallable()
- || errorCallback.isCallable()) {
- info.successCallback = successCallback;
- info.errorCallback = errorCallback;
- updateRequestIds.insert(id, info);
- }
+ update(index, item, successCallback, errorCallback);
}
void JsonDbListModel::setProperty(int index, const QString& property, const QVariant& value,
@@ -689,18 +801,61 @@ void JsonDbListModelPrivate::setProperty(int index, const QString& property, con
lastFetchedItem.clear();
lastFetchedIndex = -1;
+ update(index, item, successCallback, errorCallback);
+}
+
+void JsonDbListModelPrivate::update(int index, const QVariantMap &item,
+ const QJSValue &successCallback, const QJSValue &errorCallback)
+{
+ Q_Q(JsonDbListModel);
+ QJsonDbUpdateRequest *request = new QJsonDbUpdateRequest(QJsonObject::fromVariantMap(item));
+ QObject::connect(request, SIGNAL(finished()), q, SLOT(_q_updateResponse()));
+ QObject::connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ q, SLOT(_q_updateError(QtJsonDb::QJsonDbRequest::ErrorCode,QString)));
+ request->setPartition(partitionObject->name());
+ JsonDatabase::sharedConnection().send(request);
+ CallbackInfo info;
+ info.index = index;
+ info.successCallback = successCallback;
+ info.errorCallback = errorCallback;
+ updateCallbacks.insert(request, info);
+}
- int id = jsonDb.update(item, partitionObject->name()); // possibly change to variantToQson(item)..
- // Register any valid callbacks
- if (successCallback.isCallable()
- || errorCallback.isCallable()) {
-
- // Item will be updated through the update notification
- CallbackInfo info;
- info.index = index;
- info.successCallback = successCallback;
- info.errorCallback = errorCallback;
- updateRequestIds.insert(id, info);
+void JsonDbListModelPrivate::_q_updateResponse()
+{
+ Q_Q(JsonDbListModel);
+ QJsonDbWriteRequest *request = qobject_cast<QJsonDbWriteRequest*>(q->sender());
+ if (request) {
+ int id = request->property("requestId").toInt();
+ CallbackInfo info = updateCallbacks.value(request);
+ if (info.successCallback.isCallable()) {
+ QJSValueList args;
+ args << info.successCallback.engine()->toScriptValue(id);
+ args << info.successCallback.engine()->toScriptValue(info.index);
+ info.successCallback.call(args);
+ }
+ }
+ updateCallbacks.remove(request);
+ request->deleteLater();
+}
+
+void JsonDbListModelPrivate::_q_updateError(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString &message)
+{
+ Q_Q(JsonDbListModel);
+ QJsonDbWriteRequest *request = qobject_cast<QJsonDbWriteRequest*>(q->sender());
+ if (request) {
+ int id = request->property("requestId").toInt();
+ CallbackInfo info = updateCallbacks.value(request);
+ if (info.errorCallback.isCallable()) {
+ QJSValueList args;
+ args << info.successCallback.engine()->toScriptValue(id);
+ args << info.successCallback.engine()->toScriptValue(info.index);
+ args << info.successCallback.engine()->toScriptValue(int(code));
+ args << info.successCallback.engine()->toScriptValue(message);
+ info.errorCallback.call(args);
+ }
+ updateCallbacks.remove(request);
+ request->deleteLater();
}
}
@@ -963,94 +1118,66 @@ int JsonDbListModel::roleFromString(const QString &roleName) const
return d->roleNames.key(roleName.toLatin1(), -1);
}
-void JsonDbListModelPrivate::updateCache(const QVariantMap &m)
+void JsonDbListModelPrivate::updateCache(const QVariantList &items)
{
Q_Q(JsonDbListModel);
- if (m.contains("data")) {
- QVariantList items = m.value(QLatin1String("data")).toList();
- int size = items.size();
- int sizeAdded = 0;
- if (size) {
- DEBUG()<<"OLD Cache Start"<<cacheStart<<"Cache End:"<<cacheEnd;
- if (resetModel)
- q->beginResetModel();
- makeSpaceFor(size, newChunkOffset);
- bool appendToCache = (newChunkOffset >= cacheEnd) ? true : false;
- int insertAt = appendToCache ? itemsInCache() : 0;
- DEBUG()<<"INSERT AT :"<<insertAt<<"Elements Retrieved:"<<size<<"ChunkOffset:"<<newChunkOffset<<appendToCache << itemsInCache();
- DEBUG()<<"Cache Start"<<cacheStart<<"Cache End:"<<cacheEnd<<"Total Rows = "<<totalRowCount;
- // Add the new result to cache.
- for (int i = 0; i < size; i++) {
- QVariantMap item = items.at(i).toMap();
- const QString &uuid = item.value(JsonDbString::kUuidStr).toString();
- if (objectSortValues.contains(uuid)){
- break;
- }
- JsonDbSortKey key = sortKey(item);
- objectUuids.insert(key, uuid);
- objectSortValues.insert(uuid, key);
- data[uuid] = item;
- cachedUuids.insert(insertAt++, uuid);
- sizeAdded++;
+ int size = items.size();
+ int sizeAdded = 0;
+ if (size) {
+ DEBUG()<<"OLD Cache Start"<<cacheStart<<"Cache End:"<<cacheEnd;
+ if (resetModel)
+ q->beginResetModel();
+ makeSpaceFor(size, newChunkOffset);
+ bool appendToCache = (newChunkOffset >= cacheEnd) ? true : false;
+ int insertAt = appendToCache ? itemsInCache() : 0;
+ DEBUG()<<"INSERT AT :"<<insertAt<<"Elements Retrieved:"<<size<<"ChunkOffset:"<<newChunkOffset<<appendToCache << itemsInCache();
+ DEBUG()<<"Cache Start"<<cacheStart<<"Cache End:"<<cacheEnd<<"Total Rows = "<<totalRowCount;
+ // Add the new result to cache.
+ for (int i = 0; i < size; i++) {
+ QVariantMap item = items.at(i).toMap();
+ const QString &uuid = item.value(QStringLiteral("_uuid")).toString();
+ if (objectSortValues.contains(uuid)){
+ break;
}
- DEBUG()<<"sizeAdded:"<<sizeAdded;
- // Update the cache limits
- if (!itemsInCache()) {
- cacheStart = newChunkOffset;
- cacheEnd = cacheStart + sizeAdded;
- } else if (appendToCache) {
- cacheEnd += sizeAdded;
- } else {
- cacheStart = qMax(0, cacheStart-sizeAdded);
- }
- Q_ASSERT(cachedUuids.count() == data.count());
+ JsonDbSortKey key = sortKey(item);
+ objectUuids.insert(key, uuid);
+ objectSortValues.insert(uuid, key);
+ data[uuid] = item;
+ cachedUuids.insert(insertAt++, uuid);
+ sizeAdded++;
}
- if (resetModel && totalRowCountRecieved)
- resetModelFinished();
- else
- updateRecieved = true;
+ DEBUG()<<"sizeAdded:"<<sizeAdded;
+ // Update the cache limits
+ if (!itemsInCache()) {
+ cacheStart = newChunkOffset;
+ cacheEnd = cacheStart + sizeAdded;
+ } else if (appendToCache) {
+ cacheEnd += sizeAdded;
+ } else {
+ cacheStart = qMax(0, cacheStart-sizeAdded);
+ }
+ Q_ASSERT(cachedUuids.count() == data.count());
}
+ if (resetModel && totalRowCountRecieved)
+ resetModelFinished();
+ else
+ updateReceived = true;
}
-void JsonDbListModelPrivate::_q_jsonDbResponse(int id, const QVariant &v)
+void JsonDbListModelPrivate::_q_valueResponse(int, const QList<QJsonObject> &v)
{
- if (requestIds.contains(id)) {
- requestIds.remove(id);
- requestInProgress = false;
- updateCache(v.toMap());
- } else if (totalCountRequestId == id) {
- QVariantMap m = v.toMap();
- QVariantList items = m.value(QLatin1String("data")).toList();
- m = items.at(0).toMap();
- totalRowCount = m.value(QLatin1String("count")).toInt();
+ requestInProgress = false;
+ updateCache(qjsonobject_list_to_qvariantlist(v));
+}
+
+void JsonDbListModelPrivate::_q_countResponse(int, const QList<QJsonObject> &v)
+{
+ if (v.count()) {
+ totalRowCount = (int) v[0].value(QStringLiteral("count")).toDouble();
totalRowCountRecieved = true;
- if (updateRecieved)
+
+ if (updateReceived)
resetModelFinished();
- } else if (updateRequestIds.constFind(id) != updateRequestIds.constEnd()) {
- CallbackInfo info = updateRequestIds.value(id);
- if (info.successCallback.isCallable()) {
- QJSValueList args;
- QJSValue scriptResult = info.successCallback.engine()->toScriptValue(id);
- args << scriptResult;
- scriptResult = info.successCallback.engine()->toScriptValue(info.index);
- args << scriptResult;
- info.successCallback.call(args);
- }
- updateRequestIds.remove(id);
- } else if (sectionIndexRequestIds.constFind(id) != sectionIndexRequestIds.constEnd()) {
- CallbackInfo info = sectionIndexRequestIds.value(id);
- if (info.successCallback.isCallable()) {
- QVariantMap m = v.toMap();
- QVariantList items = m.value(QLatin1String("data")).toList();
- m = items.at(0).toMap();
- QJSValueList args;
- QJSValue scriptResult = info.successCallback.engine()->toScriptValue(id);
- args << scriptResult;
- scriptResult = info.successCallback.engine()->toScriptValue(m.value(QLatin1String("count")).toInt());
- args << scriptResult;
- info.successCallback.call(args);
- }
- sectionIndexRequestIds.remove(id);
}
}
@@ -1063,8 +1190,12 @@ void JsonDbListModelPrivate::resetModelFinished()
state = Ready;
emit q->stateChanged();
resetModel = false;
+ for (int i = 0; i<pendingNotifications.size(); i++) {
+ const NotifyItem &pending = pendingNotifications[i];
+ sendNotifications(pending.item, pending.action);
+ }
pendingNotifications.clear();
- createOrUpdateNotification();
+ //createOrUpdateNotification();
}
bool operator<(const QVariant& a, const QVariant& b)
@@ -1105,62 +1236,55 @@ bool JsonDbListModelPrivate::findSortOrder()
return true;
}
-void JsonDbListModelPrivate::_q_dbNotified(const QString &notify_uuid, const QtAddOn::JsonDb::JsonDbNotification &_notification)
+void JsonDbListModelPrivate::_q_notificationsAvailable()
{
- if (notify_uuid != notifyUuid) {
- return;
- }
- if (resetModel) {
- NotifyItem pending;
- pending.notifyUuid = notify_uuid;
- pending.item = _notification.object();
- pending.action = _notification.action();
- pendingNotifications.append(pending);
- } else {
- sendNotifications(_notification.object(), _notification.action());
+ QList<QJsonDbNotification> list = watcher->takeNotifications();
+ for (int i = 0; i < list.count(); i++) {
+ const QJsonDbNotification & notification = list[i];
+ QVariantMap object = notification.object().toVariantMap();
+ if (resetModel) {
+ NotifyItem pending;
+ pending.item = object;
+ pending.action = notification.action();
+ pendingNotifications.append(pending);
+ } else {
+ //qDebug()<<"Notify "<<object<<notification.action();
+ sendNotifications(object, notification.action());
+ }
}
}
-void JsonDbListModelPrivate::sendNotifications(const QVariant &v, JsonDbClient::NotifyType action)
+void JsonDbListModelPrivate::sendNotifications(const QVariantMap &v, QJsonDbWatcher::Action action)
{
- const QVariantMap &item = v.toMap();
- if (action == JsonDbClient::NotifyCreate) {
- insertItem(item);
- } else if (action == JsonDbClient::NotifyRemove) {
- deleteItem(item);
- } else if (action == JsonDbClient::NotifyUpdate) {
- updateItem(item);
+ if (action == QJsonDbWatcher::Created) {
+ insertItem(v);
+ } else if (action == QJsonDbWatcher::Removed) {
+ deleteItem(v);
+ } else if (action == QJsonDbWatcher::Updated) {
+ updateItem(v);
}
}
-void JsonDbListModelPrivate::_q_dbNotifyReadyResponse(int /* id */, const QVariant &/* result */)
+void JsonDbListModelPrivate::_q_notificationError(QtJsonDb::QJsonDbWatcher::ErrorCode code, const QString &message)
{
-}
-
-void JsonDbListModelPrivate::_q_dbNotifyErrorResponse(int id, int code, const QString &message)
-{
- Q_UNUSED(id);
+ Q_Q(JsonDbListModel);
qWarning() << QString("JsonDbListModel Notification error: %1 %2").arg(code).arg(message);
+ int oldErrorCode = errorCode;
+ errorCode = code;
+ errorString = message;
+ if (oldErrorCode != errorCode)
+ emit q->errorChanged(q->error());
}
-
-void JsonDbListModelPrivate::_q_jsonDbErrorResponse(int id, int code, const QString &message)
+void JsonDbListModelPrivate::_q_readError(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString & message)
{
- if (requestIds.contains(id)) {
- requestIds.remove(id);
- qWarning() << QString("JsonDb error: %1 %2").arg(code).arg(message);
- } else if (updateRequestIds.constFind(id) != updateRequestIds.constEnd()) {
- CallbackInfo info = updateRequestIds.value(id);
- if (info.errorCallback.isCallable()) {
- QJSValueList args;
- args << info.errorCallback.engine()->toScriptValue(id);
- args << info.errorCallback.engine()->toScriptValue(info.index);
- args << info.errorCallback.engine()->toScriptValue(code);
- args << info.errorCallback.engine()->toScriptValue(message);
- info.errorCallback.call(args);
- }
- updateRequestIds.remove(id);
- }
+ Q_Q(JsonDbListModel);
+ qWarning() << QString("JsonDbListModel error: %1 %2").arg(code).arg(message);
+ int oldErrorCode = errorCode;
+ errorCode = code;
+ errorString = message;
+ if (oldErrorCode != errorCode)
+ emit q->errorChanged(q->error());
}
/*!
@@ -1175,10 +1299,31 @@ QVariant JsonDbListModel::get(int idx, const QString &property) const
int role = roleFromString(property);
if (role >= 0)
return data(index(idx, 0), role);
- else
+ else {
+ qDebug()<<"JsonDbListModel::get Invalid role";
return QVariant();
+ }
}
+/*!
+ \qmlproperty object QtJsonDb::JsonDbListModel::error
+ \readonly
+
+ This property holds the current error information for the object. It contains:
+ \list
+ \o error.code - code for the current error.
+ \o error.message - detailed explanation of the error
+ \endlist
+*/
+
+QVariantMap JsonDbListModel::error() const
+{
+ Q_D(const JsonDbListModel);
+ QVariantMap errorMap;
+ errorMap.insert(QLatin1String("code"), d->errorCode);
+ errorMap.insert(QLatin1String("message"), d->errorString);
+ return errorMap;
+}
class JsonDbSortKeyPrivate : public QSharedData {
public:
diff --git a/src/imports/jsondb/jsondblistmodel.h b/src/imports/jsondb/jsondblistmodel.h
index 36494e6b..a054b52c 100644
--- a/src/imports/jsondb/jsondblistmodel.h
+++ b/src/imports/jsondb/jsondblistmodel.h
@@ -52,7 +52,7 @@
#include <QJSValue>
#include <QScopedPointer>
-#include "jsondb-global.h"
+#include <QJsonDbReadRequest>
#include "jsondbpartition.h"
QT_BEGIN_NAMESPACE_JSONDB
@@ -92,6 +92,7 @@ public:
Q_PROPERTY(int lowWaterMark READ lowWaterMark WRITE setLowWaterMark)
Q_PROPERTY(QVariant roleNames READ scriptableRoleNames WRITE setScriptableRoleNames)
Q_PROPERTY(JsonDbPartition* partition READ partition WRITE setPartition)
+ Q_PROPERTY(QVariantMap error READ error NOTIFY errorChanged)
virtual void classBegin();
virtual void componentComplete();
@@ -136,11 +137,13 @@ public:
const QJSValue &errorCallback = QJSValue(QJSValue::UndefinedValue));
Q_INVOKABLE int sectionIndex(const QString &section, const QJSValue &successCallback = QJSValue(QJSValue::UndefinedValue),
const QJSValue &errorCallback = QJSValue(QJSValue::UndefinedValue));
+ QVariantMap error() const;
signals:
void stateChanged() const;
void countChanged() const;
void rowCountChanged() const;
+ void errorChanged(QVariantMap newError);
private Q_SLOTS:
void partitionNameChanged(const QString &partitionName);
@@ -149,15 +152,39 @@ private:
Q_DISABLE_COPY(JsonDbListModel)
Q_DECLARE_PRIVATE(JsonDbListModel)
QScopedPointer<JsonDbListModelPrivate> d_ptr;
- Q_PRIVATE_SLOT(d_func(), void _q_jsonDbResponse(int, const QVariant&))
- Q_PRIVATE_SLOT(d_func(), void _q_jsonDbErrorResponse(int, int, const QString&))
Q_PRIVATE_SLOT(d_func(), void _q_requestAnotherChunk(int))
- Q_PRIVATE_SLOT(d_func(), void _q_dbNotified(QString, QtAddOn::JsonDb::JsonDbNotification))
- Q_PRIVATE_SLOT(d_func(), void _q_dbNotifyReadyResponse(int, QVariant))
- Q_PRIVATE_SLOT(d_func(), void _q_dbNotifyErrorResponse(int, int, QString))
+ Q_PRIVATE_SLOT(d_func(), void _q_notificationsAvailable())
+ Q_PRIVATE_SLOT(d_func(), void _q_notificationError(QtJsonDb::QJsonDbWatcher::ErrorCode, QString))
+ Q_PRIVATE_SLOT(d_func(), void _q_valueResponse(int, QList<QJsonObject>))
+ Q_PRIVATE_SLOT(d_func(), void _q_countResponse(int, QList<QJsonObject>))
+ Q_PRIVATE_SLOT(d_func(), void _q_readError(QtJsonDb::QJsonDbRequest::ErrorCode, QString))
+ Q_PRIVATE_SLOT(d_func(), void _q_sectionIndexResponse())
+ Q_PRIVATE_SLOT(d_func(), void _q_sectionIndexError(QtJsonDb::QJsonDbRequest::ErrorCode, QString))
+ Q_PRIVATE_SLOT(d_func(), void _q_updateResponse())
+ Q_PRIVATE_SLOT(d_func(), void _q_updateError(QtJsonDb::QJsonDbRequest::ErrorCode, QString))
};
+class ModelSyncCall : public QObject
+{
+ Q_OBJECT
+public:
+ ModelSyncCall(const QString &_query, int _offset, int _maxItems, const QString & _partitionName, QVariantList *_data);
+ ~ModelSyncCall();
+public Q_SLOTS:
+ void createSyncRequest();
+ void onQueryFinished();
+ void onQueryError(QtJsonDb::QJsonDbRequest::ErrorCode, const QString&);
+private:
+ QString query;
+ int offset;
+ int maxItems;
+ QString partitionName;
+ QVariantList *data;
+ QPointer<QJsonDbConnection> connection;
+ QPointer<QJsonDbReadRequest> request;
+};
+
QT_END_NAMESPACE_JSONDB
#endif
diff --git a/src/imports/jsondb/jsondblistmodel_p.h b/src/imports/jsondb/jsondblistmodel_p.h
index fd773b86..7852fa44 100644
--- a/src/imports/jsondb/jsondblistmodel_p.h
+++ b/src/imports/jsondb/jsondblistmodel_p.h
@@ -49,8 +49,10 @@
#include <QStringList>
#include <QPointer>
-#include "jsondb-client.h"
-#include "private/jsondb-connection_p.h"
+
+#include <QJsonDbWatcher>
+#include <QJsonDbReadRequest>
+#include <QJsonDbUpdateRequest>
#include "jsondbmodelutils.h"
QT_BEGIN_NAMESPACE_JSONDB
@@ -72,10 +74,8 @@ public:
int cacheEnd;
int newChunkOffset;
- QSet<int> requestIds;
- QMap<int, CallbackInfo> updateRequestIds;
- QMap<int, CallbackInfo> sectionIndexRequestIds;
- int totalCountRequestId;
+ QMap< QPointer<QJsonDbWriteRequest>, CallbackInfo> updateCallbacks;
+ QMap< QPointer<QJsonDbReadRequest>, CallbackInfo> sectionIndexCallbacks;
QHash<QString,QVariantMap> data; // cache that holds all the items.
QMultiMap<JsonDbSortKey,QString> objectUuids; // sort value -> uuid
@@ -94,15 +94,17 @@ public:
bool requestInProgress;
bool componentComplete;
bool resetModel;
- bool updateRecieved;
+ bool updateReceived;
bool totalRowCountRecieved;
- QString notifyUuid;
QVariantMap roleMap;
QHash<int,QByteArray> roleNames;
QHash<int,QStringList> properties;
QList<NotifyItem> pendingNotifications;
+ ModelRequest valueRequest;
+ ModelRequest countRequest;
+ QPointer<QJsonDbWatcher> watcher;
enum State {
None,
@@ -110,9 +112,9 @@ public:
Ready
};
State state;
-
- JsonDbClient jsonDb;
- JsonDbConnection *jsonDbConnection;
+ QModelIndex parent;
+ int errorCode;
+ QString errorString;
public:
JsonDbListModelPrivate(JsonDbListModel *q);
@@ -130,26 +132,31 @@ public:
QVariantMap getItem(const QModelIndex &modelIndex, int role, bool handleCacheMiss, bool &cacheMiss);
void set(int index, const QJSValue& valuemap, const QJSValue &successCallback,
const QJSValue &errorCallback);
- void setProperty(int index, const QString& property, const QVariant& value, const QJSValue &successCallback,
- const QJSValue &errorCallback);
+ void setProperty(int index, const QString& property, const QVariant& value,
+ const QJSValue &successCallback, const QJSValue &errorCallback);
void fetchChunkSynchronous(int offset);
- void updateCache(const QVariantMap &v);
+ void updateCache(const QVariantList &items);
void resetModelFinished();
-
- // private slots
- void _q_jsonDbResponse(int , const QVariant &);
- void _q_jsonDbNotified(const QString&, const QVariant &, const QString &);
- void _q_jsonDbErrorResponse(int , int, const QString&);
+ void update(int index, const QVariantMap &item,
+ const QJSValue &successCallback, const QJSValue &errorCallback);
void _q_requestAnotherChunk(int offset);
- void _q_dbNotified(const QString &notify_uuid, const QtAddOn::JsonDb::JsonDbNotification &_notification);
- void _q_dbNotifyReadyResponse(int /* id */, const QVariant &/* result */);
- void _q_dbNotifyErrorResponse(int id, int code, const QString &message);
- void sendNotifications(const QVariant &v, JsonDbClient::NotifyType action);
+ void _q_notificationsAvailable();
+ void _q_notificationError(QtJsonDb::QJsonDbWatcher::ErrorCode code, const QString &message);
+ void _q_valueResponse(int , const QList<QJsonObject>&);
+ void _q_countResponse(int , const QList<QJsonObject>&);
+ void _q_readError(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString & message);
+ void _q_sectionIndexResponse();
+ void _q_sectionIndexError(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString & message);
+ void _q_updateResponse();
+ void _q_updateError(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString & message);
+
+ void sendNotifications(const QVariantMap &v, QJsonDbWatcher::Action action);
void populateModel();
+ void clearNotification();
void createOrUpdateNotification();
bool findSortOrder();
diff --git a/src/imports/jsondb/jsondbmodelcache.cpp b/src/imports/jsondb/jsondbmodelcache.cpp
index c9817ba0..0e01cd9b 100644
--- a/src/imports/jsondb/jsondbmodelcache.cpp
+++ b/src/imports/jsondb/jsondbmodelcache.cpp
@@ -62,7 +62,7 @@ bool ModelPage::hasIndex(int pos)
return (pos >= index && pos < (index+count));
}
-QVariantMap ModelPage::value(const QString &key)
+QJsonObject ModelPage::value(const QString &key)
{
counter = ++ModelCache::currentCounter;
return objects.value(key);
@@ -74,7 +74,7 @@ bool ModelPage::hasValue(const QString &key)
return objects.contains(key);
}
-bool ModelPage::insert(int pos, const QString &key, const QVariantMap &value)
+bool ModelPage::insert(int pos, const QString &key, const QJsonObject &value)
{
// allow adding a consecutive item
if (pos >= index && pos <= (index+count)) {
@@ -86,7 +86,7 @@ bool ModelPage::insert(int pos, const QString &key, const QVariantMap &value)
return false;
}
-bool ModelPage::update(const QString &key, const QVariantMap &value)
+bool ModelPage::update(const QString &key, const QJsonObject &value)
{
bool ret = (objects.remove(key) >= 1);
if (ret) {
@@ -139,9 +139,10 @@ int ModelCache::findPage(int pos)
return -1;
}
-QVariantMap ModelCache::valueAtPage(int page, const QString &key)
+QJsonObject ModelCache::valueAtPage(int page, const QString &key)
{
Q_ASSERT(page >= 0 && page < pages.count());
+ QJsonObject o = pages[page]->value(key);
return pages[page]->value(key);
}
@@ -163,7 +164,7 @@ void ModelCache::splitPage(int page, const JsonDbModelIndexType &objectUuids)
for (int i = halfPage->index; i < halfPage->index+halfPage->count; i++) {
// transfer the items to the new page
const QString &key = (begin+i).value();
- const QVariantMap &value = pages[page]->value(key);
+ const QJsonObject &value = pages[page]->value(key);
halfPage->objects.insert(key, value);
pages[page]->objects.remove(key);
}
@@ -171,7 +172,7 @@ void ModelCache::splitPage(int page, const JsonDbModelIndexType &objectUuids)
pages.append(halfPage);
}
-bool ModelCache::insert(int pos, const QString &key, const QVariantMap &value,
+bool ModelCache::insert(int pos, const QString &key, const QJsonObject &value,
const JsonDbModelIndexType &objectUuids)
{
if (!pages.count()) {
@@ -218,7 +219,7 @@ int ModelCache::count()
return items;
}
-bool ModelCache::update(const QString &key, const QVariantMap &value)
+bool ModelCache::update(const QString &key, const QJsonObject &value)
{
for (int i = 0; i < pages.count(); i++) {
if (pages[i]->update(key, value))
@@ -296,7 +297,11 @@ void ModelCache::addObjects(int index, const JsonDbModelIndexType &objectUuids,
newPage->index = j;
for (; j < index+count && j < maxIndexForPage; j++) {
const QString &key = (begin+j).value();
- const QVariantMap& value = objects.value(key);
+ const QJsonObject& value = objects.value(key);
+#ifdef JSONDB_LISTMODEL_DEBUG
+ if (value.isEmpty()) // Could be an assert instead?
+ qDebug() << "##################Empty value###############" << key;
+#endif
newPage->objects.insert(key, value);
}
newPage->count = newPage->objects.count();
diff --git a/src/imports/jsondb/jsondbmodelcache.h b/src/imports/jsondb/jsondbmodelcache.h
index 3b0e8ace..83ace7d9 100644
--- a/src/imports/jsondb/jsondbmodelcache.h
+++ b/src/imports/jsondb/jsondbmodelcache.h
@@ -46,13 +46,13 @@
#include <QHash>
#include <QObject>
#include <QList>
-#include <QVariantMap>
+#include <QJsonObject>
#include "jsondbmodelutils.h"
QT_BEGIN_NAMESPACE_JSONDB
typedef QMap<SortingKey, QString> JsonDbModelIndexType;
-typedef QHash<QString, QVariantMap> JsonDbModelObjectType;
+typedef QHash<QString, QJsonObject> JsonDbModelObjectType;
class ModelPage
{
@@ -66,11 +66,11 @@ public:
ModelPage();
~ModelPage();
bool hasIndex(int pos);
- QVariantMap value(const QString & key);
+ QJsonObject value(const QString & key);
bool hasValue(const QString &key);
- bool insert(int pos, const QString &key, const QVariantMap &vlaue);
- bool update(const QString &key, const QVariantMap &value);
+ bool insert(int pos, const QString &key, const QJsonObject &vlaue);
+ bool update(const QString &key, const QJsonObject &value);
bool remove(int pos, const QString &key);
void dumpPageDetails();
};
@@ -88,12 +88,12 @@ public:
void clear();
int findPage(int pos);
- QVariantMap valueAtPage(int page, const QString & key);
+ QJsonObject valueAtPage(int page, const QString & key);
bool hasValueAtPage(int page, const QString &key);
- bool insert(int pos, const QString &key, const QVariantMap &vlaue,
+ bool insert(int pos, const QString &key, const QJsonObject &vlaue,
const JsonDbModelIndexType &objectUuids);
- bool update(const QString &key, const QVariantMap &value);
+ bool update(const QString &key, const QJsonObject &value);
bool remove(int pos, const QString &key);
void splitPage(int pageno, const JsonDbModelIndexType &objectUuids);
diff --git a/src/imports/jsondb/jsondbmodelutils.cpp b/src/imports/jsondb/jsondbmodelutils.cpp
index 2f48c4dc..5cadd271 100644
--- a/src/imports/jsondb/jsondbmodelutils.cpp
+++ b/src/imports/jsondb/jsondbmodelutils.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include "jsondbmodelutils.h"
+#include <qdebug.h>
QT_BEGIN_NAMESPACE_JSONDB
@@ -59,6 +60,11 @@ SortingKey::SortingKey(int partitionIndex, const QVariantList &object, const QLi
d = new SortingKeyPrivate(partitionIndex, uuid, directions, values, spec);
}
+SortingKey::SortingKey(int partitionIndex, const QByteArray &uuid, const QVariantList &object, const QList<bool> &directions, const SortIndexSpec &spec)
+{
+ d = new SortingKeyPrivate(partitionIndex, uuid, directions, object, spec);
+}
+
SortingKey::SortingKey(const SortingKey &other)
:d(other.d)
{
@@ -106,14 +112,17 @@ bool SortingKey::operator <(const SortingKey &rhs) const
// The index spec is only applied to the first item
if (!i && (dLhs->indexSpec.type == SortIndexSpec::String || dLhs->indexSpec.type == SortIndexSpec::UUID)) {
if ((cmp = equalWithSpec(lhsValue, rhsValue, dLhs->indexSpec))) {
- return (dLhs->directions[i] ? (cmp < 0) : !(cmp < 0));
+ return (dLhs->directions[i] ? (cmp < 0) : (cmp > 0));
}
} else if (lhsValue != rhsValue) {
- bool result = lhsValue < rhsValue;
- return (dLhs->directions[i] ? result :!result);
+ return (dLhs->directions[i] ? lhsValue < rhsValue : rhsValue < lhsValue);
}
}
- return (memcmp(dLhs->uuid.constData(), dRhs->uuid.constData(), qMin(dLhs->uuid.size(), dRhs->uuid.size())) < 0);
+ int cmp = memcmp(dLhs->uuid.constData(), dRhs->uuid.constData(), qMin(dLhs->uuid.size(), dRhs->uuid.size()));
+ // In case of even score jsondb sorts according to _uuid in the same direction as the last sort item
+ if (nKeys)
+ return (dLhs->directions[0] ? (cmp < 0) : (cmp > 0));
+ return (cmp < 0);
}
bool SortingKey::operator ==(const SortingKey &rhs) const
@@ -200,4 +209,43 @@ QString removeArrayOperator(QString propertyName)
return propertyName;
}
+
+ModelRequest::ModelRequest(QObject *parent)
+ :QObject(parent)
+{
+}
+
+ModelRequest::~ModelRequest()
+{
+ resetRequest();
+}
+
+QJsonDbReadRequest* ModelRequest::newRequest(int newIndex)
+{
+ resetRequest();
+ index = newIndex;
+ request = new QJsonDbReadRequest();
+ connect(request, SIGNAL(finished()), this, SLOT(onQueryFinished()));
+ connect(request, SIGNAL(finished()), request, SLOT(deleteLater()));
+ connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ this, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)));
+ connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ request, SLOT(deleteLater()));
+ return request;
+}
+
+void ModelRequest::resetRequest()
+{
+ if (request) {
+ delete request;
+ request = 0;
+ }
+}
+
+void ModelRequest::onQueryFinished()
+{
+ emit finished(index, request->takeResults(), request->sortKey());
+}
+
+#include "moc_jsondbmodelutils.cpp"
QT_END_NAMESPACE_JSONDB
diff --git a/src/imports/jsondb/jsondbmodelutils.h b/src/imports/jsondb/jsondbmodelutils.h
index 48ac8c39..10d27986 100644
--- a/src/imports/jsondb/jsondbmodelutils.h
+++ b/src/imports/jsondb/jsondbmodelutils.h
@@ -39,7 +39,6 @@
**
****************************************************************************/
-
#ifndef JSONDBMODELUTILS_H
#define JSONDBMODELUTILS_H
#include <QSharedData>
@@ -47,7 +46,9 @@
#include <QUuid>
#include <QJSValue>
#include <QVariant>
-#include "jsondb-client.h"
+#include <QPointer>
+#include <QJsonDbWatcher>
+#include <QJsonDbReadRequest>
QT_BEGIN_NAMESPACE_JSONDB
@@ -57,16 +58,21 @@ struct CallbackInfo {
QJSValue errorCallback;
};
+struct NotificationItem {
+ int partitionIndex;
+ QJsonObject item;
+ QJsonDbWatcher::Action action;
+};
+
struct NotifyItem {
- QString notifyUuid;
- QVariant item;
- JsonDbClient::NotifyType action;
+ int partitionIndex;
+ QVariantMap item;
+ QJsonDbWatcher::Action action;
};
struct SortIndexSpec
{
QString propertyName;
- QString propertyType; //### TODO remove
QString name;
bool caseSensitive;
enum Type { None, String, Number, UUID };
@@ -75,13 +81,35 @@ struct SortIndexSpec
SortIndexSpec() : caseSensitive(false), type(SortIndexSpec::None) {}
SortIndexSpec(const SortIndexSpec &other)
: propertyName(other.propertyName),
- propertyType(other.propertyType),
name(other.name),
caseSensitive(other.caseSensitive),
type(other.type)
{}
};
+class JsonDbListModelPrivate;
+class ModelRequest : public QObject
+{
+ friend class JsonDbListModelPrivate;
+ Q_OBJECT
+public:
+
+ ModelRequest(QObject *parent = 0);
+ ~ModelRequest();
+
+ QJsonDbReadRequest* newRequest(int newIndex);
+ void resetRequest();
+Q_SIGNALS:
+ void finished(int index, const QList<QJsonObject> &items, const QString &sortKey);
+ void error(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString &message);
+
+private Q_SLOTS:
+ void onQueryFinished();
+
+private:
+ QPointer<QJsonDbReadRequest> request;
+ int index;
+};
struct IndexInfo
{
@@ -102,6 +130,7 @@ class SortingKey {
public:
SortingKey(int partitionIndex, const QVariantMap &object, const QList<bool> &directions, const QList<QStringList> &paths, const SortIndexSpec &spec = SortIndexSpec());
SortingKey(int partitionIndex, const QVariantList &object, const QList<bool> &directions, const SortIndexSpec &spec = SortIndexSpec());
+ SortingKey(int partitionIndex, const QByteArray &uuid, const QVariantList &object, const QList<bool> &directions, const SortIndexSpec &spec = SortIndexSpec());
SortingKey(const SortingKey&);
SortingKey() {}
int partitionIndex() const;
@@ -113,20 +142,21 @@ private:
struct RequestInfo
{
- int requestId;
int lastOffset;
- QString notifyUuid;
int lastSize;
int requestCount;
+ QPointer<QJsonDbWatcher> watcher;
RequestInfo() { clear();}
void clear()
{
- requestId = -1;
lastOffset = 0;
lastSize = -1;
requestCount = 0;
- notifyUuid.clear();
+ if (watcher) {
+ delete watcher;
+ watcher = 0;
+ }
}
};
@@ -168,6 +198,8 @@ template <typename T> int iterator_position(T &begin, T &end, T &value)
QVariant lookupProperty(QVariantMap object, const QStringList &path);
QString removeArrayOperator(QString propertyName);
+QList<QJsonObject> qvariantlist_to_qjsonobject_list(const QVariantList &list);
+QVariantList qjsonobject_list_to_qvariantlist(const QList<QJsonObject> &list);
QT_END_NAMESPACE_JSONDB
diff --git a/src/imports/jsondb/jsondbnotification.cpp b/src/imports/jsondb/jsondbnotification.cpp
index f55b6075..65d74d70 100644
--- a/src/imports/jsondb/jsondbnotification.cpp
+++ b/src/imports/jsondb/jsondbnotification.cpp
@@ -38,11 +38,10 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-#include "jsondb-global.h"
#include "jsondbnotification.h"
#include "jsondbpartition.h"
-#include "private/jsondb-strings_p.h"
#include "plugin.h"
+#include <QJsonDbNotification>
#include <qdebug.h>
QT_BEGIN_NAMESPACE_JSONDB
@@ -118,6 +117,10 @@ JsonDbNotify::JsonDbNotify(QObject *parent)
JsonDbNotify::~JsonDbNotify()
{
+ if (partitionObject && active && watcher)
+ partitionObject->removeNotification(this);
+ if (watcher)
+ delete watcher;
if (defaultPartitionObject)
delete defaultPartitionObject;
}
@@ -347,11 +350,32 @@ void JsonDbNotify::init()
}
if (partitionObject && active) {
// remove the current notification
- partitionObject->removeNotification(this);
+ if (watcher) {
+ partitionObject->removeNotification(this);
+ delete watcher;
+ }
+ watcher = new QJsonDbWatcher();
+ watcher->setQuery(queryString);
+ QJsonDbWatcher::Actions actions;
+ if (actionsList.isEmpty()) {
+ actions = QJsonDbWatcher::Created | QJsonDbWatcher::Updated |QJsonDbWatcher::Removed;
+ } else {
+ if (actionsList.contains(JsonDbNotify::Create))
+ actions |= QJsonDbWatcher::Created;
+ if (actionsList.contains(JsonDbNotify::Update))
+ actions |= QJsonDbWatcher::Updated;
+ if (actionsList.contains(JsonDbNotify::Remove))
+ actions |= QJsonDbWatcher::Removed;
+ }
+ watcher->setWatchedActions(actions);
+ watcher->setPartition(partitionObject->name());
+ QObject::connect(watcher, SIGNAL(notificationsAvailable(int)),
+ this, SLOT(onNotificationsAvailable()));
+ QObject::connect(watcher, SIGNAL(statusChanged(QtJsonDb::QJsonDbWatcher::Status)),
+ this, SLOT(onStatusChanged(QtJsonDb::QJsonDbWatcher::Status)));
+ QObject::connect(watcher, SIGNAL(error(QtJsonDb::QJsonDbWatcher::ErrorCode,QString)),
+ this, SLOT(onNotificationError(QtJsonDb::QJsonDbWatcher::ErrorCode,QString)));
partitionObject->updateNotification(this);
- objectStatus = JsonDbNotify::Registering;
- if (objectStatus != oldStatus)
- emit statusChanged(objectStatus);
}
}
@@ -370,42 +394,54 @@ bool JsonDbNotify::parametersReady()
return (completed && !queryString.isEmpty() && actionsList.count() && partitionObject);
}
-void JsonDbNotify::dbNotified(const QString &notify_uuid, const QtAddOn::JsonDb::JsonDbNotification &_notification)
+void JsonDbNotify::onNotificationsAvailable()
{
- Q_UNUSED(notify_uuid);
if (objectStatus != JsonDbNotify::Ready) {
clearError();
objectStatus = JsonDbNotify::Ready;
emit statusChanged(objectStatus);
}
- if (active) {
- QJSValue obj = g_declEngine->toScriptValue(QVariant(_notification.object()));
- emit notification(obj, (Actions)_notification.action(), _notification.stateNumber());
+ if (active && watcher) {
+ QList<QJsonDbNotification> list = watcher->takeNotifications();
+ for (int i = 0; i < list.count(); i++) {
+ const QJsonDbNotification & _notification = list[i];
+ QJSValue obj = g_declEngine->toScriptValue(_notification.object().toVariantMap());
+ emit notification(obj, (Actions)_notification.action(), _notification.stateNumber());
+ }
}
}
-void JsonDbNotify::dbNotifyReadyResponse(int id, const QVariant &result)
+void JsonDbNotify::onStatusChanged(QtJsonDb::QJsonDbWatcher::Status newStatus)
{
- Q_UNUSED(id);
- Q_UNUSED(result);
+ JsonDbNotify::Status oldStatus = objectStatus;
+ switch (newStatus) {
+ case QJsonDbWatcher::Inactive:
+ objectStatus = JsonDbNotify::Null;
+ break;
+ case QJsonDbWatcher::Activating:
+ objectStatus = JsonDbNotify::Registering;
+ break;
+ case QJsonDbWatcher::Active:
+ objectStatus = JsonDbNotify::Ready;
+ break;
+ }
clearError();
- if (objectStatus != JsonDbNotify::Ready) {
- objectStatus = JsonDbNotify::Ready;
+ if (oldStatus != objectStatus) {
emit statusChanged(objectStatus);
}
}
-void JsonDbNotify::dbNotifyErrorResponse(int id, int code, const QString &message)
+void JsonDbNotify::onNotificationError(QtJsonDb::QJsonDbWatcher::ErrorCode code, const QString &message)
{
- Q_UNUSED(id);
int oldErrorCode = errorCode;
errorCode = code;
errorString = message;
- if (objectStatus != JsonDbNotify::Error) {
+ bool changed = (objectStatus != JsonDbNotify::Error);
+ if (changed) {
objectStatus = JsonDbNotify::Error;
emit statusChanged(objectStatus);
}
- if (oldErrorCode != errorCode) {
+ if (oldErrorCode != errorCode || changed) {
emit errorChanged(error());
}
}
diff --git a/src/imports/jsondb/jsondbnotification.h b/src/imports/jsondb/jsondbnotification.h
index 3957cd51..87af9928 100644
--- a/src/imports/jsondb/jsondbnotification.h
+++ b/src/imports/jsondb/jsondbnotification.h
@@ -48,7 +48,7 @@
#include <QJSValue>
#include <QQmlParserStatus>
#include <QQmlListProperty>
-#include "jsondb-client.h"
+#include <QJsonDbWatcher>
QT_BEGIN_NAMESPACE_JSONDB
@@ -102,10 +102,9 @@ Q_SIGNALS:
private Q_SLOTS:
void partitionNameChanged(const QString &partitionName);
- void dbNotified(const QString &notify_uuid, const QtAddOn::JsonDb::JsonDbNotification &_notification);
- void dbNotifyReadyResponse(int id, const QVariant &result);
- void dbNotifyErrorResponse(int id, int code, const QString &message);
-
+ void onNotificationsAvailable();
+ void onStatusChanged(QtJsonDb::QJsonDbWatcher::Status newStatus);
+ void onNotificationError(QtJsonDb::QJsonDbWatcher::ErrorCode code, const QString &message);
private:
bool completed;
QString queryString;
@@ -118,6 +117,7 @@ private:
QString errorString;
Status objectStatus;
bool active;
+ QPointer<QJsonDbWatcher> watcher;
void init();
void clearError();
diff --git a/src/imports/jsondb/jsondbpartition.cpp b/src/imports/jsondb/jsondbpartition.cpp
index 23023176..040e047e 100644
--- a/src/imports/jsondb/jsondbpartition.cpp
+++ b/src/imports/jsondb/jsondbpartition.cpp
@@ -38,14 +38,13 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-
-#include "private/jsondb-strings_p.h"
#include "jsondbpartition.h"
+#include "jsondatabase.h"
#include "jsondbnotification.h"
#include "plugin.h"
-#include "jsondb-client.h"
#include "jsondbqueryobject.h"
-#include "jsondbchangessinceobject.h"
+#include <QJsonDbCreateRequest>
+#include <private/qjsondbstrings_p.h>
#include <qdebug.h>
QT_BEGIN_NAMESPACE_JSONDB
@@ -67,12 +66,9 @@ JsonDbPartition::JsonDbPartition(const QString &partitionName, QObject *parent)
:QObject(parent)
,_name(partitionName)
{
- connect(&jsonDb, SIGNAL(response(int,const QVariant&)),
- this, SLOT(dbResponse(int,const QVariant&)));
- connect(&jsonDb, SIGNAL(error(int,int,QString)),
- this, SLOT(dbErrorResponse(int,int,QString)));
}
+
JsonDbPartition::~JsonDbPartition()
{
}
@@ -91,10 +87,10 @@ void JsonDbPartition::setName(const QString &partitionName)
{
if (partitionName != _name) {
_name = partitionName;
- foreach (QPointer<JsonDbNotify> notify, notifications) {
- removeNotification(notify);
+ foreach (QPointer<QJsonDbWatcher> watcher, watchers) {
+ JsonDatabase::sharedConnection().removeWatcher(watcher);
}
- notifications.clear();
+ watchers.clear();
// tell notifications to resubscribe
emit nameChanged(partitionName);
}
@@ -112,6 +108,27 @@ static QVariant qjsvalue_to_qvariant(const QJSValue &value)
}
}
}
+
+QList<QJsonObject> qvariantlist_to_qjsonobject_list(const QVariantList &list)
+{
+ QList<QJsonObject> objects;
+ int count = list.count();
+ for (int i = 0; i < count; i++) {
+ objects.append(QJsonObject::fromVariantMap(list[i].toMap()));
+ }
+ return objects;
+}
+
+QVariantList qjsonobject_list_to_qvariantlist(const QList<QJsonObject> &list)
+{
+ QVariantList objects;
+ int count = list.count();
+ for (int i = 0; i < count; i++) {
+ objects.append(list[i].toVariantMap());
+ }
+ return objects;
+}
+
/*!
\qmlmethod int QtJsonDb::Partition::create(object newObject, object options, function callback)
@@ -168,9 +185,23 @@ int JsonDbPartition::create(const QJSValue &object, const QJSValue &options, co
actualOptions = QJSValue(QJSValue::UndefinedValue);
}
//#TODO ADD options
- int id = jsonDb.create(qjsvalue_to_qvariant(object), _name);
- createCallbacks.insert(id, actualCallback);
- return id;
+ QVariant obj = qjsvalue_to_qvariant(object);
+ QJsonDbWriteRequest *request(0);
+ if (obj.type() == QVariant::List) {
+ request = new QJsonDbCreateRequest(qvariantlist_to_qjsonobject_list(obj.toList()));
+ } else {
+ request = new QJsonDbCreateRequest(QJsonObject::fromVariantMap(obj.toMap()));
+ }
+ request->setPartition(_name);
+ connect(request, SIGNAL(finished()), this, SLOT(requestFinished()));
+ connect(request, SIGNAL(finished()), request, SLOT(deleteLater()));
+ connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ this, SLOT(requestError(QtJsonDb::QJsonDbRequest::ErrorCode,QString)));
+ connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ request, SLOT(deleteLater()));
+ JsonDatabase::sharedConnection().send(request);
+ writeCallbacks.insert(request, actualCallback);
+ return request->property("requestId").toInt();
}
/*!
@@ -241,9 +272,23 @@ int JsonDbPartition::update(const QJSValue &object, const QJSValue &options, co
actualOptions = QJSValue(QJSValue::UndefinedValue);
}
//#TODO ADD options
- int id = jsonDb.update(qjsvalue_to_qvariant(object), _name);
- updateCallbacks.insert(id, actualCallback);
- return id;
+ QVariant obj = qjsvalue_to_qvariant(object);
+ QJsonDbWriteRequest *request(0);
+ if (obj.type() == QVariant::List) {
+ request = new QJsonDbUpdateRequest(qvariantlist_to_qjsonobject_list(obj.toList()));
+ } else {
+ request = new QJsonDbUpdateRequest(QJsonObject::fromVariantMap(obj.toMap()));
+ }
+ request->setPartition(_name);
+ connect(request, SIGNAL(finished()), this, SLOT(requestFinished()));
+ connect(request, SIGNAL(finished()), request, SLOT(deleteLater()));
+ connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ this, SLOT(requestError(QtJsonDb::QJsonDbRequest::ErrorCode,QString)));
+ connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ request, SLOT(deleteLater()));
+ JsonDatabase::sharedConnection().send(request);
+ writeCallbacks.insert(request, actualCallback);
+ return request->property("requestId").toInt();
}
/*!
@@ -306,9 +351,23 @@ int JsonDbPartition::remove(const QJSValue &object, const QJSValue &options, co
actualOptions = QJSValue(QJSValue::UndefinedValue);
}
//#TODO ADD options
- int id = jsonDb.remove(qjsvalue_to_qvariant(object), _name);
- removeCallbacks.insert(id, actualCallback);
- return id;
+ QVariant obj = qjsvalue_to_qvariant(object);
+ QJsonDbWriteRequest *request(0);
+ if (obj.type() == QVariant::List) {
+ request = new QJsonDbRemoveRequest(qvariantlist_to_qjsonobject_list(obj.toList()));
+ } else {
+ request = new QJsonDbRemoveRequest(QJsonObject::fromVariantMap(obj.toMap()));
+ }
+ request->setPartition(_name);
+ connect(request, SIGNAL(finished()), this, SLOT(requestFinished()));
+ connect(request, SIGNAL(finished()), request, SLOT(deleteLater()));
+ connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ this, SLOT(requestError(QtJsonDb::QJsonDbRequest::ErrorCode,QString)));
+ connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ request, SLOT(deleteLater()));
+ JsonDatabase::sharedConnection().send(request);
+ writeCallbacks.insert(request, actualCallback);
+ return request->property("requestId").toInt();
}
/*!
@@ -457,45 +516,6 @@ JsonDbQueryObject* JsonDbPartition::createQuery(const QString &query, int limit,
return queryObject;
}
-/*!
- \qmlmethod object QtJsonDb::Partition::createChangesSince(stateNumber, types)
-
- Create the ChangesSince object. It will set the \a stateNumber, filter \a types parameters
- of the object. Users have to call start() to start the changesSince query in this partition.
- The script engine decides the life time of the returned object. The returned object can be
- saved in a 'property var' until it is required.
-
- \code
- import QtJsonDb 1.0 as JsonDb
- property var changesObject;
- function onFinished()
- {
- var results = queryObject.takeResults();
- console.log("Results: Count + results.length );
- }
-
- Component.onCompleted: {
- changesObject = nokiaPartition.createChangesSince(10, ["Contact"]);
- changesObject.finished.connect(onFinished);
- changesObject.start();
-
- }
- \endcode
- \sa QtJsonDb::ChangesSince
-
-*/
-
-JsonDbChangesSinceObject* JsonDbPartition::createChangesSince(int stateNumber, const QStringList &types)
-{
- JsonDbChangesSinceObject* changesSinceObject = new JsonDbChangesSinceObject();
- changesSinceObject->setTypes(types);
- changesSinceObject->setStateNumber(stateNumber);
- changesSinceObject->setPartition(this);
- changesSinceObject->componentComplete();
- QQmlEngine::setObjectOwnership(changesSinceObject, QQmlEngine::JavaScriptOwnership);
- return changesSinceObject;
-}
-
QQmlListProperty<QObject> JsonDbPartition::childElements()
{
return QQmlListProperty<QObject>(this, childQMLElements);
@@ -503,65 +523,47 @@ QQmlListProperty<QObject> JsonDbPartition::childElements()
void JsonDbPartition::updateNotification(JsonDbNotify *notify)
{
- JsonDbClient::NotifyTypes notifyActions = JsonDbClient::NotifyCreate
- | JsonDbClient::NotifyUpdate| JsonDbClient::NotifyRemove;
- notify->uuid= jsonDb.registerNotification(notifyActions, notify->query(), _name
- , notify, SLOT(dbNotified(QString,QtAddOn::JsonDb::JsonDbNotification))
- , notify, SLOT(dbNotifyReadyResponse(int,QVariant))
- , SLOT(dbNotifyErrorResponse(int,int,QString)));
- notifications.insert(notify->uuid, notify);
+ JsonDatabase::sharedConnection().addWatcher(notify->watcher);
+ watchers.append(notify->watcher);
}
-
void JsonDbPartition::removeNotification(JsonDbNotify *notify)
{
- if (notifications.contains(notify->uuid)) {
- jsonDb.unregisterNotification(notify->uuid);
- notifications.remove(notify->uuid);
+ if (watchers.contains(notify->watcher)) {
+ JsonDatabase::sharedConnection().removeWatcher(notify->watcher);
+ watchers.removeAll(notify->watcher);
}
}
-void JsonDbPartition::call(QMap<int, QJSValue> &callbacks, int id, const QVariant &result)
+void JsonDbPartition::call(QMap<QJsonDbWriteRequest*, QJSValue> &callbacks, QJsonDbWriteRequest *request)
{
- // Make sure that id exists in the map.
- QJSValue callback = callbacks[id];
+ QJSValue callback = callbacks[request];
QJSEngine *engine = callback.engine();
if (!engine) {
- callbacks.remove(id);
+ callbacks.remove(request);
return;
}
+ QList<QJsonObject> objects = request->takeResults();
QJSValueList args;
- QVariantMap object = result.toMap();
// object : id , statenumber , items
QJSValue response= engine->newObject();
- response.setProperty(JsonDbString::kStateNumberStr, object.value(JsonDbString::kStateNumberStr).toInt());
- response.setProperty(JsonDbString::kIdStr, id);
+ response.setProperty(JsonDbStrings::Protocol::stateNumber(), request->stateNumber());
+ response.setProperty(JsonDbStrings::Protocol::requestId(), request->property("requestId").toInt());
+ QJSValue items = engine->toScriptValue(qjsonobject_list_to_qvariantlist(objects));
+ response.setProperty(QLatin1String("items"), items);
- // response object : object { _version & _uuid } (can be a list)
- if (object.contains(QLatin1String("data"))) {
- QJSValue items = engine->toScriptValue(object.value(QLatin1String("data")));
- response.setProperty(QLatin1String("items"), items);
- } else {
- // Create an array with a single element
- QJSValue responseObject = engine->newObject();
- responseObject.setProperty(JsonDbString::kUuidStr, object.value(JsonDbString::kUuidStr).toString());
- responseObject.setProperty(JsonDbString::kVersionStr, object.value(JsonDbString::kVersionStr).toString());
- QJSValue items = engine->newArray(1);
- items.setProperty(0, responseObject);
- response.setProperty(QLatin1String("items"), items);
- }
args << QJSValue(QJSValue::UndefinedValue) << response;
callback.call(args);
- callbacks.remove(id);
+ callbacks.remove(request);
}
-void JsonDbPartition::callErrorCallback(QMap<int, QJSValue> &callbacks, int id, int code, const QString &message)
+void JsonDbPartition::callErrorCallback(QMap<QJsonDbWriteRequest*, QJSValue> &callbacks, QJsonDbWriteRequest *request,
+ QtJsonDb::QJsonDbRequest::ErrorCode code, const QString &message)
{
- // Make sure that id exists in the map.
- QJSValue callback = callbacks[id];
+ QJSValue callback = callbacks[request];
QJSEngine *engine = callback.engine();
if (!engine) {
- callbacks.remove(id);
+ callbacks.remove(request);
return;
}
QJSValueList args;
@@ -571,36 +573,13 @@ void JsonDbPartition::callErrorCallback(QMap<int, QJSValue> &callbacks, int id,
// object : id
QJSValue response = engine->newObject();
- response.setProperty(JsonDbString::kStateNumberStr, -1);
- response.setProperty(JsonDbString::kIdStr, id);
+ response.setProperty(JsonDbStrings::Protocol::stateNumber(), -1);
+ response.setProperty(JsonDbStrings::Protocol::requestId(), request->property("requestId").toInt());
response.setProperty(QLatin1String("items"), engine->newArray());
args << engine->toScriptValue(QVariant(error))<< response;
callback.call(args);
- callbacks.remove(id);
-}
-
-
-void JsonDbPartition::dbResponse(int id, const QVariant &result)
-{
- if (createCallbacks.contains(id)) {
- call(createCallbacks, id, result);
- } else if (updateCallbacks.contains(id)) {
- call(updateCallbacks, id, result);
- } else if (removeCallbacks.contains(id)) {
- call(removeCallbacks, id, result);
- }
-}
-
-void JsonDbPartition::dbErrorResponse(int id, int code, const QString &message)
-{
- if (createCallbacks.contains(id)) {
- callErrorCallback(createCallbacks, id, code, message);
- } else if (removeCallbacks.contains(id)) {
- callErrorCallback(removeCallbacks, id, code, message);
- } else if (updateCallbacks.contains(id)) {
- callErrorCallback(updateCallbacks, id, code, message);
- }
+ callbacks.remove(request);
}
void JsonDbPartition::queryFinished()
@@ -614,8 +593,8 @@ void JsonDbPartition::queryFinished()
QJSValueList args;
// object : id , statenumber , items
QJSValue response= engine->newObject();
- response.setProperty(JsonDbString::kStateNumberStr, object->stateNumber());
- response.setProperty(JsonDbString::kIdStr, id);
+ response.setProperty(JsonDbStrings::Protocol::stateNumber(), object->stateNumber());
+ response.setProperty(JsonDbStrings::Protocol::requestId(), id);
response.setProperty(QLatin1String("items"), engine->toScriptValue(object->takeResults()));
args << QJSValue(QJSValue::UndefinedValue) << response;
callback.call(args);
@@ -637,8 +616,8 @@ void JsonDbPartition::queryStatusChanged()
QJSValueList args;
QJSValue response = engine->newObject();
- response.setProperty(JsonDbString::kStateNumberStr, -1);
- response.setProperty(JsonDbString::kIdStr, id);
+ response.setProperty(JsonDbStrings::Protocol::stateNumber(), -1);
+ response.setProperty(JsonDbStrings::Protocol::requestId(), id);
response.setProperty(QLatin1String("items"), engine->newArray());
args << engine->toScriptValue(object->error())<< response;
@@ -650,6 +629,22 @@ void JsonDbPartition::queryStatusChanged()
}
}
+void JsonDbPartition::requestFinished()
+{
+ QJsonDbWriteRequest *request = qobject_cast<QJsonDbWriteRequest *>(sender());
+ if (writeCallbacks.contains(request)) {
+ call(writeCallbacks, request);
+ }
+}
+
+void JsonDbPartition::requestError(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString &message)
+{
+ QJsonDbWriteRequest *request = qobject_cast<QJsonDbWriteRequest *>(sender());
+ if (writeCallbacks.contains(request)) {
+ callErrorCallback(writeCallbacks, request, code, message);
+ }
+
+}
#include "moc_jsondbpartition.cpp"
QT_END_NAMESPACE_JSONDB
diff --git a/src/imports/jsondb/jsondbpartition.h b/src/imports/jsondb/jsondbpartition.h
index 1c831c23..008cb0f7 100644
--- a/src/imports/jsondb/jsondbpartition.h
+++ b/src/imports/jsondb/jsondbpartition.h
@@ -49,8 +49,8 @@
#include <QJSValue>
#include <QJSEngine>
#include <QQmlListProperty>
-
-#include "jsondb-client.h"
+#include <QJsonDbConnection>
+#include <QJsonDbWriteRequest>
QT_BEGIN_NAMESPACE_JSONDB
@@ -58,7 +58,6 @@ class JsonDatabase;
class JsonDbNotify;
class JsonDbPartitionPrivate;
class JsonDbQueryObject;
-class JsonDbChangesSinceObject;
class JsonDbPartition: public QObject
{
@@ -89,8 +88,6 @@ public:
Q_INVOKABLE JsonDbQueryObject* createQuery(const QString &query, int limit, QVariantMap bindings);
- Q_INVOKABLE JsonDbChangesSinceObject* createChangesSince(int stateNumber, const QStringList &types);
-
QString name() const;
void setName(const QString &partitionName);
@@ -105,32 +102,29 @@ private:
QString _name;
QString _file;
QString _uuid;
- JsonDbClient jsonDb;
- QMap<int, QJSValue> createCallbacks;
- QMap<int, QJSValue> updateCallbacks;
- QMap<int, QJSValue> removeCallbacks;
- QMap<QString, QPointer<JsonDbNotify> > notifications;
+ QList<QPointer<QJsonDbWatcher> > watchers;
QList<QObject*> childQMLElements;
QMap<JsonDbQueryObject*, QJSValue> findCallbacks;
QMap<JsonDbQueryObject*, int> findIds;
+ QMap<QJsonDbWriteRequest*, QJSValue> writeCallbacks;
void updateNotification(JsonDbNotify *notify);
void removeNotification(JsonDbNotify *notify);
- void call(QMap<int, QJSValue> &callbacks, int id, const QVariant &result);
- void callErrorCallback(QMap<int, QJSValue> &callbacks, int id, int code, const QString &message);
+ void call(QMap<QJsonDbWriteRequest*, QJSValue> &callbacks, QJsonDbWriteRequest *request);
+ void callErrorCallback(QMap<QJsonDbWriteRequest*, QJSValue> &callbacks, QJsonDbWriteRequest *request,
+ QtJsonDb::QJsonDbRequest::ErrorCode code, const QString &message);
private Q_SLOTS:
- void dbResponse(int id, const QVariant &result);
- void dbErrorResponse(int id, int code, const QString &message);
void queryFinished();
void queryStatusChanged();
+ void requestFinished();
+ void requestError(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString &message);
friend class JsonDatabase;
friend class JsonDbNotify;
friend class JsonDbQueryObject;
- friend class JsonDbChangesSinceObject;
};
QT_END_NAMESPACE_JSONDB
diff --git a/src/imports/jsondb/jsondbqueryobject.cpp b/src/imports/jsondb/jsondbqueryobject.cpp
index b42daaa1..ac00e69c 100644
--- a/src/imports/jsondb/jsondbqueryobject.cpp
+++ b/src/imports/jsondb/jsondbqueryobject.cpp
@@ -38,10 +38,11 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-#include "jsondb-global.h"
#include "jsondbqueryobject.h"
#include "jsondbpartition.h"
-#include "private/jsondb-strings_p.h"
+#include "jsondatabase.h"
+#include <private/qjsondbstrings_p.h>
+#include <jsondbmodelutils.h>
#include <qdebug.h>
QT_BEGIN_NAMESPACE_JSONDB
@@ -84,7 +85,6 @@ JsonDbQueryObject::JsonDbQueryObject(QObject *parent)
, queryLimit(-1)
, partitionObject(0)
, defaultPartitionObject(0)
- , jsondbQuery(0)
, errorCode(0)
, objectStatus(JsonDbQueryObject::Null)
{
@@ -94,8 +94,8 @@ JsonDbQueryObject::~JsonDbQueryObject()
{
if (defaultPartitionObject)
delete defaultPartitionObject;
- if (jsondbQuery)
- delete jsondbQuery;
+ if (readRequest)
+ delete readRequest;
}
@@ -145,8 +145,8 @@ void JsonDbQueryObject::setPartition(JsonDbPartition *newPartition)
*/
quint32 JsonDbQueryObject::stateNumber() const
{
- if (jsondbQuery)
- return jsondbQuery->stateNumber();
+ if (readRequest)
+ return readRequest->stateNumber();
return 0;
}
@@ -240,8 +240,8 @@ void JsonDbQueryObject::setBindings(const QVariantMap &newBindings)
QVariantList JsonDbQueryObject::takeResults()
{
QVariantList list;
- if (jsondbQuery) {
- list = jsondbQuery->takeResults();
+ if (readRequest) {
+ list = qjsonobject_list_to_qvariantlist(readRequest->takeResults());
}
return list;
}
@@ -329,32 +329,29 @@ int JsonDbQueryObject::start()
return -1;
}
- if (jsondbQuery) {
- delete jsondbQuery;
+ if (readRequest) {
+ delete readRequest;
}
- jsondbQuery = partitionObject->jsonDb.query();
- jsondbQuery->setQuery(queryString);
- jsondbQuery->setQueryLimit(queryLimit);
- jsondbQuery->setQueryOffset(0);
- jsondbQuery->setPartition(partitionObject->name());
+ QJsonDbReadRequest *request = new QJsonDbReadRequest;
+ request->setQuery(queryString);
+ request->setQueryLimit(queryLimit);
+ request->setPartition(partitionObject->name());
QVariantMap::ConstIterator i = queryBindings.constBegin();
while (i != queryBindings.constEnd()) {
- jsondbQuery->bindValue(i.key(), i.value());
+ request->bindValue(i.key(), QJsonValue::fromVariant(i.value()));
++i;
}
- connect(jsondbQuery, SIGNAL(resultsReady(int)),
- this, SIGNAL(resultsReady(int)));
- connect(jsondbQuery, SIGNAL(finished()),
- this, SLOT(setReadyStatus()));
- connect(jsondbQuery, SIGNAL(finished()),
- this, SIGNAL(finished()));
- connect(jsondbQuery, SIGNAL(error(QtAddOn::JsonDb::JsonDbError::ErrorCode,QString)),
- this, SLOT(setError(QtAddOn::JsonDb::JsonDbError::ErrorCode,QString)));
-
- jsondbQuery->start();
+ connect(request, SIGNAL(resultsAvailable(int)), this, SIGNAL(resultsReady(int)));
+ connect(request, SIGNAL(finished()), this, SLOT(setReadyStatus()));
+ connect(request, SIGNAL(finished()), this, SIGNAL(finished()));
+ connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ this, SLOT(setError(QtJsonDb::QJsonDbRequest::ErrorCode,QString)));
+
objectStatus = JsonDbQueryObject::Loading;
emit statusChanged(objectStatus);
- return jsondbQuery->requestId();
+ JsonDatabase::sharedConnection().send(request);
+ readRequest = request;
+ return request->property("requestId").toInt();
}
@@ -405,16 +402,17 @@ void JsonDbQueryObject::setReadyStatus()
emit statusChanged(objectStatus);
}
-void JsonDbQueryObject::setError(QtAddOn::JsonDb::JsonDbError::ErrorCode code, const QString& message)
+void JsonDbQueryObject::setError(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString & message)
{
int oldErrorCode = errorCode;
errorCode = code;
errorString = message;
- if (objectStatus != JsonDbQueryObject::Error) {
+ bool changed = (objectStatus != JsonDbQueryObject::Error);
+ if (changed) {
objectStatus = JsonDbQueryObject::Error;
emit statusChanged(objectStatus);
}
- if (oldErrorCode != errorCode) {
+ if (oldErrorCode != errorCode || changed) {
emit errorChanged(error());
}
}
diff --git a/src/imports/jsondb/jsondbqueryobject.h b/src/imports/jsondb/jsondbqueryobject.h
index d629d26b..d7845c55 100644
--- a/src/imports/jsondb/jsondbqueryobject.h
+++ b/src/imports/jsondb/jsondbqueryobject.h
@@ -48,7 +48,7 @@
#include <QJSValue>
#include <QQmlParserStatus>
#include <QQmlListProperty>
-#include "jsondb-client.h"
+#include <QJsonDbReadRequest>
QT_BEGIN_NAMESPACE_JSONDB
@@ -106,7 +106,7 @@ Q_SIGNALS:
void errorChanged(const QVariantMap &newError);
private Q_SLOTS:
- void setError(QtAddOn::JsonDb::JsonDbError::ErrorCode code, const QString& message);
+ void setError(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString & message);
void setReadyStatus();
private:
@@ -116,11 +116,11 @@ private:
QVariantList results;
QPointer<JsonDbPartition> partitionObject;
QPointer<JsonDbPartition> defaultPartitionObject;
- QPointer<JsonDbQuery> jsondbQuery;
int errorCode;
QString errorString;
Status objectStatus;
QVariantMap queryBindings;
+ QPointer<QJsonDbReadRequest> readRequest;
void clearError();
inline bool parametersReady();
diff --git a/src/imports/jsondb/jsondbsortinglistmodel.cpp b/src/imports/jsondb/jsondbsortinglistmodel.cpp
index c70b19ed..8bb84c3a 100644
--- a/src/imports/jsondb/jsondbsortinglistmodel.cpp
+++ b/src/imports/jsondb/jsondbsortinglistmodel.cpp
@@ -41,12 +41,9 @@
#include "jsondbsortinglistmodel.h"
#include "jsondbsortinglistmodel_p.h"
-#include "private/jsondb-strings_p.h"
#include "plugin.h"
-
-#include <QJSEngine>
-#include <QJSValueIterator>
-
+#include "jsondatabase.h"
+#include <qdebug.h>
/*!
\internal
\class JsonDbSortingListModel
@@ -62,16 +59,12 @@ JsonDbSortingListModelPrivate::JsonDbSortingListModelPrivate(JsonDbSortingListMo
, limit(-1)
, chunkSize(100)
, state(JsonDbSortingListModel::None)
+ , errorCode(0)
{
}
void JsonDbSortingListModelPrivate::init()
{
- Q_Q(JsonDbSortingListModel);
- q->connect(&dbClient, SIGNAL(response(int,const QVariant&)),
- q, SLOT(_q_jsonDbResponse(int,const QVariant&)));
- q->connect(&dbClient, SIGNAL(error(int,int,const QString&)),
- q, SLOT(_q_jsonDbErrorResponse(int,int,const QString&)));
}
JsonDbSortingListModelPrivate::~JsonDbSortingListModelPrivate()
@@ -218,13 +211,9 @@ void JsonDbSortingListModelPrivate::updateItem(const QVariantMap &item, int part
}
}
-void JsonDbSortingListModelPrivate::fillData(const QVariant &v, int partitionIndex)
+void JsonDbSortingListModelPrivate::fillData(const QVariantList &items, int partitionIndex)
{
Q_Q(JsonDbSortingListModel);
- QVariantMap m = v.toMap();
- QVariantList items;
- if (m.contains(QLatin1String("data")))
- items = m.value(QLatin1String("data")).toList();
RequestInfo &r = partitionObjectDetails[partitionIndex];
r.lastSize = items.size();
if (resetModel) {
@@ -280,7 +269,7 @@ void JsonDbSortingListModelPrivate::fillData(const QVariant &v, int partitionInd
emit q->stateChanged(state);
for (int i = 0; i<pendingNotifications.size(); i++) {
const NotifyItem &pending = pendingNotifications[i];
- sendNotifications(pending.notifyUuid, pendingNotifications[i].item, pendingNotifications[i].action);
+ sendNotifications(pending.partitionIndex, pending.item, pending.action);
}
pendingNotifications.clear();
// overflow status is used when handling notifications.
@@ -290,7 +279,7 @@ void JsonDbSortingListModelPrivate::fillData(const QVariant &v, int partitionInd
overflow = false;
} else if (r.lastSize >= chunkSize){
// more items, fetch next chunk
- fetchNextChunk(partitionIndex);
+ fetchPartition(partitionIndex, false);
}
}
@@ -333,7 +322,7 @@ void JsonDbSortingListModelPrivate::reset()
emit q->stateChanged(state);
}
-void JsonDbSortingListModelPrivate::fetchPartition(int index)
+void JsonDbSortingListModelPrivate::fetchPartition(int index, bool reset)
{
Q_Q(JsonDbSortingListModel);
if (index >= partitionObjects.count())
@@ -345,11 +334,19 @@ void JsonDbSortingListModelPrivate::fetchPartition(int index)
}
RequestInfo &r = partitionObjectDetails[index];
QPointer<JsonDbPartition> p = partitionObjects[index];
- if (p) {
+ Q_ASSERT(p);
+ if (reset) {
r.lastSize = -1;
r.lastOffset = 0;
- r.requestId = dbClient.query(query, r.lastOffset, chunkSize, p->name());
+ } else {
+ r.lastOffset += chunkSize;
}
+ QJsonDbReadRequest *request = valueRequests[index]->newRequest(index);
+ request->setQuery(query);
+ request->setProperty("queryOffset", r.lastOffset);
+ request->setQueryLimit(chunkSize);
+ request->setPartition(p->name());
+ JsonDatabase::sharedConnection().send(request);
}
void JsonDbSortingListModelPrivate::fetchModel(bool reset)
@@ -365,21 +362,14 @@ void JsonDbSortingListModelPrivate::fetchModel(bool reset)
}
}
-void JsonDbSortingListModelPrivate::fetchNextChunk(int partitionIndex)
-{
- RequestInfo &r = partitionObjectDetails[partitionIndex];
- r.lastOffset += chunkSize;
- r.requestId = dbClient.query(query, r.lastOffset, chunkSize, partitionObjects[partitionIndex]->name());
-}
-
void JsonDbSortingListModelPrivate::clearNotification(int index)
{
if (index >= partitionObjects.count())
return;
RequestInfo &r = partitionObjectDetails[index];
- if (!r.notifyUuid.isEmpty()) {
- dbClient.unregisterNotification(r.notifyUuid);
+ if (r.watcher) {
+ JsonDatabase::sharedConnection().removeWatcher(r.watcher);
}
r.clear();
}
@@ -396,14 +386,16 @@ void JsonDbSortingListModelPrivate::createOrUpdateNotification(int index)
if (index >= partitionObjects.count())
return;
clearNotification(index);
- JsonDbClient::NotifyTypes notifyActions = JsonDbClient::NotifyCreate
- | JsonDbClient::NotifyUpdate| JsonDbClient::NotifyRemove;
- partitionObjectDetails[index].notifyUuid= dbClient.registerNotification(
- notifyActions , query, partitionObjects[index]->name(),
- q, SLOT(_q_dbNotified(QString,QtAddOn::JsonDb::JsonDbNotification)),
- q, SLOT(_q_dbNotifyReadyResponse(int,QVariant)),
- SLOT(_q_dbNotifyErrorResponse(int,int,QString)));
-
+ QJsonDbWatcher *watcher = new QJsonDbWatcher();
+ watcher->setQuery(query);
+ watcher->setWatchedActions(QJsonDbWatcher::Created | QJsonDbWatcher::Updated |QJsonDbWatcher::Removed);
+ watcher->setPartition(partitionObjects[index]->name());
+ QObject::connect(watcher, SIGNAL(notificationsAvailable(int)),
+ q, SLOT(_q_notificationsAvailable()));
+ QObject::connect(watcher, SIGNAL(error(QtJsonDb::QJsonDbWatcher::ErrorCode,QString)),
+ q, SLOT(_q_notificationError(QtJsonDb::QJsonDbWatcher::ErrorCode,QString)));
+ JsonDatabase::sharedConnection().addWatcher(watcher);
+ partitionObjectDetails[index].watcher = watcher;
}
void JsonDbSortingListModelPrivate::createOrUpdateNotifications()
@@ -433,19 +425,10 @@ void JsonDbSortingListModelPrivate::parseSortOrder()
}
}
-int JsonDbSortingListModelPrivate::indexOfrequestId(int requestId)
-{
- for (int i = 0; i<partitionObjectDetails.count(); i++) {
- if (requestId == partitionObjectDetails[i].requestId)
- return i;
- }
- return -1;
-}
-
-int JsonDbSortingListModelPrivate::indexOfNotifyUUID(const QString& notifyUuid)
+int JsonDbSortingListModelPrivate::indexOfWatcher(QJsonDbWatcher *watcher)
{
- for (int i = 0; i<partitionObjectDetails.count(); i++) {
- if (notifyUuid == partitionObjectDetails[i].notifyUuid)
+ for (int i = 0; i < partitionObjectDetails.count(); i++) {
+ if (watcher == partitionObjectDetails[i].watcher)
return i;
}
return -1;
@@ -489,38 +472,31 @@ int JsonDbSortingListModelPrivate::indexOf(const QString &uuid) const
return iterator_position(begin, end, i);
}
-void JsonDbSortingListModelPrivate::sendNotifications(const QString& currentNotifyUuid, const QVariant &v, JsonDbClient::NotifyType action)
+void JsonDbSortingListModelPrivate::sendNotifications(int partitionIndex, const QVariantMap &v, QJsonDbWatcher::Action action)
{
- int idx = indexOfNotifyUUID(currentNotifyUuid);
- if (idx == -1)
- return;
-
- const QVariantMap &item = v.toMap();
- if (action == JsonDbClient::NotifyCreate) {
- addItem(item, idx);
- } else if (action == JsonDbClient::NotifyRemove) {
- deleteItem(item, idx);
- } else if (action == JsonDbClient::NotifyUpdate) {
- updateItem(item, idx);
+ if (action == QJsonDbWatcher::Created) {
+ addItem(v, partitionIndex);
+ } else if (action == QJsonDbWatcher::Removed) {
+ deleteItem(v, partitionIndex);
+ } else if (action == QJsonDbWatcher::Updated) {
+ updateItem(v, partitionIndex);
}
}
-void JsonDbSortingListModelPrivate::_q_jsonDbResponse(int id, const QVariant &v)
+void JsonDbSortingListModelPrivate::_q_valueResponse(int index, const QList<QJsonObject> &v)
{
- int idx = indexOfrequestId(id);
- if (idx != -1) {
- partitionObjectDetails[idx].requestId = -1;
- fillData(v, idx);
- }
+ fillData(qjsonobject_list_to_qvariantlist(v), index);
}
-void JsonDbSortingListModelPrivate::_q_jsonDbErrorResponse(int id, int code, const QString &message)
+void JsonDbSortingListModelPrivate::_q_readError(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString & message)
{
- int idx = -1;
- if ((idx = indexOfrequestId(id)) != -1) {
- partitionObjectDetails[idx].requestId = -1;
- qWarning() << QString("JsonDb error: %1 %2").arg(code).arg(message);
- }
+ Q_Q(JsonDbSortingListModel);
+ qWarning() << QString("JsonDb error: %1 %2").arg(code).arg(message);
+ int oldErrorCode = errorCode;
+ errorCode = code;
+ errorString = message;
+ if (oldErrorCode != errorCode)
+ emit q->errorChanged(q->error());
}
void JsonDbSortingListModelPrivate::_q_refreshModel()
@@ -529,27 +505,58 @@ void JsonDbSortingListModelPrivate::_q_refreshModel()
fetchModel(false);
}
-void JsonDbSortingListModelPrivate::_q_dbNotified(const QString &notify_uuid, const QtAddOn::JsonDb::JsonDbNotification &_notification)
+void JsonDbSortingListModelPrivate::_q_notificationsAvailable()
{
- if (state == JsonDbSortingListModel::Querying) {
- NotifyItem pending;
- pending.notifyUuid = notify_uuid;
- pending.item = _notification.object();
- pending.action = _notification.action();
- pendingNotifications.append(pending);
- } else if (state == JsonDbSortingListModel::Ready) {
- sendNotifications(notify_uuid, _notification.object(), _notification.action());
+ Q_Q(JsonDbSortingListModel);
+ QJsonDbWatcher *watcher = qobject_cast<QJsonDbWatcher *>(q->sender());
+ int partitionIndex = indexOfWatcher(watcher);
+ if (!watcher || partitionIndex == -1)
+ return;
+ QList<QJsonDbNotification> list = watcher->takeNotifications();
+ for (int i = 0; i < list.count(); i++) {
+ const QJsonDbNotification & notification = list[i];
+ QVariantMap object = notification.object().toVariantMap();
+ if (state == JsonDbSortingListModel::Querying) {
+ NotifyItem pending;
+ pending.partitionIndex = partitionIndex;
+ pending.item = object;
+ pending.action = notification.action();
+ pendingNotifications.append(pending);
+ } else if (state == JsonDbSortingListModel::Ready) {
+ sendNotifications(partitionIndex, object, notification.action());
+ }
}
}
-void JsonDbSortingListModelPrivate::_q_dbNotifyReadyResponse(int /* id */, const QVariant &/* result */)
+void JsonDbSortingListModelPrivate::_q_notificationError(QtJsonDb::QJsonDbWatcher::ErrorCode code, const QString &message)
{
+ Q_Q(JsonDbSortingListModel);
+ qWarning() << QString("JsonDbSortingListModel Notification error: %1 %2").arg(code).arg(message);
+ int oldErrorCode = errorCode;
+ errorCode = code;
+ errorString = message;
+ if (oldErrorCode != errorCode)
+ emit q->errorChanged(q->error());
}
-void JsonDbSortingListModelPrivate::_q_dbNotifyErrorResponse(int id, int code, const QString &message)
+void JsonDbSortingListModelPrivate::appendPartition(JsonDbPartition *v)
{
- Q_UNUSED(id);
- qWarning() << QString("JsonDbSortingListModel Notification error: %1 %2").arg(code).arg(message);
+ Q_Q(JsonDbSortingListModel);
+ partitionObjects.append(QPointer<JsonDbPartition>(v));
+ partitionObjectDetails.append(RequestInfo());
+ ModelRequest *valueRequest = new ModelRequest();
+ QObject::connect(valueRequest, SIGNAL(finished(int,QList<QJsonObject>,QString)),
+ q, SLOT(_q_valueResponse(int,QList<QJsonObject>)));
+ QObject::connect(valueRequest, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ q, SLOT(_q_readError(QtJsonDb::QJsonDbRequest::ErrorCode,QString)));
+ valueRequests.append(valueRequest);
+ if (componentComplete && !query.isEmpty()) {
+ createOrUpdateNotification(partitionObjects.count()-1);
+ if (state == JsonDbSortingListModel::None) {
+ resetModel = true;
+ }
+ fetchPartition(partitionObjects.count()-1);
+ }
}
void JsonDbSortingListModelPrivate::partitions_append(QQmlListProperty<JsonDbPartition> *p, JsonDbPartition *v)
@@ -557,15 +564,7 @@ void JsonDbSortingListModelPrivate::partitions_append(QQmlListProperty<JsonDbPar
JsonDbSortingListModel *q = qobject_cast<JsonDbSortingListModel *>(p->object);
JsonDbSortingListModelPrivate *pThis = (q) ? q->d_func() : 0;
if (pThis) {
- pThis->partitionObjects.append(QPointer<JsonDbPartition>(v));\
- pThis->partitionObjectDetails.append(RequestInfo());
- if (pThis->componentComplete && !pThis->query.isEmpty()) {
- pThis->createOrUpdateNotification(pThis->partitionObjects.count()-1);
- if (pThis->state == JsonDbSortingListModel::None) {
- pThis->resetModel = true;
- }
- pThis->fetchPartition(pThis->partitionObjects.count()-1);
- }
+ pThis->appendPartition(v);
}
}
@@ -589,14 +588,23 @@ JsonDbPartition* JsonDbSortingListModelPrivate::partitions_at(QQmlListProperty<J
return 0;
}
+void JsonDbSortingListModelPrivate::clearPartitions()
+{
+ partitionObjects.clear();
+ partitionObjectDetails.clear();
+ while (!valueRequests.isEmpty()) {
+ delete valueRequests[0];
+ valueRequests.removeFirst();
+ }
+ reset();
+}
+
void JsonDbSortingListModelPrivate::partitions_clear(QQmlListProperty<JsonDbPartition> *p)
{
JsonDbSortingListModel *q = qobject_cast<JsonDbSortingListModel *>(p->object);
JsonDbSortingListModelPrivate *pThis = (q) ? q->d_func() : 0;
if (pThis) {
- pThis->partitionObjects.clear();
- pThis->partitionObjectDetails.clear();
- pThis->reset();
+ pThis->clearPartitions();
}
}
@@ -859,6 +867,7 @@ void JsonDbSortingListModel::setQueryLimit(int newQueryLimit)
/*!
\qmlproperty bool QtJsonDb::JsonDbSortingListModel::overflow
+ \readonly
This will be true if actual numer of results is more than the queryLimit
*/
@@ -954,6 +963,7 @@ void JsonDbSortingListModel::setSortOrder(const QString &newSortOrder)
/*!
\qmlproperty State QtJsonDb::JsonDbSortingListModel::state
+ \readonly
The current state of the model.
\list
\li State.None - The model is not initialized
@@ -1045,5 +1055,25 @@ JsonDbPartition* JsonDbSortingListModel::getPartition(int index) const
This handler is called when the number of items in the model has changed.
*/
+/*!
+ \qmlproperty object QtJsonDb::JsonDbSortingListModel::error
+ \readonly
+
+ This property holds the current error information for the object. It contains:
+ \list
+ \o error.code - code for the current error.
+ \o error.message - detailed explanation of the error
+ \endlist
+*/
+
+QVariantMap JsonDbSortingListModel::error() const
+{
+ Q_D(const JsonDbSortingListModel);
+ QVariantMap errorMap;
+ errorMap.insert(QLatin1String("code"), d->errorCode);
+ errorMap.insert(QLatin1String("message"), d->errorString);
+ return errorMap;
+}
+
#include "moc_jsondbsortinglistmodel.cpp"
QT_END_NAMESPACE_JSONDB
diff --git a/src/imports/jsondb/jsondbsortinglistmodel.h b/src/imports/jsondb/jsondbsortinglistmodel.h
index 99ef4058..cdd9f7a7 100644
--- a/src/imports/jsondb/jsondbsortinglistmodel.h
+++ b/src/imports/jsondb/jsondbsortinglistmodel.h
@@ -53,7 +53,6 @@
#include <QJSValue>
#include <QScopedPointer>
-#include "jsondb-global.h"
#include "jsondbpartition.h"
QT_BEGIN_NAMESPACE_JSONDB
@@ -79,8 +78,8 @@ public:
Q_PROPERTY(QVariant roleNames READ scriptableRoleNames WRITE setScriptableRoleNames)
Q_PROPERTY(int queryLimit READ queryLimit WRITE setQueryLimit)
Q_PROPERTY(bool overflow READ overflow)
-
Q_PROPERTY(QQmlListProperty<JsonDbPartition> partitions READ partitions)
+ Q_PROPERTY(QVariantMap error READ error NOTIFY errorChanged)
virtual void classBegin();
virtual void componentComplete();
@@ -111,10 +110,12 @@ public:
Q_INVOKABLE QJSValue get(int index) const;
Q_INVOKABLE QVariant get(int index, const QString &property) const;
Q_INVOKABLE JsonDbPartition* getPartition(int index) const;
+ QVariantMap error() const;
signals:
void stateChanged(State state) const;
void rowCountChanged(int newCount) const;
+ void errorChanged(QVariantMap newError);
private Q_SLOTS:
void partitionNameChanged(const QString &partitionName);
@@ -123,12 +124,12 @@ private:
Q_DISABLE_COPY(JsonDbSortingListModel)
Q_DECLARE_PRIVATE(JsonDbSortingListModel)
QScopedPointer<JsonDbSortingListModelPrivate> d_ptr;
- Q_PRIVATE_SLOT(d_func(), void _q_jsonDbResponse(int, const QVariant&))
- Q_PRIVATE_SLOT(d_func(), void _q_jsonDbErrorResponse(int, int, const QString&))
+
Q_PRIVATE_SLOT(d_func(), void _q_refreshModel())
- Q_PRIVATE_SLOT(d_func(), void _q_dbNotified(QString, QtAddOn::JsonDb::JsonDbNotification))
- Q_PRIVATE_SLOT(d_func(), void _q_dbNotifyReadyResponse(int, QVariant))
- Q_PRIVATE_SLOT(d_func(), void _q_dbNotifyErrorResponse(int, int, QString))
+ Q_PRIVATE_SLOT(d_func(), void _q_notificationsAvailable())
+ Q_PRIVATE_SLOT(d_func(), void _q_notificationError(QtJsonDb::QJsonDbWatcher::ErrorCode, QString))
+ Q_PRIVATE_SLOT(d_func(), void _q_valueResponse(int, QList<QJsonObject>))
+ Q_PRIVATE_SLOT(d_func(), void _q_readError(QtJsonDb::QJsonDbRequest::ErrorCode, QString))
};
diff --git a/src/imports/jsondb/jsondbsortinglistmodel_p.h b/src/imports/jsondb/jsondbsortinglistmodel_p.h
index 0cd45d02..29837a78 100644
--- a/src/imports/jsondb/jsondbsortinglistmodel_p.h
+++ b/src/imports/jsondb/jsondbsortinglistmodel_p.h
@@ -49,9 +49,9 @@
#include <QStringList>
#include <QPointer>
#include <QUuid>
+#include <QJSEngine>
+#include <QJSValueIterator>
-#include "jsondb-client.h"
-#include "private/jsondb-connection_p.h"
#include "jsondbmodelutils.h"
QT_BEGIN_NAMESPACE_JSONDB
@@ -88,10 +88,12 @@ public:
QHash<int, QStringList> properties;
QList<NotifyItem> pendingNotifications;
+ QList< QPointer<ModelRequest> >valueRequests;
JsonDbSortingListModel::State state;
- JsonDbClient dbClient;
QModelIndex parent;
+ int errorCode;
+ QString errorString;
public:
JsonDbSortingListModelPrivate(JsonDbSortingListModel *q);
@@ -102,13 +104,12 @@ public:
void addItem(const QVariantMap &item, int partitionIndex);
void deleteItem(const QVariantMap &item, int partitionIndex);
void updateItem(const QVariantMap &item, int partitionIndex);
- void fillData(const QVariant &v, int partitionIndex);
+ void fillData(const QVariantList &items, int partitionIndex);
void sortObjects();
void reset();
- void fetchPartition(int index);
+ void fetchPartition(int index, bool reset = true);
void fetchModel(bool reset = true);
- void fetchNextChunk(int partitionIndex);
void clearNotification(int index);
void clearNotifications();
@@ -118,7 +119,10 @@ public:
int indexOfrequestId(int requestId);
int indexOfNotifyUUID(const QString& notifyUuid);
+ int indexOfWatcher(QJsonDbWatcher *watcher);
+ void appendPartition(JsonDbPartition *v);
+ void clearPartitions();
QVariant getItem(int index);
QVariant getItem(int index, int role);
JsonDbPartition* getItemPartition(int index);
@@ -126,15 +130,14 @@ public:
void set(int index, const QJSValue& valuemap,
const QJSValue &successCallback,
const QJSValue &errorCallback);
- void sendNotifications(const QString&, const QVariant &, JsonDbClient::NotifyType);
+ void sendNotifications(int partitionIndex, const QVariantMap &v, QJsonDbWatcher::Action action);
// private slots
- void _q_jsonDbResponse(int , const QVariant &);
- void _q_jsonDbErrorResponse(int , int, const QString&);
void _q_refreshModel();
- void _q_dbNotified(const QString &notify_uuid, const QtAddOn::JsonDb::JsonDbNotification &_notification);
- void _q_dbNotifyReadyResponse(int id, const QVariant &result);
- void _q_dbNotifyErrorResponse(int id, int code, const QString &message);
+ void _q_notificationsAvailable();
+ void _q_notificationError(QtJsonDb::QJsonDbWatcher::ErrorCode code, const QString &message);
+ void _q_readError(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString & message);
+ void _q_valueResponse(int , const QList<QJsonObject>&);
static void partitions_append(QQmlListProperty<JsonDbPartition> *p, JsonDbPartition *v);
static int partitions_count(QQmlListProperty<JsonDbPartition> *p);
diff --git a/src/imports/jsondb/plugin.cpp b/src/imports/jsondb/plugin.cpp
index 3264b26a..5988d625 100644
--- a/src/imports/jsondb/plugin.cpp
+++ b/src/imports/jsondb/plugin.cpp
@@ -41,18 +41,16 @@
#include "plugin.h"
-#include "jsondblistmodel.h"
-#include "jsondbsortinglistmodel.h"
#include "jsondatabase.h"
#include "jsondbpartition.h"
#include "jsondbnotification.h"
#include "jsondbqueryobject.h"
-#include "jsondbchangessinceobject.h"
+#include "jsondblistmodel.h"
+#include "jsondbsortinglistmodel.h"
#include "jsondbcachinglistmodel.h"
QT_USE_NAMESPACE_JSONDB
-Q_EXPORT_PLUGIN2(jsondbplugin, JsonDbPlugin)
QQmlEngine *g_declEngine = 0;
static QObject *jsondb_new_module_api_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
@@ -74,11 +72,10 @@ void JsonDbPlugin::registerTypes(const char *uri)
{
Q_ASSERT(uri == QLatin1String("QtJsonDb"));
qmlRegisterModuleApi(uri, 1, 0, jsondb_new_module_api_provider);
- qmlRegisterType<JsonDbListModel>(uri, 1, 0, "JsonDbListModel");
- qmlRegisterType<JsonDbSortingListModel>(uri, 1, 0, "JsonDbSortingListModel");
qmlRegisterType<JsonDbPartition>(uri, 1, 0, "Partition");
qmlRegisterType<JsonDbNotify>(uri, 1, 0, "Notification");
qmlRegisterType<JsonDbQueryObject>(uri, 1, 0, "Query");
- qmlRegisterType<JsonDbChangesSinceObject>(uri, 1, 0, "ChangesSince");
+ qmlRegisterType<JsonDbListModel>(uri, 1, 0, "JsonDbListModel");
+ qmlRegisterType<JsonDbSortingListModel>(uri, 1, 0, "JsonDbSortingListModel");
qmlRegisterType<JsonDbCachingListModel>(uri, 1, 0, "JsonDbCachingListModel");
}
diff --git a/src/imports/jsondb/plugin.h b/src/imports/jsondb/plugin.h
index bc6b03ac..7db4b1e1 100644
--- a/src/imports/jsondb/plugin.h
+++ b/src/imports/jsondb/plugin.h
@@ -51,6 +51,7 @@ extern QQmlEngine *g_declEngine;
class JsonDbPlugin : public QQmlExtensionPlugin
{
Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface" FILE "jsondb.json")
public:
void initializeEngine(QQmlEngine *engine, const char *uri);
void registerTypes(const char *uri);
diff --git a/src/jsonstream/jsonstream.cpp b/src/jsonstream/jsonstream.cpp
index f4d02d22..f45af5aa 100644
--- a/src/jsonstream/jsonstream.cpp
+++ b/src/jsonstream/jsonstream.cpp
@@ -56,7 +56,7 @@
QT_BEGIN_NAMESPACE
-namespace JsonStream {
+namespace QtJsonDbJsonStream {
JsonStream::JsonStream(QObject *parent)
: QObject(parent), mDevice(0)
@@ -110,6 +110,19 @@ bool JsonStream::send(const QJsonObject &object)
void JsonStream::deviceReadyRead()
{
+ struct JsonHeader
+ {
+ struct Header
+ {
+ unsigned int tag;
+ unsigned int version;
+ } h;
+ struct Base
+ {
+ unsigned int size;
+ } b;
+ };
+
while (!mDevice->atEnd()) {
int bytesAvailable = mDevice->bytesAvailable();
int offset = mReadBuffer.size();
@@ -119,12 +132,19 @@ void JsonStream::deviceReadyRead()
qWarning() << "Error reading from socket" << mDevice->errorString();
continue;
}
- while (mReadBuffer.size()) {
+ while (mReadBuffer.size() > static_cast<int>(sizeof(JsonHeader))) {
+ JsonHeader header;
+ memcpy(&header, mReadBuffer.constData(), sizeof(header));
+ if (header.h.tag != QJsonDocument::BinaryFormatTag || header.h.version != qToLittleEndian(1u)) {
+ mReadBuffer.clear();
+ qWarning() << "Got invalid binary json data";
+ break;
+ }
QJsonDocument doc(QJsonDocument::fromBinaryData(mReadBuffer, QJsonDocument::Validate));
if (doc.isEmpty())
break;
receive(doc.object());
- mReadBuffer = mReadBuffer.mid(doc.toBinaryData().size());
+ mReadBuffer.remove(0, sizeof(header.h) + header.b.size);
}
}
}
@@ -138,7 +158,7 @@ void JsonStream::deviceBytesWritten(qint64 bytes)
}
}
-} // namespace JsonStream
+} // namespace QtJsonDbJsonStream
QT_END_NAMESPACE
diff --git a/src/jsonstream/jsonstream.h b/src/jsonstream/jsonstream.h
index f76020ff..8eceab04 100644
--- a/src/jsonstream/jsonstream.h
+++ b/src/jsonstream/jsonstream.h
@@ -42,6 +42,17 @@
#ifndef JSON_STREAM_H
#define JSON_STREAM_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtJsonDb API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
#include <QObject>
#include <QJsonObject>
@@ -49,7 +60,7 @@ QT_BEGIN_NAMESPACE
class QIODevice;
-namespace JsonStream {
+namespace QtJsonDbJsonStream {
class JsonStream : public QObject
{
@@ -76,7 +87,7 @@ private:
QByteArray mReadBuffer;
};
-} // namespace JsonStream
+} // namespace QtJsonDbJsonStream
QT_END_NAMESPACE
diff --git a/src/jsonstream/jsonstream.pri b/src/jsonstream/jsonstream.pri
index 6bbb9b79..741a53bd 100644
--- a/src/jsonstream/jsonstream.pri
+++ b/src/jsonstream/jsonstream.pri
@@ -1,2 +1,3 @@
INCLUDEPATH += $$PWD
-LIBS_PRIVATE += -L../jsonstream -lqtjsondbjsonstream
+LIBS_PRIVATE += -L$$QT_MODULE_LIB_BASE -lQtJsonDbJsonStream
+POST_TARGETDEPS += $${QT_MODULE_LIB_BASE}$${QMAKE_DIR_SEP}libQtJsonDbJsonStream.a
diff --git a/src/jsonstream/jsonstream.pro b/src/jsonstream/jsonstream.pro
index cb7ea280..133974bb 100644
--- a/src/jsonstream/jsonstream.pro
+++ b/src/jsonstream/jsonstream.pro
@@ -1,6 +1,7 @@
-TARGET = qtjsondbjsonstream
+TARGET = QtJsonDbJsonStream
TEMPLATE = lib
+DESTDIR = $$QT_MODULE_LIB_BASE
CONFIG += qt staticlib
QT = core network
diff --git a/src/daemon/jsondb.qrc b/src/partition/jsondb.qrc
index 2a12e110..2a12e110 100644
--- a/src/daemon/jsondb.qrc
+++ b/src/partition/jsondb.qrc
diff --git a/src/daemon/jsondbbtree.cpp b/src/partition/jsondbbtree.cpp
index 4efc5bbd..14c7bb30 100644
--- a/src/daemon/jsondbbtree.cpp
+++ b/src/partition/jsondbbtree.cpp
@@ -42,11 +42,11 @@
#include <QDebug>
#include <QFile>
#include <errno.h>
+
#include "jsondbbtree.h"
#include "jsondbsettings.h"
-#include "jsondb-global.h"
-QT_BEGIN_NAMESPACE_JSONDB
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
JsonDbBtree::JsonDbBtree()
: mBtree(new Btree())
@@ -161,4 +161,4 @@ JsonDbBtree::Stat JsonDbBtree::stats() const
return Stat();
}
-QT_END_NAMESPACE_JSONDB
+QT_END_NAMESPACE_JSONDB_PARTITION
diff --git a/src/daemon/jsondbbtree.h b/src/partition/jsondbbtree.h
index 791d6f8e..18387376 100644
--- a/src/daemon/jsondbbtree.h
+++ b/src/partition/jsondbbtree.h
@@ -39,12 +39,12 @@
**
****************************************************************************/
-#ifndef JSONDB_MANAGED_BTREE_H
-#define JSONDB_MANAGED_BTREE_H
+#ifndef JSONDB_BTREE_H
+#define JSONDB_BTREE_H
#define JSONDB_USE_HBTREE
-#include "jsondb-global.h"
+#include "jsondbpartitionglobal.h"
#ifndef JSONDB_USE_HBTREE
#include "qbtree.h"
@@ -58,7 +58,7 @@
QT_BEGIN_HEADER
-QT_BEGIN_NAMESPACE_JSONDB
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
class JsonDbBtree
{
@@ -85,7 +85,7 @@ public:
JsonDbBtree();
~JsonDbBtree();
- bool open(const QString &filename, OpenFlags flags);
+ bool open(const QString &filename, OpenFlags flags = Default);
void close();
Transaction *beginRead()
@@ -135,8 +135,8 @@ private:
Q_DECLARE_OPERATORS_FOR_FLAGS(JsonDbBtree::OpenFlags)
-QT_END_NAMESPACE_JSONDB
+QT_END_NAMESPACE_JSONDB_PARTITION
QT_END_HEADER
-#endif // JSONDB_MANAGED_BTREE_H
+#endif // JSONDB_BTREE_H
diff --git a/src/common/jsondbcollator.cpp b/src/partition/jsondbcollator.cpp
index 4fa45c4e..869bf3f8 100644
--- a/src/common/jsondbcollator.cpp
+++ b/src/partition/jsondbcollator.cpp
@@ -50,7 +50,7 @@
#include "qdebug.h"
-QT_BEGIN_NAMESPACE_JSONDB
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
JsonDbCollatorPrivate::~JsonDbCollatorPrivate()
{
@@ -336,6 +336,6 @@ QByteArray JsonDbCollator::sortKey(const QString &string) const
result.truncate(size);
return result;
}
-QT_END_NAMESPACE_JSONDB
+QT_END_NAMESPACE_JSONDB_PARTITION
#endif // NO_COLLATION_SUPPORT
diff --git a/src/common/jsondbcollator.h b/src/partition/jsondbcollator.h
index 6214a1a1..d23ea1d1 100644
--- a/src/common/jsondbcollator.h
+++ b/src/partition/jsondbcollator.h
@@ -47,15 +47,15 @@
#include <QString>
#include <QLocale>
-#include "jsondb-global.h"
+#include "jsondbpartitionglobal.h"
QT_BEGIN_HEADER
-QT_BEGIN_NAMESPACE_JSONDB
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
class JsonDbCollatorPrivate;
-class Q_ADDON_JSONDB_EXPORT JsonDbCollator
+class Q_JSONDB_PARTITION_EXPORT JsonDbCollator
{
public:
enum Strength {
@@ -164,7 +164,7 @@ private:
void init();
};
-QT_END_NAMESPACE_JSONDB
+QT_END_NAMESPACE_JSONDB_PARTITION
QT_END_HEADER
diff --git a/src/common/jsondbcollator_p.h b/src/partition/jsondbcollator_p.h
index 5a76f29a..1ea44fd7 100644
--- a/src/common/jsondbcollator_p.h
+++ b/src/partition/jsondbcollator_p.h
@@ -52,7 +52,7 @@
QT_BEGIN_HEADER
-QT_BEGIN_NAMESPACE_JSONDB
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
class JsonDbCollatorPrivate
{
@@ -78,7 +78,7 @@ public:
int compare(ushort *s1, int len1, ushort *s2, int len2);
};
-QT_END_NAMESPACE_JSONDB
+QT_END_NAMESPACE_JSONDB_PARTITION
QT_END_HEADER
diff --git a/src/partition/jsondberrors.cpp b/src/partition/jsondberrors.cpp
new file mode 100644
index 00000000..3a66ab49
--- /dev/null
+++ b/src/partition/jsondberrors.cpp
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "jsondbpartitionglobal.h"
+#include "jsondberrors.h"
+
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
+
+/*!
+ \class JsonDbError
+ \brief The JsonDbError class lists possible error codes.
+ \sa JsonDbError::ErrorCode
+ */
+
+/*!
+ \enum JsonDbError::ErrorCode
+ \omitvalue NoError
+ \value InvalidMessage
+ Unable to parse the query message.
+ \value InvalidRequest
+ Request object doesn't contain correct elements.
+ \value MissingObject
+ Invalid or missing "object" field.
+ \value DatabaseError
+ Error directly from the database.
+ \value MissingUUID
+ Missing id field.
+ \value MissingType
+ Missing _type field.
+ \value MissingQuery
+ Missing query field.
+ \value InvalidLimit
+ Invalid limit field.
+ \value InvalidOffset
+ Invalid offset field.
+ \value MismatchedNotifyId
+ Request to delete notify doesn't match existing notification.
+ \value InvalidActions
+ List of actions supplied to setNotification is invalid.
+ \value UpdatingStaleVersion
+ Updating stale version of object.
+ \value OperationNotPermitted
+ Operation prohibited by access control policy.
+ \value QuotaExceeded
+ Operation would exceed quota.
+ \value FailedSchemaValidation
+ Object to be created/updated was invalid according to the schema.
+ \value InvalidMap
+ The Map definition is invalid.
+ \value InvalidReduce
+ The Reduce definition is invalid.
+ \value InvalidSchemaOperation
+ Attempted to create a schema that already exists or to remove a schema when there are still objects belonging to the schema's type.
+ \value InvalidPartition
+ Invalid partition.
+ \value InvalidIndexOperation
+ An error when creating an index object
+ */
+
+QT_END_NAMESPACE_JSONDB_PARTITION
diff --git a/src/daemon/jsondbresponse.h b/src/partition/jsondberrors.h
index e6944107..482d25e3 100644
--- a/src/daemon/jsondbresponse.h
+++ b/src/partition/jsondberrors.h
@@ -39,30 +39,50 @@
**
****************************************************************************/
-#ifndef JSONDB_RESPONSE_H
-#define JSONDB_RESPONSE_H
+#ifndef JSONDB_ERRORS_H
+#define JSONDB_ERRORS_H
-#include <QString>
-#include <qjsonobject.h>
-
-#include "jsondb-global.h"
+#include "jsondbpartitionglobal.h"
QT_BEGIN_HEADER
-QT_BEGIN_NAMESPACE_JSONDB
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
+
+class Q_JSONDB_PARTITION_EXPORT JsonDbError {
+public:
+ enum ErrorCode {
+ // common errors
+ NoError = 0,
+ InvalidRequest = 1,
+ OperationNotPermitted = 2,
+ InvalidPartition = 3,
+ DatabaseConnectionError = 4,
+
+ // read / notify errors
+ MissingQuery = 5,
+ InvalidMessage= 6,
+ InvalidLimit = 7,
+ InvalidOffset = 8,
+ InvalidStateNumber = 9,
-struct JsonDbResponse {
- static void setError(QJsonObject &map, int code, const QString &message);
- static QJsonObject makeError(int code, const QString &message);
- static QJsonObject makeResponse(QJsonObject &resultmap, QJsonObject &errormap, bool silent = false);
- static QJsonObject makeResponse(QJsonObject &resultmap);
- static QJsonObject makeErrorResponse(QJsonObject &resultmap, int code, const QString &message, bool silent = false);
- static QJsonObject makeErrorResponse(int code, const QString &message, bool silent = false);
- static bool responseIsError(QJsonObject responseMap);
+ // write errors
+ MissingObject = 10,
+ DatabaseError = 11,
+ MissingUUID = 12,
+ MissingType = 13,
+ UpdatingStaleVersion = 14,
+ QuotaExceeded = 15,
+ FailedSchemaValidation = 16,
+ InvalidMap = 17,
+ InvalidReduce = 18,
+ InvalidSchemaOperation = 19,
+ InvalidIndexOperation = 20,
+ InvalidType = 21
+ };
};
-QT_END_NAMESPACE_JSONDB
+QT_END_NAMESPACE_JSONDB_PARTITION
QT_END_HEADER
-#endif // JSONDB_RESPONSE_H
+#endif // JSONDB_ERRORS_H
diff --git a/src/daemon/jsondbindex.cpp b/src/partition/jsondbindex.cpp
index 0f263f40..568fcdf3 100644
--- a/src/daemon/jsondbindex.cpp
+++ b/src/partition/jsondbindex.cpp
@@ -47,14 +47,18 @@
#include <QDir>
#include <QLocale>
-#include "jsondb-strings.h"
+#include "jsondbstrings.h"
#include "jsondbproxy.h"
#include "jsondbindex.h"
#include "jsondbbtree.h"
#include "jsondbsettings.h"
#include "jsondbobjecttable.h"
+#include "jsondbscriptengine.h"
+#include "qbtree.h"
+#include "qbtreecursor.h"
+#include "qbtreetxn.h"
-QT_BEGIN_NAMESPACE_JSONDB
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
static const int collationStringsCount = 13;
static const char * const collationStrings[collationStringsCount] = {
@@ -131,6 +135,31 @@ QString _q_bytesToHexString(const QByteArray &ba)
return result;
}
+class JsonDbIndexCursor
+{
+public:
+ JsonDbIndexCursor(JsonDbIndex *index);
+ ~JsonDbIndexCursor();
+
+ bool seek(const QJsonValue &value);
+ bool seekRange(const QJsonValue &value);
+
+ bool first();
+ bool current(QJsonValue &key, ObjectKey &value);
+ bool currentKey(QJsonValue &key);
+ bool currentValue(ObjectKey &value);
+ bool next();
+ bool prev();
+
+private:
+ bool isOwnTransaction;
+ JsonDbBtree::Transaction *mTxn;
+ JsonDbBtree::Cursor mCursor;
+ JsonDbIndex *mIndex;
+
+ JsonDbIndexCursor(const JsonDbIndexCursor&);
+};
+
JsonDbIndex::JsonDbIndex(const QString &fileName, const QString &indexName, const QString &propertyName,
const QString &propertyType, const QStringList &objectType, const QString &locale, const QString &collation,
const QString &casePreference, Qt::CaseSensitivity caseSensitivity, JsonDbObjectTable *objectTable)
@@ -175,19 +204,22 @@ JsonDbIndex::~JsonDbIndex()
bool JsonDbIndex::setPropertyFunction(const QString &propertyFunction)
{
if (!mScriptEngine)
- mScriptEngine = new QJSEngine(this);
- mPropertyFunction = mScriptEngine->evaluate(QString("var %1 = %2; %1;").arg("index").arg(propertyFunction));
- if (mPropertyFunction.isError() || !mPropertyFunction.isCallable()) {
- qDebug() << "Unable to parse index value function: " << mPropertyFunction.toString();
- return false;
- }
+ mScriptEngine = JsonDbScriptEngine::scriptEngine();
- // for "create"
+ // for "emit"
JsonDbJoinProxy *mapProxy = new JsonDbJoinProxy(0, 0, this);
connect(mapProxy, SIGNAL(viewObjectEmitted(QJSValue)),
this, SLOT(propertyValueEmitted(QJSValue)));
- mScriptEngine->globalObject().setProperty("_jsondb", mScriptEngine->newQObject(mapProxy));
- mScriptEngine->evaluate("var jsondb = {emit: _jsondb.create, lookup: _jsondb.lookup };");
+ QString proxyName(QString("_jsondbIndexProxy%1").arg(mIndexName));
+ proxyName.replace(".", "$");
+ mScriptEngine->globalObject().setProperty(proxyName, mScriptEngine->newQObject(mapProxy));
+
+ QString script(QString("(function() { var jsondb={emit: %2.create, lookup: %2.lookup }; var fcn = (%1); return fcn})()").arg(propertyFunction).arg(proxyName));
+ mPropertyFunction = mScriptEngine->evaluate(script);
+ if (mPropertyFunction.isError() || !mPropertyFunction.isCallable()) {
+ qDebug() << "Unable to parse index value function: " << mPropertyFunction.toString();
+ return false;
+ }
return true;
}
@@ -234,7 +266,7 @@ bool JsonDbIndex::validateIndex(const JsonDbObject &newIndex, const JsonDbObject
{
message.clear();
- if (!newIndex.isEmpty() && !oldIndex.isEmpty()) {
+ if (!newIndex.isEmpty() && !oldIndex.isEmpty() && oldIndex.type() == JsonDbString::kIndexTypeStr) {
if (oldIndex.value(JsonDbString::kPropertyNameStr).toString() != newIndex.value(JsonDbString::kPropertyNameStr).toString())
message = QString("Changing old index propertyName '%1' to '%2' not supported")
.arg(oldIndex.value(JsonDbString::kPropertyNameStr).toString())
@@ -326,7 +358,7 @@ QList<QJsonValue> JsonDbIndex::indexValues(JsonDbObject &object)
void JsonDbIndex::propertyValueEmitted(QJSValue value)
{
if (!value.isUndefined())
- mFieldValues.append(JsonDbObject::fromJSValue(value));
+ mFieldValues.append(JsonDbScriptEngine::fromJSValue(value));
}
void JsonDbIndex::indexObject(const ObjectKey &objectKey, JsonDbObject &object, quint32 stateNumber)
@@ -356,7 +388,7 @@ void JsonDbIndex::indexObject(const ObjectKey &objectKey, JsonDbObject &object,
QByteArray forwardKey(makeForwardKey(fieldValue, objectKey));
QByteArray forwardValue(makeForwardValue(objectKey));
- if (jsondbSettings->debug() && jsondbSettings->verbose())
+ if (jsondbSettings->debug())
qDebug() << "indexing" << objectKey << mPropertyName << fieldValue
<< "forwardIndex" << "key" << forwardKey.toHex()
<< "forwardIndex" << "value" << forwardValue.toHex()
@@ -392,7 +424,7 @@ void JsonDbIndex::deindexObject(const ObjectKey &objectKey, JsonDbObject &object
fieldValue = makeFieldValue(fieldValue, mPropertyType);
if (fieldValue.isUndefined())
continue;
- if (jsondbSettings->verbose())
+ if (jsondbSettings->debug())
qDebug() << "deindexing" << objectKey << mPropertyName << fieldValue;
QByteArray forwardKey(makeForwardKey(fieldValue, objectKey));
if (!txn->remove(forwardKey)) {
@@ -570,4 +602,6 @@ bool JsonDbIndexCursor::prev()
return mCursor.previous();
}
-QT_END_NAMESPACE_JSONDB
+#include "moc_jsondbindex.cpp"
+
+QT_END_NAMESPACE_JSONDB_PARTITION
diff --git a/src/daemon/jsondbindex.h b/src/partition/jsondbindex.h
index dfbd0846..c892723b 100644
--- a/src/daemon/jsondbindex.h
+++ b/src/partition/jsondbindex.h
@@ -53,20 +53,19 @@
#include "jsondbobject.h"
-#include "jsondb-global.h"
+#include "jsondbpartitionglobal.h"
#include "jsondbobjectkey.h"
#include "jsondbbtree.h"
-#include "jsondbbtree.h"
#include "jsondbcollator.h"
QT_BEGIN_HEADER
-QT_BEGIN_NAMESPACE_JSONDB
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
class JsonDbPartition;
class JsonDbObjectTable;
-class JsonDbIndex : public QObject
+class Q_JSONDB_PARTITION_EXPORT JsonDbIndex : public QObject
{
Q_OBJECT
public:
@@ -81,11 +80,12 @@ public:
QString propertyType() const { return mPropertyType; }
QStringList objectType() const { return mObjectType; }
- QtAddOn::JsonDb::JsonDbBtree *bdb();
+ JsonDbBtree *bdb();
bool setPropertyFunction(const QString &propertyFunction);
void indexObject(const ObjectKey &objectKey, JsonDbObject &object, quint32 stateNumber);
void deindexObject(const ObjectKey &objectKey, JsonDbObject &object, quint32 stateNumber);
+ QList<QJsonValue> indexValues(JsonDbObject &object);
quint32 stateNumber() const;
@@ -104,7 +104,6 @@ public:
static QString determineName(const JsonDbObject &index);
private:
- QList<QJsonValue> indexValues(JsonDbObject &object);
QJsonValue indexValue(const QJsonValue &v);
private slots:
@@ -133,31 +132,6 @@ private:
quint32 mCacheSize;
};
-class JsonDbIndexCursor
-{
-public:
- JsonDbIndexCursor(JsonDbIndex *index);
- ~JsonDbIndexCursor();
-
- bool seek(const QJsonValue &value);
- bool seekRange(const QJsonValue &value);
-
- bool first();
- bool current(QJsonValue &key, ObjectKey &value);
- bool currentKey(QJsonValue &key);
- bool currentValue(ObjectKey &value);
- bool next();
- bool prev();
-
-private:
- bool isOwnTransaction;
- JsonDbBtree::Transaction *mTxn;
- JsonDbBtree::Cursor mCursor;
- JsonDbIndex *mIndex;
-
- JsonDbIndexCursor(const JsonDbIndexCursor&);
-};
-
class IndexSpec {
public:
QString name;
@@ -173,7 +147,7 @@ public:
QPointer<JsonDbIndex> index;
};
-QT_END_NAMESPACE_JSONDB
+QT_END_NAMESPACE_JSONDB_PARTITION
QT_END_HEADER
diff --git a/src/daemon/jsondbindexquery.cpp b/src/partition/jsondbindexquery.cpp
index 55367eb8..02086b1b 100644
--- a/src/daemon/jsondbindexquery.cpp
+++ b/src/partition/jsondbindexquery.cpp
@@ -44,12 +44,13 @@
#include "jsondbobjecttable.h"
#include "jsondbpartition.h"
#include "jsondbsettings.h"
-
+#include "qbtree.h"
+#include "qbtreecursor.h"
#include "qbtreetxn.h"
#include <QJsonDocument>
-QT_BEGIN_NAMESPACE_JSONDB
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
JsonDbIndexQuery *JsonDbIndexQuery::indexQuery(JsonDbPartition *partition, JsonDbObjectTable *table,
const QString &propertyName, const QString &propertyType,
@@ -267,6 +268,24 @@ JsonDbObject JsonDbUuidQuery::currentObjectAndTypeNumber(ObjectKey &objectKey)
return object;
}
+void JsonDbIndexQuery::setResultExpressionList(const QStringList &resultExpressionList)
+{
+ mResultExpressionList = resultExpressionList;
+ int numExpressions = resultExpressionList.size();
+ mJoinPaths.resize(numExpressions);
+ for (int i = 0; i < numExpressions; i++) {
+ const QString &propertyName = resultExpressionList.at(i);
+ QStringList joinPath = propertyName.split("->");
+ int joinPathSize = joinPath.size();
+ QVector<QStringList> fieldPaths(joinPathSize);
+ for (int j = 0; j < joinPathSize; j++) {
+ QString joinField = joinPath[j];
+ fieldPaths[j] = joinField.split('.');
+ }
+ mJoinPaths[i] = fieldPaths;
+ }
+}
+
JsonDbObject JsonDbIndexQuery::first()
{
mSparseMatchPossible = false;
@@ -320,6 +339,7 @@ JsonDbObject JsonDbIndexQuery::next()
{
QJsonValue fieldValue;
while (seekToNext(fieldValue)) {
+ mFieldValue = fieldValue;
if (jsondbSettings->debugQuery()) {
qDebug() << "IndexQuery::next()" << "mPropertyName" << mPropertyName
<< "fieldValue" << fieldValue
@@ -353,6 +373,44 @@ JsonDbObject JsonDbIndexQuery::next()
return QJsonObject();
}
+JsonDbObject JsonDbIndexQuery::resultObject(const JsonDbObject &object)
+{
+ int numExpressions = mResultExpressionList.length();
+ QJsonObject result(object);
+
+ // insert the computed index value
+ result.insert(QLatin1String("_indexValue"), mFieldValue);
+
+ if (!numExpressions)
+ return result;
+
+ for (int i = 0; i < numExpressions; i++) {
+ QJsonValue v;
+
+ QVector<QStringList> &joinPath = mJoinPaths[i];
+ int joinPathSize = joinPath.size();
+ JsonDbObject baseObject(result);
+ for (int j = 0; j < joinPathSize-1; j++) {
+ QJsonValue uuidQJsonValue = baseObject.propertyLookup(joinPath[j]).toString();
+ QString uuid = uuidQJsonValue.toString();
+ if (uuid.isEmpty()) {
+ baseObject = JsonDbObject();
+ } else if (mObjectCache.contains(uuid)) {
+ baseObject = mObjectCache.value(uuid);
+ } else {
+ ObjectKey objectKey(uuid);
+ bool gotBaseObject = mPartition->getObject(objectKey, baseObject);
+ if (gotBaseObject)
+ mObjectCache.insert(uuid, baseObject);
+ }
+ }
+ v = baseObject.propertyLookup(joinPath[joinPathSize-1]);
+ result.insert(mResultKeyList[i], v);
+ }
+
+ return result;
+}
+
bool JsonDbIndexQuery::lessThan(const QJsonValue &a, const QJsonValue &b)
{
if (a.type() == b.type()) {
@@ -387,4 +445,4 @@ bool JsonDbIndexQuery::greaterThan(const QJsonValue &a, const QJsonValue &b)
}
}
-QT_END_NAMESPACE_JSONDB
+QT_END_NAMESPACE_JSONDB_PARTITION
diff --git a/src/daemon/jsondbindexquery.h b/src/partition/jsondbindexquery.h
index cc21517f..66845445 100644
--- a/src/daemon/jsondbindexquery.h
+++ b/src/partition/jsondbindexquery.h
@@ -46,14 +46,16 @@
#include <QRegExp>
#include <QSet>
#include <QVector>
+#include <QStringList>
+#include "jsondbpartitionglobal.h"
#include "jsondbobject.h"
#include "jsondbobjectkey.h"
#include "jsondbbtree.h"
QT_BEGIN_HEADER
-QT_BEGIN_NAMESPACE_JSONDB
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
class JsonDbObjectTable;
class JsonDbOwner;
@@ -67,7 +69,7 @@ public:
virtual bool sparseMatchPossible() const { return false; }
};
-class JsonDbIndexQuery {
+class Q_JSONDB_PARTITION_EXPORT JsonDbIndexQuery {
protected:
JsonDbIndexQuery(JsonDbPartition *partition, JsonDbObjectTable *table,
const QString &propertyName, const QString &propertyType,
@@ -88,6 +90,8 @@ public:
void setMax(const QJsonValue &maxv);
QString aggregateOperation() const { return mAggregateOperation; }
void setAggregateOperation(QString op) { mAggregateOperation = op; }
+ void setResultExpressionList(const QStringList &resultExpressionList);
+ void setResultKeyList(QStringList resultKeyList) { mResultKeyList = resultKeyList; }
JsonDbObject first(); // returns first matching object
JsonDbObject next(); // returns next matching object
@@ -97,6 +101,8 @@ public:
void setResidualQuery(JsonDbQuery *residualQuery) { mResidualQuery = residualQuery; }
virtual quint32 stateNumber() const;
+ JsonDbObject resultObject(const JsonDbObject &object);
+
static bool lessThan(const QJsonValue &a, const QJsonValue &b);
static bool greaterThan(const QJsonValue &a, const QJsonValue &b);
@@ -124,6 +130,9 @@ protected:
QJsonValue mFieldValue; // value of field for the object the cursor is pointing at
bool mSparseMatchPossible;
QHash<QString, JsonDbObject> mObjectCache;
+ QStringList mResultExpressionList;
+ QStringList mResultKeyList;
+ QVector<QVector<QStringList> > mJoinPaths;
JsonDbQuery *mResidualQuery;
};
@@ -233,7 +242,7 @@ private:
QRegExp mRegExp;
};
-QT_END_NAMESPACE_JSONDB
+QT_END_NAMESPACE_JSONDB_PARTITION
QT_END_HEADER
diff --git a/src/daemon/jsondbmapdefinition.cpp b/src/partition/jsondbmapdefinition.cpp
index 23baa645..07c4a1df 100644
--- a/src/daemon/jsondbmapdefinition.cpp
+++ b/src/partition/jsondbmapdefinition.cpp
@@ -51,17 +51,17 @@
#include <stdlib.h>
#include "jsondbpartition.h"
-#include "jsondb-strings.h"
-#include "jsondb-error.h"
-#include "json.h"
+#include "jsondbstrings.h"
+#include "jsondberrors.h"
#include "jsondbproxy.h"
#include "jsondbobjecttable.h"
#include "jsondbmapdefinition.h"
#include "jsondbsettings.h"
+#include "jsondbscriptengine.h"
#include "jsondbview.h"
-QT_BEGIN_NAMESPACE_JSONDB
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
JsonDbMapDefinition::JsonDbMapDefinition(const JsonDbOwner *owner, JsonDbPartition *partition, QJsonObject definition, QObject *parent) :
QObject(parent)
@@ -73,6 +73,8 @@ JsonDbMapDefinition::JsonDbMapDefinition(const JsonDbOwner *owner, JsonDbPartiti
, mTargetType(definition.value("targetType").toString())
, mTargetTable(mPartition->findObjectTable(mTargetType))
{
+ mMapId = mUuid;
+ mMapId.replace(QRegExp("[-{}]"), "$");
QJsonObject sourceFunctions(mDefinition.contains("join")
? mDefinition.value("join").toObject()
: mDefinition.value("map").toObject());
@@ -128,42 +130,53 @@ void JsonDbMapDefinition::initScriptEngine()
if (mScriptEngine)
return;
- mScriptEngine = new QJSEngine(this);
- QString message;
- bool compiled = compileMapFunctions(mScriptEngine, mDefinition, mMapFunctions, message);
- if (!compiled)
- setError(message);
- QJSValue globalObject = mScriptEngine->globalObject();
- globalObject.setProperty("console", mScriptEngine->newQObject(new Console()));
-
+ mScriptEngine = JsonDbScriptEngine::scriptEngine();
mJoinProxy = new JsonDbJoinProxy(mOwner, mPartition, this);
connect(mJoinProxy, SIGNAL(lookupRequested(QJSValue,QJSValue)),
this, SLOT(lookupRequested(QJSValue,QJSValue)));
connect(mJoinProxy, SIGNAL(viewObjectEmitted(QJSValue)),
this, SLOT(viewObjectEmitted(QJSValue)));
- globalObject.setProperty("_jsondb", mScriptEngine->newQObject(mJoinProxy));
- // we use this snippet of javascript so that we can bind "jsondb.emit"
- // even though "emit" is a Qt keyword
- if (mDefinition.contains("join"))
- // only joins can use lookup()
- mScriptEngine->evaluate("var jsondb = { emit: _jsondb.create, lookup: _jsondb.lookup, createUuidFromString: _jsondb.createUuidFromString};");
- else
- mScriptEngine->evaluate("var jsondb = { emit: _jsondb.create, createUuidFromString: _jsondb.createUuidFromString };");
+
+ QString message;
+ bool compiled = compileMapFunctions(mScriptEngine, mDefinition, mJoinProxy, mMapFunctions, message);
+ if (!compiled)
+ setError(message);
}
-bool JsonDbMapDefinition::compileMapFunctions(QJSEngine *scriptEngine, QJsonObject definition, QMap<QString,QJSValue> &mapFunctions, QString &message)
+bool JsonDbMapDefinition::compileMapFunctions(QJSEngine *scriptEngine, QJsonObject definition, JsonDbJoinProxy *joinProxy, QMap<QString,QJSValue> &mapFunctions, QString &message)
{
bool status = true;
QJsonObject sourceFunctions(definition.contains("join")
? definition.value("join").toObject()
: definition.value("map").toObject());
+ QJSValue svJoinProxyValue = joinProxy ? scriptEngine->newQObject(joinProxy) : QJSValue(QJSValue::UndefinedValue);
for (QJsonObject::const_iterator it = sourceFunctions.begin(); it != sourceFunctions.end(); ++it) {
const QString &sourceType = it.key();
const QString &script = it.value().toString();
- QJSValue mapFunction =
- scriptEngine->evaluate(QString("var map_%1 = (%2); map_%1;").arg(QString(sourceType).replace(".", "_")).arg(script));
- if (mapFunction.isError() || !mapFunction.isCallable()) {
- message = QString( "Unable to parse map function: " + mapFunction.toString());
+ QString jsonDbBinding;
+ if (definition.contains("join"))
+ // only joins can use lookup()
+ jsonDbBinding = QString("{ emit: proxy.create, lookup: proxy.lookup, createUuidFromString: proxy.createUuidFromString}");
+ else
+ jsonDbBinding = QString("{ emit: proxy.create, createUuidFromString: proxy.createUuidFromString }");
+
+ // first, package it as a function that takes a jsondb proxy and returns the map function
+ QJSValue moduleFunction =
+ scriptEngine->evaluate(QString("(function (proxy) { var jsondb=%3; map_%1 = (%2); return map_%1; })")
+ .arg(QString(sourceType).replace(".", "_"))
+ .arg(script)
+ .arg(jsonDbBinding));
+ if (moduleFunction.isError() || !moduleFunction.isCallable()) {
+ message = QString( "Unable to parse map function: " + moduleFunction.toString());
+ status = false;
+ }
+
+ // now pass it the jsondb proxy to get the map function
+ QJSValueList args;
+ args << svJoinProxyValue;
+ QJSValue mapFunction = moduleFunction.call(args);
+ if (moduleFunction.isError() || !moduleFunction.isCallable()) {
+ message = QString( "Unable to evaluate map function: " + moduleFunction.toString());
status = false;
}
mapFunctions[sourceType] = mapFunction;
@@ -174,7 +187,6 @@ bool JsonDbMapDefinition::compileMapFunctions(QJSEngine *scriptEngine, QJsonObje
void JsonDbMapDefinition::releaseScriptEngine()
{
mMapFunctions.clear();
- delete mScriptEngine;
mScriptEngine = 0;
}
@@ -184,8 +196,9 @@ void JsonDbMapDefinition::initIndexes()
mTargetTable->addIndexOnProperty(QLatin1String("_sourceUuids.*"), QLatin1String("string"), mTargetType);
}
-void JsonDbMapDefinition::updateObject(const JsonDbObject &beforeObject, const JsonDbObject &afterObject)
+void JsonDbMapDefinition::updateObject(const JsonDbObject &beforeObject, const JsonDbObject &afterObject, JsonDbUpdateList *changeList)
{
+ initScriptEngine();
QHash<QString, JsonDbObject> unmappedObjects;
mEmittedObjects.clear();
@@ -198,8 +211,13 @@ void JsonDbMapDefinition::updateObject(const JsonDbObject &beforeObject, const J
}
}
- mapObject(afterObject);
+ if (!afterObject.isDeleted()) {
+ if (jsondbSettings->verbose())
+ qDebug() << "Mapping object" << afterObject;
+ mapObject(afterObject);
+ }
+ JsonDbObjectList objectsToUpdate;
for (QHash<QString, JsonDbObject>::const_iterator it = unmappedObjects.begin();
it != unmappedObjects.end();
++it) {
@@ -210,33 +228,31 @@ void JsonDbMapDefinition::updateObject(const JsonDbObject &beforeObject, const J
JsonDbObject emittedObject(mEmittedObjects.value(uuid));
emittedObject.insert(JsonDbString::kVersionStr, unmappedObject.value(JsonDbString::kVersionStr));
emittedObject.insert(JsonDbString::kOwnerStr, unmappedObject.value(JsonDbString::kOwnerStr));
- if (emittedObject == it.value()) {
+ if (emittedObject == it.value())
// skip duplicates
continue;
- } else {
+ else
// update changed view objects
- res = mPartition->updateObject(mOwner, emittedObject, JsonDbPartition::ViewObject);
- }
+ objectsToUpdate.append(emittedObject);
mEmittedObjects.remove(uuid);
} else {
// remove unmatched objects
unmappedObject.markDeleted();
- res = mPartition->updateObject(mOwner, unmappedObject, JsonDbPartition::ViewObject);
+ if (jsondbSettings->verbose())
+ qDebug() << "Unmapping object" << unmappedObject;
+ objectsToUpdate.append(unmappedObject);
}
-
- if (res.code != JsonDbError::NoError)
- setError("Error updating view object: " + res.message);
}
for (QHash<QString, JsonDbObject>::const_iterator it = mEmittedObjects.begin();
it != mEmittedObjects.end();
- ++it) {
- JsonDbObject newItem(it.value());
- JsonDbWriteResult res = mPartition->updateObject(mOwner, newItem, JsonDbPartition::ViewObject);
- if (res.code != JsonDbError::NoError)
- setError("Error creating view object: " + res.message);
- }
+ ++it)
+ objectsToUpdate.append(JsonDbObject(it.value()));
+
+ JsonDbWriteResult res = mPartition->updateObjects(mOwner, objectsToUpdate, JsonDbPartition::ViewObject, changeList);
+ if (res.code != JsonDbError::NoError)
+ setError("Error creating view object: " + res.message);
}
QJSValue JsonDbMapDefinition::mapFunction(const QString &sourceType) const
@@ -249,10 +265,9 @@ QJSValue JsonDbMapDefinition::mapFunction(const QString &sourceType) const
void JsonDbMapDefinition::mapObject(JsonDbObject object)
{
- initScriptEngine();
const QString &sourceType = object.value(JsonDbString::kTypeStr).toString();
- QJSValue sv = JsonDbObject::toJSValue(object, mScriptEngine);
+ QJSValue sv = JsonDbScriptEngine::toJSValue(object, mScriptEngine);
QString uuid = object.value(JsonDbString::kUuidStr).toString();
mSourceUuids.clear();
mSourceUuids.append(mUuid); // depends on the map definition object
@@ -270,7 +285,6 @@ void JsonDbMapDefinition::mapObject(JsonDbObject object)
void JsonDbMapDefinition::unmapObject(const JsonDbObject &object)
{
Q_ASSERT(object.value(JsonDbString::kUuidStr).type() == QJsonValue::String);
- initScriptEngine();
QJsonValue uuid = object.value(JsonDbString::kUuidStr);
GetObjectsResult getObjectResponse = mTargetTable->getObjects("_sourceUuids.*", uuid, mTargetType);
JsonDbObjectList dependentObjects = getObjectResponse.data;
@@ -304,7 +318,7 @@ void JsonDbMapDefinition::lookupRequested(const QJSValue &query, const QJSValue
QString findKey = query.property("index").toString();
QJSValue findValue = query.property("value");
GetObjectsResult getObjectResponse =
- mPartition->getObjects(findKey, JsonDbObject::fromJSValue(findValue), objectType, false);
+ mPartition->getObjects(findKey, JsonDbScriptEngine::fromJSValue(findValue), objectType, false);
if (!getObjectResponse.error.isNull()) {
if (jsondbSettings->verbose())
qDebug() << "lookupRequested" << mSourceTypes << mTargetType
@@ -317,12 +331,12 @@ void JsonDbMapDefinition::lookupRequested(const QJSValue &query, const QJSValue
const QString uuid = object.value(JsonDbString::kUuidStr).toString();
if (mSourceUuids.contains(uuid)) {
if (jsondbSettings->verbose())
- qDebug() << "Lookup cycle detected" << "key" << findKey << JsonDbObject::fromJSValue(findValue) << "matching object" << uuid << "source uuids" << mSourceUuids;
+ qDebug() << "Lookup cycle detected" << "key" << findKey << JsonDbScriptEngine::fromJSValue(findValue) << "matching object" << uuid << "source uuids" << mSourceUuids;
continue;
}
mSourceUuids.append(uuid);
QJSValueList mapArgs;
- QJSValue sv = JsonDbObject::toJSValue(object, mScriptEngine);
+ QJSValue sv = JsonDbScriptEngine::toJSValue(object, mScriptEngine);
mapArgs << sv << context;
QJSValue mapped = mMapFunctions[objectType].call(mapArgs);
@@ -336,7 +350,7 @@ void JsonDbMapDefinition::lookupRequested(const QJSValue &query, const QJSValue
void JsonDbMapDefinition::viewObjectEmitted(const QJSValue &value)
{
- JsonDbObject newItem(JsonDbObject::fromJSValue(value).toObject());
+ JsonDbObject newItem(JsonDbScriptEngine::fromJSValue(value).toObject());
newItem.insert(JsonDbString::kTypeStr, mTargetType);
mSourceUuids.sort();
QJsonArray sourceUuidArray;
@@ -446,14 +460,15 @@ bool JsonDbMapDefinition::validateDefinition(const JsonDbObject &map, JsonDbPart
// check for parse errors
if (message.isEmpty()) {
- // FIXME: This is static because otherwise we leak memory per QJSEngine instance
- static QJSEngine *scriptEngine = new QJSEngine;
+ QJSEngine *scriptEngine = JsonDbScriptEngine::scriptEngine();
QMap<QString,QJSValue> mapFunctions;
- compileMapFunctions(scriptEngine, map, mapFunctions, message);
+ compileMapFunctions(scriptEngine, map, 0, mapFunctions, message);
scriptEngine->collectGarbage();
}
return message.isEmpty();
}
-QT_END_NAMESPACE_JSONDB
+#include "moc_jsondbmapdefinition.cpp"
+
+QT_END_NAMESPACE_JSONDB_PARTITION
diff --git a/src/daemon/jsondbmapdefinition.h b/src/partition/jsondbmapdefinition.h
index 61b19b35..a25f7d7d 100644
--- a/src/daemon/jsondbmapdefinition.h
+++ b/src/partition/jsondbmapdefinition.h
@@ -45,8 +45,8 @@
#include <QJSEngine>
#include <QStringList>
-#include "jsondb-global.h"
#include "jsondbpartition.h"
+#include "jsondbpartitionglobal.h"
#include <qjsonarray.h>
#include <qjsonobject.h>
@@ -56,7 +56,7 @@
QT_BEGIN_HEADER
-QT_BEGIN_NAMESPACE_JSONDB
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
class JsonDbOwner;
class JsonDbJoinProxy;
@@ -86,9 +86,9 @@ public:
void initIndexes();
void setError(const QString &errorMsg);
- void updateObject(const JsonDbObject &before, const JsonDbObject &after);
+ void updateObject(const JsonDbObject &before, const JsonDbObject &after, JsonDbUpdateList *changeList = 0);
static bool validateDefinition(const JsonDbObject &map, JsonDbPartition *partition, QString &message);
- static bool compileMapFunctions(QJSEngine *scriptEngine, QJsonObject definition, QMap<QString,QJSValue> &mapFunctions, QString &message);
+ static bool compileMapFunctions(QJSEngine *scriptEngine, QJsonObject definition, JsonDbJoinProxy *joinProxy, QMap<QString,QJSValue> &mapFunctions, QString &message);
public slots:
void viewObjectEmitted(const QJSValue &value);
@@ -108,6 +108,7 @@ private:
JsonDbJoinProxy *mJoinProxy;
QMap<QString,QJSValue> mMapFunctions;
QString mUuid;
+ QString mMapId; // uuid with special characters converted to '$'
QString mTargetType;
QStringList mSourceTypes;
JsonDbObjectTable *mTargetTable;
@@ -116,7 +117,7 @@ private:
QHash<QString,JsonDbObject> mEmittedObjects;
};
-QT_END_NAMESPACE_JSONDB
+QT_END_NAMESPACE_JSONDB_PARTITION
QT_END_HEADER
diff --git a/src/daemon/jsondbnotification.cpp b/src/partition/jsondbnotification.cpp
index 3fb12d4e..d8687309 100644
--- a/src/daemon/jsondbnotification.cpp
+++ b/src/partition/jsondbnotification.cpp
@@ -48,18 +48,20 @@
#include "jsondbnotification.h"
#include "jsondbquery.h"
-#include "jsondb-strings.h"
+#include "jsondbstrings.h"
-QT_BEGIN_NAMESPACE_JSONDB
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
JsonDbNotification::JsonDbNotification(const JsonDbOwner *owner, const QString &uuid, const QString& query,
QStringList actions, const QString &partition)
: mOwner(owner)
, mUuid(uuid)
, mQuery(query)
+ , mCompiledQuery(NULL)
, mActions(None)
, mPartition(partition)
, mInitialStateNumber(0)
+ , mLastStateNumber(0)
{
foreach (QString s, actions) {
if (s == JsonDbString::kCreateStr)
@@ -78,4 +80,4 @@ JsonDbNotification::~JsonDbNotification()
}
}
-QT_END_NAMESPACE_JSONDB
+QT_END_NAMESPACE_JSONDB_PARTITION
diff --git a/src/daemon/jsondbnotification.h b/src/partition/jsondbnotification.h
index b3de21df..9e52d4bb 100644
--- a/src/daemon/jsondbnotification.h
+++ b/src/partition/jsondbnotification.h
@@ -45,15 +45,15 @@
#include <QObject>
#include <QJSValue>
-#include "jsondb-global.h"
+#include "jsondbpartitionglobal.h"
QT_BEGIN_HEADER
-QT_BEGIN_NAMESPACE_JSONDB
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
class JsonDbOwner;
class JsonDbQuery;
-class JsonDbNotification {
+class Q_JSONDB_PARTITION_EXPORT JsonDbNotification {
public:
enum Action { None = 0x0000, Create = 0x0001, Update = 0x0002, Delete = 0x0004 };
Q_DECLARE_FLAGS(Actions, Action)
@@ -65,11 +65,13 @@ public:
const QString& uuid() const { return mUuid; }
const QString& query() const { return mQuery; }
Actions actions() const { return mActions; }
- JsonDbQuery *parsedQuery() { return mCompiledQuery; }
+ JsonDbQuery *parsedQuery() const { return mCompiledQuery; }
void setCompiledQuery(JsonDbQuery *parsedQuery) { mCompiledQuery = parsedQuery; }
const QString & partition() const { return mPartition; }
quint32 initialStateNumber() const { return mInitialStateNumber; }
void setInitialStateNumber(quint32 stateNumber) { mInitialStateNumber = stateNumber; }
+ quint32 lastStateNumber() const { return mLastStateNumber; }
+ void setLastStateNumber(quint32 stateNumber) { mLastStateNumber = stateNumber; }
private:
const JsonDbOwner *mOwner;
QString mUuid;
@@ -78,11 +80,12 @@ private:
Actions mActions;
QString mPartition;
quint32 mInitialStateNumber;
+ quint32 mLastStateNumber;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(JsonDbNotification::Actions)
-QT_END_NAMESPACE_JSONDB
+QT_END_NAMESPACE_JSONDB_PARTITION
QT_END_HEADER
diff --git a/src/daemon/jsondbobject.cpp b/src/partition/jsondbobject.cpp
index 1a7467b6..e61d6ebf 100644
--- a/src/daemon/jsondbobject.cpp
+++ b/src/partition/jsondbobject.cpp
@@ -49,9 +49,10 @@
#include <qjsondocument.h>
-#include "jsondb-strings.h"
+#include "jsondbstrings.h"
+#include "jsondbproxy.h"
-QT_ADDON_JSONDB_BEGIN_NAMESPACE
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
JsonDbObject::JsonDbObject()
{
@@ -606,70 +607,4 @@ QJsonValue JsonDbObject::propertyLookup(const QStringList &path) const
return value;
}
-QJsonValue JsonDbObject::fromJSValue(const QJSValue &v)
-{
- if (v.isNull())
- return QJsonValue(QJsonValue::Null);
- if (v.isNumber())
- return QJsonValue(v.toNumber());
- if (v.isString())
- return QJsonValue(v.toString());
- if (v.isBool())
- return QJsonValue(v.toBool());
- if (v.isArray()) {
- QJsonArray a;
- int size = v.property("length").toInt();
- for (int i = 0; i < size; i++) {
- a.append(fromJSValue(v.property(i)));
- }
- return a;
- }
- if (v.isObject()) {
- QJSValueIterator it(v);
- QJsonObject o;
- while (it.hasNext()) {
- it.next();
- QString name = it.name();
- QJSValue value = it.value();
- o.insert(name, fromJSValue(value));
- }
- return o;
- }
- return QJsonValue(QJsonValue::Undefined);
-}
-
-QJSValue JsonDbObject::toJSValue(const QJsonValue &v, QJSEngine *scriptEngine)
-{
- switch (v.type()) {
- case QJsonValue::Null:
- return QJSValue(QJSValue::NullValue);
- case QJsonValue::Undefined:
- return QJSValue(QJSValue::UndefinedValue);
- case QJsonValue::Double:
- return QJSValue(v.toDouble());
- case QJsonValue::String:
- return QJSValue(v.toString());
- case QJsonValue::Bool:
- return QJSValue(v.toBool());
- case QJsonValue::Array: {
- QJSValue jsArray = scriptEngine->newArray();
- QJsonArray array = v.toArray();
- for (int i = 0; i < array.size(); i++)
- jsArray.setProperty(i, toJSValue(array.at(i), scriptEngine));
- return jsArray;
- }
- case QJsonValue::Object:
- return toJSValue(v.toObject(), scriptEngine);
- }
- return QJSValue(QJSValue::UndefinedValue);
-}
-
-QJSValue JsonDbObject::toJSValue(const QJsonObject &object, QJSEngine *scriptEngine)
-{
- QJSValue jsObject = scriptEngine->newObject();
- for (QJsonObject::const_iterator it = object.begin(); it != object.end(); ++it)
- jsObject.setProperty(it.key(), toJSValue(it.value(), scriptEngine));
- return jsObject;
-}
-
-QT_ADDON_JSONDB_END_NAMESPACE
+QT_END_NAMESPACE_JSONDB_PARTITION
diff --git a/src/daemon/jsondbobject.h b/src/partition/jsondbobject.h
index b648518a..f5860a47 100644
--- a/src/daemon/jsondbobject.h
+++ b/src/partition/jsondbobject.h
@@ -51,13 +51,13 @@
#include <qjsonobject.h>
#include <qjsonvalue.h>
-#include "jsondb-global.h"
+#include "jsondbpartitionglobal.h"
QT_BEGIN_HEADER
-QT_ADDON_JSONDB_BEGIN_NAMESPACE
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
-class JsonDbObject : public QJsonObject
+class Q_JSONDB_PARTITION_EXPORT JsonDbObject : public QJsonObject
{
public:
JsonDbObject();
@@ -85,10 +85,6 @@ public:
QJsonValue propertyLookup(const QString &path) const;
QJsonValue propertyLookup(const QStringList &path) const;
- static QJsonValue fromJSValue(const QJSValue &v);
- static QJSValue toJSValue(const QJsonValue &v, QJSEngine *scriptEngine);
- static QJSValue toJSValue(const QJsonObject &object, QJSEngine *mScriptEngine);
-
private:
bool populateMerge(QMap<JsonDbObject, bool> *documents, const QUuid &id, const JsonDbObject &source, bool validateSource = false, bool recurse = true) const;
void populateHistory(QJsonArray *history, const JsonDbObject &doc, bool includeCurrent) const;
@@ -111,7 +107,8 @@ struct GetObjectsResult
};
-QT_ADDON_JSONDB_END_NAMESPACE
+QT_END_NAMESPACE_JSONDB_PARTITION
+
QT_END_HEADER
#endif // JSONDB_OBJECT_H
diff --git a/src/daemon/jsondbobjectkey.h b/src/partition/jsondbobjectkey.h
index 9ce9ad4a..ca51295d 100644
--- a/src/daemon/jsondbobjectkey.h
+++ b/src/partition/jsondbobjectkey.h
@@ -47,13 +47,13 @@
#include <qdebug.h>
#include <quuid.h>
-#include "jsondb-global.h"
+#include "jsondbpartitionglobal.h"
QT_BEGIN_HEADER
-QT_BEGIN_NAMESPACE_JSONDB
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
-class ObjectKey
+class Q_JSONDB_PARTITION_EXPORT ObjectKey
{
public:
QUuid key; // object uuid
@@ -80,19 +80,19 @@ inline QDebug &operator<<(QDebug &qdb, const ObjectKey &objectKey)
return qdb;
}
-QT_END_NAMESPACE_JSONDB
+QT_END_NAMESPACE_JSONDB_PARTITION
QT_BEGIN_NAMESPACE
-template <> inline void qToBigEndian(QT_PREPEND_NAMESPACE_JSONDB(ObjectKey) src, uchar *dest)
+template <> inline void qToBigEndian(QT_PREPEND_NAMESPACE_JSONDB_PARTITION(ObjectKey) src, uchar *dest)
{
//TODO: improve me
QByteArray key = src.key.toRfc4122();
memcpy(dest, key.constData(), key.size());
}
-template <> inline QT_PREPEND_NAMESPACE_JSONDB(ObjectKey) qFromBigEndian(const uchar *src)
+template <> inline QT_PREPEND_NAMESPACE_JSONDB_PARTITION(ObjectKey) qFromBigEndian(const uchar *src)
{
- QT_PREPEND_NAMESPACE_JSONDB(ObjectKey) key;
+ QT_PREPEND_NAMESPACE_JSONDB_PARTITION(ObjectKey) key;
key.key = QUuid::fromRfc4122(QByteArray::fromRawData((const char *)src, 16));
return key;
}
diff --git a/src/daemon/jsondbobjecttable.cpp b/src/partition/jsondbobjecttable.cpp
index 00bb7075..b5d606a0 100644
--- a/src/daemon/jsondbobjecttable.cpp
+++ b/src/partition/jsondbobjecttable.cpp
@@ -46,13 +46,15 @@
#include "jsondbobjecttable.h"
#include "jsondbindex.h"
-#include "jsondb-strings.h"
+#include "jsondbstrings.h"
#include "jsondbbtree.h"
#include "jsondbobject.h"
#include "jsondbsettings.h"
+#include "qbtree.h"
+#include "qbtreecursor.h"
#include "qbtreetxn.h"
-QT_BEGIN_NAMESPACE_JSONDB
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
void makeStateKey(QByteArray &baStateKey, quint32 stateNumber)
{
@@ -82,7 +84,7 @@ JsonDbObjectTable::~JsonDbObjectTable()
mBdb = 0;
}
-bool JsonDbObjectTable::open(const QString&fileName, JsonDbBtree::OpenFlags flags)
+bool JsonDbObjectTable::open(const QString &fileName)
{
mFilename = fileName;
#if 0
@@ -92,7 +94,7 @@ bool JsonDbObjectTable::open(const QString&fileName, JsonDbBtree::OpenFlags flag
}
#endif
mBdb->setCacheSize(jsondbSettings->cacheSize());
- if (!mBdb->open(mFilename, flags)) {
+ if (!mBdb->open(mFilename)) {
qCritical() << "mBdb->open" << mBdb->errorMessage();
return false;
}
@@ -209,12 +211,14 @@ JsonDbStat JsonDbObjectTable::stat() const
++it) {
const IndexSpec &indexSpec = it.value();
if (indexSpec.index->bdb()) {
- JsonDbBtree::Stat stat = indexSpec.index->bdb()->stats();
+ JsonDbBtree::Stat stat = indexSpec.index->bdb()->btree() ?
+ indexSpec.index->bdb()->stats() :
+ JsonDbBtree::Stat();
result += JsonDbStat(stat.reads, stat.hits, stat.writes);
}
// _uuid index does not have bdb() because it is actually the object table itself
}
- JsonDbBtree::Stat stat = mBdb->stats();
+ JsonDbBtree::Stat stat = mBdb->btree() ? mBdb->btree()->stats() : JsonDbBtree::Stat();
result += JsonDbStat(stat.reads, stat.hits, stat.writes);
return result;
}
@@ -422,9 +426,8 @@ void JsonDbObjectTable::updateIndex(JsonDbIndex *index)
quint32 indexStateNumber = qMax(1u, index->bdb()->tag());
if (indexStateNumber == stateNumber())
return;
- QJsonObject changes = changesSince(indexStateNumber).value("result").toObject();
- quint32 count = changes.value("count").toDouble();
- QJsonArray changeList = changes.value("changes").toArray();
+ JsonDbUpdateList changeList;
+ changesSince(indexStateNumber, QSet<QString>(), &changeList);
bool inTransaction = mBdb->isWriting();
if (!inTransaction)
index->begin();
@@ -432,14 +435,13 @@ void JsonDbObjectTable::updateIndex(JsonDbIndex *index)
index->begin();
mBdbTransactions.append(index->begin());
}
- for (quint32 i = 0; i < count; i++) {
- QJsonObject change = changeList.at(i).toObject();
- JsonDbObject before = change.value("before").toObject();
- JsonDbObject after = change.value("after").toObject();
+ foreach (const JsonDbUpdate &change, changeList) {
+ JsonDbObject before = change.oldObject;
+ JsonDbObject after = change.newObject;
ObjectKey objectKey(after.value(JsonDbString::kUuidStr).toString());
if (!before.isEmpty())
index->deindexObject(objectKey, before, stateNumber());
- if (!after.isEmpty())
+ if (!after.isDeleted())
index->indexObject(objectKey, after, stateNumber());
}
if (!inTransaction)
@@ -569,7 +571,7 @@ GetObjectsResult JsonDbObjectTable::getObjects(const QString &keyName, const QJs
return result;
}
-quint32 JsonDbObjectTable::storeStateChange(const ObjectKey &key, ObjectChange::Action action, const JsonDbObject &oldObject)
+quint32 JsonDbObjectTable::storeStateChange(const ObjectKey &key, const JsonDbUpdate &change)
{
quint32 stateNumber = mStateNumber + 1;
@@ -578,32 +580,16 @@ quint32 JsonDbObjectTable::storeStateChange(const ObjectKey &key, ObjectChange::
uchar *data = (uchar *)mStateChanges.data() + oldSize;
qToBigEndian(key, data);
- qToBigEndian<quint32>(action, data+16);
- if (!oldObject.isEmpty())
- mStateObjectChanges.append(oldObject);
+ qToBigEndian<quint32>(change.action, data+16);
+ if (!change.oldObject.isEmpty())
+ mStateObjectChanges.append(change.oldObject);
return stateNumber;
}
-quint32 JsonDbObjectTable::storeStateChange(const QList<ObjectChange> &changes)
-{
- quint32 stateNumber = mStateNumber + 1;
- int oldSize = mStateChanges.size();
- mStateChanges.resize(oldSize + changes.size() * 20);
- uchar *data = (uchar *)mStateChanges.data() + oldSize;
- foreach (const ObjectChange &change, changes) {
- qToBigEndian(change.objectKey, data);
- qToBigEndian<quint32>(change.action, data+16);
- data += 20;
- if (!change.oldObject.isEmpty())
- mStateObjectChanges.append(change.oldObject);
- }
- return stateNumber;
-}
-
-void JsonDbObjectTable::changesSince(quint32 stateNumber, QMap<ObjectKey,ObjectChange> *changes)
+quint32 JsonDbObjectTable::changesSince(quint32 stateNumber, QMap<ObjectKey,JsonDbUpdate> *changes)
{
if (!changes)
- return;
+ return -1;
stateNumber = qMax(quint32(1), stateNumber+1);
QElapsedTimer timer;
@@ -615,7 +601,7 @@ void JsonDbObjectTable::changesSince(quint32 stateNumber, QMap<ObjectKey,ObjectC
QByteArray baStateKey(5, 0);
makeStateKey(baStateKey, stateNumber);
- QMap<ObjectKey,ObjectChange> changeMap; // collect one change per uuid
+ QMap<ObjectKey,JsonDbUpdate> changeMap; // collect one change per uuid
if (cursor.seekRange(baStateKey)) {
do {
@@ -637,28 +623,34 @@ void JsonDbObjectTable::changesSince(quint32 stateNumber, QMap<ObjectKey,ObjectC
for (int i = 0; i < baObject.size() / 20; ++i) {
const uchar *data = (const uchar *)baObject.constData() + i*20;
ObjectKey objectKey = qFromBigEndian<ObjectKey>(data);
+ QByteArray baObjectKey(objectKey.key.toRfc4122());
quint32 action = qFromBigEndian<quint32>(data + 16);
- Q_ASSERT(action <= ObjectChange::LastAction);
QByteArray baValue;
QJsonObject oldObject;
- if ((action != ObjectChange::Created)
- && mBdb->getOne(baStateKey + objectKey.key.toRfc4122(), &baValue)) {
+ if ((action != JsonDbNotification::Create)
+ && mBdb->getOne(baStateKey + baObjectKey, &baValue)) {
oldObject = QJsonDocument::fromBinaryData(baValue).object();
Q_ASSERT(objectKey == ObjectKey(oldObject.value(JsonDbString::kUuidStr).toString()));
}
- ObjectChange change(objectKey, ObjectChange::Action(action), oldObject);
+ QJsonObject newObject;
+ mBdb->getOne(baObjectKey, &baValue);
+ newObject = QJsonDocument::fromBinaryData(baValue).object();
+ if (jsondbSettings->debug())
+ qDebug() << "change" << action << endl << oldObject << endl << newObject;
+
+ JsonDbUpdate change(oldObject, newObject, JsonDbNotification::Action(action));
if (changeMap.contains(objectKey)) {
- ObjectChange oldChange = changeMap.value(objectKey);
+ JsonDbUpdate oldChange = changeMap.value(objectKey);
// create followed by delete cancels out
- ObjectChange::Action newAction = ObjectChange::Action(action);
- ObjectChange::Action oldAction = oldChange.action;
- if ((oldAction == ObjectChange::Created)
- && (newAction == ObjectChange::Deleted)) {
+ JsonDbNotification::Action newAction = JsonDbNotification::Action(action);
+ JsonDbNotification::Action oldAction = oldChange.action;
+ if ((oldAction == JsonDbNotification::Create)
+ && (newAction == JsonDbNotification::Delete)) {
changeMap.remove(objectKey);
} else {
- if ((oldAction == ObjectChange::Deleted)
- && (newAction == ObjectChange::Created))
- oldChange.action = ObjectChange::Updated;
+ if ((oldAction == JsonDbNotification::Delete)
+ && (newAction == JsonDbNotification::Create))
+ oldChange.action = JsonDbNotification::Update;
changeMap.insert(objectKey, oldChange);
}
} else {
@@ -673,55 +665,43 @@ void JsonDbObjectTable::changesSince(quint32 stateNumber, QMap<ObjectKey,ObjectC
if (jsondbSettings->performanceLog())
qDebug() << "changesSince" << mFilename << timer.elapsed() << "ms";
+ return mStateNumber;
}
-QJsonObject JsonDbObjectTable::changesSince(quint32 stateNumber, const QSet<QString> &limitTypes)
+quint32 JsonDbObjectTable::changesSince(quint32 stateNumber, const QSet<QString> &limitTypes, QList<JsonDbUpdate> *updateList, JsonDbObjectTable::TypeChangeMode splitTypeChanges)
{
if (jsondbSettings->verbose())
- qDebug() << "changesSince" << stateNumber << "current state" << this->stateNumber();
-
- QJsonArray result;
- int count = 0;
-
- QMap<ObjectKey,ObjectChange> changes;
- changesSince(stateNumber, &changes);
-
- for (QMap<ObjectKey,ObjectChange>::const_iterator it = changes.begin();
- it != changes.end();
- ++it) {
- const ObjectChange &change = it.value();
- QJsonObject before;
- QJsonObject after;
- switch (change.action) {
- case ObjectChange::Created:
- get(change.objectKey, &after);
- break;
- case ObjectChange::Updated:
- before = change.oldObject;
- get(change.objectKey, &after);
- break;
- case ObjectChange::Deleted:
- before = change.oldObject;
- break;
- }
- if (!limitTypes.isEmpty()) {
- QString type = (after.isEmpty() ? before : after).value(JsonDbString::kTypeStr).toString();
- if (!limitTypes.contains(type))
- continue;
+ qDebug() << "changesSince" << stateNumber << limitTypes << "{";
+ QMap<ObjectKey,JsonDbUpdate> changeSet;
+ changesSince(stateNumber, &changeSet);
+ QList<JsonDbUpdate> changeList;
+ bool allTypes = limitTypes.isEmpty();
+ foreach (const JsonDbUpdate &update, changeSet) {
+ const JsonDbObject &oldObject = update.oldObject;
+ const JsonDbObject &newObject = update.newObject;
+ QString oldType = oldObject.value(JsonDbString::kTypeStr).toString();
+ QString newType = newObject.value(JsonDbString::kTypeStr).toString();
+ // if the types don't match, split into two updates
+ if (!oldObject.isEmpty() && oldType != newType && splitTypeChanges == JsonDbObjectTable::SplitTypeChanges) {
+ if (allTypes || limitTypes.contains(oldType)) {
+ JsonDbObject tombstone(oldObject);
+ tombstone.insert(QLatin1String("_deleted"), true);
+ changeList.append(JsonDbUpdate(oldObject, tombstone, JsonDbNotification::Delete));
+ }
+ if (allTypes || limitTypes.contains(newType)) {
+ changeList.append(JsonDbUpdate(JsonDbObject(), newObject, JsonDbNotification::Create));
+ }
+ } else if (allTypes || limitTypes.contains(oldType) || limitTypes.contains(newType)) {
+ changeList.append(update);
}
- QJsonObject res;
- res.insert("before", before);
- res.insert("after", after);
- result.append(res);
- ++count;
}
- QJsonObject resultmap, errormap;
- resultmap.insert("count", count);
- resultmap.insert("startingStateNumber", (qint32)stateNumber);
- resultmap.insert("currentStateNumber", (qint32)this->stateNumber());
- resultmap.insert("changes", result);
- QJsonObject changesSince(JsonDbPartition::makeResponse(resultmap, errormap));
- return changesSince;
+ if (updateList)
+ *updateList = changeList;
+ if (jsondbSettings->verbose())
+ qDebug() << "changesSince" << changeList.size() << "changes" << "}";
+ return mStateNumber;
}
-QT_END_NAMESPACE_JSONDB
+#include "moc_jsondbobjecttable.cpp"
+
+QT_END_NAMESPACE_JSONDB_PARTITION
diff --git a/src/daemon/jsondbobjecttable.h b/src/partition/jsondbobjecttable.h
index 61d0fc09..a98b6b47 100644
--- a/src/daemon/jsondbobjecttable.h
+++ b/src/partition/jsondbobjecttable.h
@@ -61,47 +61,29 @@
QT_BEGIN_HEADER
-QT_BEGIN_NAMESPACE_JSONDB
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
class JsonDbBtree;
-struct ObjectChange
+inline QDebug &operator<<(QDebug &qdb, const JsonDbUpdate &oc)
{
- ObjectKey objectKey;
- enum Action {
- Created,
- Updated,
- Deleted,
- LastAction = Deleted
- } action;
- QJsonObject oldObject;
-
- // needed for QMap<ObjectKey,ObjectChange>
- inline ObjectChange() {}
- inline ObjectChange(const ObjectKey &obj, Action act, const QJsonObject &old = QJsonObject())
- : objectKey(obj), action(act), oldObject(old)
- {
- }
-};
-
-inline QDebug &operator<<(QDebug &qdb, const ObjectChange &oc)
-{
- qdb.nospace() << "ObjectChange(";
- qdb.nospace() << oc.objectKey;
- qdb.nospace() << ", action = ";
+ qdb.nospace() << "JsonDbUpdate(";
+ //qdb.nospace() << oc.objectKey;
+ qdb.nospace() << "action = ";
switch (oc.action) {
- case ObjectChange::Created: qdb.nospace() << "Created"; break;
- case ObjectChange::Updated: qdb.nospace() << "Updated"; break;
- case ObjectChange::Deleted: qdb.nospace() << "Deleted"; break;
+ case JsonDbNotification::None: qdb.nospace() << "None"; break;
+ case JsonDbNotification::Create: qdb.nospace() << "Created"; break;
+ case JsonDbNotification::Update: qdb.nospace() << "Updated"; break;
+ case JsonDbNotification::Delete: qdb.nospace() << "Deleted"; break;
}
- if (oc.action != ObjectChange::Created)
+ if (oc.action != JsonDbNotification::Create)
qdb.nospace() << ", oldObject = " << oc.oldObject;
qdb.nospace() << ")";
return qdb;
}
-class JsonDbObjectTable : public QObject
+class Q_JSONDB_PARTITION_EXPORT JsonDbObjectTable : public QObject
{
Q_OBJECT
public:
@@ -115,7 +97,7 @@ public:
~JsonDbObjectTable();
QString filename() const { return mFilename; }
- bool open(const QString &filename, JsonDbBtree::OpenFlags flags);
+ bool open(const QString &filename);
void close();
JsonDbPartition *partition() const { return mPartition; }
JsonDbBtree *bdb() const { return mBdb; }
@@ -130,9 +112,11 @@ public:
void flushCaches();
quint32 stateNumber() const { return mStateNumber; }
- quint32 storeStateChange(const ObjectKey &key1, ObjectChange::Action action, const JsonDbObject &old = JsonDbObject());
- quint32 storeStateChange(const QList<ObjectChange> &stateChange);
- QJsonObject changesSince(quint32 stateNumber, const QSet<QString> &limitTypes = QSet<QString>());
+ quint32 storeStateChange(const ObjectKey &key, const JsonDbUpdate &stateChange);
+ enum TypeChangeMode {
+ SplitTypeChanges, KeepTypeChanges
+ };
+ quint32 changesSince(quint32 stateNumber, const QSet<QString> &limitTypes, QList<JsonDbUpdate> *updateList, TypeChangeMode mode=KeepTypeChanges);
IndexSpec *indexSpec(const QString &indexName);
QHash<QString, IndexSpec> indexSpecs() const;
@@ -166,7 +150,7 @@ public:
GetObjectsResult getObjects(const QString &keyName, const QJsonValue &keyValue, const QString &objectType);
private:
- void changesSince(quint32 stateNumber, QMap<ObjectKey,ObjectChange> *changes);
+ quint32 changesSince(quint32 stateNumber, QMap<ObjectKey,JsonDbUpdate> *changes);
private:
JsonDbPartition *mPartition;
@@ -187,7 +171,7 @@ bool isStateKey(const QByteArray &baStateKey);
Q_DECLARE_OPERATORS_FOR_FLAGS(JsonDbObjectTable::SyncFlags)
-QT_END_NAMESPACE_JSONDB
+QT_END_NAMESPACE_JSONDB_PARTITION
QT_END_HEADER
diff --git a/src/daemon/jsondbobjecttypes_impl_p.h b/src/partition/jsondbobjecttypes_impl_p.h
index ac0bb40a..f2833c9b 100644
--- a/src/daemon/jsondbobjecttypes_impl_p.h
+++ b/src/partition/jsondbobjecttypes_impl_p.h
@@ -42,11 +42,11 @@
#ifndef JSONDB_OBJECTTYPES_IMPL_P_H
#define JSONDB_OBJECTTYPES_IMPL_P_H
-#include "jsondb-global.h"
+#include "jsondbpartitionglobal.h"
#include "jsondbobjecttypes_p.h"
#include "jsondbschemamanager_p.h"
-QT_BEGIN_NAMESPACE_JSONDB
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
inline QJsonObjectTypes::ValueList::ValueList(const QJsonArray &list) : QJsonArray(list)
{}
@@ -347,6 +347,6 @@ inline SchemaValidation::Schema<QJsonObjectTypes> QJsonObjectTypes::Service::loa
return m_schemas->schema(schemaName, this);
}
-QT_END_NAMESPACE_JSONDB
+QT_END_NAMESPACE_JSONDB_PARTITION
#endif // JSONDB_OBJECTTYPES_IMPL_P_H
diff --git a/src/daemon/jsondbobjecttypes_p.h b/src/partition/jsondbobjecttypes_p.h
index d161286f..f2b42f58 100644
--- a/src/daemon/jsondbobjecttypes_p.h
+++ b/src/partition/jsondbobjecttypes_p.h
@@ -42,8 +42,8 @@
#ifndef JSONDB_OBJECTTYPES_P_H
#define JSONDB_OBJECTTYPES_P_H
-#include "jsondb-global.h"
-#include "jsondb-strings.h"
+#include "jsondbpartitionglobal.h"
+#include "jsondbstrings.h"
#include "schema-validation/object.h"
@@ -53,7 +53,7 @@
#include <qjsonobject.h>
#include <qjsonvalue.h>
-QT_BEGIN_NAMESPACE_JSONDB
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
class JsonDbSchemaManager;
@@ -175,6 +175,6 @@ public:
};
};
-QT_END_NAMESPACE_JSONDB
+QT_END_NAMESPACE_JSONDB_PARTITION
#endif // JSONDB_OBJECTTYPES_P_H
diff --git a/src/daemon/jsondbowner.cpp b/src/partition/jsondbowner.cpp
index fa50f31f..0d07fe3a 100644
--- a/src/daemon/jsondbowner.cpp
+++ b/src/partition/jsondbowner.cpp
@@ -42,7 +42,7 @@
#include "jsondbowner.h"
#include "jsondbpartition.h"
#include "jsondbsettings.h"
-#include "jsondb-strings.h"
+#include "jsondbstrings.h"
#include <qdebug.h>
#ifdef Q_OS_UNIX
@@ -51,22 +51,34 @@
#include <errno.h>
#endif
-QT_BEGIN_NAMESPACE_JSONDB
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
JsonDbOwner::JsonDbOwner( QObject *parent )
: QObject(parent), mStorageQuota(-1), mAllowAll(false)
{
}
+void cleanQueryList(QList<JsonDbQuery *> &queryList)
+{
+ foreach (JsonDbQuery *q, queryList)
+ delete q;
+ queryList.clear();
+}
+
JsonDbOwner::~JsonDbOwner()
{
+ QMap<QString, QList<JsonDbQuery *> > list;
+ foreach (list, mAllowedObjectQueries) {
+ foreach (QList<JsonDbQuery *> queryList, list)
+ cleanQueryList(queryList);
+ }
}
void JsonDbOwner::setAllowedObjects(const QString &partition, const QString &op,
const QList<QString> &queries)
{
mAllowedObjects[partition][op] = queries;
- mAllowedObjectQueries[partition][op].clear();
+ cleanQueryList(mAllowedObjectQueries[partition][op]);
QJsonObject bindings;
bindings.insert(QLatin1String("domain"), domain());
bindings.insert(QLatin1String("owner"), ownerId());
@@ -275,4 +287,6 @@ bool JsonDbOwner::setOwnerCapabilities(uid_t uid, JsonDbPartition *partition)
#endif
}
-QT_END_NAMESPACE_JSONDB
+#include "moc_jsondbowner.cpp"
+
+QT_END_NAMESPACE_JSONDB_PARTITION
diff --git a/src/daemon/jsondbowner.h b/src/partition/jsondbowner.h
index d4ecf28f..c3416103 100644
--- a/src/daemon/jsondbowner.h
+++ b/src/partition/jsondbowner.h
@@ -47,19 +47,18 @@
#include <QString>
#include <QSet>
-#include "jsondb-global.h"
+#include "jsondbpartitionglobal.h"
#include "jsondbquery.h"
#include "jsondbobject.h"
-
QT_BEGIN_HEADER
-class TestJsonDb;
+class TestPartition;
struct passwd;
-QT_BEGIN_NAMESPACE_JSONDB
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
-class JsonDbOwner : public QObject
+class Q_JSONDB_PARTITION_EXPORT JsonDbOwner : public QObject
{
Q_OBJECT
public:
@@ -75,6 +74,7 @@ public:
void setAllowedObjects(const QString &partition, const QString &op,
const QList<QString> &queries);
void setCapabilities(QJsonObject &capabilities, JsonDbPartition *partition);
+ bool allowAll() const { return mAllowAll; }
void setAllowAll(bool allowAll) { mAllowAll = allowAll; }
bool isAllowed(JsonDbObject &object, const QString &partition, const QString &op) const;
@@ -90,11 +90,11 @@ private:
QMap<QString, QMap<QString, QList<JsonDbQuery *> > > mAllowedObjectQueries;
int mStorageQuota;
bool mAllowAll;
- friend class ::TestJsonDb;
+ friend class ::TestPartition;
bool _setOwnerCapabilities(struct passwd *pwd, JsonDbPartition *partition);
};
-QT_END_NAMESPACE_JSONDB
+QT_END_NAMESPACE_JSONDB_PARTITION
QT_END_HEADER
diff --git a/src/daemon/jsondbpartition.cpp b/src/partition/jsondbpartition.cpp
index 75dab7b1..80500d42 100644
--- a/src/daemon/jsondbpartition.cpp
+++ b/src/partition/jsondbpartition.cpp
@@ -59,9 +59,8 @@
#include <unistd.h>
#include <stdlib.h>
-#include "json.h"
-#include "jsondb-strings.h"
-#include "jsondb-error.h"
+#include "jsondbstrings.h"
+#include "jsondberrors.h"
#include "jsondbpartition.h"
#include "jsondbindex.h"
#include "jsondbindexquery.h"
@@ -72,7 +71,7 @@
#include "jsondbschemamanager_impl_p.h"
#include "jsondbobjecttypes_impl_p.h"
-QT_BEGIN_NAMESPACE_JSONDB
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
const QString gDatabaseSchemaVersion = "0.2";
@@ -127,7 +126,7 @@ bool JsonDbPartition::open()
qDebug() << "JsonDbBtree::open" << mPartitionName << mFilename;
mObjectTable = new JsonDbObjectTable(this);
- mObjectTable->open(mFilename, JsonDbBtree::Default);
+ mObjectTable->open(mFilename);
if (!checkStateConsistency()) {
qCritical() << "JsonDbBtreePartition::open()" << "Unable to recover database";
@@ -459,7 +458,6 @@ JsonDbView *JsonDbPartition::addView(const QString &viewType)
return view;
view = new JsonDbView(this, viewType, this);
- connect(view, SIGNAL(updated(QString)), this, SIGNAL(viewUpdated(QString)));
view->open();
mViews.insert(viewType, view);
return view;
@@ -664,10 +662,26 @@ QJsonObject JsonDbPartition::changesSince(quint32 stateNumber, const QSet<QStrin
else if (ot == objectTable)
continue;
else
- return makeError(JsonDbError::InvalidRequest, "limit types must be from the same object table");
+ return JsonDbPartition::makeError(JsonDbError::InvalidRequest, "limit types must be from the same object table");
}
Q_ASSERT(objectTable);
- return objectTable->changesSince(stateNumber, limitTypes);
+ JsonDbUpdateList changeList;
+ quint32 currentStateNumber = objectTable->changesSince(stateNumber, limitTypes, &changeList);
+ QJsonArray changeArray;
+ foreach (const JsonDbUpdate &update, changeList) {
+ QJsonObject change;
+ change.insert("before", update.oldObject);
+ change.insert("after", update.newObject);
+ changeArray.append(change);
+ }
+
+ QJsonObject resultmap, errormap;
+ resultmap.insert("count", changeArray.size());
+ resultmap.insert("startingStateNumber", static_cast<qint32>(stateNumber));
+ resultmap.insert("currentStateNumber", static_cast<qint32>(currentStateNumber));
+ resultmap.insert("changes", changeArray);
+ QJsonObject changesSince(JsonDbPartition::makeResponse(resultmap, errormap));
+ return changesSince;
}
void JsonDbPartition::flushCaches()
@@ -1071,6 +1085,8 @@ JsonDbIndexQuery *JsonDbPartition::compileIndexQuery(const JsonDbOwner *owner, c
else
delete residualQuery;
indexQuery->setAggregateOperation(query->mAggregateOperation);
+ indexQuery->setResultExpressionList(query->mapExpressionList);
+ indexQuery->setResultKeyList(query->mapKeyList);
return indexQuery;
}
@@ -1091,7 +1107,8 @@ void JsonDbPartition::doIndexQuery(const JsonDbOwner *owner, JsonDbObjectList &r
if (!countOnly) {
if (jsondbSettings->debugQuery())
qDebug() << "appending result" << object << endl;
- results.append(object);
+ JsonDbObject result = indexQuery->resultObject(object);
+ results.append(result);
}
limit--;
count++;
@@ -1157,81 +1174,10 @@ JsonDbQueryResult JsonDbPartition::queryObjects(const JsonDbOwner *owner, const
delete indexQuery;
- QJsonValue::Type resultType = query->resultType;
QStringList mapExpressions = query->mapExpressionList;
QStringList mapKeys = query->mapKeyList;
- if (mapExpressions.length() && query->mAggregateOperation.compare("count")) {
- QMap<QString, JsonDbObject> objectCache;
- int nExpressions = mapExpressions.length();
- QVector<QVector<QStringList> > joinPaths(nExpressions);
- for (int i = 0; i < nExpressions; i++) {
- QString propertyName = mapExpressions[i];
- QStringList joinPath = propertyName.split("->");
- int joinPathSize = joinPath.size();
- QVector<QStringList> fieldPaths(joinPathSize);
- for (int j = 0; j < joinPathSize; j++) {
- QString joinField = joinPath[j];
- fieldPaths[j] = joinField.split('.');
- }
- joinPaths[i] = fieldPaths;
- }
-
- QList<JsonDbObject> mappedResult;
- QJsonArray valueArray;
- for (int r = 0; r < results.size(); r++) {
- const JsonDbObject obj = results.at(r);
- QJsonArray list;
- QJsonObject map;
- for (int i = 0; i < nExpressions; i++) {
- QJsonValue v;
-
- QVector<QStringList> &joinPath = joinPaths[i];
- int joinPathSize = joinPath.size();
- if (joinPathSize == 1) {
- v = obj.propertyLookup(joinPath[0]);
- QJsonObject vObj;
- vObj.insert("v", v);
- } else {
- JsonDbObject baseObject(obj);
- for (int j = 0; j < joinPathSize-1; j++) {
- QJsonValue uuidQJsonValue = baseObject.propertyLookup(joinPath[j]).toString();
- QString uuid = uuidQJsonValue.toString();
- if (uuid.isEmpty()) {
- baseObject = JsonDbObject();
- } else if (objectCache.contains(uuid)) {
- baseObject = objectCache.value(uuid);
- } else {
- ObjectKey objectKey(uuid);
- bool gotBaseObject = getObject(objectKey, baseObject);
- if (gotBaseObject)
- objectCache.insert(uuid, baseObject);
- }
- }
- v = baseObject.propertyLookup(joinPath[joinPathSize-1]);
- }
-
- if (resultType == QJsonValue::Object)
- map.insert(mapKeys[i], v);
- else if (resultType == QJsonValue::Array)
- list.append(v);
- else
- valueArray.append(v);
- }
-
- if (resultType == QJsonValue::Object) {
- mappedResult.append(map);
- } else if (resultType == QJsonValue::Array) {
- valueArray.append(list);
- }
- }
-
- result.data = mappedResult;
- result.values = valueArray;
- } else {
- result.data = results;
- }
-
+ result.data = results;
result.length = length;
result.offset = offset;
result.state = (qint32)stateNumber;
@@ -1242,7 +1188,8 @@ JsonDbQueryResult JsonDbPartition::queryObjects(const JsonDbOwner *owner, const
return result;
}
-JsonDbWriteResult JsonDbPartition::updateObjects(const JsonDbOwner *owner, const JsonDbObjectList &objects, JsonDbPartition::WriteMode mode)
+JsonDbWriteResult JsonDbPartition::updateObjects(const JsonDbOwner *owner, const JsonDbObjectList &objects, JsonDbPartition::WriteMode mode,
+ JsonDbUpdateList *changeList)
{
JsonDbWriteResult result;
WithTransaction transaction(this);
@@ -1400,19 +1347,16 @@ JsonDbWriteResult JsonDbPartition::updateObjects(const JsonDbOwner *owner, const
if (jsondbSettings->debug())
qDebug() << "Wrote object" << objectKey << endl << master << endl << oldMaster;
- JsonDbNotification::Action action;
- quint32 stateNumber;
-
- if (forRemoval) {
+ JsonDbNotification::Action action = JsonDbNotification::Update;
+ if (forRemoval)
action = JsonDbNotification::Delete;
- stateNumber = objectTable->storeStateChange(objectKey, ObjectChange::Deleted, oldMaster);
- } else if (forCreation) {
+ else if (forCreation)
action = JsonDbNotification::Create;
- stateNumber = objectTable->storeStateChange(objectKey, ObjectChange::Created);
- } else {
- action = JsonDbNotification::Update;
- stateNumber = objectTable->storeStateChange(objectKey, ObjectChange::Updated, oldMaster);
- }
+
+ JsonDbUpdate change(oldMaster, master, action);
+ quint32 stateNumber = objectTable->storeStateChange(objectKey, change);
+ if (changeList)
+ changeList->append(change);
if (!forRemoval)
objectTable->indexObject(objectKey, master, objectTable->stateNumber());
@@ -1424,7 +1368,7 @@ JsonDbWriteResult JsonDbPartition::updateObjects(const JsonDbOwner *owner, const
master.insert(JsonDbString::kVersionStr, versionWritten);
result.objectsWritten.append(master);
- updated.append(JsonDbUpdate(oldMaster, master, action));
+ updated.append(change);
}
transaction.commit();
@@ -1433,9 +1377,9 @@ JsonDbWriteResult JsonDbPartition::updateObjects(const JsonDbOwner *owner, const
return result;
}
-JsonDbWriteResult JsonDbPartition::updateObject(const JsonDbOwner *owner, const JsonDbObject &object, JsonDbPartition::WriteMode mode)
+JsonDbWriteResult JsonDbPartition::updateObject(const JsonDbOwner *owner, const JsonDbObject &object, JsonDbPartition::WriteMode mode, JsonDbUpdateList *changeList)
{
- return updateObjects(owner, JsonDbObjectList() << object, mode);
+ return updateObjects(owner, JsonDbObjectList() << object, mode, changeList);
}
void JsonDbPartition::checkIndex(const QString &propertyName)
@@ -1579,8 +1523,8 @@ bool JsonDbPartition::checkNaturalObjectType(const JsonDbObject &object, QString
{
QString type = object.value(JsonDbString::kTypeStr).toString();
if (mViewTypes.contains(type)) {
- QString str = JsonWriter().toString(object.toVariantMap());
- errorMsg = QString("Cannot create/remove object of view type '%1': '%2'").arg(type).arg(str);
+ QByteArray str = QJsonDocument(object).toJson();
+ errorMsg = QString("Cannot create/remove object of view type '%1': '%2'").arg(type).arg(QString::fromUtf8(str));
return false;
}
@@ -1589,6 +1533,9 @@ bool JsonDbPartition::checkNaturalObjectType(const JsonDbObject &object, QString
JsonDbError::ErrorCode JsonDbPartition::checkBuiltInTypeAccessControl(bool forCreation, const JsonDbOwner *owner, const JsonDbObject &object, const JsonDbObject &oldObject, QString &errorMsg)
{
+ if (!jsondbSettings->enforceAccessControl())
+ return JsonDbError::NoError;
+
QString objectType = object.value(JsonDbString::kTypeStr).toString();
errorMsg.clear();
@@ -1639,7 +1586,7 @@ JsonDbError::ErrorCode JsonDbPartition::checkBuiltInTypeAccessControl(bool forCr
}
} else if (objectType == JsonDbString::kSchemaTypeStr) {
// Check that owner can write name
- QJsonValue name = object.value(QLatin1String("name"));
+ QJsonValue name = object.value(JsonDbString::kNameStr);
JsonDbObject fake; // Just for access control
fake.insert (JsonDbString::kOwnerStr, object.value(JsonDbString::kOwnerStr));
fake.insert (JsonDbString::kTypeStr, name);
@@ -1647,6 +1594,50 @@ JsonDbError::ErrorCode JsonDbPartition::checkBuiltInTypeAccessControl(bool forCr
errorMsg = QString::fromLatin1("Access denied %1").arg(name.toString());
return JsonDbError::OperationNotPermitted;
}
+ } else if (objectType == JsonDbString::kIndexTypeStr) {
+
+ // Only the owner or admin can update Index
+ if (!forCreation) {
+ QJsonValue oldOwner = oldObject.value(JsonDbString::kOwnerStr);
+ if (owner->ownerId() != oldOwner.toString() && !owner->allowAll()) {
+ // Only admin (allowAll = true) can update Index:s owned by somebody else
+ errorMsg = QString::fromLatin1("Only admin can update Index:s not owned by itself");
+ return JsonDbError::OperationNotPermitted;
+ }
+ }
+
+ // Check that owner can read all objectTypes
+ QJsonValue objectTypeProperty = object.value(QLatin1String("objectType"));
+ JsonDbObject fake; // Just for access control
+ if (objectTypeProperty.isUndefined() || objectTypeProperty.isNull()) {
+ if (!owner->allowAll()) {
+ // Only admin (allowAll = true) can do Index:s without objectType
+ errorMsg = QString::fromLatin1("Only admin can do Index:s without objectType");
+ return JsonDbError::OperationNotPermitted;
+ }
+ } else if (objectTypeProperty.isArray()) {
+ QJsonArray arr = objectTypeProperty.toArray();
+ foreach (QJsonValue val, arr) {
+ fake.insert (JsonDbString::kOwnerStr, object.value(JsonDbString::kOwnerStr));
+ fake.insert (JsonDbString::kTypeStr, val.toString());
+ if (!owner->isAllowed(fake, mPartitionName, "read")) {
+ errorMsg = QString::fromLatin1("Access denied %1 in Index %2").arg(val.toString()).
+ arg(JsonDbIndex::determineName(object));
+ return JsonDbError::OperationNotPermitted;
+ }
+ }
+ } else if (objectTypeProperty.isString()) {
+ fake.insert (JsonDbString::kOwnerStr, object.value(JsonDbString::kOwnerStr));
+ fake.insert (JsonDbString::kTypeStr, objectTypeProperty.toString());
+ if (!owner->isAllowed(fake, mPartitionName, "read")) {
+ errorMsg = QString::fromLatin1("Access denied %1 in Index %2").arg(objectTypeProperty.toString()).
+ arg(JsonDbIndex::determineName(object));
+ return JsonDbError::OperationNotPermitted;
+ }
+ } else {
+ errorMsg = QString::fromLatin1("Invalid objectType in Index %1").arg(JsonDbIndex::determineName(object));
+ return JsonDbError::InvalidIndexOperation;
+ }
}
return JsonDbError::NoError;
}
@@ -1706,22 +1697,22 @@ void JsonDbPartition::updateBuiltInTypes(const JsonDbObject &object, const JsonD
caseSensitivity == true ? Qt::CaseSensitive : Qt::CaseInsensitive);
}
- if (oldObject.type() == JsonDbString::kSchemaTypeStr) {
+ if (oldObject.type() == JsonDbString::kSchemaTypeStr)
removeSchema(oldObject.value(JsonDbString::kNameStr).toString());
- } else if (object.type() == JsonDbString::kSchemaTypeStr &&
- object.value(JsonDbString::kSchemaStr).type() == QJsonValue::Object
- && !object.isDeleted()) {
+
+ if (object.type() == JsonDbString::kSchemaTypeStr &&
+ object.value(JsonDbString::kSchemaStr).type() == QJsonValue::Object
+ && !object.isDeleted())
setSchema(object.value(JsonDbString::kNameStr).toString(), object.value(JsonDbString::kSchemaStr).toObject());
- } else if (oldObject.type() == JsonDbString::kMapTypeStr || oldObject.type() == JsonDbString::kReduceTypeStr ||
- object.type() == JsonDbString::kMapTypeStr || object.type() == JsonDbString::kReduceTypeStr) {
- if (!oldObject.isEmpty())
- JsonDbView::removeDefinition(this, oldObject);
+ if (!oldObject.isEmpty()
+ && (oldObject.type() == JsonDbString::kMapTypeStr || oldObject.type() == JsonDbString::kReduceTypeStr))
+ JsonDbView::removeDefinition(this, oldObject);
- if (!(object.isDeleted() ||
- (object.contains(JsonDbString::kActiveStr) && !object.value(JsonDbString::kActiveStr).toBool())))
- JsonDbView::createDefinition(this, object);
- }
+ if (!object.isDeleted()
+ && (object.type() == JsonDbString::kMapTypeStr || object.type() == JsonDbString::kReduceTypeStr)
+ && !(object.contains(JsonDbString::kActiveStr) && !object.value(JsonDbString::kActiveStr).toBool()))
+ JsonDbView::createDefinition(this, object);
}
void JsonDbPartition::setSchema(const QString &schemaName, const QJsonObject &schema)
@@ -1876,13 +1867,13 @@ void JsonDbPartition::initSchemas()
if (!mSchemas.contains(schemaName)) {
QFile schemaFile(QString(":schema/%1.json").arg(schemaName));
schemaFile.open(QIODevice::ReadOnly);
- JsonReader parser;
- bool ok = parser.parse(schemaFile.readAll());
- if (!ok) {
- qWarning() << "Parsing " << schemaName << " schema" << parser.errorString();
+ QJsonParseError error;
+ QJsonDocument doc = QJsonDocument::fromJson(schemaFile.readAll(), &error);
+ if (doc.isNull()) {
+ qWarning() << "Parsing " << schemaName << " schema" << error.error;
return;
}
- QJsonObject schema = QJsonObject::fromVariantMap(parser.result().toMap());
+ QJsonObject schema = doc.object();
JsonDbObject schemaObject;
schemaObject.insert(JsonDbString::kTypeStr, JsonDbString::kSchemaTypeStr);
schemaObject.insert("name", schemaName);
@@ -1902,13 +1893,13 @@ void JsonDbPartition::initSchemas()
const QString capabilityName("RootCapability");
QFile capabilityFile(QString(":schema/%1.json").arg(capabilityName));
capabilityFile.open(QIODevice::ReadOnly);
- JsonReader parser;
- bool ok = parser.parse(capabilityFile.readAll());
- if (!ok) {
- qWarning() << "Parsing " << capabilityName << " capability" << parser.errorString();
+ QJsonParseError error;
+ QJsonDocument doc = QJsonDocument::fromJson(capabilityFile.readAll(), &error);
+ if (doc.isNull()) {
+ qWarning() << "Parsing " << capabilityName << " capability" << error.error;
return;
}
- JsonDbObject capability = QJsonObject::fromVariantMap(parser.result().toMap());
+ JsonDbObject capability = doc.object();
QString name = capability.value("name").toString();
GetObjectsResult getObjectResponse = getObjects("capabilityName", name, "Capability");
int count = getObjectResponse.data.size();
@@ -1924,4 +1915,6 @@ void JsonDbPartition::initSchemas()
}
}
-QT_END_NAMESPACE_JSONDB
+#include "moc_jsondbpartition.cpp"
+
+QT_END_NAMESPACE_JSONDB_PARTITION
diff --git a/src/daemon/jsondbpartition.h b/src/partition/jsondbpartition.h
index f56eb400..eae6f16d 100644
--- a/src/daemon/jsondbpartition.h
+++ b/src/partition/jsondbpartition.h
@@ -49,30 +49,31 @@
#include <QVector>
#include <QPointer>
+#include "jsondberrors.h"
#include "jsondbobjectkey.h"
#include "jsondbnotification.h"
#include "jsondbowner.h"
+#include "jsondbpartitionglobal.h"
#include "jsondbstat.h"
-#include "jsondbindex.h"
#include "jsondbschemamanager_p.h"
-#include "jsondbindexquery.h"
-#include "jsondbbtree.h"
QT_BEGIN_HEADER
class TestJsonDb;
-QT_BEGIN_NAMESPACE_JSONDB
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
class JsonDbBtree;
class JsonDbOwner;
class JsonDbObjectTable;
+class JsonDbIndex;
class JsonDbIndexQuery;
class JsonDbView;
struct JsonDbUpdate {
JsonDbUpdate(const JsonDbObject &oldObj, const JsonDbObject &newObj, JsonDbNotification::Action act) :
oldObject(oldObj), newObject(newObj), action(act) { }
+ JsonDbUpdate() : action(JsonDbNotification::None) {}
JsonDbObject oldObject;
JsonDbObject newObject;
JsonDbNotification::Action action;
@@ -88,7 +89,7 @@ struct JsonDbWriteResult {
QString message;
};
-class JsonDbPartition : public QObject
+class Q_JSONDB_PARTITION_EXPORT JsonDbPartition : public QObject
{
Q_OBJECT
public:
@@ -128,8 +129,8 @@ public:
bool addToQuota(const JsonDbOwner *owner, int size);
JsonDbQueryResult queryObjects(const JsonDbOwner *owner, const JsonDbQuery *query, int limit=-1, int offset=0);
- JsonDbWriteResult updateObjects(const JsonDbOwner *owner, const JsonDbObjectList &objects, WriteMode mode = OptimisticWrite);
- JsonDbWriteResult updateObject(const JsonDbOwner *owner, const JsonDbObject &object, WriteMode mode = OptimisticWrite);
+ JsonDbWriteResult updateObjects(const JsonDbOwner *owner, const JsonDbObjectList &objects, WriteMode mode = OptimisticWrite, JsonDbUpdateList *changeList = 0);
+ JsonDbWriteResult updateObject(const JsonDbOwner *owner, const JsonDbObject &object, WriteMode mode = OptimisticWrite, JsonDbUpdateList *changeList = 0);
QJsonObject flush();
@@ -169,7 +170,6 @@ public Q_SLOTS:
void updateView(const QString &objectType, quint32 stateNumber=0);
Q_SIGNALS:
- void viewUpdated(const QString &objectType);
void objectsUpdated(const JsonDbUpdateList &objects);
protected:
@@ -223,6 +223,7 @@ private:
friend class JsonDbObjectTable;
friend class JsonDbMapDefinition;
friend class WithTransaction;
+ friend class ::TestPartition;
friend class ::TestJsonDb;
};
@@ -271,8 +272,8 @@ private:
};
QJsonValue makeFieldValue(const QJsonValue &value, const QString &type);
-QByteArray makeForwardKey(const QJsonValue &fieldValue, const ObjectKey &objectKey);
-int forwardKeyCmp(const QByteArray &ab, const QByteArray &bb);
+Q_JSONDB_PARTITION_EXPORT QByteArray makeForwardKey(const QJsonValue &fieldValue, const ObjectKey &objectKey);
+Q_JSONDB_PARTITION_EXPORT int forwardKeyCmp(const QByteArray &ab, const QByteArray &bb);
void forwardKeySplit(const QByteArray &forwardKey, QJsonValue &fieldValue);
void forwardKeySplit(const QByteArray &forwardKey, QJsonValue &fieldValue, ObjectKey &objectKey);
QByteArray makeForwardValue(const ObjectKey &);
@@ -280,7 +281,7 @@ void forwardValueSplit(const QByteArray &forwardValue, ObjectKey &objectKey);
QDebug &operator<<(QDebug &, const ObjectKey &);
-QT_END_NAMESPACE_JSONDB
+QT_END_NAMESPACE_JSONDB_PARTITION
QT_END_HEADER
diff --git a/src/partition/jsondbpartitionglobal.h b/src/partition/jsondbpartitionglobal.h
new file mode 100644
index 00000000..9b88409b
--- /dev/null
+++ b/src/partition/jsondbpartitionglobal.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef JSONDB_PARTITION_GLOBAL_H
+#define JSONDB_PARTITION_GLOBAL_H
+
+#include "QtCore/qglobal.h"
+
+#if defined(QT_JSONDB_PARTITION_LIB)
+# define Q_JSONDB_PARTITION_EXPORT Q_DECL_EXPORT
+#else
+# define Q_JSONDB_PARTITION_EXPORT Q_DECL_IMPORT
+#endif
+
+#if defined(QT_NAMESPACE)
+# define QT_BEGIN_NAMESPACE_JSONDB_PARTITION namespace QT_NAMESPACE { namespace QtJsonDb { namespace Partition {
+# define QT_END_NAMESPACE_JSONDB_PARTITION } } }
+# define QT_USE_NAMESPACE_JSONDB_PARTITION using namespace QT_NAMESPACE::QtJsonDb::Partition;
+# define QT_PREPEND_NAMESPACE_JSONDB_PARTITION(name) ::QT_NAMESPACE::QtJsonDb::Partition::name
+#else
+# define QT_BEGIN_NAMESPACE_JSONDB_PARTITION namespace QtJsonDb { namespace Partition {
+# define QT_END_NAMESPACE_JSONDB_PARTITION } }
+# define QT_USE_NAMESPACE_JSONDB_PARTITION using namespace QtJsonDb::Partition;
+# define QT_PREPEND_NAMESPACE_JSONDB_PARTITION(name) ::QtJsonDb::Partition::name
+#endif
+
+// a workaround for moc - if there is a header file that doesn't use jsondb
+// namespace, we still force moc to do "using namespace" but the namespace have to
+// be defined, so let's define an empty namespace here
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
+QT_END_NAMESPACE_JSONDB_PARTITION
+
+#endif // JSONDB_PARTITION_GLOBAL_H
diff --git a/src/daemon/jsondbproxy.cpp b/src/partition/jsondbproxy.cpp
index 1d39f0a5..d6040717 100644
--- a/src/daemon/jsondbproxy.cpp
+++ b/src/partition/jsondbproxy.cpp
@@ -40,13 +40,14 @@
****************************************************************************/
#include "jsondbproxy.h"
-#include "jsondb-strings.h"
+#include "jsondbstrings.h"
#include "jsondbobject.h"
+#include "jsondbsettings.h"
#include <QDebug>
#include <QJSEngine>
-QT_BEGIN_NAMESPACE_JSONDB
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
JsonDbMapProxy::JsonDbMapProxy(const JsonDbOwner *owner, JsonDbPartition *partition, QObject *parent)
: QObject(parent)
@@ -118,13 +119,27 @@ Console::Console()
void Console::log(const QString &s)
{
- qDebug() << s;
+ if (jsondbSettings->debug())
+ qDebug() << s;
}
-
void Console::debug(const QString &s)
{
-// if (gDebug)
+ if (jsondbSettings->debug())
qDebug() << s;
}
+void Console::info(const QString &s)
+{
+ qDebug() << s;
+}
+void Console::warn(const QString &s)
+{
+ qWarning() << s;
+}
+void Console::error(const QString &s)
+{
+ qCritical() << s;
+}
+
+#include "moc_jsondbproxy.cpp"
-QT_END_NAMESPACE_JSONDB
+QT_END_NAMESPACE_JSONDB_PARTITION
diff --git a/src/daemon/jsondbproxy.h b/src/partition/jsondbproxy.h
index 9ff6b4ba..886a6ba1 100644
--- a/src/daemon/jsondbproxy.h
+++ b/src/partition/jsondbproxy.h
@@ -46,16 +46,16 @@
#include <QMultiMap>
#include <QJSValue>
-#include "jsondb-global.h"
+#include "jsondbpartitionglobal.h"
QT_BEGIN_HEADER
-QT_BEGIN_NAMESPACE_JSONDB
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
class JsonDbOwner;
class JsonDbPartition;
-class JsonDbMapProxy : public QObject {
+class Q_JSONDB_PARTITION_EXPORT JsonDbMapProxy : public QObject {
Q_OBJECT
public:
JsonDbMapProxy(const JsonDbOwner *owner, JsonDbPartition *partition, QObject *parent=0);
@@ -76,7 +76,7 @@ private:
JsonDbPartition *mPartition;
};
-class JsonDbJoinProxy : public QObject {
+class Q_JSONDB_PARTITION_EXPORT JsonDbJoinProxy : public QObject {
Q_OBJECT
public:
JsonDbJoinProxy( const JsonDbOwner *owner, JsonDbPartition *partition, QObject *parent=0 );
@@ -102,9 +102,12 @@ public:
Console();
Q_SCRIPTABLE void log(const QString &string);
Q_SCRIPTABLE void debug(const QString &string);
+ Q_SCRIPTABLE void info(const QString &string);
+ Q_SCRIPTABLE void warn(const QString &string);
+ Q_SCRIPTABLE void error(const QString &string);
};
-QT_END_NAMESPACE_JSONDB
+QT_END_NAMESPACE_JSONDB_PARTITION
QT_END_HEADER
diff --git a/src/daemon/jsondbquery.cpp b/src/partition/jsondbquery.cpp
index be38e2ce..393ec1f4 100644
--- a/src/daemon/jsondbquery.cpp
+++ b/src/partition/jsondbquery.cpp
@@ -44,45 +44,25 @@
#include <QJsonDocument>
#include <QStack>
#include <QString>
-#include <QStringList>
-#include "jsondb-strings.h"
+#include "jsondbstrings.h"
#include "jsondbindexquery.h"
#include "jsondbpartition.h"
#include "jsondbquery.h"
#include "jsondbsettings.h"
-QT_BEGIN_NAMESPACE_JSONDB
-
-struct TokenClassInitializer { QChar c; JsonDbQueryTokenizer::TokenClass tokenClass;};
-static TokenClassInitializer sTokenClasses[] = {
- { '[', JsonDbQueryTokenizer::Singleton },
- { ']', JsonDbQueryTokenizer::Singleton },
- { '{', JsonDbQueryTokenizer::Singleton },
- { '}', JsonDbQueryTokenizer::Singleton },
- { '/', JsonDbQueryTokenizer::Singleton },
- { '\\', JsonDbQueryTokenizer::Singleton },
- { '?', JsonDbQueryTokenizer::Singleton },
- { ',', JsonDbQueryTokenizer::Singleton },
- { ':', JsonDbQueryTokenizer::Singleton },
- { '=', JsonDbQueryTokenizer::Operator },
- { '>', JsonDbQueryTokenizer::Operator },
- { '<', JsonDbQueryTokenizer::Operator },
- { '!', JsonDbQueryTokenizer::Operator },
- { '-', JsonDbQueryTokenizer::Operator },
- { '~', JsonDbQueryTokenizer::Operator },
- { '|', JsonDbQueryTokenizer::Singleton }
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
+
+const char* JsonDbQueryTokenizer::sTokens[] = {
+"[", "]", "{", "}", "/", "?", ",", ":", "|", "\\"
+//operators are ordered by precedence
+, "!=", "<=", ">=", "=~", "->", "=", ">", "<"
+, ""//end of the token list
};
-JsonDbQueryTokenizer::TokenClass JsonDbQueryTokenizer::sTokenClass[128];
JsonDbQueryTokenizer::JsonDbQueryTokenizer(QString input)
: mInput(input), mPos(0)
{
- if (sTokenClass[sTokenClasses[0].c.unicode()] != sTokenClasses[0].tokenClass) {
- memset(sTokenClass, 0, sizeof(sTokenClass));
- for (unsigned int i = 0; i < sizeof(sTokenClasses)/sizeof(TokenClassInitializer); i++)
- sTokenClass[sTokenClasses[i].c.unicode()] = sTokenClasses[i].tokenClass;
- }
}
QString JsonDbQueryTokenizer::pop()
@@ -117,19 +97,10 @@ QString JsonDbQueryTokenizer::peek()
QString JsonDbQueryTokenizer::getNextToken()
{
QString result;
- bool indexExpression = false;
+
while (mPos < mInput.size()) {
QChar c = mInput[mPos++];
- JsonDbQueryTokenizer::TokenClass tokenClass = getTokenClass(c);
- if (tokenClass == JsonDbQueryTokenizer::Singleton) {
- result.append(c);
- return result;
- } else if (tokenClass == JsonDbQueryTokenizer::Operator) {
- result.append(c);
- if (getTokenClass(mInput[mPos]) == JsonDbQueryTokenizer::Operator)
- result.append(mInput[mPos++]);
- return result;
- } else if (c == '"') {
+ if (c == '"') {
// match string
result.append(c);
bool escaped = false;
@@ -160,25 +131,30 @@ QString JsonDbQueryTokenizer::getNextToken()
return result;
else
continue;
- } else {
- result.append(c);
- if (mPos < mInput.size()) {
- QChar next = mInput[mPos];
- JsonDbQueryTokenizer::TokenClass nextTokenClass = getTokenClass(next);
- //qDebug() << mInput[mPos] << mInput[mPos].unicode() << "nextTokenTokenClass" << nextTokenClass << indexExpression;
- if (nextTokenClass == JsonDbQueryTokenizer::Other)
- continue;
- else if ((next == '[')
- || (indexExpression && (next == ']'))) {
- // handle [*] as a special case
- result.append(mInput[mPos++]);
- indexExpression = (next == '[');
- continue;
- } else
+ } else if (result.size() && mPos+1 < mInput.size()) {
+ //index expression?[n],[*]
+ if (c == '[' && mInput[mPos+1] == ']') {
+ result.append(mInput.mid(mPos-1,3));
+ mPos += 2;
+ continue;
+ }
+ }
+ //operators
+ int i = 0;
+ while (sTokens[i][0] != 0) {
+ if (mInput.midRef(mPos - 1,2).startsWith(sTokens[i])) {
+ if (!result.isEmpty()) {
+ mPos --;
return result;
+ }
+ result.append(sTokens[i]);
+ mPos += strlen(sTokens[i]) - 1;
+ return result;
}
+ i++;
}
- }
+ result.append(mInput[mPos-1]);
+ }//while
return QString();
}
@@ -313,7 +289,14 @@ JsonDbQuery *JsonDbQuery::parse(const QString &query, const QJsonObject &binding
term.setOp(op);
if (op == "=~") {
QString tvs = tokenizer.pop();
- if (!tvs.startsWith("\"")) {
+ int sepPos = 1; // assuming it's a literal "/regexp/modifiers"
+ if (tvs.startsWith(QChar('%'))) {
+ const QString name = tvs.mid(1);
+ if (bindings.contains(name)) {
+ tvs = bindings.value(name).toString();
+ sepPos = 0;
+ }
+ } else if (!tvs.startsWith("\"")) {
parsedQuery->queryExplanation.append(QString("Failed to parse query regular expression '%1' in query '%2' %3 op %4")
.arg(tvs)
.arg(parsedQuery->query)
@@ -322,27 +305,27 @@ JsonDbQuery *JsonDbQuery::parse(const QString &query, const QJsonObject &binding
parseError = true;
break;
}
- QChar sep = tvs[1];
- int eor = 1;
+ QChar sep = tvs[sepPos];
+ int eor = sepPos;
do {
eor = tvs.indexOf(sep, eor+1); // end of regexp;
//qDebug() << "tvs" << tvs << "eor" << eor << "tvs[eor-1]" << ((eor > 0) ? tvs[eor-1] : QChar('*'));
- if (eor <= 1) {
+ if (eor <= sepPos) {
parseError = true;
break;
}
} while ((eor > 0) && (tvs[eor-1] == '\\'));
- QString modifiers = tvs.mid(eor+1,tvs.size()-eor-2);
+ QString modifiers = tvs.mid(eor+1,tvs.size()-eor-2*sepPos);
if (jsondbSettings->debug()) {
qDebug() << "modifiers" << modifiers;
- qDebug() << "regexp" << tvs.mid(2, eor-2);
+ qDebug() << "regexp" << tvs.mid(sepPos + 1, eor-sepPos-1);
}
if (modifiers.contains('w'))
term.regExp().setPatternSyntax(QRegExp::Wildcard);
if (modifiers.contains('i'))
term.regExp().setCaseSensitivity(Qt::CaseInsensitive);
//qDebug() << "pattern" << tvs.mid(2, eor-2);
- term.regExp().setPattern(tvs.mid(2, eor-2));
+ term.regExp().setPattern(tvs.mid(sepPos + 1, eor-sepPos-1));
} else if (op == "contains") {
bool ok = true;;
@@ -429,36 +412,29 @@ JsonDbQuery *JsonDbQuery::parse(const QString &query, const QJsonObject &binding
} while (tokenizer.peek() != "]");
parsedQuery->queryTerms.append(oqt);
} else if (token == "=") {
- bool isMapObject = false;
- bool isListObject = false;
- bool inListObject = false;
+ QString curlyBraceToken = tokenizer.pop();
+ if (curlyBraceToken != "{") {
+ parsedQuery->queryExplanation.append(QString("Parse error: expecting '{' but got '%1'")
+ .arg(curlyBraceToken));
+ parseError = true;
+ break;
+ }
QString nextToken;
while (!(nextToken = tokenizer.popIdentifier()).isEmpty()) {
- if (nextToken == "{")
- isMapObject = true;
- else if (nextToken == "[") {
- isListObject = true;
- inListObject = true;
- } else if (nextToken == "]") {
- if (!inListObject)
- tokenizer.push(nextToken);
- else
- inListObject = false;
- break;
- } else if (nextToken == "}") {
+ if (nextToken == "}") {
break;
} else {
- if (isMapObject) {
- //qDebug() << "isMapObject" << nextToken << tokenizer.peek();
- parsedQuery->mapKeyList.append(nextToken);
- QString colon = tokenizer.pop();
- if (colon != ":") {
- parsedQuery->queryExplanation.append(QString("Parse error: expecting ':' but got '%1'").arg(colon));
- parseError = true;
- break;
- }
- nextToken = tokenizer.popIdentifier();
+
+ //qDebug() << "isMapObject" << nextToken << tokenizer.peek();
+ parsedQuery->mapKeyList.append(nextToken);
+ QString colon = tokenizer.pop();
+ if (colon != ":") {
+ parsedQuery->queryExplanation.append(QString("Parse error: expecting ':' but got '%1'").arg(colon));
+ parseError = true;
+ break;
}
+ nextToken = tokenizer.popIdentifier();
+
while (tokenizer.peek() == "->") {
QString op = tokenizer.pop();
nextToken.append(op);
@@ -466,25 +442,17 @@ JsonDbQuery *JsonDbQuery::parse(const QString &query, const QJsonObject &binding
}
parsedQuery->mapExpressionList.append(nextToken);
QString maybeComma = tokenizer.pop();
- if ((maybeComma == "}") || (maybeComma == "]")) {
+ if (maybeComma == "}") {
tokenizer.push(maybeComma);
continue;
} else if (maybeComma != ",") {
- parsedQuery->queryExplanation.append(QString("Parse error: expecting ',', ']', or '}' but got '%1'")
+ parsedQuery->queryExplanation.append(QString("Parse error: expecting ',', or '}' but got '%1'")
.arg(maybeComma));
parseError = true;
break;
}
}
}
- if (jsondbSettings->debug())
- qDebug() << "isListObject" << isListObject << parsedQuery->mapExpressionList;
- if (isListObject)
- parsedQuery->resultType = QJsonValue::Array;
- else if (isMapObject)
- parsedQuery->resultType = QJsonValue::Object;
- else
- parsedQuery->resultType = QJsonValue::String;
} else if ((token == "/") || (token == "\\") || (token == ">") || (token == "<")) {
QString ordering = token;
OrderTerm term;
@@ -510,9 +478,10 @@ JsonDbQuery *JsonDbQuery::parse(const QString &query, const QJsonObject &binding
if (parseError) {
QStringList explanation = parsedQuery->queryExplanation;
+ delete parsedQuery;
parsedQuery = new JsonDbQuery;
parsedQuery->queryExplanation = explanation;
- qCritical() << "Parser error: query" << query;
+ qCritical() << "Parser error: query" << query << explanation;
return parsedQuery;
}
@@ -716,4 +685,4 @@ JsonDbQueryResult JsonDbQueryResult::makeErrorResponse(JsonDbError::ErrorCode co
return result;
}
-QT_END_NAMESPACE_JSONDB
+QT_END_NAMESPACE_JSONDB_PARTITION
diff --git a/src/daemon/jsondbquery.h b/src/partition/jsondbquery.h
index 30b75017..324f9ee1 100644
--- a/src/daemon/jsondbquery.h
+++ b/src/partition/jsondbquery.h
@@ -47,7 +47,7 @@
#include <QHash>
#include <QStringList>
#include <QVariant>
-#include "jsondb-error.h"
+#include "jsondberrors.h"
#include <qjsonarray.h>
#include <qjsonobject.h>
@@ -57,18 +57,12 @@
QT_BEGIN_HEADER
-QT_BEGIN_NAMESPACE_JSONDB
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
class JsonDbPartition;
-class JsonDbQueryTokenizer {
+class Q_JSONDB_PARTITION_EXPORT JsonDbQueryTokenizer {
public:
- enum TokenClass {
- Other = 0,
- Singleton,
- Operator
- };
-
JsonDbQueryTokenizer(QString input);
QString pop();
QString popIdentifier();
@@ -80,20 +74,15 @@ public:
}
protected:
QString getNextToken();
- TokenClass getTokenClass(QChar c) {
- int u = c.unicode();
- TokenClass tc = (u < 128) ? sTokenClass[u] : Other;
- return tc;
- }
+ static const char* sTokens[];
private:
QString mInput;
int mPos;
QString mNextToken;
- static TokenClass sTokenClass[128];
};
class JsonDbQuery;
-class QueryTerm {
+class Q_JSONDB_PARTITION_EXPORT QueryTerm {
public:
QueryTerm(const JsonDbQuery *query);
~QueryTerm();
@@ -154,7 +143,7 @@ private:
QList<QueryTerm> mTerms;
};
-class OrderTerm {
+class Q_JSONDB_PARTITION_EXPORT OrderTerm {
public:
OrderTerm();
~OrderTerm();
@@ -162,7 +151,7 @@ public:
QString propertyName;
};
-class JsonDbQuery {
+class Q_JSONDB_PARTITION_EXPORT JsonDbQuery {
public:
JsonDbQuery() { }
JsonDbQuery(const QList<OrQueryTerm> &qt, const QList<OrderTerm> &ot);
@@ -170,7 +159,6 @@ public:
QList<OrQueryTerm> queryTerms;
QList<OrderTerm> orderTerms;
QString query;
- QJsonValue::Type resultType;
QStringList mapExpressionList;
QStringList mapKeyList;
QStringList queryExplanation;
@@ -193,10 +181,9 @@ private:
typedef QList<QJsonValue> QJsonValueList;
typedef QList<QJsonObject> QJsonObjectList;
typedef QList<JsonDbObject> JsonDbObjectList;
-class JsonDbQueryResult {
+class Q_JSONDB_PARTITION_EXPORT JsonDbQueryResult {
public:
JsonDbObjectList data;
- QJsonArray values; // for queries returning single values or arrays of values
QJsonValue length;
QJsonValue offset;
QJsonValue explanation;
@@ -207,7 +194,7 @@ public:
static JsonDbQueryResult makeErrorResponse(JsonDbError::ErrorCode, const QString&, bool silent=false);
};
-QT_END_NAMESPACE_JSONDB
+QT_END_NAMESPACE_JSONDB_PARTITION
QT_END_HEADER
diff --git a/src/daemon/jsondbreducedefinition.cpp b/src/partition/jsondbreducedefinition.cpp
index 1021413c..ded9357e 100644
--- a/src/daemon/jsondbreducedefinition.cpp
+++ b/src/partition/jsondbreducedefinition.cpp
@@ -50,17 +50,17 @@
#include <stdlib.h>
#include "jsondbpartition.h"
-#include "jsondb-strings.h"
-#include "jsondb-error.h"
-#include "json.h"
+#include "jsondbstrings.h"
+#include "jsondberrors.h"
#include "jsondbproxy.h"
#include "jsondbsettings.h"
#include "jsondbobjecttable.h"
#include "jsondbreducedefinition.h"
+#include "jsondbscriptengine.h"
#include "jsondbview.h"
-QT_BEGIN_NAMESPACE_JSONDB
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
JsonDbReduceDefinition::JsonDbReduceDefinition(const JsonDbOwner *owner, JsonDbPartition *partition,
QJsonObject definition, QObject *parent) :
@@ -107,6 +107,8 @@ void JsonDbReduceDefinition::definitionCreated()
void JsonDbReduceDefinition::definitionRemoved(JsonDbPartition *partition, JsonDbObjectTable *table, const QString targetType, const QString &definitionUuid)
{
+ if (jsondbSettings->verbose())
+ qDebug() << "Removing Reduce view objects" << targetType;
// remove the output objects
GetObjectsResult getObjectResponse = table->getObjects(QLatin1String("_reduceUuid"), definitionUuid, targetType);
JsonDbObjectList objects = getObjectResponse.data;
@@ -122,7 +124,7 @@ void JsonDbReduceDefinition::initScriptEngine()
if (mScriptEngine)
return;
- mScriptEngine = new QJSEngine(this);
+ mScriptEngine = JsonDbScriptEngine::scriptEngine();
QString message;
bool status = compileFunctions(mScriptEngine, mDefinition, mFunctions, message);
if (!status)
@@ -130,15 +132,11 @@ void JsonDbReduceDefinition::initScriptEngine()
Q_ASSERT(!mDefinition.value("add").toString().isEmpty());
Q_ASSERT(!mDefinition.value("subtract").toString().isEmpty());
-
- QJSValue globalObject = mScriptEngine->globalObject();
- globalObject.setProperty("console", mScriptEngine->newQObject(new Console()));
}
void JsonDbReduceDefinition::releaseScriptEngine()
{
mFunctions.clear();
- delete mScriptEngine;
mScriptEngine = 0;
}
@@ -154,7 +152,7 @@ void JsonDbReduceDefinition::initIndexes()
mTargetTable->addIndexOnProperty(QLatin1String("_reduceUuid"), QLatin1String("string"), mTargetType);
}
-void JsonDbReduceDefinition::updateObject(JsonDbObject before, JsonDbObject after)
+void JsonDbReduceDefinition::updateObject(JsonDbObject before, JsonDbObject after, JsonDbUpdateList *changeList)
{
initScriptEngine();
@@ -164,13 +162,13 @@ void JsonDbReduceDefinition::updateObject(JsonDbObject before, JsonDbObject afte
if (!after.isEmpty() && !before.isEmpty() && (beforeKeyValue != afterKeyValue)) {
// do a subtract only on the before key
if (!beforeKeyValue.isUndefined())
- updateObject(before, QJsonObject());
+ updateObject(before, QJsonObject(), changeList);
// and then continue here with the add with the after key
before = QJsonObject();
}
- const QJsonValue keyValue(after.isEmpty() ? beforeKeyValue : afterKeyValue);
+ const QJsonValue keyValue(after.isDeleted() ? beforeKeyValue : afterKeyValue);
if (keyValue.isUndefined())
return;
@@ -194,17 +192,17 @@ void JsonDbReduceDefinition::updateObject(JsonDbObject before, JsonDbObject afte
QJsonValue value = previousValue;
if (!before.isEmpty())
value = addObject(JsonDbReduceDefinition::Subtract, keyValue, value, before);
- if (!after.isEmpty())
+ if (!after.isDeleted())
value = addObject(JsonDbReduceDefinition::Add, keyValue, value, after);
- JsonDbWriteResult res;
+ JsonDbObjectList objectsToUpdate;
// if we had a previous object to reduce
if (previousObject.contains(JsonDbString::kUuidStr)) {
// and now the value is undefined
if (value.isUndefined()) {
// then remove it
previousObject.markDeleted();
- res = mPartition->updateObject(mOwner, previousObject, JsonDbPartition::ViewObject);
+ objectsToUpdate.append(previousObject);
} else {
//otherwise update it
JsonDbObject reduced(value.toObject());
@@ -215,18 +213,19 @@ void JsonDbReduceDefinition::updateObject(JsonDbObject before, JsonDbObject afte
previousObject.value(JsonDbString::kVersionStr));
reduced.insert(mTargetKeyName, keyValue);
reduced.insert("_reduceUuid", mUuid);
- res = mPartition->updateObject(mOwner, reduced, JsonDbPartition::ViewObject);
+ objectsToUpdate.append(reduced);
}
- } else {
+ } else if (!value.isUndefined()) {
// otherwise create the new object
JsonDbObject reduced(value.toObject());
reduced.insert(JsonDbString::kTypeStr, mTargetType);
reduced.insert(mTargetKeyName, keyValue);
reduced.insert("_reduceUuid", mUuid);
- res = mPartition->updateObject(mOwner, reduced, JsonDbPartition::ViewObject);
+ objectsToUpdate.append(reduced);
}
+ JsonDbWriteResult res = mPartition->updateObjects(mOwner, objectsToUpdate, JsonDbPartition::ViewObject, changeList);
if (res.code != JsonDbError::NoError)
setError(QString("Error executing add function: %1").arg(res.message));
}
@@ -235,18 +234,18 @@ QJsonValue JsonDbReduceDefinition::addObject(JsonDbReduceDefinition::FunctionNum
const QJsonValue &keyValue, QJsonValue previousValue, JsonDbObject object)
{
initScriptEngine();
- QJSValue svKeyValue = JsonDbObject::toJSValue(keyValue, mScriptEngine);
+ QJSValue svKeyValue = JsonDbScriptEngine::toJSValue(keyValue, mScriptEngine);
if (!mTargetValueName.isEmpty())
previousValue = previousValue.toObject().value(mTargetValueName);
- QJSValue svPreviousValue = JsonDbObject::toJSValue(previousValue, mScriptEngine);
- QJSValue svObject = JsonDbObject::toJSValue(object, mScriptEngine);
+ QJSValue svPreviousValue = JsonDbScriptEngine::toJSValue(previousValue, mScriptEngine);
+ QJSValue svObject = JsonDbScriptEngine::toJSValue(object, mScriptEngine);
QJSValueList reduceArgs;
reduceArgs << svKeyValue << svPreviousValue << svObject;
QJSValue reduced = mFunctions[functionNumber].call(reduceArgs);
if (!reduced.isUndefined() && !reduced.isError()) {
- QJsonValue jsonReduced = JsonDbObject::fromJSValue(reduced);
+ QJsonValue jsonReduced = JsonDbScriptEngine::fromJSValue(reduced);
QJsonObject jsonReducedObject;
if (!mTargetValueName.isEmpty())
jsonReducedObject.insert(mTargetValueName, jsonReduced);
@@ -305,8 +304,7 @@ bool JsonDbReduceDefinition::validateDefinition(const JsonDbObject &reduce, Json
&& !(reduce.value("targetValueName").isString() || reduce.value("targetValueName").isNull()))
message = QLatin1Literal("targetValueName for Reduce must be a string or null");
else {
- // FIXME: This is static because otherwise we leak memory per QJSEngine instance
- static QJSEngine *scriptEngine = new QJSEngine;
+ QJSEngine *scriptEngine = JsonDbScriptEngine::scriptEngine();
QVector<QJSValue> functions;
// check for script errors
compileFunctions(scriptEngine, reduce, functions, message);
@@ -342,18 +340,20 @@ bool JsonDbReduceDefinition::compileFunctions(QJSEngine *scriptEngine, QJsonObje
return status;
}
-QJsonValue JsonDbReduceDefinition::sourceKeyValue(const QJsonObject &object)
+QJsonValue JsonDbReduceDefinition::sourceKeyValue(const JsonDbObject &object)
{
- if (object.isEmpty()) {
+ if (object.isEmpty() || object.isDeleted()) {
return QJsonValue(QJsonValue::Undefined);
} else if (mFunctions[JsonDbReduceDefinition::SourceKeyValue].isCallable()) {
QJSValueList args;
- args << JsonDbObject::toJSValue(object, mScriptEngine);
- QJsonValue keyValue = JsonDbObject::fromJSValue(mFunctions[JsonDbReduceDefinition::SourceKeyValue].call(args));
+ args << JsonDbScriptEngine::toJSValue(object, mScriptEngine);
+ QJsonValue keyValue = JsonDbScriptEngine::fromJSValue(mFunctions[JsonDbReduceDefinition::SourceKeyValue].call(args));
return keyValue;
} else
return mSourceKeyName.contains(".") ? JsonDbObject(object).propertyLookup(mSourceKeyNameList) : object.value(mSourceKeyName);
}
-QT_END_NAMESPACE_JSONDB
+#include "moc_jsondbreducedefinition.cpp"
+
+QT_END_NAMESPACE_JSONDB_PARTITION
diff --git a/src/daemon/jsondbreducedefinition.h b/src/partition/jsondbreducedefinition.h
index 214153ec..8b063338 100644
--- a/src/daemon/jsondbreducedefinition.h
+++ b/src/partition/jsondbreducedefinition.h
@@ -45,16 +45,17 @@
#include <QJSEngine>
#include <QStringList>
-#include "jsondb-global.h"
+#include "jsondbpartitionglobal.h"
#include <qjsonarray.h>
#include <qjsonobject.h>
#include <qjsonvalue.h>
#include <jsondbobject.h>
+#include <jsondbpartition.h>
QT_BEGIN_HEADER
-QT_BEGIN_NAMESPACE_JSONDB
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
class JsonDbOwner;
class JsonDbJoinProxy;
@@ -86,7 +87,7 @@ public:
void releaseScriptEngine();
void initIndexes();
- void updateObject(JsonDbObject before, JsonDbObject after);
+ void updateObject(JsonDbObject before, JsonDbObject after, JsonDbUpdateList *changeList = 0);
void setError(const QString &errorMsg);
@@ -99,7 +100,7 @@ private:
SourceKeyValue = 2
};
static bool compileFunctions(QJSEngine *scriptEngine, QJsonObject definition, QVector<QJSValue> &mFunctions, QString &message);
- QJsonValue sourceKeyValue(const QJsonObject &object);
+ QJsonValue sourceKeyValue(const JsonDbObject &object);
QJsonValue addObject(FunctionNumber fn, const QJsonValue &keyValue, QJsonValue previousResult, JsonDbObject object);
private:
@@ -119,7 +120,7 @@ private:
QStringList mSourceKeyNameList;
};
-QT_END_NAMESPACE_JSONDB
+QT_END_NAMESPACE_JSONDB_PARTITION
QT_END_HEADER
diff --git a/src/daemon/jsondbschemamanager_impl_p.h b/src/partition/jsondbschemamanager_impl_p.h
index 8c49d655..21d03746 100644
--- a/src/daemon/jsondbschemamanager_impl_p.h
+++ b/src/partition/jsondbschemamanager_impl_p.h
@@ -45,7 +45,7 @@
#include "jsondbschemamanager_p.h"
#include "schema-validation/object.h"
-QT_BEGIN_NAMESPACE_JSONDB
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
bool JsonDbSchemaManager::contains(const QString &name) const
{
@@ -103,6 +103,6 @@ inline QJsonObject JsonDbSchemaManager::validate(const QString &schemaName, Json
return callbacks.error();
}
-QT_END_NAMESPACE_JSONDB
+QT_END_NAMESPACE_JSONDB_PARTITION
#endif // JSONDB_SCHEMA_MANAGER_IMPL_P_H
diff --git a/src/daemon/jsondbschemamanager_p.h b/src/partition/jsondbschemamanager_p.h
index 0e90a978..18958c27 100644
--- a/src/daemon/jsondbschemamanager_p.h
+++ b/src/partition/jsondbschemamanager_p.h
@@ -42,7 +42,7 @@
#ifndef JSONDB_SCHEMA_MANAGER_P_H
#define JSONDB_SCHEMA_MANAGER_P_H
-#include "jsondb-global.h"
+#include "jsondbpartitionglobal.h"
#include <QtCore/qstring.h>
#include <QtCore/qpair.h>
@@ -52,7 +52,7 @@
#include "jsondbobjecttypes_p.h"
#include "jsondbobject.h"
-QT_BEGIN_NAMESPACE_JSONDB
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
//FIXME This can have better performance
class JsonDbSchemaManager
@@ -73,6 +73,6 @@ private:
QMap<QString, QJsonObjectSchemaPair> m_schemas;
};
-QT_END_NAMESPACE_JSONDB
+QT_END_NAMESPACE_JSONDB_PARTITION
#endif // JSONDB_SCHEMA_MANAGER_P_H
diff --git a/src/partition/jsondbscriptengine.cpp b/src/partition/jsondbscriptengine.cpp
new file mode 100644
index 00000000..e4c80967
--- /dev/null
+++ b/src/partition/jsondbscriptengine.cpp
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "jsondbobject.h"
+
+#include <QJSValue>
+#include <QJSValueIterator>
+#include <QStringBuilder>
+#include <QStringList>
+#include <QCryptographicHash>
+
+#include <qjsondocument.h>
+
+#include "jsondbstrings.h"
+#include "jsondbproxy.h"
+#include "jsondbscriptengine.h"
+
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
+
+QJsonValue JsonDbScriptEngine::fromJSValue(const QJSValue &v)
+{
+ if (v.isNull())
+ return QJsonValue(QJsonValue::Null);
+ if (v.isNumber())
+ return QJsonValue(v.toNumber());
+ if (v.isString())
+ return QJsonValue(v.toString());
+ if (v.isBool())
+ return QJsonValue(v.toBool());
+ if (v.isArray()) {
+ QJsonArray a;
+ int size = v.property("length").toInt();
+ for (int i = 0; i < size; i++) {
+ a.append(fromJSValue(v.property(i)));
+ }
+ return a;
+ }
+ if (v.isObject()) {
+ QJSValueIterator it(v);
+ QJsonObject o;
+ while (it.hasNext()) {
+ it.next();
+ QString name = it.name();
+ QJSValue value = it.value();
+ o.insert(name, fromJSValue(value));
+ }
+ return o;
+ }
+ return QJsonValue(QJsonValue::Undefined);
+}
+
+QJSValue JsonDbScriptEngine::toJSValue(const QJsonValue &v, QJSEngine *scriptEngine)
+{
+ switch (v.type()) {
+ case QJsonValue::Null:
+ return QJSValue(QJSValue::NullValue);
+ case QJsonValue::Undefined:
+ return QJSValue(QJSValue::UndefinedValue);
+ case QJsonValue::Double:
+ return QJSValue(v.toDouble());
+ case QJsonValue::String:
+ return QJSValue(v.toString());
+ case QJsonValue::Bool:
+ return QJSValue(v.toBool());
+ case QJsonValue::Array: {
+ QJSValue jsArray = scriptEngine->newArray();
+ QJsonArray array = v.toArray();
+ for (int i = 0; i < array.size(); i++)
+ jsArray.setProperty(i, toJSValue(array.at(i), scriptEngine));
+ return jsArray;
+ }
+ case QJsonValue::Object:
+ return toJSValue(v.toObject(), scriptEngine);
+ }
+ return QJSValue(QJSValue::UndefinedValue);
+}
+
+QJSValue JsonDbScriptEngine::toJSValue(const QJsonObject &object, QJSEngine *scriptEngine)
+{
+ QJSValue jsObject = scriptEngine->newObject();
+ for (QJsonObject::const_iterator it = object.begin(); it != object.end(); ++it)
+ jsObject.setProperty(it.key(), toJSValue(it.value(), scriptEngine));
+ return jsObject;
+}
+
+static QJSEngine *sScriptEngine;
+
+QJSEngine *JsonDbScriptEngine::scriptEngine()
+{
+ if (!sScriptEngine) {
+ sScriptEngine = new QJSEngine();
+ QJSValue globalObject = sScriptEngine->globalObject();
+ globalObject.setProperty("console", sScriptEngine->newQObject(new Console()));
+ }
+ return sScriptEngine;
+}
+
+QT_END_NAMESPACE_JSONDB_PARTITION
diff --git a/src/common/jsonstream.h b/src/partition/jsondbscriptengine.h
index eab8bda0..663a38fc 100644
--- a/src/common/jsonstream.h
+++ b/src/partition/jsondbscriptengine.h
@@ -39,51 +39,37 @@
**
****************************************************************************/
-#ifndef JSON_STREAM_H
-#define JSON_STREAM_H
+#ifndef JSONDB_SCRIPT_ENGINE_H
+#define JSONDB_SCRIPT_ENGINE_H
+
+#include <QJSEngine>
+#include <QUuid>
-#include <QIODevice>
-#include <qjsondocument.h>
#include <qjsonarray.h>
#include <qjsonobject.h>
#include <qjsonvalue.h>
-#include "jsondb-global.h"
+#include "jsondbpartitionglobal.h"
QT_BEGIN_HEADER
-QT_BEGIN_NAMESPACE_JSONDB
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
-class JsonStream : public QObject
+class JsonDbScriptEngine : public QObject
{
- Q_OBJECT
public:
- explicit JsonStream(QIODevice *device = 0, QObject *parent = 0);
-
- QIODevice *device() const;
- void setDevice(QIODevice *device);
-
- bool send(const QJsonObject &document);
-
-Q_SIGNALS:
- void receive(const QJsonObject &data);
- void aboutToClose();
- void readyWrite();
-
-protected slots:
- void deviceReadyRead();
- void deviceBytesWritten(qint64 bytes);
-
-private:
-
- QIODevice *mDevice;
- QByteArray mWriteBuffer;
- QByteArray mReadBuffer;
-
+ JsonDbScriptEngine();
+ JsonDbScriptEngine(const QJsonObject &object);
+ ~JsonDbScriptEngine();
+
+ static QJsonValue fromJSValue(const QJSValue &v);
+ static QJSValue toJSValue(const QJsonValue &v, QJSEngine *scriptEngine);
+ static QJSValue toJSValue(const QJsonObject &object, QJSEngine *mScriptEngine);
+ static QJSEngine *scriptEngine();
};
-QT_END_NAMESPACE_JSONDB
+QT_END_NAMESPACE_JSONDB_PARTITION
QT_END_HEADER
-#endif // JSON_STREAM_H
+#endif // JSONDB_OBJECT_H
diff --git a/src/daemon/jsondbsettings.cpp b/src/partition/jsondbsettings.cpp
index cf349c59..44343cea 100644
--- a/src/daemon/jsondbsettings.cpp
+++ b/src/partition/jsondbsettings.cpp
@@ -45,7 +45,7 @@
#include <QMetaObject>
#include <QMetaProperty>
-QT_BEGIN_NAMESPACE_JSONDB
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
Q_GLOBAL_STATIC(JsonDbSettings, staticInstance)
@@ -90,7 +90,9 @@ void JsonDbSettings::loadEnvironment()
else if (property.type() == QVariant::Int)
property.write(this, qgetenv(envVariable.toLatin1()).toInt());
else if (property.type() == QVariant::String)
- property.write(this, envVariable);
+ property.write(this, qgetenv(envVariable.toLatin1()));
+ else if (property.type() == QVariant::StringList)
+ property.write(this, QString::fromLatin1(qgetenv(envVariable.toLatin1())).split(':'));
else
qWarning() << "JsonDbSettings: unknown property type" << property.name() << property.type();
}
@@ -102,4 +104,6 @@ JsonDbSettings *JsonDbSettings::instance()
return staticInstance();
}
-QT_END_NAMESPACE_JSONDB
+#include "moc_jsondbsettings.cpp"
+
+QT_END_NAMESPACE_JSONDB_PARTITION
diff --git a/src/daemon/jsondbsettings.h b/src/partition/jsondbsettings.h
index c19af2d5..19ee5422 100644
--- a/src/daemon/jsondbsettings.h
+++ b/src/partition/jsondbsettings.h
@@ -42,17 +42,18 @@
#ifndef JSONDB_SETTINGS_H
#define JSONDB_SETTINGS_H
-#include "jsondb-global.h"
+#include "jsondbpartitionglobal.h"
#include <QObject>
+#include <QStringList>
QT_BEGIN_HEADER
-QT_BEGIN_NAMESPACE_JSONDB
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
#define jsondbSettings JsonDbSettings::instance()
-class JsonDbSettings : public QObject
+class Q_JSONDB_PARTITION_EXPORT JsonDbSettings : public QObject
{
Q_OBJECT
Q_PROPERTY(bool rejectStaleUpdates READ rejectStaleUpdates WRITE setRejectStaleUpdates)
@@ -67,6 +68,7 @@ class JsonDbSettings : public QObject
Q_PROPERTY(int syncInterval READ syncInterval WRITE setSyncInterval)
Q_PROPERTY(int indexSyncInterval READ indexSyncInterval WRITE setIndexSyncInterval)
Q_PROPERTY(bool debugQuery READ debugQuery WRITE setDebugQuery)
+ Q_PROPERTY(QStringList configSearchPath READ configSearchPath WRITE setConfigSearchPath)
public:
static JsonDbSettings *instance();
@@ -109,6 +111,9 @@ public:
inline bool debugQuery() const { return mDebugQuery; }
inline void setDebugQuery(bool debug) { mDebugQuery = debug; }
+ inline QStringList configSearchPath() const { return mConfigSearchPath; }
+ inline void setConfigSearchPath(const QStringList &searchPath) { mConfigSearchPath = searchPath; }
+
JsonDbSettings();
private:
@@ -126,9 +131,10 @@ private:
int mSyncInterval;
int mIndexSyncInterval;
bool mDebugQuery;
+ QStringList mConfigSearchPath;
};
-QT_END_NAMESPACE_JSONDB
+QT_END_NAMESPACE_JSONDB_PARTITION
QT_END_HEADER
diff --git a/src/daemon/jsondbstat.h b/src/partition/jsondbstat.h
index 7fb76263..f2d6f7ac 100644
--- a/src/daemon/jsondbstat.h
+++ b/src/partition/jsondbstat.h
@@ -42,11 +42,13 @@
#ifndef JSONDB_STAT_H
#define JSONDB_STAT_H
+#include "jsondbpartitionglobal.h"
+
QT_BEGIN_HEADER
-QT_BEGIN_NAMESPACE_JSONDB
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
-class JsonDbStat
+class Q_JSONDB_PARTITION_EXPORT JsonDbStat
{
public:
qint32 reads;
@@ -70,7 +72,7 @@ public:
};
};
-QT_END_NAMESPACE_JSONDB
+QT_END_NAMESPACE_JSONDB_PARTITION
QT_END_HEADER
diff --git a/src/partition/jsondbstrings.cpp b/src/partition/jsondbstrings.cpp
new file mode 100644
index 00000000..661b941b
--- /dev/null
+++ b/src/partition/jsondbstrings.cpp
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "jsondbstrings.h"
+
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
+
+const QString JsonDbString::kUuidStr = QString::fromLatin1("_uuid");
+const QString JsonDbString::kVersionStr = QString::fromLatin1("_version");
+const QString JsonDbString::kIdStr = QString::fromLatin1("id");
+const QString JsonDbString::kResultStr = QString::fromLatin1("result");
+const QString JsonDbString::kErrorStr = QString::fromLatin1("error");
+const QString JsonDbString::kFieldNameStr = QString::fromLatin1("fieldName");
+const QString JsonDbString::kCodeStr = QString::fromLatin1("code");
+const QString JsonDbString::kMessageStr = QString::fromLatin1("message");
+const QString JsonDbString::kNameStr = QString::fromLatin1("name");
+const QString JsonDbString::kCountStr = QString::fromLatin1("count");
+const QString JsonDbString::kCurrentStr = QString::fromLatin1("_current");
+const QString JsonDbString::kDomainStr = QString::fromLatin1("_domain");
+const QString JsonDbString::kIndexValueStr = QString::fromLatin1("_indexValue");
+const QString JsonDbString::kOwnerStr = QString::fromLatin1("_owner");
+const QString JsonDbString::kTypeStr = QString::fromLatin1("_type");
+const QString JsonDbString::kTypesStr = QString::fromLatin1("types");
+const QString JsonDbString::kParentStr = QString::fromLatin1("_parent");
+const QString JsonDbString::kSchemaTypeStr = QString::fromLatin1("_schemaType");
+
+const QString JsonDbString::kActionStr = QString::fromLatin1("action");
+const QString JsonDbString::kActionsStr = QString::fromLatin1("actions");
+const QString JsonDbString::kActiveStr = QString::fromLatin1("active");
+const QString JsonDbString::kAddIndexStr = QString::fromLatin1("addIndex");
+const QString JsonDbString::kCreateStr = QString::fromLatin1("create");
+const QString JsonDbString::kDropStr = QString::fromLatin1("drop");
+const QString JsonDbString::kConflictsStr = QString::fromLatin1("conflicts");
+const QString JsonDbString::kConnectStr = QString::fromLatin1("connect");
+const QString JsonDbString::kDataStr = QString::fromLatin1("data");
+const QString JsonDbString::kDeletedStr = QString::fromLatin1("_deleted");
+const QString JsonDbString::kDisconnectStr = QString::fromLatin1("disconnect");
+const QString JsonDbString::kExplanationStr = QString::fromLatin1("explanation");
+const QString JsonDbString::kFindStr = QString::fromLatin1("find");
+const QString JsonDbString::kLengthStr = QString::fromLatin1("length");
+const QString JsonDbString::kLimitStr = QString::fromLatin1("limit");
+const QString JsonDbString::kMapTypeStr = QString::fromLatin1("Map");
+const QString JsonDbString::kMetaStr = QString::fromLatin1("_meta");
+const QString JsonDbString::kNotifyStr = QString::fromLatin1("notify");
+const QString JsonDbString::kNotificationTypeStr = QString::fromLatin1("notification");
+const QString JsonDbString::kObjectStr = QString::fromLatin1("object");
+const QString JsonDbString::kOffsetStr = QString::fromLatin1("offset");
+const QString JsonDbString::kQueryStr = QString::fromLatin1("query");
+const QString JsonDbString::kReduceTypeStr = QString::fromLatin1("Reduce");
+const QString JsonDbString::kRemoveStr = QString::fromLatin1("remove");
+const QString JsonDbString::kSchemaStr = QString::fromLatin1("schema");
+const QString JsonDbString::kUpdateStr = QString::fromLatin1("update");
+const QString JsonDbString::kTokenStr = QString::fromLatin1("token");
+const QString JsonDbString::kFlushStr = QString::fromLatin1("flush");
+const QString JsonDbString::kSettingsStr = QString::fromLatin1("settings");
+const QString JsonDbString::kViewTypeStr = QString::fromLatin1("View");
+const QString JsonDbString::kChangesSinceStr = QString::fromLatin1("changesSince");
+const QString JsonDbString::kStateNumberStr = QString::fromLatin1("stateNumber");
+const QString JsonDbString::kCollapsedStr = QString::fromLatin1("collapsed");
+const QString JsonDbString::kCurrentStateNumberStr = QString::fromLatin1("currentStateNumber");
+const QString JsonDbString::kStartingStateNumberStr = QString::fromLatin1("startingStateNumber");
+const QString JsonDbString::kTombstoneStr = QString::fromLatin1("Tombstone");
+const QString JsonDbString::kPartitionTypeStr = QString::fromLatin1("Partition");
+const QString JsonDbString::kPartitionStr = QString::fromLatin1("partition");
+const QString JsonDbString::kLogStr = QString::fromLatin1("log");
+const QString JsonDbString::kPropertyNameStr = QString::fromLatin1("propertyName");
+const QString JsonDbString::kPropertyTypeStr = QString::fromLatin1("propertyType");
+const QString JsonDbString::kPropertyFunctionStr = QString::fromLatin1("propertyFunction");
+const QString JsonDbString::kObjectTypeStr = QString::fromLatin1("objectType");
+const QString JsonDbString::kDbidTypeStr = QString::fromLatin1("DatabaseId");
+const QString JsonDbString::kIndexTypeStr = QString::fromLatin1("Index");
+const QString JsonDbString::kLocaleStr = QString::fromLatin1("locale");
+const QString JsonDbString::kCollationStr = QString::fromLatin1("collation");
+const QString JsonDbString::kCaseSensitiveStr = QString::fromLatin1("caseSensitive");
+const QString JsonDbString::kCasePreferenceStr = QString::fromLatin1("casePreference");
+const QString JsonDbString::kDatabaseSchemaVersionStr = QString::fromLatin1("databaseSchemaVersion");
+const QString JsonDbString::kPathStr = QString::fromLatin1("path");
+const QString JsonDbString::kDefaultStr = QString::fromLatin1("default");
+
+QT_END_NAMESPACE_JSONDB_PARTITION
diff --git a/src/partition/jsondbstrings.h b/src/partition/jsondbstrings.h
new file mode 100644
index 00000000..60fb7c23
--- /dev/null
+++ b/src/partition/jsondbstrings.h
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef JSONDB_STRINGS_H
+#define JSONDB_STRINGS_H
+
+#include <QString>
+#include "jsondbpartitionglobal.h"
+
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
+
+class Q_JSONDB_PARTITION_EXPORT JsonDbString {
+public:
+ static const QString kActionStr;
+ static const QString kActionsStr;
+ static const QString kActiveStr;
+ static const QString kAddIndexStr;
+ static const QString kCodeStr;
+ static const QString kConflictsStr;
+ static const QString kConnectStr;
+ static const QString kCountStr;
+ static const QString kCreateStr;
+ static const QString kDropStr;
+ static const QString kCurrentStr;
+ static const QString kDataStr;
+ static const QString kDeletedStr;
+ static const QString kDisconnectStr;
+ static const QString kDomainStr;
+ static const QString kErrorStr;
+ static const QString kExplanationStr;
+ static const QString kFieldNameStr;
+ static const QString kFindStr;
+ static const QString kNameStr;
+ static const QString kIdStr;
+ static const QString kIndexValueStr;
+ static const QString kLengthStr;
+ static const QString kLimitStr;
+ static const QString kMapTypeStr;
+ static const QString kMessageStr;
+ static const QString kMetaStr;
+ static const QString kNotifyStr;
+ static const QString kNotificationTypeStr;
+ static const QString kObjectStr;
+ static const QString kParentStr;
+ static const QString kOffsetStr;
+ static const QString kOwnerStr;
+ static const QString kQueryStr;
+ static const QString kReduceTypeStr;
+ static const QString kRemoveStr;
+ static const QString kResultStr;
+ static const QString kSchemaStr;
+ static const QString kSchemaTypeStr;
+ static const QString kTypeStr;
+ static const QString kTypesStr;
+ static const QString kUpdateStr;
+ static const QString kUuidStr;
+ static const QString kVersionStr;
+ static const QString kViewTypeStr;
+ static const QString kTokenStr;
+ static const QString kFlushStr;
+ static const QString kSettingsStr;
+ static const QString kChangesSinceStr;
+ static const QString kStateNumberStr;
+ static const QString kCollapsedStr;
+ static const QString kCurrentStateNumberStr;
+ static const QString kStartingStateNumberStr;
+ static const QString kTombstoneStr;
+ static const QString kPartitionTypeStr;
+ static const QString kPartitionStr;
+ static const QString kLogStr;
+ static const QString kPropertyNameStr;
+ static const QString kPropertyTypeStr;
+ static const QString kPropertyFunctionStr;
+ static const QString kObjectTypeStr;
+ static const QString kDbidTypeStr;
+ static const QString kIndexTypeStr;
+ static const QString kLocaleStr;
+ static const QString kCollationStr;
+ static const QString kCaseSensitiveStr;
+ static const QString kCasePreferenceStr;
+ static const QString kDatabaseSchemaVersionStr;
+ static const QString kPathStr;
+ static const QString kDefaultStr;
+};
+
+QT_END_NAMESPACE_JSONDB_PARTITION
+
+#endif /* JSONDB-STRINGS_H */
diff --git a/src/daemon/jsondbview.cpp b/src/partition/jsondbview.cpp
index 4adc5d65..0c862b5d 100644
--- a/src/daemon/jsondbview.cpp
+++ b/src/partition/jsondbview.cpp
@@ -46,7 +46,6 @@
#include <QString>
#include <QElapsedTimer>
-#include "jsondb-global.h"
#include "jsondbpartition.h"
#include "jsondbobject.h"
#include "jsondbview.h"
@@ -54,8 +53,9 @@
#include "jsondbobjecttable.h"
#include "jsondbreducedefinition.h"
#include "jsondbsettings.h"
+#include "jsondbscriptengine.h"
-QT_BEGIN_NAMESPACE_JSONDB
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
JsonDbView::JsonDbView(JsonDbPartition *partition, const QString &viewType, QObject *parent) :
QObject(parent)
@@ -66,6 +66,7 @@ JsonDbView::JsonDbView(JsonDbPartition *partition, const QString &viewType, QObj
, mUpdating(false)
{
mViewObjectTable = new JsonDbObjectTable(mPartition);
+ mViewStateNumber = 0; // FIXME: should be able to read it from the object table
}
JsonDbView::~JsonDbView()
@@ -83,8 +84,7 @@ void JsonDbView::open()
if (!mViewObjectTable->open(QString("%1/%2-%3-View.db")
.arg(dirName)
.arg(baseName)
- .arg(mViewType),
- JsonDbBtree::Default)) {
+ .arg(mViewType))) {
qCritical() << "viewDb->open" << mViewObjectTable->errorMessage();
return;
}
@@ -261,16 +261,16 @@ void JsonDbView::updateSourceTypesList()
mObjectTableSourceTypeMap = objectTableSourceTypeMap;
}
-void JsonDbView::updateView(quint32 desiredStateNumber)
+void JsonDbView::updateView(quint32 desiredStateNumber, JsonDbUpdateList *resultingChanges)
{
QElapsedTimer timer;
if (jsondbSettings->performanceLog())
timer.start();
if (jsondbSettings->verbose())
- qDebug() << endl << "updateView" << mViewType << "{" << endl;
+ qDebug() << "updateView" << mViewType << "{";
// current state of the main object table of the partition
quint32 partitionStateNumber = mMainObjectTable->stateNumber();
- quint32 viewStateNumber = mViewObjectTable->stateNumber();
+ quint32 viewStateNumber = mViewStateNumber;
// if the view is up to date, then return
if ((desiredStateNumber && viewStateNumber >= desiredStateNumber)
@@ -281,7 +281,7 @@ void JsonDbView::updateView(quint32 desiredStateNumber)
}
if (mUpdating) {
if (jsondbSettings->verbose())
- qDebug() << endl << "Update already in progess" << endl
+ qDebug() << "Update already in progess"
<< "updateView" << mViewType << "}";
return;
}
@@ -324,56 +324,127 @@ void JsonDbView::updateView(quint32 desiredStateNumber)
// up-to-date with respect this source table
continue;
- QJsonObject changesSince(sourceTable->changesSince(viewStateNumber, sourceTypes));
- QJsonObject changes(changesSince.value("result").toObject());
- QJsonArray changeList(changes.value("changes").toArray());
- quint32 count = changeList.size();
- for (quint32 i = 0; i < count; i++) {
- QJsonObject change = changeList.at(i).toObject();
- QJsonValue before = change.value("before");
- QJsonValue after = change.value("after");
-
- QJsonObject beforeObject = before.toObject();
- QJsonObject afterObject = after.toObject();
- QString beforeType = beforeObject.value(JsonDbString::kTypeStr).toString();
- QString afterType = afterObject.value(JsonDbString::kTypeStr).toString();
-
- if (mMapDefinitionsBySource.contains(beforeType)) {
- JsonDbMapDefinition *def = mMapDefinitionsBySource.value(beforeType);
- if (processedDefinitionUuids.contains(def->uuid()))
- continue;
- def->updateObject(beforeObject, afterObject);
- } else if (mMapDefinitionsBySource.contains(afterType)) {
- JsonDbMapDefinition *def = mMapDefinitionsBySource.value(afterType);
- if (processedDefinitionUuids.contains(def->uuid()))
- continue;
- def->updateObject(beforeObject, afterObject);
- }
-
- if (mReduceDefinitionsBySource.contains(beforeType)) {
- JsonDbReduceDefinition *def = mReduceDefinitionsBySource.value(beforeType);
- if (processedDefinitionUuids.contains(def->uuid()))
- continue;
- def->updateObject(beforeObject, afterObject);
- } else if (mReduceDefinitionsBySource.contains(afterType)) {
- JsonDbReduceDefinition *def = mReduceDefinitionsBySource.value(afterType);
- if (processedDefinitionUuids.contains(def->uuid()))
- continue;
- def->updateObject(beforeObject, afterObject);
- }
- }
+ QList<JsonDbUpdate> changeList;
+ sourceTable->changesSince(viewStateNumber, sourceTypes, &changeList, JsonDbObjectTable::SplitTypeChanges);
+ updateViewOnChanges(changeList, processedDefinitionUuids, resultingChanges);
}
+ mViewStateNumber = partitionStateNumber;
+ mUpdating = false;
+ JsonDbScriptEngine::scriptEngine()->collectGarbage();
if (inTransaction)
mViewObjectTable->commit(partitionStateNumber);
if (jsondbSettings->verbose())
- qDebug() << endl << "}" << "updateView" << mViewType << endl;
+ qDebug() << "}" << "updateView" << mViewType << partitionStateNumber;
if (jsondbSettings->performanceLog())
- qDebug() << "updateView" << mViewType << timer.elapsed() << "ms";
- mUpdating = false;
+ qDebug() << "updateView" << "stateNumber" << mViewStateNumber << mViewType << timer.elapsed() << "ms";
emit updated(mViewType);
}
+void JsonDbView::updateEagerView(const JsonDbUpdateList &objectsUpdated, JsonDbUpdateList *resultingChanges)
+{
+ quint32 partitionStateNumber = mMainObjectTable->stateNumber();
+ quint32 viewStateNumber = mViewStateNumber;
+
+ // make sure we can run this set of updates
+ if (mViewStateNumber != (partitionStateNumber - 1)
+ || viewDefinitionUpdated(objectsUpdated)) {
+ // otherwise do a full update
+ if (jsondbSettings->verbose())
+ qDebug() << "updateEagerView" << mViewType << "full update"
+ << "viewStateNumber" << mViewStateNumber << "partitionStateNumber" << partitionStateNumber
+ << (viewDefinitionUpdated(objectsUpdated) ? "definition updated" : "");
+ updateView(partitionStateNumber, resultingChanges);
+ return;
+ }
+
+ QElapsedTimer timer;
+ if (jsondbSettings->performanceLog())
+ timer.start();
+ if (jsondbSettings->verbose())
+ qDebug() << "updateEagerView" << mViewType << "{";
+
+ // begin transaction
+ mViewObjectTable->begin();
+
+ // then do the update
+ QSet<QString> processedDefinitionUuids;
+ updateViewOnChanges(objectsUpdated, processedDefinitionUuids, resultingChanges);
+
+ // end transaction
+ JsonDbScriptEngine::scriptEngine()->collectGarbage();
+ mViewObjectTable->commit(partitionStateNumber);
+ mViewStateNumber = partitionStateNumber;
+
+ if (jsondbSettings->verbose())
+ qDebug() << "updateEagerView" << mViewType << viewStateNumber << "}";
+ if (jsondbSettings->performanceLog())
+ qDebug() << "updateEagerView" << "stateNumber" << mViewStateNumber << mViewType << timer.elapsed() << "ms";
+}
+
+// Updates the in-memory state numbers on the view so that we know it
+// has seen all relevant updates from this transaction
+void JsonDbView::updateViewStateNumber(quint32 partitionStateNumber)
+{
+ // If the change is not zero or one it's an error
+ if (jsondbSettings->verbose() || (mViewStateNumber != (partitionStateNumber - 1) && mViewStateNumber != partitionStateNumber))
+ qCritical() << "updateViewStateNumber" << mViewType << "viewStateNumber" << mViewStateNumber << "partitionStateNumber" << partitionStateNumber;
+ mViewStateNumber = partitionStateNumber;
+}
+
+bool JsonDbView::viewDefinitionUpdated(const JsonDbUpdateList &objectsUpdated) const
+{
+ foreach (const JsonDbUpdate &update, objectsUpdated) {
+ QJsonObject beforeObject = update.oldObject;
+ QJsonObject afterObject = update.newObject;
+ QString beforeUuid = beforeObject.value(JsonDbString::kUuidStr).toString();
+ QString afterUuid = afterObject.value(JsonDbString::kUuidStr).toString();
+
+ if ((!beforeObject.isEmpty()
+ && (mMapDefinitions.contains(beforeUuid) || mReduceDefinitions.contains(beforeUuid)))
+ || (!afterObject.isEmpty()
+ && (mMapDefinitions.contains(afterUuid) || mReduceDefinitions.contains(afterUuid))))
+ return false;
+ }
+ return false;
+}
+
+void JsonDbView::updateViewOnChanges(const JsonDbUpdateList &objectsUpdated,
+ QSet<QString> &processedDefinitionUuids,
+ JsonDbUpdateList *changeList)
+{
+ foreach (const JsonDbUpdate &update, objectsUpdated) {
+ QJsonObject beforeObject = update.oldObject;
+ QJsonObject afterObject = update.newObject;
+ QString beforeType = beforeObject.value(JsonDbString::kTypeStr).toString();
+ QString afterType = afterObject.value(JsonDbString::kTypeStr).toString();
+
+ if (mMapDefinitionsBySource.contains(beforeType)) {
+ JsonDbMapDefinition *def = mMapDefinitionsBySource.value(beforeType);
+ if (processedDefinitionUuids.contains(def->uuid()))
+ continue;
+ def->updateObject(beforeObject, afterObject, changeList);
+ } else if (mMapDefinitionsBySource.contains(afterType)) {
+ JsonDbMapDefinition *def = mMapDefinitionsBySource.value(afterType);
+ if (processedDefinitionUuids.contains(def->uuid()))
+ continue;
+ def->updateObject(beforeObject, afterObject, changeList);
+ }
+
+ if (mReduceDefinitionsBySource.contains(beforeType)) {
+ JsonDbReduceDefinition *def = mReduceDefinitionsBySource.value(beforeType);
+ if (processedDefinitionUuids.contains(def->uuid()))
+ continue;
+ def->updateObject(beforeObject, afterObject, changeList);
+ } else if (mReduceDefinitionsBySource.contains(afterType)) {
+ JsonDbReduceDefinition *def = mReduceDefinitionsBySource.value(afterType);
+ if (processedDefinitionUuids.contains(def->uuid()))
+ continue;
+ def->updateObject(beforeObject, afterObject, changeList);
+ }
+ }
+}
+
bool JsonDbView::processUpdatedDefinitions(const QString &viewType, quint32 targetStateNumber,
QSet<QString> &processedDefinitionUuids)
{
@@ -383,18 +454,19 @@ bool JsonDbView::processUpdatedDefinitions(const QString &viewType, quint32 targ
return inTransaction;
QSet<QString> limitTypes;
limitTypes << JsonDbString::kMapTypeStr << JsonDbString::kReduceTypeStr;
- QJsonObject changes = mMainObjectTable->changesSince(targetStateNumber, limitTypes).value("result").toObject();
- quint32 count = changes.value("count").toDouble();
- QJsonArray changeList = changes.value("changes").toArray();
- for (quint32 i = 0; i < count; i++) {
- QJsonObject change = changeList.at(i).toObject();
+ QList<JsonDbUpdate> changeList;
+ mMainObjectTable->changesSince(targetStateNumber, limitTypes, &changeList, JsonDbObjectTable::SplitTypeChanges);
+ foreach (const JsonDbUpdate &change, changeList) {
QString definitionUuid;
+ JsonDbNotification::Action action = change.action;
+ JsonDbObject before = change.oldObject;
+ JsonDbObject after = change.newObject;
+ QString beforeType = before.value(JsonDbString::kTypeStr).toString();
+ QString afterType = after.value(JsonDbString::kTypeStr).toString();
if (jsondbSettings->verbose())
- qDebug() << "change" << change;
- if (change.contains("before")) {
- QJsonObject before = change.value("before").toObject();
- QString beforeType = before.value(JsonDbString::kTypeStr).toString();
- if ((limitTypes.contains(beforeType))
+ qDebug() << "definition change" << change;
+ if (action != JsonDbNotification::Create) {
+ if (limitTypes.contains(beforeType)
&& (before.value("targetType").toString() == viewType)) {
if (!inTransaction) {
mViewObjectTable->begin();
@@ -409,11 +481,7 @@ bool JsonDbView::processUpdatedDefinitions(const QString &viewType, quint32 targ
JsonDbReduceDefinition::definitionRemoved(mPartition, mViewObjectTable, targetType, definitionUuid);
}
}
- if (change.contains("after")) {
- QJsonObject after = change.value("after").toObject();
- QString afterType = after.value(JsonDbString::kTypeStr).toString();
- if (jsondbSettings->verbose())
- qDebug() << "afterVersion" << after.value(JsonDbString::kVersionStr).toString();
+ if (action != JsonDbNotification::Delete) {
if ((limitTypes.contains(afterType))
&& (after.value("targetType").toString() == viewType)) {
if (!inTransaction) {
@@ -465,4 +533,6 @@ bool JsonDbView::isActive() const
return false;
}
-QT_END_NAMESPACE_JSONDB
+#include "moc_jsondbview.cpp"
+
+QT_END_NAMESPACE_JSONDB_PARTITION
diff --git a/src/daemon/jsondbview.h b/src/partition/jsondbview.h
index a2d56756..70a1bda4 100644
--- a/src/daemon/jsondbview.h
+++ b/src/partition/jsondbview.h
@@ -45,19 +45,19 @@
#include <QObject>
#include <QString>
-#include "jsondb-global.h"
+#include "jsondbpartitionglobal.h"
#include "jsondbmapdefinition.h"
#include "jsondbreducedefinition.h"
QT_BEGIN_HEADER
-QT_BEGIN_NAMESPACE_JSONDB
+QT_BEGIN_NAMESPACE_JSONDB_PARTITION
class JsonDbOwner;
class JsonDbPartition;
class JsonDbObjectTable;
-class JsonDbView : public QObject
+class Q_JSONDB_PARTITION_EXPORT JsonDbView : public QObject
{
Q_OBJECT
public:
@@ -67,6 +67,7 @@ public:
JsonDbPartition *partition() const { return mPartition; }
JsonDbObjectTable *objectTable() const { return mViewObjectTable; }
QStringList sourceTypes() const { return mSourceTypes; }
+ QSet<QString> sourceTypeSet() const { return QSet<QString>::fromList(mSourceTypes); }
void open();
void close();
@@ -75,7 +76,9 @@ public:
static void createDefinition(JsonDbPartition *partition, QJsonObject definition);
static void removeDefinition(JsonDbPartition *partition, QJsonObject definition);
- void updateView(quint32 stateNumber=0);
+ void updateView(quint32 stateNumber=0, JsonDbUpdateList *resultingChanges=0);
+ void updateEagerView(const JsonDbUpdateList &objectsUpdated, JsonDbUpdateList *resultingChanges);
+ void updateViewStateNumber(quint32 partitionStateNumber);
void reduceMemoryUsage();
bool isActive() const;
@@ -91,10 +94,14 @@ private:
bool processUpdatedDefinitions(const QString &viewType, quint32 targetStateNumber,
QSet<QString> &processedDefinitions);
void updateSourceTypesList();
+ bool viewDefinitionUpdated(const JsonDbUpdateList &objectsUpdated) const;
+ void updateViewOnChanges(const JsonDbUpdateList &objectsUpdated, QSet<QString> &processedDefinitionUuids, JsonDbUpdateList *changeList);
+
private:
JsonDbPartition *mPartition;
JsonDbObjectTable *mViewObjectTable; // view object table
JsonDbObjectTable *mMainObjectTable; // partition's main object table
+ quint32 mViewStateNumber;
QString mViewType;
QStringList mSourceTypes;
typedef QMap<JsonDbObjectTable*,QSet<QString> > ObjectTableSourceTypeMap;
@@ -109,7 +116,7 @@ private:
friend class JsonDbReduceDefinition;
};
-QT_END_NAMESPACE_JSONDB
+QT_END_NAMESPACE_JSONDB_PARTITION
QT_END_HEADER
diff --git a/src/partition/partition.pro b/src/partition/partition.pro
new file mode 100644
index 00000000..063e5d48
--- /dev/null
+++ b/src/partition/partition.pro
@@ -0,0 +1,78 @@
+TEMPLATE = lib
+TARGET = $$QT.jsondbpartition.name
+MODULE = jsondbpartition
+
+load(qt_module)
+load(qt_module_config)
+
+DESTDIR = $$QT.jsondbpartition.libs
+VERSION = $$QT.jsondbpartition.VERSION
+DEFINES += QT_JSONDB_PARTITION_LIB
+
+QT = core network qml
+
+CONFIG += module create_prl
+MODULE_PRI = ../../modules/qt_jsondbpartition.pri
+
+include(../3rdparty/btree/btree.pri)
+include(../hbtree/hbtree.pri)
+
+RESOURCES = jsondb.qrc
+
+HEADERS += \
+ jsondbowner.h \
+ jsondbproxy.h \
+ jsondbindex.h \
+ jsondbobject.h \
+ jsondbpartition.h \
+ jsondbquery.h \
+ jsondbstat.h \
+ jsondbview.h \
+ jsondbmapdefinition.h \
+ jsondbnotification.h \
+ jsondbobjectkey.h \
+ jsondbobjecttable.h \
+ jsondbbtree.h \
+ jsondbobjecttypes_impl_p.h \
+ jsondbobjecttypes_p.h \
+ jsondbreducedefinition.h \
+ schema-validation/checkpoints.h \
+ schema-validation/object.h \
+ jsondbschemamanager_impl_p.h \
+ jsondbschemamanager_p.h \
+ jsondbscriptengine.h \
+ jsondbsettings.h \
+ jsondbindexquery.h \
+ jsondberrors.h \
+ jsondbstrings.h \
+ jsondbpartitionglobal.h \
+ jsondbcollator.h \
+ jsondbcollator_p.h
+
+SOURCES += \
+ jsondbowner.cpp \
+ jsondbproxy.cpp \
+ jsondbindex.cpp \
+ jsondbobject.cpp \
+ jsondbpartition.cpp \
+ jsondbquery.cpp \
+ jsondbview.cpp \
+ jsondbmapdefinition.cpp \
+ jsondbnotification.cpp \
+ jsondbobjecttable.cpp \
+ jsondbbtree.cpp \
+ jsondbreducedefinition.cpp \
+ jsondbscriptengine.cpp \
+ jsondbsettings.cpp \
+ jsondbindexquery.cpp \
+ jsondberrors.cpp \
+ jsondbstrings.cpp \
+ jsondbcollator.cpp
+
+mac:QMAKE_FRAMEWORK_BUNDLE_NAME = $$QT.jsondbpartition.name
+
+contains(config_test_icu, yes) {
+ LIBS += -licuuc -licui18n
+} else {
+ DEFINES += NO_COLLATION_SUPPORT
+}
diff --git a/src/daemon/schema-validation/checkpoints.h b/src/partition/schema-validation/checkpoints.h
index 34e2e164..34e2e164 100644
--- a/src/daemon/schema-validation/checkpoints.h
+++ b/src/partition/schema-validation/checkpoints.h
diff --git a/src/daemon/schema-validation/object.h b/src/partition/schema-validation/object.h
index 2725647e..2725647e 100644
--- a/src/daemon/schema-validation/object.h
+++ b/src/partition/schema-validation/object.h
diff --git a/src/daemon/schema/Capability.json b/src/partition/schema/Capability.json
index 27f49859..27f49859 100644
--- a/src/daemon/schema/Capability.json
+++ b/src/partition/schema/Capability.json
diff --git a/src/daemon/schema/Index.json b/src/partition/schema/Index.json
index 7c60d153..7c60d153 100644
--- a/src/daemon/schema/Index.json
+++ b/src/partition/schema/Index.json
diff --git a/src/daemon/schema/RootCapability.json b/src/partition/schema/RootCapability.json
index 9d4869fa..9d4869fa 100644
--- a/src/daemon/schema/RootCapability.json
+++ b/src/partition/schema/RootCapability.json
diff --git a/src/daemon/schema/View.json b/src/partition/schema/View.json
index 6130fa33..6130fa33 100644
--- a/src/daemon/schema/View.json
+++ b/src/partition/schema/View.json
diff --git a/src/daemon/schema/notification.json b/src/partition/schema/notification.json
index 360be3b2..360be3b2 100644
--- a/src/daemon/schema/notification.json
+++ b/src/partition/schema/notification.json
diff --git a/src/src.pro b/src/src.pro
index 33992b82..ae3b872a 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -1,3 +1,3 @@
TEMPLATE = subdirs
CONFIG += ordered
-SUBDIRS += 3rdparty jsonstream clientcompat client daemon imports
+SUBDIRS += 3rdparty jsonstream clientcompat partition client daemon imports
diff --git a/sync.profile b/sync.profile
index 218659e3..52ea3f27 100644
--- a/sync.profile
+++ b/sync.profile
@@ -1,5 +1,6 @@
%modules = ( # path to module name map
"QtJsonDb" => "$basedir/src/client",
+ "QtJsonDbPartition" => "$basedir/src/partition",
"QtJsonDbCompat" => "$basedir/src/clientcompat",
);
%moduleheaders = ( # restrict the module headers to those found in relative path
@@ -14,6 +15,7 @@
);
%modulepris = (
"QtJsonDb" => "$basedir/modules/qt_jsondb.pri",
+ "QtJsonDbPartition" => "$basedir/modules/qt_jsondbpartition.pri",
"QtJsonDbCompat" => "$basedir/modules/qt_jsondbcompat.pri",
);
$publicclassregexp = "QJsonDb.+";
@@ -29,3 +31,6 @@ $publicclassregexp = "QJsonDb.+";
"qtjsbackend" => "refs/heads/master",
"qtxmlpatterns" => "refs/heads/master",
);
+%configtests = (
+ "icu" => {}
+);
diff --git a/tests/auto/accesscontrol/accesscontrol.pro b/tests/auto/accesscontrol/accesscontrol.pro
index e15c1c62..83bfadfc 100644
--- a/tests/auto/accesscontrol/accesscontrol.pro
+++ b/tests/auto/accesscontrol/accesscontrol.pro
@@ -1,16 +1,14 @@
TARGET = tst_accesscontrol
CONFIG += debug
-QT = network qml testlib
+QT = network qml testlib jsondbpartition
CONFIG -= app_bundle
CONFIG += testcase
-INCLUDEPATH += $$PWD/../../../src/daemon
LIBS += -L$$QT.jsondb.libs
DEFINES += SRCDIR=\\\"$$PWD/\\\"
-include($$PWD/../../../src/daemon/daemon.pri)
RESOURCES+= accesscontrol.qrc
SOURCES += \
testjsondb.cpp \
diff --git a/tests/auto/accesscontrol/json/capabilities-indexes.json b/tests/auto/accesscontrol/json/capabilities-indexes.json
new file mode 100644
index 00000000..777329fb
--- /dev/null
+++ b/tests/auto/accesscontrol/json/capabilities-indexes.json
@@ -0,0 +1,24 @@
+[
+ {
+ "_type": "Capability",
+ "name": "indexes",
+ "partition": "all",
+ "accessRules": {
+ "rw": {
+ "read": ["[?_type startsWith \"Phone\"]", "[?_type = \"Contact\"]", "[?_type = \"Index\"]"],
+ "write": ["[?_type = \"Index\"]"]
+ }
+ }
+ },
+{
+ "_type": "Capability",
+ "name": "noindexes",
+ "partition": "all",
+ "accessRules": {
+ "rw": {
+ "read": ["[?_type startsWith \"Phone\"]", "[?_type = \"Index\"]"],
+ "write": ["[?_type = \"Index\"]"]
+ }
+ }
+}
+]
diff --git a/tests/auto/accesscontrol/json/index-test.json b/tests/auto/accesscontrol/json/index-test.json
new file mode 100644
index 00000000..1fca6652
--- /dev/null
+++ b/tests/auto/accesscontrol/json/index-test.json
@@ -0,0 +1,25 @@
+[
+{
+ "_type": "Index",
+ "objectType": "Phone",
+ "name": "name",
+ "propertyName": "name",
+ "propertyType": "string"
+},
+{
+ "_type": "Index",
+ "name": "another",
+ "objectType": ["Phone", "Contact"],
+ "propertyName": "field",
+ "propertyType": "string",
+ "locale": "en_US",
+ "collation": "default",
+ "casePreference": "IgnoreCase"
+},
+{
+ "_type": "Index",
+ "name": "noObjectType",
+ "propertyName": "field",
+ "propertyType": "string"
+}
+]
diff --git a/tests/auto/accesscontrol/testjsondb.cpp b/tests/auto/accesscontrol/testjsondb.cpp
index 43399343..3f18ff58 100644
--- a/tests/auto/accesscontrol/testjsondb.cpp
+++ b/tests/auto/accesscontrol/testjsondb.cpp
@@ -47,13 +47,12 @@
#include <QDir>
#include <QTime>
-#include "json.h"
#include "jsondbpartition.h"
#include "jsondbsettings.h"
#include "../../shared/util.h"
-QT_USE_NAMESPACE_JSONDB
+QT_USE_NAMESPACE_JSONDB_PARTITION
/*
Ensure that a good result object contains the correct fields
@@ -103,6 +102,7 @@ private slots:
void testAccessControl();
void testFindAccessControl();
void testViewAccessControl();
+ void testIndexAccessControl();
private:
JsonDbQueryResult find(JsonDbOwner *owner, const QString &query, const QJsonObject bindings = QJsonObject());
@@ -110,15 +110,13 @@ private:
JsonDbWriteResult update(JsonDbOwner *owner, JsonDbObject &object, JsonDbPartition::WriteMode mode = JsonDbPartition::OptimisticWrite);
JsonDbWriteResult remove(JsonDbOwner *owner, JsonDbObject &object, JsonDbPartition::WriteMode mode = JsonDbPartition::OptimisticWrite);
- QJsonValue readJsonFile(const QString &filename);
- QJsonValue readJson(const QByteArray& json);
void removeDbFiles();
private:
JsonDbPartition *mJsonDbPartition;
QStringList mNotificationsReceived;
QList<JsonDbObject> mContactList;
- JsonDbOwner *mOwner;
+ QScopedPointer<JsonDbOwner> mOwner;
};
const char *kFilename = "testdatabase";
@@ -151,10 +149,10 @@ void TestJsonDb::initTestCase()
QCoreApplication::setApplicationVersion("1.0");
removeDbFiles();
- mOwner = new JsonDbOwner(this);
+ mOwner.reset (new JsonDbOwner(this));
mOwner->setOwnerId(QStringLiteral("com.example.JsonDbTest"));
- mJsonDbPartition = new JsonDbPartition(kFilename, QStringLiteral("com.example.JsonDbTest"), mOwner, this);
+ mJsonDbPartition = new JsonDbPartition(kFilename, QStringLiteral("com.example.JsonDbTest"), mOwner.data(), this);
mJsonDbPartition->open();
}
@@ -175,7 +173,8 @@ void TestJsonDb::cleanup()
JsonDbQueryResult TestJsonDb::find(JsonDbOwner *owner, const QString &query, const QJsonObject bindings)
{
- return mJsonDbPartition->queryObjects(owner, JsonDbQuery::parse(query, bindings));
+ QScopedPointer<JsonDbQuery> q(JsonDbQuery::parse(query, bindings));
+ return mJsonDbPartition->queryObjects(owner, q.data());
}
JsonDbWriteResult TestJsonDb::create(JsonDbOwner *owner, JsonDbObject &object, JsonDbPartition::WriteMode mode)
@@ -220,7 +219,7 @@ void TestJsonDb::capabilities()
QJsonObject capabilities(object.value("capabilities").toObject());
owner->setCapabilities(capabilities, mJsonDbPartition);
} else {
- JsonDbWriteResult result = create(mOwner, object);
+ JsonDbWriteResult result = create(mOwner.data(), object);
verifyGoodResult(result);
}
}
@@ -235,7 +234,7 @@ void TestJsonDb::allowAll()
// can delete me when this goes away
jsondbSettings->setEnforceAccessControl(true);
- JsonDbOwner *owner = new JsonDbOwner();
+ QScopedPointer<JsonDbOwner> owner(new JsonDbOwner());
owner->setAllowedObjects(QLatin1String("all"), QLatin1String("read"), QStringList());
owner->setAllowedObjects(QLatin1String("all"), QLatin1String("write"), QStringList());
owner->setStorageQuota(-1);
@@ -243,14 +242,14 @@ void TestJsonDb::allowAll()
JsonDbObject toPut;
toPut.insert("_type", QLatin1String("TestObject"));
- JsonDbWriteResult result = create(owner, toPut);
+ JsonDbWriteResult result = create(owner.data(), toPut);
verifyErrorResult(result);
JsonDbObject toPut2;
toPut2.insert("_type", QLatin1String("TestObject"));
- owner->setAllowAll(true);
- result = create(owner, toPut2);
+ owner.data()->setAllowAll(true);
+ result = create(owner.data(), toPut2);
verifyGoodResult(result);
mJsonDbPartition->removeIndex("TestObject");
@@ -276,7 +275,7 @@ void TestJsonDb::testAccessControl()
item.insert(JsonDbString::kTypeStr, QLatin1String("create-test-type"));
item.insert("access-control-test", 22);
- JsonDbWriteResult result = create(mOwner, item);
+ JsonDbWriteResult result = create(mOwner.data(), item);
verifyErrorResult(result);
@@ -284,14 +283,14 @@ void TestJsonDb::testAccessControl()
item.insert(JsonDbString::kTypeStr, QLatin1String("Contact"));
item.insert("access-control-test", 23);
- result = create(mOwner, item);
+ result = create(mOwner.data(), item);
verifyGoodResult(result);
item.insert("access-control-test", 24);
- result = update(mOwner, item);
+ result = update(mOwner.data(), item);
verifyGoodResult(result);
- result = remove(mOwner, item);
+ result = remove(mOwner.data(), item);
verifyGoodResult(result);
// Test some %owner and %typeDomain horror
@@ -304,7 +303,7 @@ void TestJsonDb::testAccessControl()
item.insert(JsonDbString::kTypeStr, QLatin1String("com.example.foo.bar.FooType"));
item.insert("access-control-test", 25);
- result = create(mOwner, item);
+ result = create(mOwner.data(), item);
QJsonValue uuid = item.value(JsonDbString::kUuidStr);
@@ -321,7 +320,7 @@ void TestJsonDb::testAccessControl()
item.insert(JsonDbString::kTypeStr, QLatin1String("com.example.foo.bar.FooType"));
item.insert("access-control-test", 26);
- result = create(mOwner, item);
+ result = create(mOwner.data(), item);
verifyErrorResult(result);
@@ -329,12 +328,12 @@ void TestJsonDb::testAccessControl()
item.insert(JsonDbString::kUuidStr, uuid);
item.insert("access-control-test", 27);
- result = update(mOwner, item);
+ result = update(mOwner.data(), item);
verifyErrorResult(result);
// .. or remove
item.insert(JsonDbString::kUuidStr, uuid);
- result = remove(mOwner, item);
+ result = remove(mOwner.data(), item);
verifyErrorResult(result);
// Positive tests
@@ -344,10 +343,10 @@ void TestJsonDb::testAccessControl()
item.insert(JsonDbString::kTypeStr, QLatin1String("com.example.foo.FooType"));
item.insert("access-control-test", 28);
- result = create(mOwner, item);
+ result = create(mOwner.data(), item);
verifyGoodResult(result);
- result = remove(mOwner, item);
+ result = remove(mOwner.data(), item);
verifyGoodResult(result);
item.remove(JsonDbString::kUuidStr);
@@ -356,14 +355,14 @@ void TestJsonDb::testAccessControl()
item.insert(JsonDbString::kTypeStr, QLatin1String("com.example.FooType"));
item.insert("access-control-test", 29);
- result = create(mOwner, item);
+ result = create(mOwner.data(), item);
verifyGoodResult(result);
item.insert("access-control-test", 30);
- result = update(mOwner, item);
+ result = update(mOwner.data(), item);
verifyGoodResult(result);
- result = remove(mOwner, item);
+ result = remove(mOwner.data(), item);
verifyGoodResult(result);
jsondbSettings->setEnforceAccessControl(false);
}
@@ -375,12 +374,12 @@ void TestJsonDb::testFindAccessControl()
JsonDbObject item;
item.insert(JsonDbString::kTypeStr, QLatin1String("find-access-control-test-type"));
item.insert("find-access-control-test", 50);
- JsonDbWriteResult result = create(mOwner, item);
+ JsonDbWriteResult result = create(mOwner.data(), item);
verifyGoodResult(result);
item.remove(JsonDbString::kUuidStr);
item.insert(JsonDbString::kTypeStr, QLatin1String("Contact"));
item.insert("find-access-control-test", 51);
- result = create(mOwner, item);
+ result = create(mOwner.data(), item);
verifyGoodResult(result);
QJsonObject contactsCapabilities;
@@ -390,12 +389,12 @@ void TestJsonDb::testFindAccessControl()
mOwner->setAllowAll(false);
mOwner->setCapabilities(contactsCapabilities, mJsonDbPartition);
- JsonDbQueryResult queryResult = find(mOwner, QString("[?%1=\"%2\"]").arg(JsonDbString::kTypeStr).arg("find-access-control-test-type"));
+ JsonDbQueryResult queryResult = find(mOwner.data(), QString("[?%1=\"%2\"]").arg(JsonDbString::kTypeStr).arg("find-access-control-test-type"));
verifyGoodQueryResult(queryResult);
QVERIFY(queryResult.length.toDouble() < 1);
- queryResult= find(mOwner, QString("[?%1=\"%2\"]").arg(JsonDbString::kTypeStr).arg("Contact"));
+ queryResult= find(mOwner.data(), QString("[?%1=\"%2\"]").arg(JsonDbString::kTypeStr).arg("Contact"));
verifyGoodQueryResult(queryResult);
QVERIFY(queryResult.length.toDouble() > 0);
@@ -405,13 +404,13 @@ void TestJsonDb::testFindAccessControl()
item.remove(JsonDbString::kUuidStr);
item.insert(JsonDbString::kTypeStr, QLatin1String("com.example.foo.bar.FooType"));
item.insert("find-access-control-test", 55);
- result = create(mOwner, item);
+ result = create(mOwner.data(), item);
verifyGoodResult(result);
item.remove(JsonDbString::kUuidStr);
item.insert(JsonDbString::kTypeStr, QLatin1String("com.example.foo.FooType"));
item.insert("find-access-control-test", 56);
- result = create(mOwner, item);
+ result = create(mOwner.data(), item);
verifyGoodResult(result);
mOwner->setOwnerId(QStringLiteral("com.example.foo.App"));
@@ -423,12 +422,12 @@ void TestJsonDb::testFindAccessControl()
mOwner->setAllowAll(false);
mOwner->setCapabilities(ownDomainCapabilities, mJsonDbPartition);
- queryResult = find(mOwner, QString("[?%1=\"%2\"]").arg(JsonDbString::kTypeStr).arg("com.example.foo.bar.FooType"));
+ queryResult = find(mOwner.data(), QString("[?%1=\"%2\"]").arg(JsonDbString::kTypeStr).arg("com.example.foo.bar.FooType"));
verifyGoodQueryResult(queryResult);
QVERIFY(queryResult.length.toDouble() < 1);
- queryResult= find(mOwner, QString("[?%1=\"%2\"]").arg(JsonDbString::kTypeStr).arg("com.example.foo.FooType"));
+ queryResult= find(mOwner.data(), QString("[?%1=\"%2\"]").arg(JsonDbString::kTypeStr).arg("com.example.foo.FooType"));
verifyGoodQueryResult(queryResult);
QVERIFY(queryResult.length.toDouble() > 0);
@@ -445,7 +444,7 @@ void TestJsonDb::testViewAccessControl()
QJsonArray defs(readJsonFile(":/security/json/capabilities-view.json").toArray());
for (int i = 0; i < defs.size(); ++i) {
JsonDbObject object(defs.at(i).toObject());
- JsonDbWriteResult result = create(mOwner, object);
+ JsonDbWriteResult result = create(mOwner.data(), object);
verifyGoodResult(result);
}
@@ -460,7 +459,7 @@ void TestJsonDb::testViewAccessControl()
defs = readJsonFile(":/security/json/view-test.json").toArray();
for (int i = 0; i < defs.size(); ++i) {
JsonDbObject object(defs.at(i).toObject());
- JsonDbWriteResult result = create(mOwner, object);
+ JsonDbWriteResult result = create(mOwner.data(), object);
verifyGoodResult(result);
}
@@ -474,48 +473,73 @@ void TestJsonDb::testViewAccessControl()
defs = readJsonFile(":/security/json/view-test2.json").toArray();
for (int i = 0; i < defs.size(); ++i) {
JsonDbObject object(defs.at(i).toObject());
- JsonDbWriteResult result = create(mOwner, object);
+ JsonDbWriteResult result = create(mOwner.data(), object);
verifyErrorResult(result);
}
}
-QStringList strings = (QStringList()
- << "abc"
- << "def"
- << "deaf"
- << "leaf"
- << "DEAF"
- << "LEAF"
- << "ghi"
- << "foo/bar");
-
-QStringList patterns = (QStringList()
- );
+/*
+ * Create Index objects and check access control
+ */
-QJsonValue TestJsonDb::readJsonFile(const QString& filename)
+void TestJsonDb::testIndexAccessControl()
{
- QString filepath = filename;
- QFile jsonFile(filepath);
- jsonFile.open(QIODevice::ReadOnly);
- QByteArray json = jsonFile.readAll();
- JsonReader parser;
- bool ok = parser.parse(json);
- if (!ok) {
- qDebug() << filepath << parser.errorString() << json;
+ jsondbSettings->setEnforceAccessControl(false);
+ QJsonArray defs(readJsonFile(":/security/json/capabilities-indexes.json").toArray());
+ for (int i = 0; i < defs.size(); ++i) {
+ JsonDbObject object(defs.at(i).toObject());
+ JsonDbWriteResult result = create(mOwner.data(), object);
+ verifyGoodResult(result);
}
- QVariant v = parser.result();
- return QJsonValue::fromVariant(v);
-}
-QJsonValue TestJsonDb::readJson(const QByteArray& json)
-{
- JsonReader parser;
- bool ok = parser.parse(json);
- if (!ok) {
- qDebug() << parser.errorString();
+ JsonDbWriteResult result;
+
+ defs = readJsonFile(":/security/json/index-test.json").toArray();
+ for (int i = 0; i < defs.size(); ++i) {
+ JsonDbObject object(defs.at(i).toObject());
+ result = create(mOwner.data(), object);
+ verifyGoodResult(result);
+ result = remove(mOwner.data(), object);
+ }
+
+ jsondbSettings->setEnforceAccessControl(true);
+ QJsonObject indexCapabilities;
+ QJsonArray value;
+ value.append (QLatin1String("rw"));
+ indexCapabilities.insert (QLatin1String("indexes"), value);
+ mOwner->setAllowAll(false);
+ mOwner->setCapabilities(indexCapabilities, mJsonDbPartition);
+
+ for (int i = 0; i < defs.size(); ++i) {
+ JsonDbObject object(defs.at(i).toObject());
+ result = create(mOwner.data(), object);
+ if (i<2){
+ verifyGoodResult(result);
+ result = remove(mOwner.data(), object);
+ } else {
+ // Third one should fail as there is no objectType given
+ verifyErrorResult(result);
+ }
+ }
+
+ QJsonObject indexCapabilities2;
+ QJsonArray value2;
+ value2.append (QLatin1String("rw"));
+ indexCapabilities2.insert (QLatin1String("noindexes"), value2);
+ mOwner->setAllowAll(false);
+ mOwner->setCapabilities(indexCapabilities2, mJsonDbPartition);
+
+ for (int i = 0; i < defs.size(); ++i) {
+ JsonDbObject object(defs.at(i).toObject());
+ result = create(mOwner.data(), object);
+ if (i<1){
+ verifyGoodResult(result);
+ result = remove(mOwner.data(), object);
+ } else {
+ // Second & Third should fail as there is no objectType given
+ verifyErrorResult(result);
+ }
}
- QVariant v = parser.result();
- return QJsonObject::fromVariantMap(v.toMap());
}
void TestJsonDb::notified(const QString nid, const JsonDbObject &o, const QString action)
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro
index dc243370..9d3ad2e2 100644
--- a/tests/auto/auto.pro
+++ b/tests/auto/auto.pro
@@ -1,7 +1,7 @@
TEMPLATE = subdirs
SUBDIRS = \
client \
- daemon \
+ partition \
accesscontrol \
qbtree \
jsondb-listmodel \
@@ -11,8 +11,9 @@ SUBDIRS = \
jsondbpartition \
jsondbnotification \
jsondbqueryobject \
- jsondbchangessinceobject \
queries \
+ qjsondbrequest \
qjsondbwatcher \
+ qjsondbflushrequest \
jsonstream \
hbtree
diff --git a/tests/auto/client/client.pro b/tests/auto/client/client.pro
index 8ea5097f..765bdbc1 100644
--- a/tests/auto/client/client.pro
+++ b/tests/auto/client/client.pro
@@ -5,7 +5,6 @@ CONFIG -= app_bundle
CONFIG += testcase
include($$PWD/../../shared/shared.pri)
-include($$PWD/../../../src/3rdparty/qjson/qjson.pri)
DEFINES += JSONDB_DAEMON_BASE=\\\"$$QT.jsondb.bins\\\"
DEFINES += SRCDIR=\\\"$$PWD/\\\"
@@ -15,3 +14,6 @@ NSS_PREFIX = $$(NSS_PREFIX)
DEFINES += NSS_PREFIX=\\\"$$NSS_PREFIX\\\"
SOURCES += test-jsondb-client.cpp
+
+OTHER_FILES += \
+ partitions.json
diff --git a/tests/auto/client/json/index-test.json b/tests/auto/client/json/index-test.json
index 102d85eb..5b4579ea 100644
--- a/tests/auto/client/json/index-test.json
+++ b/tests/auto/client/json/index-test.json
@@ -1,11 +1,13 @@
[
{
"_type": "Index",
+ "objectType": "com.test.indextest",
"propertyName": "test1",
"propertyType": "string"
},
{
"_type": "Index",
+ "objectType": "com.test.indextest",
"propertyName": "test2.nested",
"propertyType": "string"
},
diff --git a/tests/auto/client/partitions.json b/tests/auto/client/partitions.json
new file mode 100644
index 00000000..05222ec7
--- /dev/null
+++ b/tests/auto/client/partitions.json
@@ -0,0 +1,5 @@
+[
+ { "name" : "test-jsondb-client" },
+ { "name" : "com.example.autotest.Partition1" },
+ { "name" : "com.example.autotest.Partition2" }
+]
diff --git a/tests/auto/client/test-jsondb-client.cpp b/tests/auto/client/test-jsondb-client.cpp
index 81290c56..13d353a5 100644
--- a/tests/auto/client/test-jsondb-client.cpp
+++ b/tests/auto/client/test-jsondb-client.cpp
@@ -67,8 +67,6 @@
#include "jsondb-object.h"
#include "jsondb-error.h"
-#include "json.h"
-
#include "util.h"
#include "clientwrapper.h"
@@ -90,6 +88,8 @@ public:
private slots:
void initTestCase();
void cleanupTestCase();
+ void init();
+ void cleanup();
void connectionStatus();
@@ -248,7 +248,7 @@ void TestJsonDbClient::initTestCase()
arg_list << "-enforce-access-control";
arg_list << "-base-name";
arg_list << QString::fromLatin1(dbfileprefix);
- mProcess = launchJsonDbDaemonDetached(JSONDB_DAEMON_BASE, QString("testjsondb_%1").arg(getpid()), arg_list);
+ mProcess = launchJsonDbDaemonDetached(JSONDB_DAEMON_BASE, QString("testjsondb_%1").arg(getpid()), arg_list, __FILE__);
#endif
#if !defined(Q_OS_MAC)
if (wasRoot) {
@@ -256,7 +256,7 @@ void TestJsonDbClient::initTestCase()
JsonDbObject capa_obj;
capa_obj.insert(QLatin1String("_type"), QLatin1String("Capability"));
capa_obj.insert(QLatin1String("name"), QLatin1String("User"));
- capa_obj.insert(QLatin1String("partition"), QLatin1String(dbfileprefix) + QLatin1String(".System"));
+ capa_obj.insert(QLatin1String("partition"), QLatin1String("default"));
QVariantMap access_rules;
QVariantMap rw_rule;
rw_rule.insert(QLatin1String("read"), (QStringList() << QLatin1String("[*]")));
@@ -348,14 +348,7 @@ void TestJsonDbClient::initTestCase()
waitForResponse1(id);
// Add a schemaValidation tests object (must be done as root)
- QFile schemaFile(findFile("create-test.json"));
- schemaFile.open(QIODevice::ReadOnly);
- QByteArray json = schemaFile.readAll();
- schemaFile.close();
- JsonReader parser;
- bool ok = parser.parse(json);
- QVERIFY2(ok, parser.errorString().toLocal8Bit());
- QVariantMap schemaBody = parser.result().toMap();
+ QVariantMap schemaBody = readJsonFile(findFile("create-test.json")).toObject().toVariantMap();
//qDebug() << "schemaBody" << schemaBody;
QVariantMap schemaObject;
schemaObject.insert(JsonDbString::kTypeStr, JsonDbString::kSchemaTypeStr);
@@ -462,7 +455,6 @@ void TestJsonDbClient::initTestCase()
}
}
#endif
- connectToServer();
}
void TestJsonDbClient::cleanupTestCase()
@@ -516,6 +508,19 @@ void TestJsonDbClient::cleanupTestCase()
#endif
}
+void TestJsonDbClient::init()
+{
+ connectToServer();
+}
+
+void TestJsonDbClient::cleanup()
+{
+ if (mClient) {
+ delete mClient;
+ mClient = NULL;
+ }
+}
+
void TestJsonDbClient::connectionStatus()
{
JsonDbConnection *connection = new JsonDbConnection;
@@ -672,15 +677,15 @@ void TestJsonDbClient::update()
item[QLatin1String("name")] = QLatin1String("fail");
id = mClient->update(item1);
- // Should fail because of access control (error code 13)
- waitForResponse2(id, 13);
+ // Should fail because of access control
+ waitForResponse2(id, JsonDbError::OperationNotPermitted);
item1.insert(QLatin1String("_type"), QLatin1String("com.test.FooType"));
id = mClient->update(item1);
- // Should fail because of access control (error code 13)
+ // Should fail because of access control
// The new _type is ok, but the old _type is not
- waitForResponse2(id, 13);
+ waitForResponse2(id, JsonDbError::OperationNotPermitted);
}
}
@@ -785,14 +790,7 @@ void TestJsonDbClient::find()
void TestJsonDbClient::index()
{
- QFile dataFile(":/json/client/index-test.json");
- dataFile.open(QIODevice::ReadOnly);
- QByteArray json = dataFile.readAll();
- dataFile.close();
- JsonReader parser;
- bool ok = parser.parse(json);
- QVERIFY2(ok, parser.errorString().toLocal8Bit());
- QVariantList data = parser.result().toList();
+ QVariantList data = readJsonFile(":/json/client/index-test.json").toArray().toVariantList();
int id = mClient->create(data);
waitForResponse1(id);
@@ -1160,14 +1158,7 @@ void TestJsonDbClient::schemaValidation()
{
int id;
if (!wasRoot) {
- QFile schemaFile(findFile("create-test.json"));
- schemaFile.open(QIODevice::ReadOnly);
- QByteArray json = schemaFile.readAll();
- schemaFile.close();
- JsonReader parser;
- bool ok = parser.parse(json);
- QVERIFY2(ok, parser.errorString().toLocal8Bit());
- QVariantMap schemaBody = parser.result().toMap();
+ QVariantMap schemaBody = readJsonFile(findFile("create-test.json")).toObject().toVariantMap();
//qDebug() << "schemaBody" << schemaBody;
QVariantMap schemaObject;
schemaObject.insert(JsonDbString::kTypeStr, JsonDbString::kSchemaTypeStr);
@@ -1307,17 +1298,11 @@ void TestJsonDbClient::notifyMultiple()
void TestJsonDbClient::mapNotification()
{
- QFile jsonFile(":/json/auto/daemon/json/map-reduce.json");
- jsonFile.open(QIODevice::ReadOnly);
- QByteArray json = jsonFile.readAll();
- JsonReader parser;
- bool ok = parser.parse(json);
- QVERIFY(ok);
-
+ QVariantList list = readJsonFile(":/json/auto/partition/json/map-reduce.json").toArray().toVariantList();
QList<QVariantMap> mapsReduces;
QList<QVariantMap> schemas;
QMap<QString, QVariantMap> toDelete;
- waitForResponse1(mClient->create(parser.result().toList()));
+ waitForResponse1(mClient->create(list));
QVariantList created = mData.toList();
foreach (const QVariant &c, created) {
@@ -1406,9 +1391,6 @@ void TestJsonDbClient::changesSince()
QVariantList results(data["changes"].toList());
QCOMPARE(results.count(), 2);
- JsonWriter writer;
- //qDebug() << writer.toByteArray(results[0]);
- //qDebug() << writer.toByteArray(results[1]);
QVERIFY(results[0].toMap()["before"].toMap().isEmpty());
QVERIFY(results[1].toMap()["before"].toMap().isEmpty());
@@ -1590,24 +1572,7 @@ void TestJsonDbClient::partition()
const QString firstPartitionName = "com.example.autotest.Partition1";
const QString secondPartitionName = "com.example.autotest.Partition2";
- QVariantMap item;
- item.insert(JsonDbString::kTypeStr, "Partition");
- item.insert("name", firstPartitionName);
- id = mClient->create(item);
- waitForResponse1(id);
- QVERIFY(mData.toMap().contains("_uuid"));
- QVariant firstPartitionUuid = mData.toMap().value("_uuid");
-
- item = QVariantMap();
- item.insert(JsonDbString::kTypeStr, "Partition");
- item.insert("name", secondPartitionName);
- id = mClient->create(item);
- waitForResponse1(id);
- QVERIFY(mData.toMap().contains("_uuid"));
- QVariant secondPartitionUuid = mData.toMap().value("_uuid");
-
-
- item = QVariantMap();
+ QVariantMap item = QVariantMap();
item.insert(JsonDbString::kTypeStr, "Foobar");
item.insert("one", "one");
id = mClient->create(item, firstPartitionName);
@@ -1829,7 +1794,7 @@ void TestJsonDbClient::sigstop()
QStringList argList = QStringList() << "-sigstop";
argList << QString::fromLatin1("sigstop.db");
- QProcess *jsondb = launchJsonDbDaemon(JSONDB_DAEMON_BASE, QString("testjsondb_sigstop%1").arg(getpid()), argList);
+ QProcess *jsondb = launchJsonDbDaemon(JSONDB_DAEMON_BASE, QString("testjsondb_sigstop%1").arg(getpid()), argList, __FILE__);
int status;
::waitpid(jsondb->pid(), &status, WUNTRACED);
QVERIFY(WIFSTOPPED(status));
diff --git a/tests/auto/daemon/daemon.pro b/tests/auto/daemon/daemon.pro
deleted file mode 100644
index ec251ea2..00000000
--- a/tests/auto/daemon/daemon.pro
+++ /dev/null
@@ -1,17 +0,0 @@
-TARGET = tst_daemon
-CONFIG += debug
-
-QT = network qml testlib
-CONFIG -= app_bundle
-CONFIG += testcase
-
-INCLUDEPATH += $$PWD/../../../src/daemon
-LIBS += -L$$QT.jsondb.libs
-
-DEFINES += SRCDIR=\\\"$$PWD/\\\"
-
-include($$PWD/../../../src/daemon/daemon.pri)
-RESOURCES += json-validation.qrc daemon.qrc
-
-SOURCES += \
- testjsondb.cpp \
diff --git a/tests/auto/jsondb-listmodel/jsondb-listmodel.pro b/tests/auto/jsondb-listmodel/jsondb-listmodel.pro
index 07d4eafc..fceabaaf 100644
--- a/tests/auto/jsondb-listmodel/jsondb-listmodel.pro
+++ b/tests/auto/jsondb-listmodel/jsondb-listmodel.pro
@@ -8,7 +8,6 @@ CONFIG -= app_bundle
CONFIG += testcase
include($$PWD/../../shared/shared.pri)
-include($$PWD/../../../src/3rdparty/qjson/qjson.pri)
DEFINES += JSONDB_DAEMON_BASE=\\\"$$QT.jsondb.bins\\\"
DEFINES += SRCDIR=\\\"$$PWD/\\\"
diff --git a/tests/auto/jsondb-listmodel/test-jsondb-listmodel.cpp b/tests/auto/jsondb-listmodel/test-jsondb-listmodel.cpp
index 257b4323..f0ba021a 100644
--- a/tests/auto/jsondb-listmodel/test-jsondb-listmodel.cpp
+++ b/tests/auto/jsondb-listmodel/test-jsondb-listmodel.cpp
@@ -48,7 +48,6 @@
#include <QQmlComponent>
#include <QQmlContext>
#include <QDir>
-#include "json.h"
static const char dbfile[] = "dbFile-jsondb-listmodel";
ModelData::ModelData(): engine(0), component(0), model(0)
@@ -89,20 +88,6 @@ void TestJsonDbListModel::deleteDbFiles()
}
}
-QVariant TestJsonDbListModel::readJsonFile(const QString& filename)
-{
- QString filepath = findFile(filename);
- QFile jsonFile(filepath);
- jsonFile.open(QIODevice::ReadOnly);
- QByteArray json = jsonFile.readAll();
- JsonReader parser;
- bool ok = parser.parse(json);
- if (!ok) {
- qDebug() << filepath << parser.errorString();
- }
- return parser.result();
-}
-
void TestJsonDbListModel::connectListModel(JsonDbListModel *model)
{
connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(dataChanged(QModelIndex,QModelIndex)));
@@ -119,7 +104,7 @@ void TestJsonDbListModel::initTestCase()
deleteDbFiles();
QString socketName = QString("testjsondb_%1").arg(getpid());
- mProcess = launchJsonDbDaemon(JSONDB_DAEMON_BASE, socketName, QStringList() << "-base-name" << dbfile);
+ mProcess = launchJsonDbDaemon(JSONDB_DAEMON_BASE, socketName, QStringList() << "-base-name" << dbfile, __FILE__);
mClient = new JsonDbClient(this);
connect(mClient, SIGNAL(notified(QString,QtAddOn::JsonDb::JsonDbNotification)),
@@ -230,12 +215,13 @@ void TestJsonDbListModel::createItem()
waitForExitOrTimeout();
QCOMPARE(listModel->count(), 1);
+ mItemsCreated = 0;
item.insert("_type", __FUNCTION__);
item.insert("name", "Baker");
id = mClient->create(item);
waitForResponse1(id);
-
- waitForExitOrTimeout();;
+ if (!mItemsCreated)
+ waitForExitOrTimeout();;
QCOMPARE(listModel->count(), 2);
deleteModel(listModel);
}
@@ -382,10 +368,12 @@ void TestJsonDbListModel::deleteItem()
waitForExitOrTimeout();
QCOMPARE(listModel->rowCount(), 1);
+ mItemsCreated = 0;
item.insert("name", "Baker");
id = mClient->create(item);
waitForResponse1(id);
- waitForExitOrTimeout();
+ if (!mItemsCreated)
+ waitForExitOrTimeout();;
QCOMPARE(listModel->rowCount(), 2);
mWaitingForRowsRemoved = true;
@@ -677,7 +665,7 @@ void TestJsonDbListModel::totalRowCount()
void TestJsonDbListModel::listProperty()
{
- QVariant jsonData = readJsonFile("list-objects.json");
+ QVariant jsonData = readJsonFile(findFile("list-objects.json")).toVariant();
QVariantList itemList = jsonData.toList();
int id = 0;
for (int i = 0; i < itemList.count(); i++) {
diff --git a/tests/auto/jsondb-listmodel/test-jsondb-listmodel.h b/tests/auto/jsondb-listmodel/test-jsondb-listmodel.h
index 96813049..a9d699f6 100644
--- a/tests/auto/jsondb-listmodel/test-jsondb-listmodel.h
+++ b/tests/auto/jsondb-listmodel/test-jsondb-listmodel.h
@@ -114,7 +114,6 @@ private:
QStringList getOrderValues(const JsonDbListModel *listModel);
JsonDbListModel *createModel();
void deleteModel(JsonDbListModel *model);
- QVariant readJsonFile(const QString &filename);
private:
QProcess *mProcess;
diff --git a/tests/auto/jsondbcachinglistmodel/jsondbcachinglistmodel.pro b/tests/auto/jsondbcachinglistmodel/jsondbcachinglistmodel.pro
index eff7faa3..01e0ae4e 100644
--- a/tests/auto/jsondbcachinglistmodel/jsondbcachinglistmodel.pro
+++ b/tests/auto/jsondbcachinglistmodel/jsondbcachinglistmodel.pro
@@ -1,17 +1,20 @@
TEMPLATE = app
TARGET = tst_jsondbcachinglistmodel
DEPENDPATH += .
-INCLUDEPATH += .
+INCLUDEPATH += . ../../shared/
-QT = core network testlib gui qml jsondbcompat-private
+QT = core network testlib gui qml jsondb
CONFIG -= app_bundle
CONFIG += testcase
include($$PWD/../../shared/shared.pri)
-include($$PWD/../../../src/3rdparty/qjson/qjson.pri)
DEFINES += JSONDB_DAEMON_BASE=\\\"$$QT.jsondb.bins\\\"
DEFINES += SRCDIR=\\\"$$PWD/\\\"
-HEADERS += testjsondbcachinglistmodel.h
+HEADERS += testjsondbcachinglistmodel.h \
+ $$PWD/../../shared/requestwrapper.h
SOURCES += testjsondbcachinglistmodel.cpp
+
+OTHER_FILES += \
+ partitions.json
diff --git a/tests/auto/jsondbcachinglistmodel/partitions.json b/tests/auto/jsondbcachinglistmodel/partitions.json
new file mode 100644
index 00000000..1cdd0fa5
--- /dev/null
+++ b/tests/auto/jsondbcachinglistmodel/partitions.json
@@ -0,0 +1,4 @@
+[
+ { "name" :"com.nokia.shared.1" },
+ { "name" :"com.nokia.shared.2" }
+]
diff --git a/tests/auto/jsondbcachinglistmodel/testjsondbcachinglistmodel.cpp b/tests/auto/jsondbcachinglistmodel/testjsondbcachinglistmodel.cpp
index c11f048b..e7f534cd 100644
--- a/tests/auto/jsondbcachinglistmodel/testjsondbcachinglistmodel.cpp
+++ b/tests/auto/jsondbcachinglistmodel/testjsondbcachinglistmodel.cpp
@@ -45,7 +45,6 @@
#include "../../shared/util.h"
#include <QQmlListReference>
-#include "json.h"
static const char dbfile[] = "dbFile-jsondb-cached-listmodel";
ModelData::ModelData(): engine(0), component(0), model(0)
@@ -56,18 +55,8 @@ ModelData::~ModelData()
{
if (model)
delete model;
- if (partition1)
- delete partition1;
- if (partition2)
- delete partition2;
-
if (component)
delete component;
- if (partitionComponent1)
- delete partitionComponent1;
- if (partitionComponent2)
- delete partitionComponent2;
-
if (engine)
delete engine;
}
@@ -75,12 +64,15 @@ ModelData::~ModelData()
const QString qmlProgram = QLatin1String(
"import QtQuick 2.0 \n"
"import QtJsonDb 1.0 as JsonDb \n"
- "signal callbackSignal(variant index, variant response)"
- "function updateItemCallback(index, response) { callbackSignal( index, response); }");
-
+ "JsonDb.JsonDbCachingListModel {"
+ "id: contactsModel; cacheSize: 200;"
+ "partitions: ["
+ "JsonDb.Partition {name: \"com.nokia.shared.1\"},"
+ "JsonDb.Partition {name: \"com.nokia.shared.2\"}"
+ "]"
+ "}");
TestJsonDbCachingListModel::TestJsonDbCachingListModel()
- : mWaitingForNotification(false), mWaitingForDataChange(false), mWaitingForRowsRemoved(false)
{
}
@@ -97,26 +89,11 @@ void TestJsonDbCachingListModel::deleteDbFiles()
nameFilter << "objectFile.bin" << "objectFile2.bin";
QFileInfoList databaseFiles = currentDir.entryInfoList(nameFilter, QDir::Files);
foreach (QFileInfo fileInfo, databaseFiles) {
- //qDebug() << "Deleted : " << fileInfo.fileName();
QFile file(fileInfo.fileName());
file.remove();
}
}
-QVariant TestJsonDbCachingListModel::readJsonFile(const QString& filename)
-{
- QString filepath = findFile(filename);
- QFile jsonFile(filepath);
- jsonFile.open(QIODevice::ReadOnly);
- QByteArray json = jsonFile.readAll();
- JsonReader parser;
- bool ok = parser.parse(json);
- if (!ok) {
- qDebug() << filepath << parser.errorString();
- }
- return parser.result();
-}
-
void TestJsonDbCachingListModel::connectListModel(QAbstractListModel *model)
{
connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(dataChanged(QModelIndex,QModelIndex)));
@@ -135,31 +112,14 @@ void TestJsonDbCachingListModel::initTestCase()
deleteDbFiles();
QString socketName = QString("testjsondb_%1").arg(getpid());
- mProcess = launchJsonDbDaemon(JSONDB_DAEMON_BASE, socketName, QStringList() << "-base-name" << dbfile);
+ mProcess = launchJsonDbDaemon(JSONDB_DAEMON_BASE, socketName, QStringList() << "-base-name" << dbfile, __FILE__);
- mClient = new JsonDbClient(this);
- connect(mClient, SIGNAL(notified(QString,QtAddOn::JsonDb::JsonDbNotification)),
- this, SLOT(notified(QString,QtAddOn::JsonDb::JsonDbNotification)));
- connect( mClient, SIGNAL(response(int, const QVariant&)),
- this, SLOT(response(int, const QVariant&)));
- connect( mClient, SIGNAL(error(int, int, const QString&)),
- this, SLOT(error(int, int, const QString&)));
+ connection = new QJsonDbConnection();
+ connection->connectToServer();
mPluginPath = findQMLPluginPath("QtJsonDb");
-
- // Create the shared Partitions
- QVariantMap item;
- item.insert("_type", "Partition");
- item.insert("name", "com.nokia.shared.1");
- int id = mClient->create(item);
- waitForResponse1(id);
-
- item.clear();
- item.insert("_type", "Partition");
- item.insert("name", "com.nokia.shared.2");
- id = mClient->create(item);
- waitForResponse1(id);
-
+ if (mPluginPath.isEmpty())
+ qDebug() << "Couldn't find the plugin path for the plugin QtJsonDb";
}
QAbstractListModel *TestJsonDbCachingListModel::createModel()
@@ -173,37 +133,12 @@ QAbstractListModel *TestJsonDbCachingListModel::createModel()
return 0;
}
newModel->component = new QQmlComponent(newModel->engine);
- newModel->component->setData("import QtQuick 2.0\nimport QtJsonDb 1.0 as JsonDb \n"
- "JsonDb.JsonDbCachingListModel {signal callbackSignal(variant index, variant response); id: contactsModel; cacheSize: 200;}",
- QUrl());
+ newModel->component->setData(qmlProgram.toLocal8Bit(), QUrl());
+
newModel->model = newModel->component->create();
if (newModel->component->isError())
qDebug() << newModel->component->errors();
- QObject::connect(newModel->model, SIGNAL(callbackSignal(QVariant, QVariant)),
- this, SLOT(callbackSlot(QVariant, QVariant)));
-
- newModel->partitionComponent1 = new QQmlComponent(newModel->engine);
- newModel->partitionComponent1->setData("import QtQuick 2.0\nimport QtJsonDb 1.0 as JsonDb \n"
- "JsonDb.Partition {name: \"com.nokia.shared.1\"}",
- QUrl());
- newModel->partition1 = newModel->partitionComponent1->create();
- if (newModel->partitionComponent1->isError())
- qDebug() << newModel->partitionComponent1->errors();
-
-
- newModel->partitionComponent2 = new QQmlComponent(newModel->engine);
- newModel->partitionComponent2->setData("import QtQuick 2.0\nimport QtJsonDb 1.0 as JsonDb \n"
- "JsonDb.Partition {name: \"com.nokia.shared.2\"}",
- QUrl());
- newModel->partition2 = newModel->partitionComponent2->create();
- if (newModel->partitionComponent2->isError())
- qDebug() << newModel->partitionComponent2->errors();
-
- QQmlListReference partitions(newModel->model, "partitions", newModel->engine);
- partitions.append(newModel->partition1);
- partitions.append(newModel->partition2);
-
mModels.append(newModel);
return (QAbstractListModel*)(newModel->model);
}
@@ -230,26 +165,17 @@ void TestJsonDbCachingListModel::cleanupTestCase()
deleteDbFiles();
}
-void TestJsonDbCachingListModel::callbackSlot(QVariant error, QVariant response)
-{
- mCallbackReceived = true;
- callbackError = error.isValid();
- callbackMeta = response;
- callbackResponse = response.toMap().value("object");
- mEventLoop.quit();
-}
-
-void TestJsonDbCachingListModel::getIndex(int index)
+QVariant TestJsonDbCachingListModel::getIndex(QAbstractListModel *model, int index, int role)
{
- mCallbackReceived = false;
-
- const QString createString = QString("get(%1, function (error, response) {callbackSignal(error, response);});");
- const QString getString = QString(createString).arg(index);
- QQmlExpression expr(mModels.last()->engine->rootContext(), mModels.last()->model, getString);
- expr.evaluate().toInt();
-
- if (!mCallbackReceived)
- waitForCallback();
+ mWaitingForIndexChanged = true;
+ mWaitingForChanged = false;
+ mIndexWaited = index;
+ QVariant val = model->data(model->index(index), role);
+ while (!val.isValid()) {
+ waitForIndexChanged();
+ val = model->data(model->index(index), role);
+ }
+ return val;
}
int indexOf(QObject* object, const QString &uuid)
@@ -269,21 +195,21 @@ void TestJsonDbCachingListModel::createIndex(const QString &property, const QStr
item.insert("propertyName", property);
item.insert("propertyType", propertyType);
- int id = mClient->create(item, "com.nokia.shared.1");
+ int id = create(item, "com.nokia.shared.1");
waitForResponse1(id);
- id = mClient->create(item, "com.nokia.shared.2");
+ id = create(item, "com.nokia.shared.2");
waitForResponse1(id);
}
-
// Create items in the model.
void TestJsonDbCachingListModel::createItem()
{
+ resetWaitFlags();
QVariantMap item;
item.insert("_type", __FUNCTION__);
item.insert("name", "Arnie");
- int id = mClient->create(item, "com.nokia.shared.1");
+ int id = create(item, "com.nokia.shared.1");
waitForResponse1(id);
createIndex("name", "string");
@@ -301,25 +227,36 @@ void TestJsonDbCachingListModel::createItem()
// now start it working
QCOMPARE(listModel->rowCount(), 0);
- waitForStateOrTimeout();
+ mWaitingForReset = true;
+ waitForExitOrTimeout();
+ QCOMPARE(mWaitingForReset, false);
+
QCOMPARE(listModel->rowCount(), 1);
QCOMPARE(listModel->property("cacheSize").toInt(), 200);
- getIndex(0);
- QCOMPARE(callbackResponse.toMap().value("_type").toString(), QLatin1String(__FUNCTION__));
- QCOMPARE(callbackResponse.toMap().value("name").toString(), QLatin1String("Arnie"));
+ QVariant val = getIndex(listModel, 0, 0);
+ QCOMPARE(val.toString(), QLatin1String(__FUNCTION__));
+ val = getIndex(listModel, 0, 2);
+ QCOMPARE(val.toString(), QLatin1String("Arnie"));
item.clear();
item.insert("_type", __FUNCTION__);
item.insert("name", "Barney");
- id = mClient->create(item, "com.nokia.shared.1");
- waitForItemChanged();
+ mItemsCreated = 0;
+ id = create(item, "com.nokia.shared.1");
+ waitForResponse1(id);
+ while (!mItemsCreated) {
+ mWaitingForRowsInserted = true;
+ waitForExitOrTimeout();
+ }
+ QCOMPARE(mWaitingForRowsInserted, false);
QCOMPARE(listModel->rowCount(), 2);
- getIndex(1);
- QCOMPARE(callbackResponse.toMap().value("_type").toString(), QLatin1String(__FUNCTION__));
- QCOMPARE(callbackResponse.toMap().value("name").toString(), QLatin1String("Barney"));
+ val = getIndex(listModel, 1, 0);
+ QCOMPARE(val.toString(), QLatin1String(__FUNCTION__));
+ val = getIndex(listModel, 1, 2);
+ QCOMPARE(val.toString(), QLatin1String("Barney"));
deleteModel(listModel);
}
@@ -327,132 +264,171 @@ void TestJsonDbCachingListModel::createItem()
// Populate model of 300 items two partitions.
void TestJsonDbCachingListModel::createModelTwoPartitions()
{
+ resetWaitFlags();
QVariantMap item;
for (int i=0; i < 300; i = i+2) {
item.insert("_type", __FUNCTION__);
item.insert("name", QString("Arnie_%1").arg(i));
- int id = mClient->create(item, "com.nokia.shared.1");
+ int id = create(item, "com.nokia.shared.1");
waitForResponse1(id);
}
for (int i=1; i < 300; i = i+2) {
item.insert("_type", __FUNCTION__);
item.insert("name", QString("Arnie_%1").arg(i));
- int id = mClient->create(item, "com.nokia.shared.2");
+ int id = create(item, "com.nokia.shared.2");
waitForResponse1(id);
}
- createIndex("name", "string");
-
QAbstractListModel *listModel = createModel();
if (!listModel) return;
QStringList roleNames = (QStringList() << "_type" << "_uuid" << "name");
listModel->setProperty("roleNames", roleNames);
+ listModel->setProperty("sortOrder", "[/name]");
+ listModel->setProperty("cacheSize", 50);
listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__));
connectListModel(listModel);
// now start it working
QCOMPARE(listModel->rowCount(), 0);
- waitForStateOrTimeout();
+ mWaitingForReset = true;
+ waitForExitOrTimeout();
+ QCOMPARE(mWaitingForReset, false);
QCOMPARE(listModel->rowCount(), 300);
deleteModel(listModel);
}
-
-
// Create an item and then update it.
void TestJsonDbCachingListModel::updateItemClient()
{
+ resetWaitFlags();
QVariantMap item;
item.insert("_type", __FUNCTION__);
item.insert("name", "Charlie");
- int id = mClient->create(item,"com.nokia.shared.1");
+ int id = create(item,"com.nokia.shared.1");
waitForResponse1(id);
QAbstractListModel *listModel = createModel();
if (!listModel) return;
- listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__));
QStringList roleNames = (QStringList() << "_type" << "_uuid" << "name");
listModel->setProperty("roleNames", roleNames);
+ listModel->setProperty("sortOrder", "[/name]");
+ listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__));
connectListModel(listModel);
// now start it working
QCOMPARE(listModel->rowCount(), 0);
- waitForStateOrTimeout();
- QCOMPARE(listModel->rowCount(), 1);
+ mWaitingForReset = true;
+ waitForExitOrTimeout();
+ QCOMPARE(mWaitingForReset, false);
- getIndex(0);
- QCOMPARE(callbackResponse.toMap().value("_type").toString(), QLatin1String(__FUNCTION__));
- QCOMPARE(callbackResponse.toMap().value("name").toString(), QLatin1String("Charlie"));
+ QCOMPARE(listModel->rowCount(), 1);
- item.insert("_uuid", mLastUuid);
+ QVariant val = getIndex(listModel, 0, 0);
+ QCOMPARE(val.toString(), QLatin1String(__FUNCTION__));
+ val = getIndex(listModel, 0, 2);
+ QCOMPARE(val.toString(), QLatin1String("Charlie"));
+
+ QString lastUuid,lastVersion;
+ QVariantMap lastItem;
+ if (lastResult.count()) {
+ lastItem = lastResult[0].toMap();
+ lastUuid = lastItem.value("_uuid").toString();
+ lastVersion = lastItem.value("_version").toString();
+ }
+ item.insert("_uuid", lastUuid);
item.insert("name", "Baker");
- mWaitingForDataChange = true;
-
- id = mClient->update(item, "com.nokia.shared.1");
- waitForItemChanged();
+ mItemsUpdated = 0;
+ id = update(item, "com.nokia.shared.1");
+ waitForResponse1(id);
+ while (!mItemsUpdated) {
+ mWaitingForChanged = true;
+ waitForExitOrTimeout();
+ }
QCOMPARE(listModel->rowCount(), 1);
- getIndex(0);
- QCOMPARE(callbackResponse.toMap().value("_type").toString(), QLatin1String(__FUNCTION__));
- QCOMPARE(callbackResponse.toMap().value("name").toString(), QLatin1String("Baker"));
+ val = getIndex(listModel, 0, 0);
+ QCOMPARE(val.toString(), QLatin1String(__FUNCTION__));
+ val = getIndex(listModel, 0, 2);
+ QCOMPARE(val.toString(), QLatin1String("Baker"));
deleteModel(listModel);
}
void TestJsonDbCachingListModel::deleteItem()
{
+ resetWaitFlags();
QVariantMap item;
item.insert("_type", __FUNCTION__);
item.insert("name", "Charlie");
- int id = mClient->create(item, "com.nokia.shared.1");
+ int id = create(item, "com.nokia.shared.1");
waitForResponse1(id);
QAbstractListModel *listModel = createModel();
if (!listModel) return;
- listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__));
QStringList roleNames = (QStringList() << "_type" << "_uuid" << "name");
listModel->setProperty("roleNames", roleNames);
+ listModel->setProperty("sortOrder", "[/name]");
+ listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__));
connectListModel(listModel);
// now start it working
- waitForStateOrTimeout();
+ mWaitingForReset = true;
+ waitForExitOrTimeout();
+ QCOMPARE(mWaitingForReset, false);
+
QCOMPARE(listModel->rowCount(), 1);
item.insert("name", "Baker");
- id = mClient->create(item, "com.nokia.shared.2");
+ mItemsCreated = 0;
+ id = create(item, "com.nokia.shared.2");
waitForResponse1(id);
+ waitForItemsCreated(1);
QCOMPARE(listModel->rowCount(), 2);
- mWaitingForRowsRemoved = true;
- item.insert("_uuid", mLastUuid);
- id = mClient->remove(item, "com.nokia.shared.2");
- waitForItemChanged(true);
+ QString lastUuid,lastVersion;
+ QVariantMap lastItem;
+ if (lastResult.count()) {
+ lastItem = lastResult[0].toMap();
+ lastUuid = lastItem.value("_uuid").toString();
+ lastVersion = lastItem.value("_version").toString();
+ }
+ item.insert("_uuid", lastUuid);
+ mItemsRemoved = 0;
+ id = remove(item, "com.nokia.shared.2");
+ waitForResponse1(id);
+ while (!mItemsRemoved) {
+ mWaitingForRemoved = true;
+ waitForExitOrTimeout();
+ }
+ QCOMPARE(mWaitingForRemoved, false);
QCOMPARE(listModel->rowCount(), 1);
- getIndex(0);
- QCOMPARE(callbackResponse.toMap().value("_type").toString(), QLatin1String(__FUNCTION__));
- QCOMPARE(callbackResponse.toMap().value("name").toString(), QLatin1String("Charlie"));
+ QVariant val = getIndex(listModel, 0, 0);
+ QCOMPARE(val.toString(), QLatin1String(__FUNCTION__));
+ val = getIndex(listModel, 0, 2);
+ QCOMPARE(val.toString(), QLatin1String("Charlie"));
deleteModel(listModel);
}
void TestJsonDbCachingListModel::sortedQuery()
{
+ resetWaitFlags();
int id = 0;
for (int i = 0; i < 1000; i++) {
QVariantMap item;
item.insert("_type", "RandNumber");
item.insert("number", i);
- id = mClient->create(item,"com.nokia.shared.2");
+ id = create(item,"com.nokia.shared.2");
waitForResponse1(id);
}
@@ -467,27 +443,32 @@ void TestJsonDbCachingListModel::sortedQuery()
rolenames << "_uuid" << "_type" << "number";
listModel->setProperty("roleNames", rolenames);
listModel->setProperty("sortOrder", "[/number]");
+ listModel->setProperty("cacheSize", 100);
listModel->setProperty("query", "[?_type=\"RandNumber\"]");
- waitForStateOrTimeout();
+ mWaitingForReset = true;
+ waitForExitOrTimeout();
+ QCOMPARE(mWaitingForReset, false);
- QCOMPARE(listModel->property("sortOrder").toString(), QString("[/number]"));
QCOMPARE(listModel->rowCount(), 1000);
+
for (int i = 0; i < 1000; i++) {
- getIndex(i);
- QCOMPARE(callbackResponse.toMap().value("number").toInt(), i);
+ QVariant num = getIndex(listModel, i, 2);
+ QCOMPARE(num.toInt(), i);
}
listModel->setProperty("sortOrder", "[\\number]");
- waitForStateOrTimeout();
+ mWaitingForReset = true;
+ waitForExitOrTimeout();
+ QCOMPARE(mWaitingForReset, false);
QCOMPARE(listModel->property("sortOrder").toString(), QString("[\\number]"));
QCOMPARE(listModel->rowCount(), 1000);
for (int i = 0; i < 1000; i++) {
- getIndex(i);
- QCOMPARE(callbackResponse.toMap().value("number").toInt(), 999-i);
+ QVariant num = getIndex(listModel, i, 2);
+ QCOMPARE(num.toInt(), 999-i);
}
listModel->setProperty("query", QString());
@@ -509,12 +490,13 @@ bool greaterThan(const QString &s1, const QString &s2)
void TestJsonDbCachingListModel::ordering()
{
+ resetWaitFlags();
for (int i = 9; i >= 1; --i) {
QVariantMap item;
item.insert("_type", __FUNCTION__);
item.insert("name", "Charlie");
item.insert("ordering", QString::number(i));
- int id = mClient->create(item, "com.nokia.shared.2");
+ int id = create(item, "com.nokia.shared.2");
waitForResponse1(id);
}
@@ -524,22 +506,24 @@ void TestJsonDbCachingListModel::ordering()
createIndex("ordering", "string");
listModel->setProperty("sortOrder", "[/ordering]");
- listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__));
QStringList roleNames = (QStringList() << "_type" << "_uuid" << "name" << "ordering");
listModel->setProperty("roleNames", roleNames);
+ listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__));
connectListModel(listModel);
// now start it working
QCOMPARE(listModel->rowCount(), 0);
- waitForStateOrTimeout();
+ mWaitingForReset = true;
+ waitForExitOrTimeout();
+ QCOMPARE(mWaitingForReset, false);
+ mItemsUpdated = 0;
QStringList expectedOrder = QStringList() << "1" << "2" << "3" << "4" <<
"5" << "6" << "7" << "8" << "9";
QCOMPARE(getOrderValues(listModel), expectedOrder);
{
- getIndex(4);
- QVariant uuid = callbackResponse.toMap().value("_uuid");
+ QVariant uuid = getIndex(listModel, 4, 1);
QVERIFY(!uuid.toString().isEmpty());
QVariantMap item;
@@ -547,16 +531,22 @@ void TestJsonDbCachingListModel::ordering()
item.insert("_type", __FUNCTION__);
item.insert("name", "Charlie");
item.insert("ordering", "99"); // move it to the end
- mClient->update(item, "com.nokia.shared.2");
+ int id = update(item, "com.nokia.shared.2");
+ waitForResponse1(id);
}
- waitForItemChanged();
+ while (!mItemsUpdated) {
+ mWaitingForChanged = true;
+ waitForExitOrTimeout();
+ }
+ QCOMPARE(mWaitingForChanged, false);
+
+ mItemsUpdated = 0;
expectedOrder = QStringList() << "1" << "2" << "3" <<
"4" << "6" << "7" << "8" << "9" << "99";
QCOMPARE(getOrderValues(listModel), expectedOrder);
{
- getIndex(8);
- QVariant uuid =callbackResponse.toMap().value("_uuid");
+ QVariant uuid = getIndex(listModel, 8, 1);
QVERIFY(!uuid.toString().isEmpty());
QVariantMap item;
@@ -564,16 +554,21 @@ void TestJsonDbCachingListModel::ordering()
item.insert("_type", __FUNCTION__);
item.insert("name", "Charlie");
item.insert("ordering", "22"); // move it after "2"
- mClient->update(item, "com.nokia.shared.2");
+ int id = update(item, "com.nokia.shared.2");
+ waitForResponse1(id);
+ }
+ while (!mItemsUpdated) {
+ mWaitingForChanged = true;
+ waitForExitOrTimeout();
}
- waitForItemChanged();
+ QCOMPARE(mWaitingForChanged, false);
+ mItemsUpdated = 0;
expectedOrder = QStringList() << "1" << "2" << "22" << "3" <<
"4" << "6" << "7" << "8" << "9";
QCOMPARE(getOrderValues(listModel), expectedOrder);
{
- getIndex(5);
- QVariant uuid =callbackResponse.toMap().value("_uuid");
+ QVariant uuid = getIndex(listModel, 5, 1);
QVERIFY(!uuid.toString().isEmpty());
QVariantMap item;
@@ -581,9 +576,14 @@ void TestJsonDbCachingListModel::ordering()
item.insert("_type", __FUNCTION__);
item.insert("name", "Charlie");
item.insert("ordering", "0"); // move it to the beginning
- mClient->update(item, "com.nokia.shared.2");
+ int id = update(item, "com.nokia.shared.2");
+ waitForResponse1(id);
+ }
+ while (!mItemsUpdated) {
+ mWaitingForChanged = true;
+ waitForExitOrTimeout();
}
- waitForItemChanged();
+ QCOMPARE(mWaitingForChanged, false);
expectedOrder = QStringList() << "0" << "1" << "2" << "22" << "3" <<
"4" << "7" << "8" << "9";
@@ -591,7 +591,9 @@ void TestJsonDbCachingListModel::ordering()
listModel->setProperty("sortOrder", "[\\ordering]");
- waitForStateOrTimeout();
+ mWaitingForReset = true;
+ waitForExitOrTimeout();
+ QCOMPARE(mWaitingForReset, false);
QStringList reverseOrder = expectedOrder;
qSort(reverseOrder.begin(), reverseOrder.end(), greaterThan);
@@ -599,17 +601,18 @@ void TestJsonDbCachingListModel::ordering()
QCOMPARE(getOrderValues(listModel), reverseOrder);
listModel->setProperty("sortOrder", "[/ordering]");
- waitForStateOrTimeout();
-
+ mWaitingForReset = true;
+ waitForExitOrTimeout();
+ QCOMPARE(mWaitingForReset, false);
QCOMPARE(getOrderValues(listModel), expectedOrder);
deleteModel(listModel);
-
}
void TestJsonDbCachingListModel::checkRemoveNotification()
{
+ resetWaitFlags();
QVariantList itemList;
for (int i = 0; i < 50; i++) {
QVariantMap item;
@@ -618,7 +621,7 @@ void TestJsonDbCachingListModel::checkRemoveNotification()
item.insert("order", i);
itemList << item;
}
- int id = mClient->create(itemList,"com.nokia.shared.2");
+ int id = create(itemList,"com.nokia.shared.2");
waitForResponse1(id);
{
@@ -629,56 +632,63 @@ void TestJsonDbCachingListModel::checkRemoveNotification()
connectListModel(listModel);
listModel->setProperty("sortOrder", "[/order]");
- listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__));
QStringList roleNames = (QStringList() << "_type" << "_uuid" << "_version"<< "name" << "order");
listModel->setProperty("roleNames", roleNames);
+ listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__));
- waitForStateOrTimeout();
+ mWaitingForReset = true;
+ waitForExitOrTimeout();
+ QCOMPARE(mWaitingForReset, false);
QCOMPARE(listModel->rowCount(), 50);
- getIndex(0);
- QVariant result = callbackResponse.toMap().value("order");
+ QVariant result = getIndex(listModel, 0, 4);
QVERIFY(result.isValid());
QCOMPARE(result.toInt(), 0);
- getIndex(9);
- result = callbackResponse.toMap().value("order");
+ result = getIndex(listModel, 9, 4);
QVERIFY(result.isValid());
QCOMPARE(result.toInt(), 9);
//Remove item at 0
QVariantMap item;
- getIndex(0);
- item.insert("_uuid", callbackResponse.toMap().value("_uuid"));
- item.insert("_version", callbackResponse.toMap().value("_version"));
- id = mClient->remove(item, "com.nokia.shared.2");
- waitForItemChanged(true);
+ QVariant uuid = getIndex(listModel, 0, 1);
+ item.insert("_uuid", uuid);
+ QVariant version = getIndex(listModel, 0, 2);
+ item.insert("_version", version);
+ mItemsRemoved = 0;
+ id = remove(item, "com.nokia.shared.2");
+ waitForResponse1(id);
+ waitForItemsRemoved(1);
QCOMPARE(listModel->rowCount(), 49);
- getIndex(9);
- result = callbackResponse.toMap().value("order");
+
+ result = getIndex(listModel, 9, 4);
QVERIFY(result.isValid());
QCOMPARE(result.toInt(), 10);
//Remove item at 9
- getIndex(9);
- item.insert("_uuid", callbackResponse.toMap().value("_uuid"));
- item.insert("_version", callbackResponse.toMap().value("_version"));
- id = mClient->remove(item, "com.nokia.shared.2");
- waitForItemChanged(true);
+ uuid = getIndex(listModel, 9, 1);
+ item.insert("_uuid", uuid);
+ version = getIndex(listModel, 9, 2);
+ item.insert("_version", version);
+ mItemsRemoved = 0;
+ id = remove(item, "com.nokia.shared.2");
+ waitForResponse1(id);
+ waitForItemsRemoved(1);
QCOMPARE(listModel->rowCount(), 48);
- getIndex(9);
- result = callbackResponse.toMap().value("order");
+ result = getIndex(listModel, 9, 4);
QVERIFY(result.isValid());
QCOMPARE(result.toInt(), 11);
//Remove item at 4
- getIndex(4);
- item.insert("_uuid", callbackResponse.toMap().value("_uuid"));
- item.insert("_version", callbackResponse.toMap().value("_version"));
- id = mClient->remove(item, "com.nokia.shared.2");
- waitForItemChanged(true);
+ uuid = getIndex(listModel, 4, 1);
+ item.insert("_uuid", uuid);
+ version = getIndex(listModel, 9, 2);
+ item.insert("_version", version);
+ mItemsRemoved = 0;
+ id = remove(item, "com.nokia.shared.2");
+ waitForResponse1(id);
+ waitForItemsRemoved(1);
QCOMPARE(listModel->rowCount(), 47);
- getIndex(4);
- result = callbackResponse.toMap().value("order");
+ result = getIndex(listModel, 4, 4);
QVERIFY(result.isValid());
QCOMPARE(result.toInt(), 6);
@@ -688,6 +698,7 @@ void TestJsonDbCachingListModel::checkRemoveNotification()
void TestJsonDbCachingListModel::checkUpdateNotification()
{
+ resetWaitFlags();
QVariantList itemList;
for (int i = 0; i < 50; i++) {
if (i%2)
@@ -698,7 +709,7 @@ void TestJsonDbCachingListModel::checkUpdateNotification()
item.insert("order", i);
itemList << item;
}
- int id = mClient->create(itemList, "com.nokia.shared.1");
+ int id = create(itemList, "com.nokia.shared.1");
waitForResponse1(id);
{
@@ -713,106 +724,138 @@ void TestJsonDbCachingListModel::checkUpdateNotification()
listModel->setProperty("roleNames", roleNames);
listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__));
- waitForStateOrTimeout();
+ mWaitingForReset = true;
+ waitForExitOrTimeout();
+ QCOMPARE(mWaitingForReset, false);
QCOMPARE(listModel->rowCount(), 25);
- getIndex(0);
- QVariant result = callbackResponse.toMap().value("order");
+ QVariant result = getIndex(listModel, 0, 4);
QVERIFY(result.isValid());
QCOMPARE(result.toInt(), 0);
- getIndex(9);
- result = callbackResponse.toMap().value("order");
+ result = getIndex(listModel, 9, 4);
QVERIFY(result.isValid());
QCOMPARE(result.toInt(), 18);
//Update item at 0
QVariantMap item;
- getIndex(0);
- item.insert("_uuid", callbackResponse.toMap().value("_uuid"));
- item.insert("_type", callbackResponse.toMap().value("_type"));
- item.insert("name", callbackResponse.toMap().value("name"));
+ QVariant uuid = getIndex(listModel, 0, 1);
+ item.insert("_uuid", uuid);
+ QVariant _type = getIndex(listModel, 0, 0);
+ item.insert("_type", _type);
+ QVariant _version = getIndex(listModel, 0, 2);
+ item.insert("_version", _version);
+ QVariant name = getIndex(listModel, 0, 3);
+ item.insert("name", name);
item.insert("order", 1);
- id = mClient->update(item, "com.nokia.shared.1");
- waitForItemChanged();
+ mItemsUpdated = 0;
+ id = update(item, "com.nokia.shared.1");
+ waitForResponse1(id);
+ while (!mItemsUpdated) {
+ mWaitingForChanged = true;
+ waitForExitOrTimeout();
+ }
QCOMPARE(listModel->rowCount(), 25);
- getIndex(0);
- result = callbackResponse.toMap().value("order");
+ result = getIndex(listModel, 0, 4);
QVERIFY(result.isValid());
QCOMPARE(result.toInt(), 1);
- getIndex(9);
- result = callbackResponse.toMap().value("order");
+ result = getIndex(listModel, 9, 4);
QVERIFY(result.isValid());
QCOMPARE(result.toInt(), 18);
//Update item at 9
item.clear();
- getIndex(9);
- item.insert("_uuid", callbackResponse.toMap().value("_uuid"));
- item.insert("_type", callbackResponse.toMap().value("_type"));
- item.insert("name", callbackResponse.toMap().value("name"));
+ uuid = getIndex(listModel, 9, 1);
+ item.insert("_uuid", uuid);
+ _type = getIndex(listModel, 9, 0);
+ item.insert("_type", _type);
+ _version = getIndex(listModel, 9, 2);
+ item.insert("_version", _version);
+ name = getIndex(listModel, 9, 3);
+ item.insert("name", name);
item.insert("order", 19);
- id = mClient->update(item,"com.nokia.shared.1");
- waitForItemChanged();
+ mItemsUpdated = 0;
+ id = update(item,"com.nokia.shared.1");
+ waitForResponse1(id);
+ while (!mItemsUpdated) {
+ mWaitingForChanged = true;
+ waitForExitOrTimeout();
+ }
item.clear();
- getIndex(9);
- item.insert("_uuid", callbackResponse.toMap().value("_uuid"));
- item.insert("_type", callbackResponse.toMap().value("_type"));
- item.insert("name", callbackResponse.toMap().value("name"));
+ uuid = getIndex(listModel, 9, 1);
+ item.insert("_uuid", uuid);
+ _type = getIndex(listModel, 9, 0);
+ item.insert("_type", _type);
+ name = getIndex(listModel, 9, 3);
+ item.insert("name", name);
+ _version = getIndex(listModel, 9, 2);
+ item.insert("_version", _version);
item.insert("order", 19);
- id = mClient->update(item,"com.nokia.shared.1");
- waitForItemChanged();
+ mItemsUpdated = 0;
+ id = update(item,"com.nokia.shared.1");
+ waitForResponse1(id);
+ while (!mItemsUpdated) {
+ mWaitingForChanged = true;
+ waitForExitOrTimeout();
+ }
QCOMPARE(listModel->rowCount(), 25);
- getIndex(0);
- result = callbackResponse.toMap().value("order");
+ result = getIndex(listModel, 0, 4);
QVERIFY(result.isValid());
QCOMPARE(result.toInt(), 1);
- getIndex(9);
- result = callbackResponse.toMap().value("order");
+ result = getIndex(listModel, 9, 4);
QVERIFY(result.isValid());
QCOMPARE(result.toInt(), 19);
//Update item at 9
- getIndex(9);
- item.insert("_uuid", callbackResponse.toMap().value("_uuid"));
- item.insert("_type", callbackResponse.toMap().value("_type"));
- item.insert("name", callbackResponse.toMap().value("name"));
+ item.clear();
+ uuid = getIndex(listModel, 9, 1);
+ item.insert("_uuid", uuid);
+ _type = getIndex(listModel, 9, 0);
+ item.insert("_type", _type);
+ name = getIndex(listModel, 9, 3);
+ item.insert("name", name);
item.insert("order", 59);
- id = mClient->update(item, "com.nokia.shared.1");
- waitForItemChanged();
-
+ mItemsUpdated = 0;
+ id = update(item, "com.nokia.shared.1");
+ waitForResponse1(id);
+ while (!mItemsUpdated) {
+ mWaitingForChanged = true;
+ waitForExitOrTimeout();
+ }
QCOMPARE(listModel->rowCount(), 25);
- getIndex(0);
- result = callbackResponse.toMap().value("order");
+ result = getIndex(listModel, 0, 4);
QVERIFY(result.isValid());
QCOMPARE(result.toInt(), 1);
- getIndex(9);
- result = callbackResponse.toMap().value("order");
+ result = getIndex(listModel, 9, 4);
QVERIFY(result.isValid());
QCOMPARE(result.toInt(), 20);
//Update item at 8
- getIndex(8);
- item.insert("_uuid", callbackResponse.toMap().value("_uuid"));
- item.insert("_type", callbackResponse.toMap().value("_type"));
- item.insert("name", callbackResponse.toMap().value("name"));
+ item.clear();
+ uuid = getIndex(listModel, 8, 1);
+ item.insert("_uuid", uuid);
+ _type = getIndex(listModel, 8, 0);
+ item.insert("_type", _type);
+ name = getIndex(listModel, 8, 3);
+ item.insert("name", name);
item.insert("order", 17);
- id = mClient->update(item, "com.nokia.shared.1");
- waitForItemChanged();
-
+ mItemsUpdated = 0;
+ id = update(item, "com.nokia.shared.1");
+ waitForResponse1(id);
+ while (!mItemsUpdated) {
+ mWaitingForChanged = true;
+ waitForExitOrTimeout();
+ }
QCOMPARE(listModel->rowCount(), 25);
- getIndex(8);
- result = callbackResponse.toMap().value("order");
+ result = getIndex(listModel, 8, 4);
QVERIFY(result.isValid());
QCOMPARE(result.toInt(), 17);
- getIndex(0);
- result = callbackResponse.toMap().value("order");
+ result = getIndex(listModel, 0, 4);
QVERIFY(result.isValid());
QCOMPARE(result.toInt(), 1);
- getIndex(9);
- result = callbackResponse.toMap().value("order");
+ result = getIndex(listModel, 9, 4);
QVERIFY(result.isValid());
QCOMPARE(result.toInt(), 20);
@@ -822,15 +865,16 @@ void TestJsonDbCachingListModel::checkUpdateNotification()
void TestJsonDbCachingListModel::totalRowCount()
{
+ resetWaitFlags();
int id = 0;
QVariantList insertedItems;
for (int i = 0; i < 10; i++) {
QVariantMap item;
item.insert("_type", __FUNCTION__);
item.insert("order", i);
- id = mClient->create(item, "com.nokia.shared.1");
+ id = create(item, "com.nokia.shared.1");
waitForResponse1(id);
- insertedItems << mData;
+ insertedItems << lastResult;
}
QAbstractListModel *listModel = createModel();
@@ -839,55 +883,120 @@ void TestJsonDbCachingListModel::totalRowCount()
connectListModel(listModel);
- listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__));
QStringList roleNames = (QStringList() << "_type" << "_uuid" << "order");
listModel->setProperty("roleNames", roleNames);
+ listModel->setProperty("sortOrder", "[/order]");
+ listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__));
- waitForStateOrTimeout();
+ mWaitingForReset = true;
+ waitForExitOrTimeout();
+ QCOMPARE(mWaitingForReset, false);
QCOMPARE(listModel->rowCount(), 10);
+ mItemsCreated = 0;
for (int i = 10; i < 50; i++) {
QVariantMap item;
item.insert("_type", __FUNCTION__);
item.insert("order", i);
- mClient->create(item, "com.nokia.shared.2");
+ id = create(item, "com.nokia.shared.2");
+ waitForResponse1(id);
}
waitForItemsCreated(40);
+ //wait for the last one
+ if (id != lastRequestId)
+ waitForResponse1(id);
QCOMPARE(listModel->rowCount(), 50);
-
- createIndex("order", "number");
-
// Change sort order
listModel->setProperty("sortOrder", "[\\order]");
+
+ mWaitingForStateChanged = true;
waitForStateOrTimeout();
+ QCOMPARE(mWaitingForStateChanged, false);
QCOMPARE(listModel->rowCount(), 50);
// Delete the first 10 items
+ mItemsRemoved = 0;
foreach (QVariant item, insertedItems) {
- mWaitingForRowsRemoved = true;
- id = mClient->remove(item.toMap(), "com.nokia.shared.1");
- waitForItemChanged(true);
+ id = remove(item.toMap(), "com.nokia.shared.1");
+ waitForResponse1(id);
}
+ waitForItemsRemoved(10);
QCOMPARE(listModel->rowCount(), 40);
deleteModel(listModel);
}
+void TestJsonDbCachingListModel::checkAddNotification()
+{
+ resetWaitFlags();
+ int id = 0;
+ QVariantList insertedItems;
+ for (int i = 0; i < 10; i++) {
+ QVariantMap item;
+ item.insert("_type", __FUNCTION__);
+ item.insert("order", i);
+ id = create(item, "com.nokia.shared.1");
+ waitForResponse1(id);
+ }
+
+ QAbstractListModel *listModel = createModel();
+ if (!listModel)
+ return;
+
+ connectListModel(listModel);
+
+ QStringList roleNames = (QStringList() << "_type" << "_uuid" << "order");
+ listModel->setProperty("roleNames", roleNames);
+ listModel->setProperty("sortOrder", "[/order]");
+ listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__));
+
+ mWaitingForReset = true;
+ waitForExitOrTimeout();
+ QCOMPARE(mWaitingForReset, false);
+
+ QCOMPARE(listModel->rowCount(), 10);
+
+ mItemsCreated = 0;
+ QVariantList items;
+ for (int i = 0; i < 50; i++) {
+ QVariantMap item;
+ item.insert("_type", __FUNCTION__);
+ item.insert("order", i);
+ items << item;
+ }
+ id = create(items, "com.nokia.shared.2");
+ items.clear();
+ waitForResponse1(id);
+ for (int i = 0; i < 50; i++) {
+ QVariantMap item;
+ item.insert("_type", __FUNCTION__);
+ item.insert("order", i);
+ items << item;
+ }
+ id = create(items, "com.nokia.shared.1");
+ waitForResponse1(id);
+ waitForItemsCreated(100);
+ QCOMPARE(listModel->rowCount(), 110);
+
+ deleteModel(listModel);
+}
+
void TestJsonDbCachingListModel::listProperty()
{
- QVariant jsonData = readJsonFile("list-objects.json");
+ resetWaitFlags();
+ QVariant jsonData = readJsonFile(findFile("list-objects.json")).toVariant();
QVariantList itemList = jsonData.toList();
int id = 0;
for (int i = 0; i < itemList.count()/2; i++) {
- id = mClient->create(itemList[i].toMap(), "com.nokia.shared.1");
+ id = create(itemList[i].toMap(), "com.nokia.shared.1");
waitForResponse1(id);
}
for (int i = itemList.count()/2; i < itemList.count(); i++) {
- id = mClient->create(itemList[i].toMap(), "com.nokia.shared.2");
+ id = create(itemList[i].toMap(), "com.nokia.shared.2");
waitForResponse1(id);
}
@@ -900,21 +1009,28 @@ void TestJsonDbCachingListModel::listProperty()
connectListModel(listModel);
QString type = itemList[0].toMap()["_type"].toString();
listModel->setProperty("sortOrder", "[/features.0.properties.0.description]");
- listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(type));
QStringList roleNames = (QStringList() << "_type" << "_uuid" << "features.0.properties.0.description"<< "features.0.feature");
listModel->setProperty("roleNames", roleNames);
+ listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(type));
- waitForStateOrTimeout();
+ mWaitingForReset = true;
+ waitForExitOrTimeout();
+ QCOMPARE(mWaitingForReset, false);
QCOMPARE(listModel->rowCount(), itemList.count());
- getIndex(0);
- QCOMPARE(callbackResponse.toMap().value("_type").toString(), type);
- QCOMPARE(callbackResponse.toMap().value("features").toList().at(0).toMap().value("properties").toList().at(0).toMap().value("description").toString(), QLatin1String("Facebook account provider"));
- QCOMPARE(callbackResponse.toMap().value("features").toList().at(0).toMap().value("feature").toString(), QLatin1String("provide Facebook"));
- getIndex(1);
- QCOMPARE(callbackResponse.toMap().value("_type").toString(), type);
- QCOMPARE(callbackResponse.toMap().value("features").toList().at(0).toMap().value("properties").toList().at(0).toMap().value("description").toString(), QLatin1String("Gmail account provider"));
- QCOMPARE(callbackResponse.toMap().value("features").toList().at(0).toMap().value("feature").toString(), QLatin1String("provide Gmail"));
+ QVariant _type = getIndex(listModel, 0, 0);
+ QCOMPARE(_type.toString(), type);
+ QVariant featuresDesc = getIndex(listModel, 0, 2);
+ QCOMPARE(featuresDesc.toString(), QLatin1String("Facebook account provider"));
+ QVariant features = getIndex(listModel, 0, 3);
+ QCOMPARE(features.toString(), QLatin1String("provide Facebook"));
+
+ _type = getIndex(listModel, 1, 0);
+ QCOMPARE(_type.toString(), type);
+ featuresDesc = getIndex(listModel, 1, 2);
+ QCOMPARE(featuresDesc.toString(), QLatin1String("Gmail account provider"));
+ features = getIndex(listModel, 1, 3);
+ QCOMPARE(features.toString(), QLatin1String("provide Gmail"));
deleteModel(listModel);
@@ -924,33 +1040,42 @@ void TestJsonDbCachingListModel::listProperty()
connectListModel(listModel);
type = itemList[0].toMap()["_type"].toString();
listModel->setProperty("sortOrder", "[/features.0.properties.0.description]");
- listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(type));
roleNames.clear();
roleNames = (QStringList() << "_type" << "_uuid" << "features[0].properties[0].description"<< "features[0].supported[0]");
listModel->setProperty("roleNames", roleNames);
- waitForStateOrTimeout();
+ listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(type));
+
+ mWaitingForReset = true;
+ waitForExitOrTimeout();
+ QCOMPARE(mWaitingForReset, false);
QCOMPARE(listModel->rowCount(), itemList.count());
- getIndex(0);
- QCOMPARE(callbackResponse.toMap().value("_type").toString(), type);
- QCOMPARE(callbackResponse.toMap().value("features").toList().at(0).toMap().value("properties").toList().at(0).toMap().value("description").toString(), QLatin1String("Facebook account provider"));
- QCOMPARE(callbackResponse.toMap().value("features").toList().at(0).toMap().value("supported").toList().at(0).toString(), QLatin1String("share"));
- getIndex(1);
- QCOMPARE(callbackResponse.toMap().value("_type").toString(), type);
- QCOMPARE(callbackResponse.toMap().value("features").toList().at(0).toMap().value("properties").toList().at(0).toMap().value("description").toString(), QLatin1String("Gmail account provider"));
- QCOMPARE(callbackResponse.toMap().value("features").toList().at(0).toMap().value("supported").toList().at(0).toString(), QLatin1String("share"));
+ _type = getIndex(listModel, 0, 0);
+ QCOMPARE(_type.toString(), type);
+ featuresDesc = getIndex(listModel, 0, 2);
+ QCOMPARE(featuresDesc.toString(), QLatin1String("Facebook account provider"));
+ features = getIndex(listModel, 0, 3);
+ QCOMPARE(features.toString(), QLatin1String("share"));
+
+ _type = getIndex(listModel, 1, 0);
+ QCOMPARE(_type.toString(), type);
+ featuresDesc = getIndex(listModel, 1, 2);
+ QCOMPARE(featuresDesc.toString(), QLatin1String("Gmail account provider"));
+ features = getIndex(listModel, 1, 3);
+ QCOMPARE(features.toString(), QLatin1String("share"));
deleteModel(listModel);
}
void TestJsonDbCachingListModel::changeQuery()
{
+ resetWaitFlags();
QVariantMap item;
for (int i=0; i < 10; i++) {
item.insert("_type", __FUNCTION__);
item.insert("name", QString("Arnie_%1").arg(i));
- int id = mClient->create(item, "com.nokia.shared.1");
+ int id = create(item, "com.nokia.shared.1");
waitForResponse1(id);
}
@@ -965,7 +1090,9 @@ void TestJsonDbCachingListModel::changeQuery()
listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__));
connectListModel(listModel);
- waitForStateOrTimeout();
+ mWaitingForReset = true;
+ waitForExitOrTimeout();
+ QCOMPARE(mWaitingForReset, false);
QCOMPARE(listModel->rowCount(), 10);
QCOMPARE(listModel->property("query").toString(), QString("[?_type=\"%1\"]").arg(__FUNCTION__));
@@ -981,7 +1108,10 @@ void TestJsonDbCachingListModel::changeQuery()
QCOMPARE(listModel->property("query").toString(), QString(""));
listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__));
- waitForStateOrTimeout();
+
+ mWaitingForReset = true;
+ waitForExitOrTimeout();
+ QCOMPARE(mWaitingForReset, false);
QCOMPARE(listModel->rowCount(), 10);
QCOMPARE(listModel->property("query").toString(), QString("[?_type=\"%1\"]").arg(__FUNCTION__));
@@ -991,10 +1121,11 @@ void TestJsonDbCachingListModel::changeQuery()
void TestJsonDbCachingListModel::indexOfUuid()
{
+ resetWaitFlags();
QVariantMap item;
item.insert("_type", __FUNCTION__);
item.insert("name", QString("Arnie_0"));
- int id = mClient->create(item, "com.nokia.shared.1");
+ int id = create(item, "com.nokia.shared.1");
waitForResponse1(id);
createIndex("name", "string");
@@ -1008,23 +1139,28 @@ void TestJsonDbCachingListModel::indexOfUuid()
listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__));
connectListModel(listModel);
- waitForStateOrTimeout();
+ mWaitingForReset = true;
+ waitForExitOrTimeout();
+ QCOMPARE(mWaitingForReset, false);
QCOMPARE(listModel->rowCount(), 1);
- getIndex(0);
- QCOMPARE(callbackResponse.toMap().value("name").toString(), QString("Arnie_0"));
- QCOMPARE(indexOf(listModel, callbackResponse.toMap().value("_uuid").toString()), 0);
+ QVariant name = getIndex(listModel, 0, 2);
+ QCOMPARE(name.toString(), QString("Arnie_0"));
+ QVariant uuid = getIndex(listModel, 0, 1);
+ QCOMPARE(indexOf(listModel, uuid.toString()), 0);
item.insert("_type", __FUNCTION__);
item.insert("name", QString("Arnie_1"));
- id = mClient->create(item, "com.nokia.shared.1");
-
+ mItemsCreated = 0;
+ id = create(item, "com.nokia.shared.1");
+ waitForResponse1(id);
waitForItemsCreated(1);
QCOMPARE(listModel->rowCount(), 2);
- getIndex(1);
- QCOMPARE(callbackResponse.toMap().value("name").toString(), QString("Arnie_1"));
- QCOMPARE(indexOf(listModel, callbackResponse.toMap().value("_uuid").toString()), 1);
+ name = getIndex(listModel, 1, 2);
+ QCOMPARE(name.toString(), QString("Arnie_1"));
+ uuid = getIndex(listModel, 1, 1);
+ QCOMPARE(indexOf(listModel, uuid.toString()), 1);
QCOMPARE(indexOf(listModel, "notValid"), -1);
deleteModel(listModel);
@@ -1032,15 +1168,15 @@ void TestJsonDbCachingListModel::indexOfUuid()
void TestJsonDbCachingListModel::roleNames()
{
+ resetWaitFlags();
QVariantMap item;
item.insert("_type", __FUNCTION__);
item.insert("name", QString("Arnie"));
item.insert("friend", QString("Bert"));
- int id = mClient->create(item, "com.nokia.shared.1");
+ int id = create(item, "com.nokia.shared.1");
waitForResponse1(id);
-
QAbstractListModel *listModel = createModel();
if (!listModel) return;
@@ -1049,7 +1185,9 @@ void TestJsonDbCachingListModel::roleNames()
listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__));
connectListModel(listModel);
- waitForStateOrTimeout();
+ mWaitingForReset = true;
+ waitForExitOrTimeout();
+ QCOMPARE(mWaitingForReset, false);
QCOMPARE(listModel->rowCount(), 1);
@@ -1073,11 +1211,12 @@ void TestJsonDbCachingListModel::roleNames()
void TestJsonDbCachingListModel::getItemNotInCache()
{
+ resetWaitFlags();
QVariantMap item;
- for (int i=0; i < 300; i++) {
+ for (int i=0; i < 3000; i++) {
item.insert("_type", __FUNCTION__);
item.insert("number", i);
- int id = mClient->create(item, "com.nokia.shared.1");
+ int id = create(item, "com.nokia.shared.1");
waitForResponse1(id);
}
@@ -1085,7 +1224,7 @@ void TestJsonDbCachingListModel::getItemNotInCache()
QAbstractListModel *listModel = createModel();
if (!listModel) return;
- listModel->setProperty("cacheSize", 100);
+ listModel->setProperty("cacheSize", 50);
listModel->setProperty("sortOrder", "[/number]");
QStringList roleNames = (QStringList() << "_type" << "_uuid" << "number");
listModel->setProperty("roleNames", roleNames);
@@ -1095,47 +1234,54 @@ void TestJsonDbCachingListModel::getItemNotInCache()
// now start it working
QCOMPARE(listModel->rowCount(), 0);
- waitForStateOrTimeout();
- QCOMPARE(listModel->rowCount(), 300);
- QCOMPARE(listModel->property("cacheSize").toInt(), 100);
-
- getIndex(100);
- QCOMPARE(callbackResponse.toMap().value("number").toInt(), 100);
- getIndex(151);
- QCOMPARE(callbackResponse.toMap().value("number").toInt(), 151);
- getIndex(202);
- QCOMPARE(callbackResponse.toMap().value("number").toInt(), 202);
- getIndex(255);
- QCOMPARE(callbackResponse.toMap().value("number").toInt(), 255);
- getIndex(20);
- QCOMPARE(callbackResponse.toMap().value("number").toInt(), 20);
+ mWaitingForReset = true;
+ waitForExitOrTimeout();
+ QCOMPARE(mWaitingForReset, false);
+
+ QCOMPARE(listModel->rowCount(), 3000);
- deleteModel(listModel);
-}
+ QVariant number = getIndex(listModel, 2967, 2);
+ QCOMPARE(number.toInt(), 2967);
+ number = getIndex(listModel, 100, 2);
+ QCOMPARE(number.toInt(), 100);
+ number = getIndex(listModel, 1701, 2);
+ QCOMPARE(number.toInt(), 1701);
+ number = getIndex(listModel, 20, 2);
+ QCOMPARE(number.toInt(), 20);
+ deleteModel(listModel);
+}
QStringList TestJsonDbCachingListModel::getOrderValues(QAbstractListModel *listModel)
{
QStringList vals;
for (int i = 0; i < listModel->rowCount(); ++i) {
- getIndex(i);
- vals << callbackResponse.toMap().value("ordering").toString();
+ vals << getIndex(listModel, i, 3).toString();
}
return vals;
}
void TestJsonDbCachingListModel::modelReset()
{
- mWaitingForReset = false;
- mEventLoop2.exit(0);
+ if (mWaitingForReset) {
+ mWaitingForReset = false;
+ eventLoop1.exit(0);
+ }
}
void TestJsonDbCachingListModel::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
{
Q_UNUSED(topLeft);
Q_UNUSED(bottomRight);
- mWaitingForDataChange = false;
+ mItemsUpdated++;
+ if (mWaitingForChanged) {
+ mWaitingForChanged = false;
+ eventLoop1.exit(0);
+ } else if (mWaitingForIndexChanged && mIndexWaited >= topLeft.row() && mIndexWaited <= bottomRight.row()) {
+ mWaitingForIndexChanged = false;
+ eventLoop1.exit(0);
+ }
}
void TestJsonDbCachingListModel::rowsInserted(const QModelIndex &parent, int first, int last)
@@ -1143,8 +1289,11 @@ void TestJsonDbCachingListModel::rowsInserted(const QModelIndex &parent, int fir
Q_UNUSED(parent);
Q_UNUSED(first);
Q_UNUSED(last);
- mItemsCreated++;
- mEventLoop2.exit(0);
+ mItemsCreated += last-first+1;
+ if (mWaitingForRowsInserted) {
+ mWaitingForRowsInserted = false;
+ eventLoop1.exit(0);
+ }
}
void TestJsonDbCachingListModel::rowsRemoved(const QModelIndex &parent, int first, int last)
@@ -1152,7 +1301,11 @@ void TestJsonDbCachingListModel::rowsRemoved(const QModelIndex &parent, int firs
Q_UNUSED(parent);
Q_UNUSED(first);
Q_UNUSED(last);
- mWaitingForRowsRemoved = false;
+ mItemsRemoved += last-first+1;
+ if (mWaitingForRemoved) {
+ mWaitingForRemoved = false;
+ eventLoop1.exit(0);
+ }
}
void TestJsonDbCachingListModel::rowsMoved( const QModelIndex &parent, int start, int end, const QModelIndex &destination, int row )
@@ -1168,83 +1321,141 @@ void TestJsonDbCachingListModel::stateChanged()
{
// only exit on ready state.
QAbstractListModel *model = qobject_cast<QAbstractListModel *>(sender());
- if (model->property("state") == 2) {
+ if (model->property("state").toInt() == 2 && mWaitingForStateChanged) {
mWaitingForStateChanged = false;
- mEventLoop2.exit(0);
+ eventLoop1.exit(0);
}
}
void TestJsonDbCachingListModel::waitForItemsCreated(int items)
{
- mTimeoutCalled = false;
+ mTimedOut = false;
QTimer timer;
QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout()));
- QObject::connect(&timer, SIGNAL(timeout()), &mEventLoop2, SLOT(quit()));
- timer.start(mClientTimeout);
- mElapsedTimer.start();
+ timer.start(clientTimeout);
+ elapsedTimer.start();
- mItemsCreated = 0;
- while (mItemsCreated != items && !mTimeoutCalled)
- mEventLoop2.processEvents(QEventLoop::AllEvents, mClientTimeout);
+ while (!mTimedOut && mItemsCreated != items) {
+ mWaitingForRowsInserted = true;
+ eventLoop1.exec(QEventLoop::AllEvents);
+ }
+ if (mTimedOut)
+ qDebug () << "waitForItemsCreated Timed out";
+}
+
+void TestJsonDbCachingListModel::waitForIndexChanged()
+{
+
+ mTimedOut = false;
+ QTimer timer;
+ QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout()));
+ timer.start(clientTimeout);
+ elapsedTimer.start();
+
+ while (!mTimedOut && mWaitingForIndexChanged) {
+ eventLoop1.exec(QEventLoop::AllEvents);
+ }
+ if (mTimedOut)
+ qDebug () << "waitForIndexChanged Timed out";
+}
+
+void TestJsonDbCachingListModel::waitForItemsRemoved(int items)
+{
+ mTimedOut = false;
+ QTimer timer;
+ QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout()));
+ timer.start(clientTimeout);
+ elapsedTimer.start();
+
+ while (!mTimedOut && mItemsRemoved != items) {
+ mWaitingForRemoved = true;
+ eventLoop1.exec(QEventLoop::AllEvents);
+ }
+ if (mTimedOut)
+ qDebug () << "waitForItemsRemoved Timed out";
}
void TestJsonDbCachingListModel::waitForExitOrTimeout()
{
- mTimeoutCalled = false;
QTimer timer;
QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout()));
- QObject::connect(&timer, SIGNAL(timeout()), &mEventLoop2, SLOT(quit()));
- timer.start(mClientTimeout);
- mElapsedTimer.start();
- mEventLoop2.exec(QEventLoop::AllEvents);
+ timer.start(clientTimeout);
+ elapsedTimer.start();
+ eventLoop1.exec(QEventLoop::AllEvents);
}
void TestJsonDbCachingListModel::waitForStateOrTimeout()
{
- mTimeoutCalled = false;
+ mTimedOut = false;
QTimer timer;
QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout()));
- QObject::connect(&timer, SIGNAL(timeout()), &mEventLoop2, SLOT(quit()));
- timer.start(mClientTimeout);
- mElapsedTimer.start();
+ timer.start(clientTimeout);
+ elapsedTimer.start();
- mWaitingForStateChanged = true;
- while (mWaitingForStateChanged && !mTimeoutCalled)
- mEventLoop2.processEvents(QEventLoop::AllEvents, mClientTimeout);
+ while (mWaitingForStateChanged && !mTimedOut) {
+ eventLoop1.exec(QEventLoop::AllEvents);
+ }
+ if (mTimedOut)
+ qDebug () << "waitForStateOrTimeout Timed out";
}
void TestJsonDbCachingListModel::timeout()
{
- ClientWrapper::timeout();
- mTimeoutCalled = true;
+ qDebug () << "TestJsonDbCachingListModel::timeout()";
+ RequestWrapper::timeout();
mTimedOut = true;
+ eventLoop1.quit();
+}
+
+void TestJsonDbCachingListModel::resetWaitFlags()
+{
+ mItemsCreated = 0;
+ mItemsUpdated = 0;
+ mItemsRemoved = 0;
+ mWaitingForStateChanged = false;
+ mWaitingForRowsInserted = false;
+ mWaitingForReset = false;
+ mWaitingForChanged = false;
+ mWaitingForRemoved = false;
}
void TestJsonDbCachingListModel::waitForItemChanged(bool waitForRemove)
{
- mTimeoutCalled = false;
+ mTimedOut = false;
QTimer timer;
QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout()));
- QObject::connect(&timer, SIGNAL(timeout()), &mEventLoop2, SLOT(quit()));
- timer.start(mClientTimeout);
- mElapsedTimer.start();
+ timer.start(clientTimeout);
+ elapsedTimer.start();
- mWaitingForRowsRemoved = true;
- mWaitingForDataChange = true;
+ mWaitingForRemoved = true;
+ mWaitingForChanged = true;
mItemsCreated = 0;
mWaitingForReset = true;
+ mWaitingForStateChanged = true;
bool waitMore = true;
- while (waitMore && !mTimeoutCalled) {
- if (!mWaitingForDataChange)
+ while (waitMore && !mTimedOut) {
+ if (!mWaitingForChanged) {
+ //qDebug() << "waitForItemChanged: mWaitingForChanged";
break;
- if (mItemsCreated)
+ }
+ if (!mWaitingForStateChanged) {
+ //qDebug() << "waitForItemChanged: mWaitingForStateChanged";
break;
- if (!mWaitingForReset)
+ }
+ if (mItemsCreated){
+ //qDebug() << "waitForItemChanged: mItemsCreated";
break;
- if (waitForRemove && !mWaitingForRowsRemoved)
+ }
+ if (!mWaitingForReset){
+ //qDebug() << "waitForItemChanged: mWaitingForReset";
break;
- mEventLoop2.processEvents(QEventLoop::AllEvents);
+ }
+ if (waitForRemove && !mWaitingForRemoved){
+ //qDebug() << "waitForItemChanged: mWaitingForRemoved";
+ break;
+ }
+ eventLoop1.exec(QEventLoop::AllEvents);
}
}
QTEST_MAIN(TestJsonDbCachingListModel)
diff --git a/tests/auto/jsondbcachinglistmodel/testjsondbcachinglistmodel.h b/tests/auto/jsondbcachinglistmodel/testjsondbcachinglistmodel.h
index 695efaf1..02bb0521 100644
--- a/tests/auto/jsondbcachinglistmodel/testjsondbcachinglistmodel.h
+++ b/tests/auto/jsondbcachinglistmodel/testjsondbcachinglistmodel.h
@@ -41,22 +41,9 @@
#ifndef TestJsonDbCachingListModel_H
#define TestJsonDbCachingListModel_H
-#include <QCoreApplication>
-#include <QList>
-#include <QTest>
-#include <QFile>
-#include <QProcess>
-#include <QEventLoop>
-#include <QDebug>
-#include <QLocalSocket>
-#include <QTimer>
-
-#include <jsondb-client.h>
-#include <jsondb-error.h>
-
#include <QAbstractListModel>
-#include "clientwrapper.h"
-#include "../../shared/qmltestutil.h"
+#include "requestwrapper.h"
+#include "qmltestutil.h"
QT_BEGIN_NAMESPACE
class QQmlEngine;
@@ -73,14 +60,10 @@ public:
~ModelData();
QQmlEngine *engine;
QQmlComponent *component;
- QQmlComponent *partitionComponent1;
- QQmlComponent *partitionComponent2;
QObject *model;
- QObject *partition1;
- QObject *partition2;
};
-class TestJsonDbCachingListModel: public ClientWrapper
+class TestJsonDbCachingListModel: public RequestWrapper
{
Q_OBJECT
public:
@@ -98,15 +81,10 @@ public slots:
void modelReset();
void stateChanged();
- void callbackSlot(QVariant error, QVariant response);
-
-
-protected slots:
- void timeout();
-
private slots:
void initTestCase();
void cleanupTestCase();
+
void createItem();
void createModelTwoPartitions();
void updateItemClient();
@@ -116,46 +94,46 @@ private slots:
void checkRemoveNotification();
void checkUpdateNotification();
void totalRowCount();
+ void checkAddNotification();
void listProperty();
void changeQuery();
void indexOfUuid();
void roleNames();
void getItemNotInCache();
-
+public:
+ void timeout();
private:
void waitForExitOrTimeout();
void waitForItemsCreated(int items);
+ void waitForItemsRemoved(int items);
void waitForStateOrTimeout();
void waitForItemChanged(bool waitForRemove = false);
+ void waitForIndexChanged();
QStringList getOrderValues(QAbstractListModel *listModel);
- void getIndex(int index);
+ QVariant getIndex(QAbstractListModel *model, int index, int role);
void createIndex(const QString &property, const QString &propertyType);
QAbstractListModel *createModel();
void deleteModel(QAbstractListModel *model);
- QVariant readJsonFile(const QString &filename);
+ void resetWaitFlags();
private:
QProcess *mProcess;
- QStringList mNotificationsReceived;
+ //QStringList mNotificationsReceived;
QList<ModelData*> mModels;
QString mPluginPath;
- QEventLoop mEventLoop2; // for all listmodel slots
// Response values
+ bool mTimedOut;
int mItemsCreated;
- bool mWaitingForNotification;
- bool mWaitingForDataChange;
- bool mWaitingForRowsRemoved;
- bool mTimeoutCalled;
- bool mWaitingForReset;
+ int mItemsUpdated;
+ int mItemsRemoved;
bool mWaitingForStateChanged;
-
- bool mTimedOut;
- bool callbackError;
- bool mCallbackReceived;
- QVariant callbackMeta;
- QVariant callbackResponse;
-
+ bool mWaitingForRowsInserted;
+ bool mWaitingForReset;
+ bool mWaitingForChanged;
+ bool mWaitingForIndexChanged;
+ int mIndexWaited;
+ bool mWaitingForRemoved;
};
#endif
diff --git a/tests/auto/jsondbchangessinceobject/jsondbchangessinceobject.pro b/tests/auto/jsondbchangessinceobject/jsondbchangessinceobject.pro
deleted file mode 100644
index cb94df5d..00000000
--- a/tests/auto/jsondbchangessinceobject/jsondbchangessinceobject.pro
+++ /dev/null
@@ -1,17 +0,0 @@
-TEMPLATE = app
-TARGET = tst_jsondbchangessinceobject
-DEPENDPATH += .
-INCLUDEPATH += .
-
-QT = core network testlib gui qml jsondbcompat-private
-CONFIG -= app_bundle
-CONFIG += testcase
-
-include($$PWD/../../shared/shared.pri)
-include($$PWD/../../../src/3rdparty/qjson/qjson.pri)
-
-DEFINES += JSONDB_DAEMON_BASE=\\\"$$QT.jsondb.bins\\\"
-DEFINES += SRCDIR=\\\"$$PWD/\\\"
-
-HEADERS += testjsondbchangessinceobject.h
-SOURCES += testjsondbchangessinceobject.cpp
diff --git a/tests/auto/jsondbchangessinceobject/testjsondbchangessinceobject.cpp b/tests/auto/jsondbchangessinceobject/testjsondbchangessinceobject.cpp
deleted file mode 100644
index 8ad35d50..00000000
--- a/tests/auto/jsondbchangessinceobject/testjsondbchangessinceobject.cpp
+++ /dev/null
@@ -1,332 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-#include <QJSEngine>
-#include "testjsondbchangessinceobject.h"
-#include "../../shared/util.h"
-#include <QJSValueIterator>
-#include "json.h"
-
-static const char dbfile[] = "dbFile-jsondb-partition";
-
-const QString qmlProgram = QLatin1String(
- "import QtQuick 2.0 \n"
- "import QtJsonDb 1.0 as JsonDb \n"
- "JsonDb.ChangesSince { "
- "id:changessinceObject;"
- "partition :JsonDb.Partition { "
- "name: \"com.nokia.shared\";"
- "}"
- "}");
-
-const QString qmlProgramForPartition = QLatin1String(
- "import QtQuick 2.0 \n"
- "import QtJsonDb 1.0 as JsonDb \n"
- "JsonDb.Partition { "
- "id: sharedPartition;"
- "name: \"com.nokia.shared\";"
- "}");
-
-TestJsonDbChangesSinceObject::TestJsonDbChangesSinceObject()
- : mTimedOut(false)
-{
- qsrand(QTime::currentTime().msec());
-}
-
-TestJsonDbChangesSinceObject::~TestJsonDbChangesSinceObject()
-{
-}
-
-void TestJsonDbChangesSinceObject::timeout()
-{
- ClientWrapper::timeout();
- mTimedOut = true;
-}
-
-void TestJsonDbChangesSinceObject::deleteDbFiles()
-{
- // remove all the test files.
- QDir currentDir;
- QStringList nameFilter;
- nameFilter << QString("*.db");
- nameFilter << "objectFile.bin" << "objectFile2.bin";
- QFileInfoList databaseFiles = currentDir.entryInfoList(nameFilter, QDir::Files);
- foreach (QFileInfo fileInfo, databaseFiles) {
- QFile file(fileInfo.fileName());
- file.remove();
- }
-}
-
-void TestJsonDbChangesSinceObject::initTestCase()
-{
- // make sure there is no old db files.
- deleteDbFiles();
-
- QString socketName = QString("testjsondb_%1").arg(getpid());
- mProcess = launchJsonDbDaemon(JSONDB_DAEMON_BASE, socketName, QStringList() << "-base-name" << dbfile);
-
- mClient = new JsonDbClient(this);
- connect(mClient, SIGNAL(notified(QString,QtAddOn::JsonDb::JsonDbNotification)),
- this, SLOT(notified(QString,QtAddOn::JsonDb::JsonDbNotification)));
- connect( mClient, SIGNAL(response(int, const QVariant&)),
- this, SLOT(response(int, const QVariant&)));
- connect( mClient, SIGNAL(error(int, int, const QString&)),
- this, SLOT(error(int, int, const QString&)));
-
- mPluginPath = findQMLPluginPath("QtJsonDb");
-
- // Create the shared Partitions
- QVariantMap item;
- item.insert("_type", "Partition");
- item.insert("name", "com.nokia.shared");
- int id = mClient->create(item);
- waitForResponse1(id);
-
-}
-
-ComponentData *TestJsonDbChangesSinceObject::createComponent()
-{
- ComponentData *componentData = new ComponentData();
- componentData->engine = new QQmlEngine();
- QString error;
- if (!componentData->engine->importPlugin(mPluginPath, QString("QtJsonDb"), &error)) {
- qDebug()<<"Unable to load the plugin :"<<error;
- delete componentData->engine;
- return 0;
- }
- componentData->component = new QQmlComponent(componentData->engine);
- componentData->component->setData(qmlProgram.toUtf8(), QUrl());
- componentData->qmlElement = componentData->component->create();
- if (componentData->component->isError())
- qDebug() << componentData->component->errors();
- QObject::connect(componentData->qmlElement, SIGNAL(finished()),
- this, SLOT(finishedSlot()));
- QObject::connect(componentData->qmlElement, SIGNAL(errorChanged(const QVariantMap&)),
- this, SLOT(errorSlot(const QVariantMap&)));
- mComponents.append(componentData);
- return componentData;
-}
-
-ComponentData *TestJsonDbChangesSinceObject::createPartitionComponent()
-{
- ComponentData *componentData = new ComponentData();
- componentData->engine = new QQmlEngine();
- QString error;
- if (!componentData->engine->importPlugin(mPluginPath, QString("QtJsonDb"), &error)) {
- qDebug()<<"Unable to load the plugin :"<<error;
- delete componentData->engine;
- return 0;
- }
- componentData->component = new QQmlComponent(componentData->engine);
- componentData->component->setData(qmlProgramForPartition.toUtf8(), QUrl());
- componentData->qmlElement = componentData->component->create();
- if (componentData->component->isError())
- qDebug() << componentData->component->errors();
- mComponents.append(componentData);
- return componentData;
-}
-
-void TestJsonDbChangesSinceObject::deleteComponent(ComponentData *componentData)
-{
- mComponents.removeOne(componentData);
- if (componentData)
- delete componentData;
-}
-
-void TestJsonDbChangesSinceObject::cleanupTestCase()
-{
- if (mProcess) {
- mProcess->kill();
- mProcess->waitForFinished();
- delete mProcess;
- }
-
- deleteDbFiles();
-}
-
-void TestJsonDbChangesSinceObject::errorSlot(const QVariantMap &newError)
-{
- int code = newError.value("code").toInt();
- QString message = newError.value("message").toString();
- callbackError = true;
- callbackErrorCode = code;
- callbackErrorMessage = message;
- mEventLoop2.quit();
-}
-
-void TestJsonDbChangesSinceObject::finishedSlot()
-{
- QMetaObject::invokeMethod(currentQmlElement, "takeResults", Qt::DirectConnection,
- Q_RETURN_ARG(QVariantList, cbData));
- mEventLoop2.quit();
-}
-
-bool posLessThan(const QVariant &v1, const QVariant &v2)
-{
- QVariantMap v1Map = v1.toMap();
- QVariantMap v2Map = v2.toMap();
-
- return v1Map.value("pos").toInt() < v2Map.value("pos").toInt();
-}
-
-void TestJsonDbChangesSinceObject::singleType()
-{
- ComponentData *changesSinceObject = createComponent();
- if (!changesSinceObject || !changesSinceObject->qmlElement) return;
-
- const QString typeString( __FUNCTION__ );
- changesSinceObject->qmlElement->setProperty("types", QStringList(typeString));
- currentQmlElement = changesSinceObject->qmlElement;
-
- //Create an object
- QVariantMap item = createObject(__FUNCTION__).toMap();
- int id = mClient->create(item, "com.nokia.shared");
- waitForResponse1(id);
- const QString expression("start();");
- QQmlExpression *expr;
- expr = new QQmlExpression(changesSinceObject->engine->rootContext(), changesSinceObject->qmlElement, expression);
- expr->evaluate();
- waitForCallback2();
- QCOMPARE(cbData.size(), 1);
- QCOMPARE(callbackError, false);
- delete expr;
- deleteComponent(changesSinceObject);
-}
-
-void TestJsonDbChangesSinceObject::multipleObjects()
-{
- ComponentData *changesSinceObject = createComponent();
- if (!changesSinceObject || !changesSinceObject->qmlElement) return;
-
- const QString typeString( __FUNCTION__ );
- changesSinceObject->qmlElement->setProperty("types", QStringList(typeString));
- currentQmlElement = changesSinceObject->qmlElement;
-
- //Create objects
- QVariantList items = createObjectList(__FUNCTION__, 10).toList();
- int id = mClient->create(QVariant(items), "com.nokia.shared");
- waitForResponse1(id);
- qSort(items.begin(), items.end(), posLessThan);
- const QString expression("start();");
- QQmlExpression *expr;
- expr = new QQmlExpression(changesSinceObject->engine->rootContext(), changesSinceObject->qmlElement, expression);
- expr->evaluate();
- waitForCallback2();
- QCOMPARE(callbackError, false);
- QCOMPARE(cbData.size(), 10);
- QVariantList result;
- for (int i = 0; i<10; i++) {
- QVariantMap obj = cbData[i].toMap();
- result.append(obj.value("after"));
- }
- qSort(result.begin(), result.end(), posLessThan);
- for (int i = 0; i<10; i++) {
- QVariantMap item = items[i].toMap();
- QVariantMap obj = result[i].toMap();
- QCOMPARE(obj.value("alphabet"), item.value("alphabet"));
- }
-
- delete expr;
- deleteComponent(changesSinceObject);
-}
-
-void TestJsonDbChangesSinceObject::multipleTypes()
-{
- ComponentData *changesSinceObject = createComponent();
- if (!changesSinceObject || !changesSinceObject->qmlElement) return;
-
- QStringList types;
- types << __FUNCTION__
- <<QString(__FUNCTION__)+".2";
- changesSinceObject->qmlElement->setProperty("types", types);
- currentQmlElement = changesSinceObject->qmlElement;
-
- //Create an object
- QVariantMap item = createObject(types[0]).toMap();
- int id = mClient->create(item, "com.nokia.shared");
- waitForResponse1(id);
- item = createObject(types[1]).toMap();
- id = mClient->create(item, "com.nokia.shared");
- waitForResponse1(id);
- const QString expression("start();");
- QQmlExpression *expr;
- expr = new QQmlExpression(changesSinceObject->engine->rootContext(), changesSinceObject->qmlElement, expression);
- expr->evaluate();
- waitForCallback2();
- QCOMPARE(cbData.size(), 2);
- QCOMPARE(callbackError, false);
- delete expr;
- deleteComponent(changesSinceObject);
-}
-
-void TestJsonDbChangesSinceObject::createChangesSince()
-{
- const QString createString = QString("createChangesSince(0, [\"%1\"]);");
- ComponentData *partition = createPartitionComponent();
- if (!partition || !partition->qmlElement) return;
- QString expression;
-
- expression = QString(createString).arg(__FUNCTION__);
- QQmlExpression *expr;
- expr = new QQmlExpression(partition->engine->rootContext(), partition->qmlElement, expression);
- QPointer<QObject> queryObject = expr->evaluate().value<QObject*>();
- QVERIFY(!queryObject.isNull());
- queryObject->setParent(partition->qmlElement);
- currentQmlElement = queryObject;
- QObject::connect(currentQmlElement, SIGNAL(finished()),
- this, SLOT(finishedSlot()));
- QObject::connect(currentQmlElement, SIGNAL(errorChanged(const QVariantMap&)),
- this, SLOT(errorSlot(const QVariantMap&)));
- //Create an object
- QVariantMap item = createObject(__FUNCTION__).toMap();
- mClient->create(item, "com.nokia.shared");
- QMetaObject::invokeMethod(currentQmlElement, "start", Qt::DirectConnection);
- cbData.clear();
- waitForCallback2();
- QCOMPARE(cbData.size(), 1);
- QCOMPARE(callbackError, false);
- delete expr;
- deleteComponent(partition);
-}
-
-QTEST_MAIN(TestJsonDbChangesSinceObject)
-
diff --git a/tests/auto/jsondbchangessinceobject/testjsondbchangessinceobject.h b/tests/auto/jsondbchangessinceobject/testjsondbchangessinceobject.h
deleted file mode 100644
index 5e98bdce..00000000
--- a/tests/auto/jsondbchangessinceobject/testjsondbchangessinceobject.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#ifndef TESTJSONDBCHANGESSINCEOBJECT_H
-#define TESTJSONDBCHANGESSINCEOBJECT_H
-
-#include <QCoreApplication>
-#include <QList>
-#include <QTest>
-#include <QFile>
-#include <QProcess>
-#include <QEventLoop>
-#include <QDebug>
-#include <QLocalSocket>
-#include <QTimer>
-#include <QJSValue>
-
-#include <jsondb-client.h>
-#include <jsondb-error.h>
-
-#include <QAbstractItemModel>
-#include "clientwrapper.h"
-#include "../../shared/qmltestutil.h"
-
-QT_USE_NAMESPACE_JSONDB
-
-class TestJsonDbChangesSinceObject: public ClientWrapper
-{
- Q_OBJECT
-public:
- TestJsonDbChangesSinceObject();
- ~TestJsonDbChangesSinceObject();
- void deleteDbFiles();
-
-private slots:
- void initTestCase();
- void cleanupTestCase();
-
- void singleType();
- void multipleObjects();
- void multipleTypes();
- void createChangesSince();
-
-public slots:
- void errorSlot(const QVariantMap &newError);
- void finishedSlot();
-
-protected slots:
- void timeout();
-
-private:
- ComponentData *createComponent();
- ComponentData *createPartitionComponent();
- void deleteComponent(ComponentData *componentData);
-
-private:
- QProcess *mProcess;
- QStringList mNotificationsReceived;
- QList<ComponentData*> mComponents;
- QString mPluginPath;
- bool mTimedOut;
- bool callbackError;
- int callbackErrorCode;
- QString callbackErrorMessage;
- QVariantList cbData;
- QEventLoop mEventLoop2;
- QObject *currentQmlElement;
-
-};
-
-#endif
diff --git a/tests/auto/jsondblistmodel/jsondblistmodel.pro b/tests/auto/jsondblistmodel/jsondblistmodel.pro
index 7aafd6ad..1001c605 100644
--- a/tests/auto/jsondblistmodel/jsondblistmodel.pro
+++ b/tests/auto/jsondblistmodel/jsondblistmodel.pro
@@ -1,17 +1,20 @@
TEMPLATE = app
TARGET = tst_jsondblistmodel
DEPENDPATH += .
-INCLUDEPATH += .
+INCLUDEPATH += . ../../shared/
-QT = core network testlib gui qml jsondbcompat-private
+QT = core network testlib gui qml jsondb
CONFIG -= app_bundle
CONFIG += testcase
include($$PWD/../../shared/shared.pri)
-include($$PWD/../../../src/3rdparty/qjson/qjson.pri)
DEFINES += JSONDB_DAEMON_BASE=\\\"$$QT.jsondb.bins\\\"
DEFINES += SRCDIR=\\\"$$PWD/\\\"
-HEADERS += testjsondblistmodel.h
+HEADERS += testjsondblistmodel.h \
+ $$PWD/../../shared/requestwrapper.h
SOURCES += testjsondblistmodel.cpp
+
+OTHER_FILES += \
+ partitions.json
diff --git a/tests/auto/jsondblistmodel/partitions.json b/tests/auto/jsondblistmodel/partitions.json
new file mode 100644
index 00000000..c312e702
--- /dev/null
+++ b/tests/auto/jsondblistmodel/partitions.json
@@ -0,0 +1,3 @@
+[
+ { "name" :"com.example.shared.1" }
+]
diff --git a/tests/auto/jsondblistmodel/testjsondblistmodel.cpp b/tests/auto/jsondblistmodel/testjsondblistmodel.cpp
index 598353ca..bd0e40d7 100644
--- a/tests/auto/jsondblistmodel/testjsondblistmodel.cpp
+++ b/tests/auto/jsondblistmodel/testjsondblistmodel.cpp
@@ -43,7 +43,6 @@
#include <QJSEngine>
#include "testjsondblistmodel.h"
#include "../../shared/util.h"
-#include "json.h"
static const char dbfile[] = "dbFile-jsondb-listmodel";
ModelData::ModelData(): engine(0), component(0), model(0)
@@ -60,6 +59,14 @@ ModelData::~ModelData()
delete engine;
}
+const QString qmlProgram = QLatin1String(
+ "import QtQuick 2.0\n"
+ "import QtJsonDb 1.0 as JsonDb\n"
+ "JsonDb.JsonDbListModel {"
+ "id: contactsModel;"
+ "partition: JsonDb.Partition {name: \"com.example.shared.1\"}"
+ "}");
+
QVariant get(QObject* object, int index, QString propertyName)
{
QVariant retVal;
@@ -86,7 +93,6 @@ void listSetProperty(QObject* object, int index, QString propertyName, QVariant
}
TestJsonDbListModel::TestJsonDbListModel()
- : mWaitingForNotification(false), mWaitingForDataChange(false), mWaitingForRowsRemoved(false)
{
}
@@ -108,20 +114,6 @@ void TestJsonDbListModel::deleteDbFiles()
}
}
-QVariant TestJsonDbListModel::readJsonFile(const QString& filename)
-{
- QString filepath = findFile(filename);
- QFile jsonFile(filepath);
- jsonFile.open(QIODevice::ReadOnly);
- QByteArray json = jsonFile.readAll();
- JsonReader parser;
- bool ok = parser.parse(json);
- if (!ok) {
- qDebug() << filepath << parser.errorString();
- }
- return parser.result();
-}
-
void TestJsonDbListModel::connectListModel(QAbstractItemModel *model)
{
connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(dataChanged(QModelIndex,QModelIndex)));
@@ -138,27 +130,14 @@ void TestJsonDbListModel::initTestCase()
deleteDbFiles();
QString socketName = QString("testjsondb_%1").arg(getpid());
- mProcess = launchJsonDbDaemon(JSONDB_DAEMON_BASE, socketName, QStringList() << "-base-name" << dbfile);
+ mProcess = launchJsonDbDaemon(JSONDB_DAEMON_BASE, socketName, QStringList() << "-base-name" << dbfile, __FILE__);
- mClient = new JsonDbClient(this);
- connect(mClient, SIGNAL(notified(QString,QtAddOn::JsonDb::JsonDbNotification)),
- this, SLOT(notified(QString,QtAddOn::JsonDb::JsonDbNotification)));
- connect( mClient, SIGNAL(response(int, const QVariant&)),
- this, SLOT(response(int, const QVariant&)));
- connect( mClient, SIGNAL(error(int, int, const QString&)),
- this, SLOT(error(int, int, const QString&)));
+ connection = new QJsonDbConnection();
+ connection->connectToServer();
mPluginPath = findQMLPluginPath("QtJsonDb");
if (mPluginPath.isEmpty())
qDebug() << "Couldn't find the plugin path for the plugin QtJsonDb";
-
- // Create the shared Partitions
- QVariantMap item;
- item.insert("_type", "Partition");
- item.insert("name", "com.example.shared.1");
- int id = mClient->create(item);
- waitForResponse1(id);
-
}
QAbstractItemModel *TestJsonDbListModel::createModel()
@@ -173,7 +152,7 @@ QAbstractItemModel *TestJsonDbListModel::createModel()
return 0;
}
newModel->component = new QQmlComponent(newModel->engine);
- newModel->component->setData("import QtQuick 2.0\nimport QtJsonDb 1.0 as JsonDb \n JsonDb.JsonDbListModel {id: contactsModel; partition: JsonDb.Partition {name: \"com.example.shared.1\"}}", QUrl());
+ newModel->component->setData(qmlProgram.toLocal8Bit(), QUrl());
newModel->model = newModel->component->create();
if (newModel->component->isError())
qDebug() << newModel->component->errors();
@@ -203,31 +182,56 @@ void TestJsonDbListModel::cleanupTestCase()
deleteDbFiles();
}
+void TestJsonDbListModel::timeout()
+{
+ RequestWrapper::timeout();
+ mTimedOut = true;
+ eventLoop1.quit();
+}
+
void TestJsonDbListModel::waitForItemsCreated(int items)
{
+ mTimedOut = false;
+ QTimer timer;
+ QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout()));
+ timer.start(clientTimeout);
+ elapsedTimer.start();
+
mItemsCreated = 0;
- while(mItemsCreated != items)
- mEventLoop.processEvents(QEventLoop::AllEvents, mClientTimeout);
+ while (!mTimedOut && mItemsCreated != items) {
+ mWaitingForRowsInserted = true;
+ eventLoop1.exec(QEventLoop::AllEvents);
+ }
}
void TestJsonDbListModel::waitForExitOrTimeout()
{
QTimer timer;
QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout()));
- QObject::connect(&timer, SIGNAL(timeout()), &mEventLoop, SLOT(quit()));
- timer.start(mClientTimeout);
- mElapsedTimer.start();
- mEventLoop.exec(QEventLoop::AllEvents);
+ timer.start(clientTimeout);
+ elapsedTimer.start();
+ eventLoop1.exec(QEventLoop::AllEvents);
+}
+
+void TestJsonDbListModel::resetWaitFlags()
+{
+ mItemsCreated = 0;
+ mItemsUpdated = 0;
+ mItemsRemoved = 0;
+ mWaitingForRowsInserted = false;
+ mWaitingForReset = false;
+ mWaitingForChanged = false;
+ mWaitingForRemoved = false;
}
// Create items in the model.
void TestJsonDbListModel::createItem()
{
+ resetWaitFlags();
QVariantMap item;
item.insert("_type", __FUNCTION__);
item.insert("name", "Charlie");
- int id = mClient->create(item, "com.example.shared.1");
-
+ int id = create(item, "com.example.shared.1");
waitForResponse1(id);
QAbstractItemModel *listModel = createModel();
@@ -239,17 +243,21 @@ void TestJsonDbListModel::createItem()
// now start it working
QCOMPARE(listModel->property("count").toInt(), 0);
-
+ mWaitingForReset = true;
waitForExitOrTimeout();
+ QCOMPARE(mWaitingForReset, false);
QCOMPARE(listModel->property("count").toInt(), 1);
item.insert("_type", __FUNCTION__);
item.insert("name", "Baker");
mItemsCreated = 0;
- id = mClient->create(item, "com.example.shared.1");
+ id = create(item, "com.example.shared.1");
waitForResponse1(id);
- if (!mItemsCreated)
+ while (!mItemsCreated) {
+ mWaitingForRowsInserted = true;
waitForExitOrTimeout();
+ }
+ QCOMPARE(mWaitingForRowsInserted, false);
QCOMPARE(listModel->property("count").toInt(), 2);
deleteModel(listModel);
@@ -258,12 +266,12 @@ void TestJsonDbListModel::createItem()
// Create an item and then update it.
void TestJsonDbListModel::updateItemClient()
{
+ resetWaitFlags();
QVariantMap item;
item.insert("_type", __FUNCTION__);
item.insert("name", "Charlie");
- int id = mClient->create(item, "com.example.shared.1");
+ int id = create(item, "com.example.shared.1");
waitForResponse1(id);
-
QAbstractItemModel *listModel = createModel();
if (!listModel) return;
listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__));
@@ -273,36 +281,45 @@ void TestJsonDbListModel::updateItemClient()
// now start it working
QCOMPARE(listModel->property("count").toInt(), 0);
-
+ mWaitingForReset = true;
waitForExitOrTimeout();
+ QCOMPARE(mWaitingForReset, false);
QCOMPARE(listModel->property("count").toInt(), 1);
- item.insert("_uuid", mLastUuid);
+ QString lastUuid,lastVersion;
+ QVariantMap lastItem;
+ if (lastResult.count()) {
+ lastItem = lastResult[0].toMap();
+ lastUuid = lastItem.value("_uuid").toString();
+ lastVersion = lastItem.value("_version").toString();
+ }
+ item.insert("_uuid", lastUuid);
+ item.insert("_version", lastVersion);
item.insert("name", "Baker");
-
- mWaitingForDataChange = true;
- id = mClient->update(item, "com.example.shared.1");
+ id = update(item, "com.example.shared.1");
waitForResponse1(id);
-
- while (mWaitingForDataChange)
- mEventLoop.processEvents(QEventLoop::AllEvents);
+ while (!mItemsUpdated) {
+ mWaitingForChanged = true;
+ waitForExitOrTimeout();
+ }
+ QCOMPARE(mWaitingForChanged, false);
QCOMPARE(listModel->property("count").toInt(), 1);
- QCOMPARE(get(listModel, 0, "_uuid").toString(), mLastUuid);
+ QCOMPARE(get(listModel, 0, "_uuid").toString(), lastUuid);
QCOMPARE(get(listModel, 0, "_type").toString(), QLatin1String(__FUNCTION__));
QCOMPARE(get(listModel, 0, "name").toString(), QLatin1String("Baker"));
deleteModel(listModel);
}
-
// Create an item and then update it.
void TestJsonDbListModel::updateItemSet()
{
+ resetWaitFlags();
QVariantMap item;
item.insert("_type", __FUNCTION__);
item.insert("name", "Charlie");
item.insert("phone", "123456789");
- int id = mClient->create(item, "com.example.shared.1");
+ int id = create(item, "com.example.shared.1");
waitForResponse1(id);
QAbstractItemModel *listModel = createModel();
@@ -314,8 +331,9 @@ void TestJsonDbListModel::updateItemSet()
// now start it working
QCOMPARE(listModel->property("count").toInt(), 0);
-
+ mWaitingForReset = true;
waitForExitOrTimeout();
+ QCOMPARE(mWaitingForReset, false);
QCOMPARE(listModel->property("count").toInt(), 1);
QJSEngine engine;
@@ -324,12 +342,12 @@ void TestJsonDbListModel::updateItemSet()
value.setProperty("name", "Baker");
value.setProperty("phone", "987654321");
- mWaitingForDataChange = true;
-
set(listModel, 0, value);
-
- while (mWaitingForDataChange)
- mEventLoop.processEvents(QEventLoop::AllEvents);
+ while (!mItemsUpdated) {
+ mWaitingForChanged = true;
+ waitForExitOrTimeout();
+ }
+ QCOMPARE(mWaitingForChanged, false);
QCOMPARE(listModel->property("count").toInt(), 1);
QCOMPARE(get(listModel, 0, "_type").toString(), QLatin1String(__FUNCTION__));
@@ -337,13 +355,15 @@ void TestJsonDbListModel::updateItemSet()
QCOMPARE(get(listModel, 0, "phone").toString(), QLatin1String("987654321"));
deleteModel(listModel);
}
+
void TestJsonDbListModel::updateItemSetProperty()
{
+ resetWaitFlags();
QVariantMap item;
item.insert("_type", __FUNCTION__);
item.insert("name", "Charlie");
item.insert("phone", "123456789");
- int id = mClient->create(item, "com.example.shared.1");
+ int id = create(item, "com.example.shared.1");
waitForResponse1(id);
QAbstractItemModel *listModel = createModel();
@@ -355,16 +375,17 @@ void TestJsonDbListModel::updateItemSetProperty()
// now start it working
QCOMPARE(listModel->property("count").toInt(), 0);
-
+ mWaitingForReset = true;
waitForExitOrTimeout();
+ QCOMPARE(mWaitingForReset, false);
QCOMPARE(listModel->property("count").toInt(), 1);
- mWaitingForDataChange = true;
-
listSetProperty(listModel, 0, QString("phone"), QVariant("987654321"));
-
- while (mWaitingForDataChange)
- mEventLoop.processEvents(QEventLoop::AllEvents);
+ while (!mItemsUpdated) {
+ mWaitingForChanged = true;
+ waitForExitOrTimeout();
+ }
+ QCOMPARE(mWaitingForChanged, false);
QCOMPARE(listModel->property("count").toInt(), 1);
QCOMPARE(get(listModel, 0, "_type").toString(), QLatin1String(__FUNCTION__));
@@ -375,10 +396,11 @@ void TestJsonDbListModel::updateItemSetProperty()
void TestJsonDbListModel::deleteItem()
{
+ resetWaitFlags();
QVariantMap item;
item.insert("_type", __FUNCTION__);
item.insert("name", "Charlie");
- int id = mClient->create(item, "com.example.shared.1");
+ int id = create(item, "com.example.shared.1");
waitForResponse1(id);
QAbstractItemModel *listModel = createModel();
@@ -389,24 +411,38 @@ void TestJsonDbListModel::deleteItem()
connectListModel(listModel);
// now start it working
+ mWaitingForReset = true;
waitForExitOrTimeout();
+ QCOMPARE(mWaitingForReset, false);
QCOMPARE(listModel->property("count").toInt(), 1);
item.insert("name", "Baker");
mItemsCreated = 0;
- id = mClient->create(item,"com.example.shared.1");
+ id = create(item,"com.example.shared.1");
waitForResponse1(id);
- if (!mItemsCreated)
+ while (!mItemsCreated) {
+ mWaitingForRowsInserted = true;
waitForExitOrTimeout();
+ }
+ QCOMPARE(mWaitingForRowsInserted, false);
QCOMPARE(listModel->property("count").toInt(), 2);
- mWaitingForRowsRemoved = true;
- item.insert("_uuid", mLastUuid);
- id = mClient->remove(item, "com.example.shared.1");
-
+ QString lastUuid,lastVersion;
+ QVariantMap lastItem;
+ if (lastResult.count()) {
+ lastItem = lastResult[0].toMap();
+ lastUuid = lastItem.value("_uuid").toString();
+ lastVersion = lastItem.value("_version").toString();
+ }
+ item.insert("_uuid", lastUuid);
+ item.insert("_version", lastVersion);
+ id = remove(item, "com.example.shared.1");
waitForResponse1(id);
- while (mWaitingForRowsRemoved)
- mEventLoop.processEvents(QEventLoop::AllEvents);
+ while (!mItemsRemoved) {
+ mWaitingForRemoved = true;
+ waitForExitOrTimeout();
+ }
+ QCOMPARE(mWaitingForRemoved, false);
QCOMPARE(listModel->property("count").toInt(), 1);
QCOMPARE(get(listModel, 0, "_type").toString(), QLatin1String(__FUNCTION__));
@@ -414,9 +450,9 @@ void TestJsonDbListModel::deleteItem()
deleteModel(listModel);
}
-
void TestJsonDbListModel::sortedQuery()
{
+ resetWaitFlags();
int id = 0;
QVariantMap index;
@@ -424,14 +460,14 @@ void TestJsonDbListModel::sortedQuery()
index.insert("name", "number");
index.insert("propertyName", "number");
index.insert("propertyType", "number");
- id = mClient->create(index, "com.example.shared.1");
+ id = create(index, "com.example.shared.1");
waitForResponse1(id);
for (int i = 0; i < 1000; i++) {
QVariantMap item;
item.insert("_type", "RandNumber");
item.insert("number", i);
- id = mClient->create(item, "com.example.shared.1");
+ id = create(item, "com.example.shared.1");
waitForResponse1(id);
}
@@ -445,29 +481,36 @@ void TestJsonDbListModel::sortedQuery()
listModel->setProperty("roleNames", rolenames);
listModel->setProperty("query", "[?_type=\"RandNumber\"][/number]");
+ QCOMPARE(listModel->property("count").toInt(), 0);
+ mWaitingForReset = true;
waitForExitOrTimeout();
+ QCOMPARE(mWaitingForReset, false);
QCOMPARE(listModel->property("count").toInt(), 1000);
+
for (int i = 0; i < 1000; i++)
QCOMPARE(get(listModel, i,"number").toInt(), i);
-
listModel->setProperty("query","[?_type=\"RandNumber\"][\\number]");
+ mWaitingForReset = true;
waitForExitOrTimeout();
- for (int i = 0; i < 1000; i++)
+ QCOMPARE(mWaitingForReset, false);
+ QCOMPARE(listModel->property("count").toInt(), 1000);
+ for (int i = 0; i < 1000; i++) {
QCOMPARE(get(listModel, i,"number").toInt(), 999-i);
+ }
QCoreApplication::instance()->processEvents();
deleteModel(listModel);
}
-
void TestJsonDbListModel::ordering()
{
+ resetWaitFlags();
for (int i = 9; i >= 1; --i) {
QVariantMap item;
item.insert("_type", __FUNCTION__);
item.insert("name", "Charlie");
item.insert("order", QString::number(i));
- int id = mClient->create(item, "com.example.shared.1");
+ int id = create(item, "com.example.shared.1");
waitForResponse1(id);
}
@@ -480,13 +523,13 @@ void TestJsonDbListModel::ordering()
// now start it working
QCOMPARE(listModel->property("count").toInt(), 0);
-
+ mWaitingForReset = true;
waitForExitOrTimeout();
+ QCOMPARE(mWaitingForReset, false);
QStringList expectedOrder = QStringList() << "1" << "2" << "3" << "4" <<
"5" << "6" << "7" << "8" << "9";
QCOMPARE(getOrderValues(listModel), expectedOrder);
- mWaitingForDataChange = true;
{
QVariant uuid = get(listModel, 4, "_uuid");
QVERIFY(!uuid.toString().isEmpty());
@@ -496,17 +539,19 @@ void TestJsonDbListModel::ordering()
item.insert("_type", __FUNCTION__);
item.insert("name", "Charlie");
item.insert("order", "99"); // move it to the end
- int id = mClient->update(item, "com.example.shared.1");
+ int id = update(item, "com.example.shared.1");
waitForResponse1(id);
}
-
- while (mWaitingForDataChange)
- mEventLoop.processEvents(QEventLoop::AllEvents);
+ while (!mItemsUpdated) {
+ mWaitingForChanged = true;
+ waitForExitOrTimeout();
+ }
+ QCOMPARE(mWaitingForChanged, false);
expectedOrder = QStringList() << "1" << "2" << "3" <<
"4" << "6" << "7" << "8" << "9" << "99";
QCOMPARE(getOrderValues(listModel), expectedOrder);
- mWaitingForDataChange = true;
+ mItemsUpdated = 0;
{
QVariant uuid = get(listModel, 8, "_uuid");
QVERIFY(!uuid.toString().isEmpty());
@@ -516,17 +561,19 @@ void TestJsonDbListModel::ordering()
item.insert("_type", __FUNCTION__);
item.insert("name", "Charlie");
item.insert("order", "22"); // move it after "2"
- int id = mClient->update(item, "com.example.shared.1");
+ int id = update(item, "com.example.shared.1");
waitForResponse1(id);
}
-
- while (mWaitingForDataChange)
- mEventLoop.processEvents(QEventLoop::AllEvents);
+ while (!mItemsUpdated) {
+ mWaitingForChanged = true;
+ waitForExitOrTimeout();
+ }
+ QCOMPARE(mWaitingForChanged, false);
expectedOrder = QStringList() << "1" << "2" << "22" << "3" <<
"4" << "6" << "7" << "8" << "9";
QCOMPARE(getOrderValues(listModel), expectedOrder);
- mWaitingForDataChange = true;
+ mItemsUpdated = 0;
{
QVariant uuid = get(listModel, 5, "_uuid");
QVERIFY(!uuid.toString().isEmpty());
@@ -536,29 +583,30 @@ void TestJsonDbListModel::ordering()
item.insert("_type", __FUNCTION__);
item.insert("name", "Charlie");
item.insert("order", "0"); // move it to the beginning
- int id = mClient->update(item, "com.example.shared.1");
+ int id = update(item, "com.example.shared.1");
waitForResponse1(id);
}
-
- while (mWaitingForDataChange)
- mEventLoop.processEvents(QEventLoop::AllEvents);
+ while (!mItemsUpdated) {
+ mWaitingForChanged = true;
+ waitForExitOrTimeout();
+ }
+ QCOMPARE(mWaitingForChanged, false);
expectedOrder = QStringList() << "0" << "1" << "2" << "22" << "3" <<
"4" << "7" << "8" << "9";
QCOMPARE(getOrderValues(listModel), expectedOrder);
deleteModel(listModel);
-
}
void TestJsonDbListModel::itemNotInCache()
{
+ resetWaitFlags();
QVariantMap index;
index.insert("_type", "Index");
index.insert("name", "order");
index.insert("propertyName", "order");
index.insert("propertyType", "number");
- //index.insert("partition", "com.example.shared.1");
- int indexId = mClient->create(index, "com.example.shared.1");
+ int indexId = create(index, "com.example.shared.1");
waitForResponse1(indexId);
QVariantList itemList;
@@ -569,7 +617,7 @@ void TestJsonDbListModel::itemNotInCache()
item.insert("order", i);
itemList << item;
}
- int id = mClient->create(itemList, "com.example.shared.1");
+ int id = create(itemList, "com.example.shared.1");
waitForResponse1(id);
QAbstractItemModel *listModel = createModel();
@@ -579,14 +627,16 @@ void TestJsonDbListModel::itemNotInCache()
listModel->setProperty("query", QString("[?_type=\"%1\"][/order]").arg(__FUNCTION__));
QStringList roleNames = (QStringList() << "_type" << "_uuid" << "name" << "order");
listModel->setProperty("roleNames",roleNames);
+ mWaitingForReset = true;
waitForExitOrTimeout();
-
+ QCOMPARE(mWaitingForReset, false);
QCOMPARE(listModel->property("count").toInt(), 1000);
// Make sure that the first items in the list is in the cache.
QVariant result = listModel->data(listModel->index(10,0), 3);
QVERIFY(result.isValid());
QCOMPARE(result.toInt(), 10);
+
// This item should not be in the cache now.
QVariant res = listModel->data(listModel->index(960,0), 3);
QCOMPARE(res.toInt(), 960);
@@ -595,11 +645,12 @@ void TestJsonDbListModel::itemNotInCache()
void TestJsonDbListModel::roles()
{
+ resetWaitFlags();
QVariantMap item;
item.insert("_type", __FUNCTION__);
item.insert("name", "Charlie");
item.insert("phone", "123456789");
- int id = mClient->create(item, "com.example.shared.1");
+ int id = create(item, "com.example.shared.1");
waitForResponse1(id);
@@ -612,7 +663,9 @@ void TestJsonDbListModel::roles()
connectListModel(listModel);
// now start it working
+ mWaitingForReset = true;
waitForExitOrTimeout();
+ QCOMPARE(mWaitingForReset, false);
QCOMPARE(listModel->property("count").toInt(), 1);
QVariantMap roles = listModel->property("roleNames").toMap();
@@ -624,17 +677,17 @@ void TestJsonDbListModel::roles()
void TestJsonDbListModel::totalRowCount()
{
+ resetWaitFlags();
int id = 0;
QVariantList insertedItems;
for (int i = 0; i < 10; i++) {
QVariantMap item;
item.insert("_type", __FUNCTION__);
item.insert("order", i);
- id = mClient->create(item, "com.example.shared.1");
+ id = create(item, "com.example.shared.1");
waitForResponse1(id);
- insertedItems << mData;
+ insertedItems << lastResult;
}
-
QAbstractItemModel *listModel = createModel();
if (!listModel)
return;
@@ -645,14 +698,16 @@ void TestJsonDbListModel::totalRowCount()
QStringList roleNames = (QStringList() << "_type" << "_uuid" << "order");
listModel->setProperty("roleNames",roleNames);
+ mWaitingForReset = true;
waitForExitOrTimeout();
+ QCOMPARE(mWaitingForReset, false);
QCOMPARE(listModel->property("count").toInt(), 10);
for (int i = 10; i < 50; i++) {
QVariantMap item;
item.insert("_type", __FUNCTION__);
item.insert("order", i);
- mClient->create(item, "com.example.shared.1");
+ create(item, "com.example.shared.1");
}
waitForItemsCreated(40);
@@ -660,15 +715,22 @@ void TestJsonDbListModel::totalRowCount()
// Change query
listModel->setProperty("query", QString("[?_type=\"%1\"][\\order]").arg(__FUNCTION__));
+ mWaitingForReset = true;
waitForExitOrTimeout();
+ QCOMPARE(mWaitingForReset, false);
QCOMPARE(listModel->property("count").toInt(), 50);
// Delete the first 10 items
foreach (QVariant item, insertedItems) {
- mWaitingForRowsRemoved = true;
- id = mClient->remove(item.toMap(), "com.example.shared.1");
- while(mWaitingForRowsRemoved)
- mEventLoop.processEvents(QEventLoop::AllEvents);
+ mItemsRemoved = 0;
+ id = remove(item.toMap(), "com.example.shared.1");
+ waitForResponse1(id);
+
+ while (!mTimedOut && !mItemsRemoved) {
+ mWaitingForRemoved = true;
+ waitForExitOrTimeout();
+ }
+ QCOMPARE(mWaitingForRemoved, false);
}
QCOMPARE(listModel->property("count").toInt(), 40);
@@ -678,11 +740,13 @@ void TestJsonDbListModel::totalRowCount()
void TestJsonDbListModel::listProperty()
{
- QVariant jsonData = readJsonFile("list-objects.json");
+ resetWaitFlags();
+ QVariant jsonData = readJsonFile(findFile("list-objects.json")).toVariant();
QVariantList itemList = jsonData.toList();
+
int id = 0;
for (int i = 0; i < itemList.count(); i++) {
- id = mClient->create(itemList[i].toMap(), "com.example.shared.1");
+ id = create(itemList[i].toMap(), "com.example.shared.1");
waitForResponse1(id);
}
@@ -695,13 +759,23 @@ void TestJsonDbListModel::listProperty()
listModel->setProperty("query", QString("[?_type=\"%1\"][/features.0.properties.0.description]").arg(type));
QStringList roleNames = (QStringList() << "_type" << "_uuid" << "features.0.properties.0.description"<< "features.0.feature");
listModel->setProperty("roleNames",roleNames);
+ mWaitingForReset = true;
waitForExitOrTimeout();
+ QCOMPARE(mWaitingForReset, false);
+
+ QString lastUuid,lastVersion;
+ QVariantMap lastItem;
+ if (lastResult.count()) {
+ lastItem = lastResult[0].toMap();
+ lastUuid = lastItem.value("_uuid").toString();
+ lastVersion = lastItem.value("_version").toString();
+ }
QCOMPARE(listModel->property("count").toInt(), itemList.count());
QCOMPARE(get(listModel, 0, "_type").toString(), type);
QCOMPARE(get(listModel, 0, "features.0.properties.0.description").toString(), QLatin1String("Facebook account provider"));
QCOMPARE(get(listModel, 0, "features.0.feature").toString(), QLatin1String("provide Facebook"));
- QCOMPARE(get(listModel, 1, "_uuid").toString(), mLastUuid);
+ QCOMPARE(get(listModel, 1, "_uuid").toString(), lastUuid);
QCOMPARE(get(listModel, 1, "_type").toString(), type);
QCOMPARE(get(listModel, 1, "features.0.properties.0.description").toString(), QLatin1String("Gmail account provider"));
QCOMPARE(get(listModel, 1, "features.0.feature").toString(), QLatin1String("provide Gmail"));
@@ -718,7 +792,9 @@ void TestJsonDbListModel::listProperty()
roleNames.clear();
roleNames = (QStringList() << "_type" << "_uuid" << "features[0].properties[0].description"<< "features[0].supported[0]");
listModel->setProperty("roleNames",roleNames);
+ mWaitingForReset = true;
waitForExitOrTimeout();
+ QCOMPARE(mWaitingForReset, false);
QCOMPARE(listModel->property("count").toInt(), itemList.count());
QCOMPARE(get(listModel, 0, "_type").toString(), type);
@@ -739,18 +815,22 @@ QStringList TestJsonDbListModel::getOrderValues(QAbstractItemModel *listModel)
return vals;
}
-
void TestJsonDbListModel::modelReset()
{
- //qDebug() << "TestJsonDbListModel::modelReset";
- mEventLoop.exit(0);
+ if (mWaitingForReset) {
+ mWaitingForReset = false;
+ eventLoop1.exit(0);
+ }
}
void TestJsonDbListModel::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
{
Q_UNUSED(topLeft);
Q_UNUSED(bottomRight);
- //qDebug() << "TestJsonDbListModel::dataChanged";
- mWaitingForDataChange = false;
+ mItemsUpdated++;
+ if (mWaitingForChanged) {
+ mWaitingForChanged = false;
+ eventLoop1.exit(0);
+ }
}
void TestJsonDbListModel::rowsInserted(const QModelIndex &parent, int first, int last)
{
@@ -758,16 +838,21 @@ void TestJsonDbListModel::rowsInserted(const QModelIndex &parent, int first, int
Q_UNUSED(first);
Q_UNUSED(last);
mItemsCreated++;
- //qDebug() << "TestJsonDbListModel::rowsInserted";
- mEventLoop.exit(0);
+ if (mWaitingForRowsInserted) {
+ mWaitingForRowsInserted = false;
+ eventLoop1.exit(0);
+ }
}
void TestJsonDbListModel::rowsRemoved(const QModelIndex &parent, int first, int last)
{
Q_UNUSED(parent);
Q_UNUSED(first);
Q_UNUSED(last);
- mWaitingForRowsRemoved = false;
- //qDebug() << "TestJsonDbListModel::rowsRemoved";
+ mItemsRemoved++;
+ if (mWaitingForRemoved) {
+ mWaitingForRemoved = false;
+ eventLoop1.exit(0);
+ }
}
void TestJsonDbListModel::rowsMoved( const QModelIndex &parent, int start, int end, const QModelIndex &destination, int row )
{
@@ -776,7 +861,6 @@ void TestJsonDbListModel::rowsMoved( const QModelIndex &parent, int start, int e
Q_UNUSED(end);
Q_UNUSED(destination);
Q_UNUSED(row);
- //qDebug() << "TestJsonDbListModel::rowsMoved";
}
QTEST_MAIN(TestJsonDbListModel)
diff --git a/tests/auto/jsondblistmodel/testjsondblistmodel.h b/tests/auto/jsondblistmodel/testjsondblistmodel.h
index 79b8b851..8be75759 100644
--- a/tests/auto/jsondblistmodel/testjsondblistmodel.h
+++ b/tests/auto/jsondblistmodel/testjsondblistmodel.h
@@ -41,22 +41,9 @@
#ifndef TestJsonDbListModel_H
#define TestJsonDbListModel_H
-#include <QCoreApplication>
-#include <QList>
-#include <QTest>
-#include <QFile>
-#include <QProcess>
-#include <QEventLoop>
-#include <QDebug>
-#include <QLocalSocket>
-#include <QTimer>
-
-#include <jsondb-client.h>
-#include <jsondb-error.h>
-
#include <QAbstractItemModel>
-#include "clientwrapper.h"
-#include "../../shared/qmltestutil.h"
+#include "requestwrapper.h"
+#include "qmltestutil.h"
QT_BEGIN_NAMESPACE
class QQmlEngine;
@@ -76,7 +63,7 @@ public:
QObject *model;
};
-class TestJsonDbListModel: public ClientWrapper
+class TestJsonDbListModel: public RequestWrapper
{
Q_OBJECT
public:
@@ -108,26 +95,30 @@ private slots:
void roles();
void totalRowCount();
void listProperty();
-
+public:
+ void timeout();
private:
void waitForExitOrTimeout();
void waitForItemsCreated(int items);
QStringList getOrderValues(QAbstractItemModel *listModel);
QAbstractItemModel *createModel();
void deleteModel(QAbstractItemModel *model);
- QVariant readJsonFile(const QString &filename);
+ void resetWaitFlags();
private:
- QProcess *mProcess;
- QStringList mNotificationsReceived;
+ QProcess *mProcess;
QList<ModelData*> mModels;
QString mPluginPath;
// Response values
- int mItemsCreated;
- bool mWaitingForNotification;
- bool mWaitingForDataChange;
- bool mWaitingForRowsRemoved;
+ bool mTimedOut;
+ int mItemsCreated;
+ int mItemsUpdated;
+ int mItemsRemoved;
+ bool mWaitingForRowsInserted;
+ bool mWaitingForReset;
+ bool mWaitingForChanged;
+ bool mWaitingForRemoved;
};
#endif
diff --git a/tests/auto/jsondbnotification/jsondbnotification.pro b/tests/auto/jsondbnotification/jsondbnotification.pro
index f4e1fd67..1703343d 100644
--- a/tests/auto/jsondbnotification/jsondbnotification.pro
+++ b/tests/auto/jsondbnotification/jsondbnotification.pro
@@ -1,17 +1,20 @@
TEMPLATE = app
TARGET = tst_jsondbnotification
DEPENDPATH += .
-INCLUDEPATH += .
+INCLUDEPATH += . ../../shared/
-QT = core network testlib gui qml jsondbcompat-private
+QT = core network testlib gui qml jsondb
CONFIG -= app_bundle
CONFIG += testcase
include($$PWD/../../shared/shared.pri)
-include($$PWD/../../../src/3rdparty/qjson/qjson.pri)
DEFINES += JSONDB_DAEMON_BASE=\\\"$$QT.jsondb.bins\\\"
DEFINES += SRCDIR=\\\"$$PWD/\\\"
-HEADERS += testjsondbnotification.h
+HEADERS += testjsondbnotification.h \
+ $$PWD/../../shared/requestwrapper.h
SOURCES += testjsondbnotification.cpp
+
+OTHER_FILES += \
+ partitions.json
diff --git a/tests/auto/jsondbnotification/partitions.json b/tests/auto/jsondbnotification/partitions.json
new file mode 100644
index 00000000..c77651a0
--- /dev/null
+++ b/tests/auto/jsondbnotification/partitions.json
@@ -0,0 +1,3 @@
+[
+ { "name" :"com.nokia.shared" }
+]
diff --git a/tests/auto/jsondbnotification/testjsondbnotification.cpp b/tests/auto/jsondbnotification/testjsondbnotification.cpp
index 6e3610f5..418b1100 100644
--- a/tests/auto/jsondbnotification/testjsondbnotification.cpp
+++ b/tests/auto/jsondbnotification/testjsondbnotification.cpp
@@ -41,10 +41,9 @@
#include <QtTest/QtTest>
#include <QJSEngine>
+#include <QJSValueIterator>
#include "testjsondbnotification.h"
#include "../../shared/util.h"
-#include <QJSValueIterator>
-#include "json.h"
static const char dbfile[] = "dbFile-jsondb-partition";
@@ -71,6 +70,20 @@ const QString qmlProgramForPartition = QLatin1String(
"name: \"com.nokia.shared\";"
"}");
+#define waitForReadyStatus(obj) \
+ { \
+ int status = 0; \
+ while ((status = obj->property("status").toInt()) < 2) { \
+ waitForCallback1(); \
+ } \
+ }
+
+#define waitForCallbackNId(id) \
+ { \
+ waitForCallback1(); \
+ if (id != lastRequestId) \
+ waitForResponse1(id); \
+ }
TestJsonDbNotification::TestJsonDbNotification()
: mTimedOut(false)
@@ -84,8 +97,9 @@ TestJsonDbNotification::~TestJsonDbNotification()
void TestJsonDbNotification::timeout()
{
- ClientWrapper::timeout();
+ RequestWrapper::timeout();
mTimedOut = true;
+ eventLoop1.quit();
}
void TestJsonDbNotification::deleteDbFiles()
@@ -108,25 +122,12 @@ void TestJsonDbNotification::initTestCase()
deleteDbFiles();
QString socketName = QString("testjsondb_%1").arg(getpid());
- mProcess = launchJsonDbDaemon(JSONDB_DAEMON_BASE, socketName, QStringList() << "-base-name" << dbfile);
+ mProcess = launchJsonDbDaemon(JSONDB_DAEMON_BASE, socketName, QStringList() << "-base-name" << dbfile, __FILE__);
- mClient = new JsonDbClient(this);
- connect(mClient, SIGNAL(notified(QString,QtAddOn::JsonDb::JsonDbNotification)),
- this, SLOT(notified(QString,QtAddOn::JsonDb::JsonDbNotification)));
- connect( mClient, SIGNAL(response(int, const QVariant&)),
- this, SLOT(response(int, const QVariant&)));
- connect( mClient, SIGNAL(error(int, int, const QString&)),
- this, SLOT(error(int, int, const QString&)));
+ connection = new QJsonDbConnection();
+ connection->connectToServer();
mPluginPath = findQMLPluginPath("QtJsonDb");
-
- // Create the shared Partitions
- QVariantMap item;
- item.insert("_type", "Partition");
- item.insert("name", "com.nokia.shared");
- int id = mClient->create(item);
- waitForResponse1(id);
-
}
ComponentData *TestJsonDbNotification::createComponent()
@@ -146,6 +147,8 @@ ComponentData *TestJsonDbNotification::createComponent()
qDebug() << componentData->component->errors();
QObject::connect(componentData->qmlElement, SIGNAL(notificationSignal(QVariant, int, int)),
this, SLOT(notificationSlot(QVariant, int, int)));
+ QObject::connect(componentData->qmlElement, SIGNAL(statusChanged(JsonDbNotify::Status)),
+ this, SLOT(statusChangedSlot2()));
mComponents.append(componentData);
return componentData;
}
@@ -193,8 +196,8 @@ void TestJsonDbNotification::notificationSlot(QVariant result, int action, int s
data.result = result.toMap();
data.action = action;
data.stateNumber = stateNumber;
- cbData.append(data);
- mEventLoop2.quit();
+ callbackData.append(data);
+ eventLoop1.quit();
}
void TestJsonDbNotification::errorSlot(int code, const QString &message)
@@ -202,7 +205,7 @@ void TestJsonDbNotification::errorSlot(int code, const QString &message)
callbackError = true;
callbackErrorCode = code;
callbackErrorMessage = message;
- mEventLoop2.quit();
+ eventLoop1.quit();
}
void TestJsonDbNotification::notificationSlot2(QJSValue result, Actions action, int stateNumber)
@@ -211,8 +214,13 @@ void TestJsonDbNotification::notificationSlot2(QJSValue result, Actions action,
data.result = result.toVariant().toMap();
data.action = action;
data.stateNumber = stateNumber;
- cbData.append(data);
- mEventLoop2.quit();
+ callbackData.append(data);
+ eventLoop1.quit();
+}
+
+void TestJsonDbNotification::statusChangedSlot2()
+{
+ eventLoop1.quit();
}
void TestJsonDbNotification::singleObjectNotifications()
@@ -227,31 +235,35 @@ void TestJsonDbNotification::singleObjectNotifications()
actionsList.append(2);
actionsList.append(4);
notification->qmlElement->setProperty("actions", actionsList);
+ waitForReadyStatus(notification->qmlElement);
CallbackData data;
//Create an object
QVariantMap item = createObject(__FUNCTION__).toMap();
- mClient->create(item, "com.nokia.shared");
- waitForCallback2();
- QCOMPARE(cbData.size(), 1);
- data = cbData.takeAt(0);
+ int id = create(item, "com.nokia.shared");
+ waitForCallbackNId(id);
+
+ QCOMPARE(callbackData.size(), 1);
+ data = callbackData.takeAt(0);
QCOMPARE(data.action, 1);
QCOMPARE(data.result.value("alphabet"), item.value("alphabet"));
QString uuid = data.result.value("_uuid").toString();
//update the object
QString newAlphabet = data.result.value("alphabet").toString()+QString("**");
data.result.insert("alphabet", newAlphabet);
- mClient->update(data.result, "com.nokia.shared");
- waitForCallback2();
- QCOMPARE(cbData.size(), 1);
- data = cbData.takeAt(0);
+ id = update(data.result, "com.nokia.shared");
+ waitForCallbackNId(id);
+
+ QCOMPARE(callbackData.size(), 1);
+ data = callbackData.takeAt(0);
QCOMPARE(data.action, 2);
QCOMPARE(data.result.value("alphabet").toString(), newAlphabet);
//Remove the object
- mClient->remove(data.result, "com.nokia.shared");
- waitForCallback2();
- QCOMPARE(cbData.size(), 1);
- data = cbData.takeAt(0);
+ id = remove(data.result, "com.nokia.shared");
+ waitForCallbackNId(id);
+
+ QCOMPARE(callbackData.size(), 1);
+ data = callbackData.takeAt(0);
QCOMPARE(data.action, 4);
QCOMPARE(data.result.value("_uuid").toString(), uuid);
deleteComponent(notification);
@@ -269,62 +281,72 @@ void TestJsonDbNotification::multipleObjectNotifications()
actionsList.append(2);
actionsList.append(4);
notification->qmlElement->setProperty("actions", actionsList);
+ waitForReadyStatus(notification->qmlElement);
//Create objects
QVariantList items = createObjectList(__FUNCTION__, 10).toList();
- mClient->create(QVariant(items), "com.nokia.shared");
+ int id = create(items, "com.nokia.shared");
for (int i = 0; i<10; i++) {
- waitForCallback2();
- if (cbData.size() >= 10)
+ waitForCallback1();
+ if (callbackData.size() >= 10)
break;
}
- QCOMPARE(cbData.size(), 10);
+ if (id != lastRequestId)
+ waitForResponse1(id);
+
+ QCOMPARE(callbackData.size(), 10);
QVariantList objList;
for (int i = 0; i<10; i++) {
- QCOMPARE(cbData[i].action, 1);
+ QCOMPARE(callbackData[i].action, 1);
QVariantMap item = items[i].toMap();
- QVariantMap obj = cbData[i].result;
+ QVariantMap obj = callbackData[i].result;
QCOMPARE(obj.value("alphabet"), item.value("alphabet"));
- QString newAlphabet = cbData[i].result.value("alphabet").toString()+QString("**");
+ QString newAlphabet = callbackData[i].result.value("alphabet").toString()+QString("**");
obj.insert("alphabet", newAlphabet);
objList.append(obj);
}
- cbData.clear();
+ callbackData.clear();
//update the object
- mClient->update(QVariant(objList), "com.nokia.shared");
+ id = update(objList, "com.nokia.shared");
for (int i = 0; i<10; i++) {
- waitForCallback2();
- if (cbData.size() >= 10)
+ waitForCallback1();
+ if (callbackData.size() >= 10)
break;
}
- QCOMPARE(cbData.size(), 10);
+ if (id != lastRequestId)
+ waitForResponse1(id);
+
+ QCOMPARE(callbackData.size(), 10);
QVariantList lst = objList;
objList.clear();
for (int i = 0; i<10; i++) {
- QCOMPARE(cbData[i].action, 2);
+ QCOMPARE(callbackData[i].action, 2);
QVariantMap item = lst[i].toMap();
- QVariantMap obj = cbData[i].result;
+ QVariantMap obj = callbackData[i].result;
QCOMPARE(obj.value("alphabet"), item.value("alphabet"));
objList.append(obj);
}
- cbData.clear();
+ callbackData.clear();
//Remove the object
- mClient->remove(objList, "com.nokia.shared");
+ id = remove(objList, "com.nokia.shared");
for (int i = 0; i<10; i++) {
- waitForCallback2();
- if (cbData.size() >= 10)
+ waitForCallback1();
+ if (callbackData.size() >= 10)
break;
}
- QCOMPARE(cbData.size(), 10);
+ if (id != lastRequestId)
+ waitForResponse1(id);
+
+ QCOMPARE(callbackData.size(), 10);
for (int i = 0; i<10; i++) {
- QCOMPARE(cbData[i].action, 4);
+ QCOMPARE(callbackData[i].action, 4);
QVariantMap item = objList[i].toMap();
- QVariantMap obj = cbData[i].result;
+ QVariantMap obj = callbackData[i].result;
QCOMPARE(obj.value("_uuid"), item.value("_uuid"));
}
- cbData.clear();
+ callbackData.clear();
deleteComponent(notification);
}
@@ -341,15 +363,21 @@ void TestJsonDbNotification::createNotification()
QPointer<QObject> notification = expr->evaluate().value<QObject*>();
QVERIFY(!notification.isNull());
notification->setParent(partition->qmlElement);
- QObject::connect(notification, SIGNAL(notification(QJSValue, Actions, int)),
- this, SLOT(notificationSlot2(QJSValue, Actions, int)));
+ QObject::connect(notification, SIGNAL(notification(QJSValue,Actions,int)),
+ this, SLOT(notificationSlot2(QJSValue,Actions,int)));
+ QObject::connect(notification, SIGNAL(statusChanged(JsonDbNotify::Status)),
+ this, SLOT(statusChangedSlot2()));
+ waitForReadyStatus(notification);
+
+
CallbackData data;
//Create an object
QVariantMap item = createObject(__FUNCTION__).toMap();
- mClient->create(item, "com.nokia.shared");
- waitForCallback2();
- QCOMPARE(cbData.size(), 1);
- data = cbData.takeAt(0);
+ int id = create(item, "com.nokia.shared");
+ waitForCallbackNId(id);
+
+ QCOMPARE(callbackData.size(), 1);
+ data = callbackData.takeAt(0);
QCOMPARE(data.action, 1);
QCOMPARE(data.result.value("alphabet"), item.value("alphabet"));
diff --git a/tests/auto/jsondbnotification/testjsondbnotification.h b/tests/auto/jsondbnotification/testjsondbnotification.h
index 9b728a61..158eba59 100644
--- a/tests/auto/jsondbnotification/testjsondbnotification.h
+++ b/tests/auto/jsondbnotification/testjsondbnotification.h
@@ -41,23 +41,9 @@
#ifndef TESTJSONDBNOTIFICATION_H
#define TESTJSONDBNOTIFICATION_H
-#include <QCoreApplication>
-#include <QList>
-#include <QTest>
-#include <QFile>
-#include <QProcess>
-#include <QEventLoop>
-#include <QDebug>
-#include <QLocalSocket>
-#include <QTimer>
-#include <QJSValue>
-
-#include <jsondb-client.h>
-#include <jsondb-error.h>
-
#include <QAbstractItemModel>
-#include "clientwrapper.h"
-#include "../../shared/qmltestutil.h"
+#include "requestwrapper.h"
+#include "qmltestutil.h"
QT_USE_NAMESPACE_JSONDB
@@ -67,7 +53,7 @@ struct CallbackData {
QVariantMap result;
};
-class TestJsonDbNotification: public ClientWrapper
+class TestJsonDbNotification: public RequestWrapper
{
Q_OBJECT
public:
@@ -91,8 +77,9 @@ public slots:
void notificationSlot(QVariant result, int action, int stateNumber);
void errorSlot(int code, const QString &message);
void notificationSlot2(QJSValue result, Actions action, int stateNumber);
+ void statusChangedSlot2();
-protected slots:
+public:
void timeout();
private:
@@ -105,12 +92,10 @@ private:
QStringList mNotificationsReceived;
QList<ComponentData*> mComponents;
QString mPluginPath;
+
+ // Response values
bool mTimedOut;
- bool callbackError;
- int callbackErrorCode;
- QString callbackErrorMessage;
- QList<CallbackData> cbData;
- QEventLoop mEventLoop2;
+ QList<CallbackData> callbackData;
};
#endif
diff --git a/tests/auto/jsondbpartition/jsondbpartition.pro b/tests/auto/jsondbpartition/jsondbpartition.pro
index 09433e1f..be202eb4 100644
--- a/tests/auto/jsondbpartition/jsondbpartition.pro
+++ b/tests/auto/jsondbpartition/jsondbpartition.pro
@@ -1,17 +1,20 @@
TEMPLATE = app
TARGET = tst_jsondbpartition
DEPENDPATH += .
-INCLUDEPATH += .
+INCLUDEPATH += . ../../shared/
-QT = core network testlib gui qml jsondbcompat-private
+QT = core network testlib gui qml jsondb
CONFIG -= app_bundle
CONFIG += testcase
include($$PWD/../../shared/shared.pri)
-include($$PWD/../../../src/3rdparty/qjson/qjson.pri)
DEFINES += JSONDB_DAEMON_BASE=\\\"$$QT.jsondb.bins\\\"
DEFINES += SRCDIR=\\\"$$PWD/\\\"
-HEADERS += testjsondbpartition.h
+HEADERS += testjsondbpartition.h \
+ $$PWD/../../shared/requestwrapper.h
SOURCES += testjsondbpartition.cpp
+
+OTHER_FILES += \
+ partitions.json
diff --git a/tests/auto/jsondbpartition/partitions.json b/tests/auto/jsondbpartition/partitions.json
new file mode 100644
index 00000000..9788d134
--- /dev/null
+++ b/tests/auto/jsondbpartition/partitions.json
@@ -0,0 +1,3 @@
+[
+ { "name" :"com.nokia.shared.1" }
+]
diff --git a/tests/auto/jsondbpartition/testjsondbpartition.cpp b/tests/auto/jsondbpartition/testjsondbpartition.cpp
index bfdafa62..2f275434 100644
--- a/tests/auto/jsondbpartition/testjsondbpartition.cpp
+++ b/tests/auto/jsondbpartition/testjsondbpartition.cpp
@@ -41,10 +41,9 @@
#include <QtTest/QtTest>
#include <QJSEngine>
+#include <QJSValueIterator>
#include "testjsondbpartition.h"
#include "../../shared/util.h"
-#include <QJSValueIterator>
-#include "json.h"
static const char dbfile[] = "dbFile-jsondb-partition";
@@ -69,8 +68,9 @@ TestJsonDbPartition::~TestJsonDbPartition()
void TestJsonDbPartition::timeout()
{
- ClientWrapper::timeout();
+ RequestWrapper::timeout();
mTimedOut = true;
+ eventLoop1.quit();
}
void TestJsonDbPartition::deleteDbFiles()
@@ -87,45 +87,20 @@ void TestJsonDbPartition::deleteDbFiles()
}
}
-QVariant TestJsonDbPartition::readJsonFile(const QString& filename)
-{
- QString filepath = findFile(filename);
- QFile jsonFile(filepath);
- jsonFile.open(QIODevice::ReadOnly);
- QByteArray json = jsonFile.readAll();
- JsonReader parser;
- bool ok = parser.parse(json);
- if (!ok) {
- qDebug() << filepath << parser.errorString();
- }
- return parser.result();
-}
-
void TestJsonDbPartition::initTestCase()
{
// make sure there is no old db files.
deleteDbFiles();
QString socketName = QString("testjsondb_%1").arg(getpid());
- mProcess = launchJsonDbDaemon(JSONDB_DAEMON_BASE, socketName, QStringList() << "-base-name" << dbfile);
+ mProcess = launchJsonDbDaemon(JSONDB_DAEMON_BASE, socketName, QStringList() << "-base-name" << dbfile, __FILE__);
- mClient = new JsonDbClient(this);
- connect(mClient, SIGNAL(notified(QString,QtAddOn::JsonDb::JsonDbNotification)),
- this, SLOT(notified(QString,QtAddOn::JsonDb::JsonDbNotification)));
- connect( mClient, SIGNAL(response(int, const QVariant&)),
- this, SLOT(response(int, const QVariant&)));
- connect( mClient, SIGNAL(error(int, int, const QString&)),
- this, SLOT(error(int, int, const QString&)));
+ connection = new QJsonDbConnection();
+ connection->connectToServer();
mPluginPath = findQMLPluginPath("QtJsonDb");
-
- // Create the shared Partitions
- QVariantMap item;
- item.insert("_type", "Partition");
- item.insert("name", "com.nokia.shared.1");
- int id = mClient->create(item);
- waitForResponse1(id);
-
+ if (mPluginPath.isEmpty())
+ qDebug() << "Couldn't find the plugin path for the plugin QtJsonDb";
}
ComponentData *TestJsonDbPartition::createComponent()
@@ -173,7 +148,7 @@ void TestJsonDbPartition::callbackSlot(QVariant error, QVariant response)
callbackError = error.isValid();
callbackMeta = response;
callbackResponse = response.toMap().value("items").toList();
- mEventLoop.quit();
+ eventLoop1.quit();
}
// JsonDb.Partition.create()
@@ -192,7 +167,7 @@ void TestJsonDbPartition::create()
int id = 0;
expr = new QQmlExpression(partition->engine->rootContext(), partition->qmlElement, expression);
id = expr->evaluate().toInt();
- waitForCallback();
+ waitForCallback1();
QCOMPARE(callbackError, false);
QCOMPARE(callbackMeta.toMap()["id"].toInt(), id);
QCOMPARE(callbackResponse.toList().size(), 1);
@@ -201,7 +176,7 @@ void TestJsonDbPartition::create()
expression = QString(createString).arg(objectString(QString(), obj));
expr->setExpression(expression);
id = expr->evaluate().toInt();
- waitForCallback();
+ waitForCallback1();
QCOMPARE(callbackError, false);
QCOMPARE(callbackMeta.toMap()["id"].toInt(), id);
QCOMPARE(callbackResponse.toList().size(), 1);
@@ -210,7 +185,7 @@ void TestJsonDbPartition::create()
expression = QString(createString).arg(objectString(QString(), obj));
expr->setExpression(expression);
id = expr->evaluate().toInt();
- waitForCallback();
+ waitForCallback1();
QCOMPARE(callbackError, false);
QCOMPARE(callbackMeta.toMap()["id"].toInt(), id);
QCOMPARE(callbackResponse.toList().size(), 5);
@@ -238,7 +213,7 @@ void TestJsonDbPartition::update()
int id = 0;
expr = new QQmlExpression(partition->engine->rootContext(), partition->qmlElement, expression);
id = expr->evaluate().toInt();
- waitForCallback();
+ waitForCallback1();
QCOMPARE(callbackError, false);
QCOMPARE(callbackMeta.toMap()["id"].toInt(), id);
QCOMPARE(callbackResponse.toList().size(), 1);
@@ -250,7 +225,7 @@ void TestJsonDbPartition::update()
expression = QString(updateString).arg(objectString(QString(), obj));
expr->setExpression(expression);
id = expr->evaluate().toInt();
- waitForCallback();
+ waitForCallback1();
QCOMPARE(callbackError, false);
QCOMPARE(callbackMeta.toMap()["id"].toInt(), id);
QCOMPARE(callbackResponse.toList().size(), 1);
@@ -259,7 +234,7 @@ void TestJsonDbPartition::update()
expression = QString(createString).arg(objectString(QString(), obj));
expr->setExpression(expression);
id = expr->evaluate().toInt();
- waitForCallback();
+ waitForCallback1();
QCOMPARE(callbackError, false);
QCOMPARE(callbackMeta.toMap()["id"].toInt(), id);
QCOMPARE(callbackResponse.toList().size(), 5);
@@ -275,7 +250,7 @@ void TestJsonDbPartition::update()
expression = QString(updateString).arg(objectString(QString(), obj));
expr->setExpression(expression);
id = expr->evaluate().toInt();
- waitForCallback();
+ waitForCallback1();
QCOMPARE(callbackError, false);
QCOMPARE(callbackMeta.toMap()["id"].toInt(), id);
QCOMPARE(callbackResponse.toList().size(), 5);
@@ -303,17 +278,26 @@ void TestJsonDbPartition::remove()
int id = 0;
expr = new QQmlExpression(partition->engine->rootContext(), partition->qmlElement, expression);
id = expr->evaluate().toInt();
- waitForCallback();
+ waitForCallback1();
QCOMPARE(callbackError, false);
QCOMPARE(callbackMeta.toMap()["id"].toInt(), id);
QCOMPARE(callbackResponse.toList().size(), 1);
//Remove this object
- obj = callbackResponse.toList();
+ {
+ QVariantList newList;
+ QVariantList list = callbackResponse.toList();
+ for (int i = 0; i<list.count(); i++) {
+ QVariantMap objMap = list[i].toMap();
+ objMap.insert("_type", __FUNCTION__);
+ newList.append(objMap);
+ }
+ obj = newList;
+ }
expression = QString(removeString).arg(objectString(QString(), obj));
expr->setExpression(expression);
id = expr->evaluate().toInt();
- waitForCallback();
+ waitForCallback1();
QCOMPARE(callbackError, false);
QCOMPARE(callbackMeta.toMap()["id"].toInt(), id);
QCOMPARE(callbackResponse.toList().size(), 1);
@@ -322,17 +306,26 @@ void TestJsonDbPartition::remove()
expression = QString(createString).arg(objectString(QString(), obj));
expr->setExpression(expression);
id = expr->evaluate().toInt();
- waitForCallback();
+ waitForCallback1();
QCOMPARE(callbackError, false);
QCOMPARE(callbackMeta.toMap()["id"].toInt(), id);
QCOMPARE(callbackResponse.toList().size(), 5);
//Remove all objects
- obj = callbackResponse.toList();
+ {
+ QVariantList newList;
+ QVariantList list = callbackResponse.toList();
+ for (int i = 0; i<list.count(); i++) {
+ QVariantMap objMap = list[i].toMap();
+ objMap.insert("_type", __FUNCTION__);
+ newList.append(objMap);
+ }
+ obj = newList;
+ }
expression = QString(removeString).arg(objectString(QString(), obj));
expr->setExpression(expression);
id = expr->evaluate().toInt();
- waitForCallback();
+ waitForCallback1();
QCOMPARE(callbackError, false);
QCOMPARE(callbackMeta.toMap()["id"].toInt(), id);
QCOMPARE(callbackResponse.toList().size(), 5);
@@ -359,7 +352,7 @@ void TestJsonDbPartition::find()
int id = 0;
expr = new QQmlExpression(partition->engine->rootContext(), partition->qmlElement, expression);
id = expr->evaluate().toInt();
- waitForCallback();
+ waitForCallback1();
QCOMPARE(callbackError, false);
QCOMPARE(callbackMeta.toMap()["id"].toInt(), id);
QCOMPARE(callbackResponse.toList().size(), 1);
@@ -368,7 +361,7 @@ void TestJsonDbPartition::find()
expression = findString;
expr->setExpression(expression);
id = expr->evaluate().toInt();
- waitForCallback();
+ waitForCallback1();
QCOMPARE(callbackError, false);
QCOMPARE(callbackMeta.toMap()["id"].toInt(), id);
QCOMPARE(callbackResponse.toList().size(), 1);
@@ -377,7 +370,7 @@ void TestJsonDbPartition::find()
expression = QString(createString).arg(objectString(QString(), obj));
expr->setExpression(expression);
id = expr->evaluate().toInt();
- waitForCallback();
+ waitForCallback1();
QCOMPARE(callbackError, false);
QCOMPARE(callbackMeta.toMap()["id"].toInt(), id);
QCOMPARE(callbackResponse.toList().size(), 5);
@@ -386,7 +379,7 @@ void TestJsonDbPartition::find()
expression = findString;
expr->setExpression(expression);
id = expr->evaluate().toInt();
- waitForCallback();
+ waitForCallback1();
QCOMPARE(callbackError, false);
QCOMPARE(callbackMeta.toMap()["id"].toInt(), id);
QCOMPARE(callbackResponse.toList().size(), 6);
diff --git a/tests/auto/jsondbpartition/testjsondbpartition.h b/tests/auto/jsondbpartition/testjsondbpartition.h
index 74896a8a..5ab757bf 100644
--- a/tests/auto/jsondbpartition/testjsondbpartition.h
+++ b/tests/auto/jsondbpartition/testjsondbpartition.h
@@ -41,26 +41,13 @@
#ifndef TESTJSONDBPARTITION_H
#define TESTJSONDBPARTITION_H
-#include <QCoreApplication>
-#include <QList>
-#include <QTest>
-#include <QFile>
-#include <QProcess>
-#include <QEventLoop>
-#include <QDebug>
-#include <QLocalSocket>
-#include <QTimer>
-
-#include <jsondb-client.h>
-#include <jsondb-error.h>
-
#include <QAbstractItemModel>
-#include "clientwrapper.h"
-#include "../../shared/qmltestutil.h"
+#include "requestwrapper.h"
+#include "qmltestutil.h"
QT_USE_NAMESPACE_JSONDB
-class TestJsonDbPartition: public ClientWrapper
+class TestJsonDbPartition: public RequestWrapper
{
Q_OBJECT
public:
@@ -80,23 +67,21 @@ private slots:
public slots:
void callbackSlot(QVariant error, QVariant response);
-protected slots:
+public:
void timeout();
private:
ComponentData *createComponent();
void deleteComponent(ComponentData *componentData);
- QVariant readJsonFile(const QString &filename);
private:
QProcess *mProcess;
QStringList mNotificationsReceived;
QList<ComponentData*> mComponents;
QString mPluginPath;
+
+ // Response values
bool mTimedOut;
- bool callbackError;
- QVariant callbackMeta;
- QVariant callbackResponse;
};
#endif
diff --git a/tests/auto/jsondbqueryobject/jsondbqueryobject.pro b/tests/auto/jsondbqueryobject/jsondbqueryobject.pro
index 62157bb2..717acef4 100644
--- a/tests/auto/jsondbqueryobject/jsondbqueryobject.pro
+++ b/tests/auto/jsondbqueryobject/jsondbqueryobject.pro
@@ -1,17 +1,20 @@
TEMPLATE = app
TARGET = tst_jsondbqueryobject
DEPENDPATH += .
-INCLUDEPATH += .
+INCLUDEPATH += . ../../shared/
-QT = core network testlib gui qml jsondbcompat-private
+QT = core network testlib gui qml jsondb
CONFIG -= app_bundle
CONFIG += testcase
include($$PWD/../../shared/shared.pri)
-include($$PWD/../../../src/3rdparty/qjson/qjson.pri)
DEFINES += JSONDB_DAEMON_BASE=\\\"$$QT.jsondb.bins\\\"
DEFINES += SRCDIR=\\\"$$PWD/\\\"
-HEADERS += testjsondbqueryobject.h
+HEADERS += testjsondbqueryobject.h \
+ $$PWD/../../shared/requestwrapper.h
SOURCES += testjsondbqueryobject.cpp
+
+OTHER_FILES += \
+ partitions.json
diff --git a/tests/auto/jsondbqueryobject/partitions.json b/tests/auto/jsondbqueryobject/partitions.json
new file mode 100644
index 00000000..c77651a0
--- /dev/null
+++ b/tests/auto/jsondbqueryobject/partitions.json
@@ -0,0 +1,3 @@
+[
+ { "name" :"com.nokia.shared" }
+]
diff --git a/tests/auto/jsondbqueryobject/testjsondbqueryobject.cpp b/tests/auto/jsondbqueryobject/testjsondbqueryobject.cpp
index 8205a18f..2a214dbb 100644
--- a/tests/auto/jsondbqueryobject/testjsondbqueryobject.cpp
+++ b/tests/auto/jsondbqueryobject/testjsondbqueryobject.cpp
@@ -41,10 +41,9 @@
#include <QtTest/QtTest>
#include <QJSEngine>
+#include <QJSValueIterator>
#include "testjsondbqueryobject.h"
#include "../../shared/util.h"
-#include <QJSValueIterator>
-#include "json.h"
static const char dbfile[] = "dbFile-jsondb-partition";
@@ -86,8 +85,9 @@ TestJsonDbQueryObject::~TestJsonDbQueryObject()
void TestJsonDbQueryObject::timeout()
{
- ClientWrapper::timeout();
+ RequestWrapper::timeout();
mTimedOut = true;
+ eventLoop1.quit();
}
void TestJsonDbQueryObject::deleteDbFiles()
@@ -110,25 +110,14 @@ void TestJsonDbQueryObject::initTestCase()
deleteDbFiles();
QString socketName = QString("testjsondb_%1").arg(getpid());
- mProcess = launchJsonDbDaemon(JSONDB_DAEMON_BASE, socketName, QStringList() << "-base-name" << dbfile);
+ mProcess = launchJsonDbDaemon(JSONDB_DAEMON_BASE, socketName, QStringList() << "-base-name" << dbfile, __FILE__);
- mClient = new JsonDbClient(this);
- connect(mClient, SIGNAL(notified(QString,QtAddOn::JsonDb::JsonDbNotification)),
- this, SLOT(notified(QString,QtAddOn::JsonDb::JsonDbNotification)));
- connect( mClient, SIGNAL(response(int, const QVariant&)),
- this, SLOT(response(int, const QVariant&)));
- connect( mClient, SIGNAL(error(int, int, const QString&)),
- this, SLOT(error(int, int, const QString&)));
+ connection = new QJsonDbConnection();
+ connection->connectToServer();
mPluginPath = findQMLPluginPath("QtJsonDb");
-
- // Create the shared Partitions
- QVariantMap item;
- item.insert("_type", "Partition");
- item.insert("name", "com.nokia.shared");
- int id = mClient->create(item);
- waitForResponse1(id);
-
+ if (mPluginPath.isEmpty())
+ qDebug() << "Couldn't find the plugin path for the plugin QtJsonDb";
}
ComponentData *TestJsonDbQueryObject::createComponent(const QString &qml)
@@ -201,14 +190,14 @@ void TestJsonDbQueryObject::errorSlot(const QVariantMap &newError)
callbackError = true;
callbackErrorCode = code;
callbackErrorMessage = message;
- mEventLoop2.quit();
+ eventLoop1.quit();
}
void TestJsonDbQueryObject::finishedSlot()
{
QMetaObject::invokeMethod(currentQmlElement, "takeResults", Qt::DirectConnection,
- Q_RETURN_ARG(QVariantList, cbData));
- mEventLoop2.quit();
+ Q_RETURN_ARG(QVariantList, callbackData));
+ eventLoop1.quit();
}
bool posLessThan(const QVariant &v1, const QVariant &v2)
@@ -230,13 +219,14 @@ void TestJsonDbQueryObject::singleObject()
//Create an object
QVariantMap item = createObject(__FUNCTION__).toMap();
- mClient->create(item, "com.nokia.shared");
+ create(item, "com.nokia.shared");
const QString expression("start();");
QQmlExpression *expr;
expr = new QQmlExpression(queryObject->engine->rootContext(), queryObject->qmlElement, expression);
expr->evaluate();
- waitForCallback2();
- QCOMPARE(cbData.size(), 1);
+ callbackData.clear();
+ waitForCallback1();
+ QCOMPARE(callbackData.size(), 1);
QCOMPARE(callbackError, false);
delete expr;
deleteComponent(queryObject);
@@ -252,7 +242,8 @@ void TestJsonDbQueryObject::multipleObjects()
index.insert("_type", "Index");
index.insert("propertyName", "pos");
index.insert("propertyType", "number");
- mClient->create(index, "com.nokia.shared");
+ int id = create(index, "com.nokia.shared");
+ waitForResponse1(id);
const QString queryString = QString("[?_type = \""+QString( __FUNCTION__ )+"\"][/pos]");
queryObject->qmlElement->setProperty("query", queryString);
@@ -260,18 +251,19 @@ void TestJsonDbQueryObject::multipleObjects()
//Create objects
QVariantList items = createObjectList(__FUNCTION__, 10).toList();
- mClient->create(QVariant(items), "com.nokia.shared");
+ create(items, "com.nokia.shared");
qSort(items.begin(), items.end(), posLessThan);
const QString expression("start();");
QQmlExpression *expr;
expr = new QQmlExpression(queryObject->engine->rootContext(), queryObject->qmlElement, expression);
expr->evaluate();
- waitForCallback2();
+ callbackData.clear();
+ waitForCallback1();
QCOMPARE(callbackError, false);
- QCOMPARE(cbData.size(), 10);
+ QCOMPARE(callbackData.size(), 10);
for (int i = 0; i<10; i++) {
QVariantMap item = items[i].toMap();
- QVariantMap obj = cbData[i].toMap();
+ QVariantMap obj = callbackData[i].toMap();
QCOMPARE(obj.value("alphabet"), item.value("alphabet"));
}
@@ -299,11 +291,13 @@ void TestJsonDbQueryObject::createQuery()
this, SLOT(errorSlot(QVariantMap)));
//Create an object
QVariantMap item = createObject(__FUNCTION__).toMap();
- mClient->create(item, "com.nokia.shared");
+ int id = create(item, "com.nokia.shared");
+ waitForResponse1(id);
+
QMetaObject::invokeMethod(currentQmlElement, "start", Qt::DirectConnection);
- cbData.clear();
- waitForCallback2();
- QCOMPARE(cbData.size(), 1);
+ callbackData.clear();
+ waitForCallback1();
+ QCOMPARE(callbackData.size(), 1);
QCOMPARE(callbackError, false);
delete expr;
deleteComponent(partition);
@@ -319,7 +313,8 @@ void TestJsonDbQueryObject::queryWithoutPartition()
index.insert("_type", "Index");
index.insert("propertyName", "pos");
index.insert("propertyType", "number");
- mClient->create(index);
+ int id = create(index);
+ waitForResponse1(id);
const QString queryString = QString("[?_type = \""+QString( __FUNCTION__ )+"\"][/pos]");
queryObject->qmlElement->setProperty("query", queryString);
@@ -327,18 +322,19 @@ void TestJsonDbQueryObject::queryWithoutPartition()
//Create objects
QVariantList items = createObjectList(__FUNCTION__, 10).toList();
- mClient->create(QVariant(items));
+ create(items);
qSort(items.begin(), items.end(), posLessThan);
const QString expression("start();");
QQmlExpression *expr;
expr = new QQmlExpression(queryObject->engine->rootContext(), queryObject->qmlElement, expression);
expr->evaluate();
- waitForCallback2();
+ callbackData.clear();
+ waitForCallback1();
QCOMPARE(callbackError, false);
- QCOMPARE(cbData.size(), 10);
+ QCOMPARE(callbackData.size(), 10);
for (int i = 0; i<10; i++) {
QVariantMap item = items[i].toMap();
- QVariantMap obj = cbData[i].toMap();
+ QVariantMap obj = callbackData[i].toMap();
QCOMPARE(obj.value("alphabet"), item.value("alphabet"));
}
@@ -361,19 +357,20 @@ void TestJsonDbQueryObject::queryBinding()
queryObject->qmlElement->setProperty("bindings", bindingMap);
currentQmlElement = queryObject->qmlElement;
- mClient->create(QVariant(items), "com.nokia.shared");
+ create(items, "com.nokia.shared");
qSort(items.begin(), items.end(), posLessThan);
const QString expression("start();");
QQmlExpression *expr;
expr = new QQmlExpression(queryObject->engine->rootContext(), queryObject->qmlElement, expression);
expr->evaluate();
- waitForCallback2();
+ callbackData.clear();
+ waitForCallback1();
QCOMPARE(callbackError, false);
- QCOMPARE(cbData.size(), 1);
+ QCOMPARE(callbackData.size(), 1);
QVariantMap item = items[0].toMap();
- QVariantMap obj = cbData[0].toMap();
+ QVariantMap obj = callbackData[0].toMap();
QCOMPARE(obj.value("alphabet"), item.value("alphabet"));
delete expr;
deleteComponent(queryObject);
@@ -394,13 +391,14 @@ void TestJsonDbQueryObject::queryError()
queryObject->qmlElement->setProperty("bindings", bindingMap);
currentQmlElement = queryObject->qmlElement;
- mClient->create(QVariant(items), "com.nokia.shared");
+ create(items, "com.nokia.shared");
qSort(items.begin(), items.end(), posLessThan);
const QString expression("start();");
QQmlExpression *expr;
expr = new QQmlExpression(queryObject->engine->rootContext(), queryObject->qmlElement, expression);
expr->evaluate();
- waitForCallback2();
+ callbackData.clear();
+ waitForCallback1();
QCOMPARE(callbackError, true);
delete expr;
@@ -417,7 +415,8 @@ void TestJsonDbQueryObject::queryLimit()
index.insert("_type", "Index");
index.insert("propertyName", "pos");
index.insert("propertyType", "number");
- mClient->create(index, "com.nokia.shared");
+ int id = create(index, "com.nokia.shared");
+ waitForResponse1(id);
const QString queryString = QString("[?_type = \""+QString( __FUNCTION__ )+"\"][/pos]");
queryObject->qmlElement->setProperty("query", queryString);
@@ -426,18 +425,19 @@ void TestJsonDbQueryObject::queryLimit()
//Create objects
QVariantList items = createObjectList(__FUNCTION__, 10).toList();
- mClient->create(QVariant(items), "com.nokia.shared");
+ create(items, "com.nokia.shared");
qSort(items.begin(), items.end(), posLessThan);
const QString expression("start();");
QQmlExpression *expr;
expr = new QQmlExpression(queryObject->engine->rootContext(), queryObject->qmlElement, expression);
expr->evaluate();
- waitForCallback2();
+ callbackData.clear();
+ waitForCallback1();
QCOMPARE(callbackError, false);
- QCOMPARE(cbData.size(), 5);
+ QCOMPARE(callbackData.size(), 5);
for (int i = 0; i<5; i++) {
QVariantMap item = items[i].toMap();
- QVariantMap obj = cbData[i].toMap();
+ QVariantMap obj = callbackData[i].toMap();
QCOMPARE(obj.value("alphabet"), item.value("alphabet"));
}
@@ -445,6 +445,5 @@ void TestJsonDbQueryObject::queryLimit()
deleteComponent(queryObject);
}
-
QTEST_MAIN(TestJsonDbQueryObject)
diff --git a/tests/auto/jsondbqueryobject/testjsondbqueryobject.h b/tests/auto/jsondbqueryobject/testjsondbqueryobject.h
index c79745a3..4c2645f6 100644
--- a/tests/auto/jsondbqueryobject/testjsondbqueryobject.h
+++ b/tests/auto/jsondbqueryobject/testjsondbqueryobject.h
@@ -41,27 +41,13 @@
#ifndef TESTJSONDBQUERYOBJECT_H
#define TESTJSONDBQUERYOBJECT_H
-#include <QCoreApplication>
-#include <QList>
-#include <QTest>
-#include <QFile>
-#include <QProcess>
-#include <QEventLoop>
-#include <QDebug>
-#include <QLocalSocket>
-#include <QTimer>
-#include <QJSValue>
-
-#include <jsondb-client.h>
-#include <jsondb-error.h>
-
#include <QAbstractItemModel>
-#include "clientwrapper.h"
-#include "../../shared/qmltestutil.h"
+#include "requestwrapper.h"
+#include "qmltestutil.h"
QT_USE_NAMESPACE_JSONDB
-class TestJsonDbQueryObject: public ClientWrapper
+class TestJsonDbQueryObject: public RequestWrapper
{
Q_OBJECT
public:
@@ -85,7 +71,7 @@ public slots:
void errorSlot(const QVariantMap &newError);
void finishedSlot();
-protected slots:
+public:
void timeout();
private:
@@ -95,17 +81,12 @@ private:
private:
QProcess *mProcess;
- QStringList mNotificationsReceived;
QList<ComponentData*> mComponents;
QString mPluginPath;
+
bool mTimedOut;
- bool callbackError;
- int callbackErrorCode;
- QString callbackErrorMessage;
- QVariantList cbData;
- QEventLoop mEventLoop2;
QObject *currentQmlElement;
-
+ QVariantList callbackData;
};
#endif
diff --git a/tests/auto/jsondbsortinglistmodel/jsondbsortinglistmodel.pro b/tests/auto/jsondbsortinglistmodel/jsondbsortinglistmodel.pro
index cea282e6..7d1b4f74 100644
--- a/tests/auto/jsondbsortinglistmodel/jsondbsortinglistmodel.pro
+++ b/tests/auto/jsondbsortinglistmodel/jsondbsortinglistmodel.pro
@@ -1,17 +1,20 @@
TEMPLATE = app
TARGET = tst_jsondbsortinglistmodel
DEPENDPATH += .
-INCLUDEPATH += .
+INCLUDEPATH += . ../../shared/
-QT = core network testlib gui qml jsondbcompat-private
+QT = core network testlib gui qml jsondb
CONFIG -= app_bundle
CONFIG += testcase
include($$PWD/../../shared/shared.pri)
-include($$PWD/../../../src/3rdparty/qjson/qjson.pri)
DEFINES += JSONDB_DAEMON_BASE=\\\"$$QT.jsondb.bins\\\"
DEFINES += SRCDIR=\\\"$$PWD/\\\"
-HEADERS += testjsondbsortinglistmodel.h
+HEADERS += testjsondbsortinglistmodel.h \
+ $$PWD/../../shared/requestwrapper.h
SOURCES += testjsondbsortinglistmodel.cpp
+
+OTHER_FILES += \
+ partitions.json
diff --git a/tests/auto/jsondbsortinglistmodel/partitions.json b/tests/auto/jsondbsortinglistmodel/partitions.json
new file mode 100644
index 00000000..1cdd0fa5
--- /dev/null
+++ b/tests/auto/jsondbsortinglistmodel/partitions.json
@@ -0,0 +1,4 @@
+[
+ { "name" :"com.nokia.shared.1" },
+ { "name" :"com.nokia.shared.2" }
+]
diff --git a/tests/auto/jsondbsortinglistmodel/testjsondbsortinglistmodel.cpp b/tests/auto/jsondbsortinglistmodel/testjsondbsortinglistmodel.cpp
index 762ce59b..f9edeedb 100644
--- a/tests/auto/jsondbsortinglistmodel/testjsondbsortinglistmodel.cpp
+++ b/tests/auto/jsondbsortinglistmodel/testjsondbsortinglistmodel.cpp
@@ -41,11 +41,9 @@
#include <QtTest/QtTest>
#include <QJSEngine>
+#include <QQmlListReference>
#include "testjsondbsortinglistmodel.h"
-
#include "../../shared/util.h"
-#include <QQmlListReference>
-#include "json.h"
static const char dbfile[] = "dbFile-jsondb-listmodel";
ModelData::ModelData(): engine(0), component(0), model(0)
@@ -56,22 +54,20 @@ ModelData::~ModelData()
{
if (model)
delete model;
- if (parttion1)
- delete parttion1;
- if (parttion2)
- delete parttion2;
-
if (component)
delete component;
- if (partitionComponent1)
- delete partitionComponent1;
- if (partitionComponent2)
- delete partitionComponent2;
-
if (engine)
delete engine;
}
+const QString qmlProgram = QLatin1String(
+ "import QtQuick 2.0\n"
+ "import QtJsonDb 1.0 as JsonDb \n"
+ "JsonDb.JsonDbSortingListModel {"
+ "id: contactsModel;"
+ "partitions: [JsonDb.Partition {name: \"com.nokia.shared.1\"}, JsonDb.Partition {name: \"com.nokia.shared.2\"}]"
+ "}");
+
QVariant get(QObject* object, int index, QString propertyName)
{
QVariant retVal;
@@ -101,7 +97,6 @@ int indexOf(QObject* object, const QString &uuid)
}
TestJsonDbSortingListModel::TestJsonDbSortingListModel()
- : mWaitingForNotification(false), mWaitingForDataChange(false), mWaitingForRowsRemoved(false)
{
}
@@ -118,26 +113,11 @@ void TestJsonDbSortingListModel::deleteDbFiles()
nameFilter << "objectFile.bin" << "objectFile2.bin";
QFileInfoList databaseFiles = currentDir.entryInfoList(nameFilter, QDir::Files);
foreach (QFileInfo fileInfo, databaseFiles) {
- //qDebug() << "Deleted : " << fileInfo.fileName();
QFile file(fileInfo.fileName());
file.remove();
}
}
-QVariant TestJsonDbSortingListModel::readJsonFile(const QString& filename)
-{
- QString filepath = findFile(filename);
- QFile jsonFile(filepath);
- jsonFile.open(QIODevice::ReadOnly);
- QByteArray json = jsonFile.readAll();
- JsonReader parser;
- bool ok = parser.parse(json);
- if (!ok) {
- qDebug() << filepath << parser.errorString();
- }
- return parser.result();
-}
-
void TestJsonDbSortingListModel::connectListModel(QAbstractListModel *model)
{
connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(dataChanged(QModelIndex,QModelIndex)));
@@ -147,7 +127,7 @@ void TestJsonDbSortingListModel::connectListModel(QAbstractListModel *model)
connect(model, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
this, SLOT(rowsMoved(QModelIndex,int,int,QModelIndex,int)));
connect(model, SIGNAL(stateChanged(State)),
- this, SLOT(stateChanged()));
+ this, SLOT(stateChanged(State)));
}
void TestJsonDbSortingListModel::initTestCase()
@@ -156,31 +136,27 @@ void TestJsonDbSortingListModel::initTestCase()
deleteDbFiles();
QString socketName = QString("testjsondb_%1").arg(getpid());
- mProcess = launchJsonDbDaemon(JSONDB_DAEMON_BASE, socketName, QStringList() << "-base-name" << dbfile);
+ mProcess = launchJsonDbDaemon(JSONDB_DAEMON_BASE, socketName, QStringList() << "-base-name" << dbfile, __FILE__);
- mClient = new JsonDbClient(this);
- connect(mClient, SIGNAL(notified(QString,QtAddOn::JsonDb::JsonDbNotification)),
- this, SLOT(notified(QString,QtAddOn::JsonDb::JsonDbNotification)));
- connect( mClient, SIGNAL(response(int, const QVariant&)),
- this, SLOT(response(int, const QVariant&)));
- connect( mClient, SIGNAL(error(int, int, const QString&)),
- this, SLOT(error(int, int, const QString&)));
+ connection = new QJsonDbConnection();
+ connection->connectToServer();
mPluginPath = findQMLPluginPath("QtJsonDb");
+ if (mPluginPath.isEmpty())
+ qDebug() << "Couldn't find the plugin path for the plugin QtJsonDb";
// Create the shared Partitions
QVariantMap item;
item.insert("_type", "Partition");
item.insert("name", "com.nokia.shared.1");
- int id = mClient->create(item);
+ int id = create(item);
waitForResponse1(id);
item.clear();
item.insert("_type", "Partition");
item.insert("name", "com.nokia.shared.2");
- id = mClient->create(item);
+ id = create(item);
waitForResponse1(id);
-
}
QAbstractListModel *TestJsonDbSortingListModel::createModel()
@@ -188,40 +164,17 @@ QAbstractListModel *TestJsonDbSortingListModel::createModel()
ModelData *newModel = new ModelData();
newModel->engine = new QQmlEngine();
QString error;
+ Q_ASSERT(!mPluginPath.isEmpty());
if (!newModel->engine->importPlugin(mPluginPath, QString("QtJsonDb"), &error)) {
qDebug()<<"Unable to load the plugin :"<<error;
delete newModel->engine;
return 0;
}
newModel->component = new QQmlComponent(newModel->engine);
- newModel->component->setData("import QtQuick 2.0\nimport QtJsonDb 1.0 as JsonDb \n"
- "JsonDb.JsonDbSortingListModel {id: contactsModel}",
- QUrl());
+ newModel->component->setData(qmlProgram.toLocal8Bit(), QUrl());
newModel->model = newModel->component->create();
if (newModel->component->isError())
qDebug() << newModel->component->errors();
-
- newModel->partitionComponent1 = new QQmlComponent(newModel->engine);
- newModel->partitionComponent1->setData("import QtQuick 2.0\nimport QtJsonDb 1.0 as JsonDb \n"
- "JsonDb.Partition {name: \"com.nokia.shared.1\"}",
- QUrl());
- newModel->parttion1 = newModel->partitionComponent1->create();
- if (newModel->partitionComponent1->isError())
- qDebug() << newModel->partitionComponent1->errors();
-
-
- newModel->partitionComponent2 = new QQmlComponent(newModel->engine);
- newModel->partitionComponent2->setData("import QtQuick 2.0\nimport QtJsonDb 1.0 as JsonDb \n"
- "JsonDb.Partition {name: \"com.nokia.shared.2\"}",
- QUrl());
- newModel->parttion2 = newModel->partitionComponent2->create();
- if (newModel->partitionComponent2->isError())
- qDebug() << newModel->partitionComponent2->errors();
-
- QQmlListReference partitions(newModel->model, "partitions", newModel->engine);
- partitions.append(newModel->parttion1);
- partitions.append(newModel->parttion2);
-
mModels.append(newModel);
return (QAbstractListModel*)(newModel->model);
}
@@ -251,33 +204,39 @@ void TestJsonDbSortingListModel::cleanupTestCase()
// Create items in the model.
void TestJsonDbSortingListModel::createItem()
{
+ resetWaitFlags();
QVariantMap item;
item.insert("_type", __FUNCTION__);
item.insert("name", "Charlie");
- int id = mClient->create(item, "com.nokia.shared.1");
-
+ int id = create(item, "com.nokia.shared.1");
waitForResponse1(id);
QAbstractListModel *listModel = createModel();
if (!listModel) return;
listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__));
-
QStringList roleNames = (QStringList() << "_type" << "_uuid" << "name");
listModel->setProperty("roleNames", roleNames);
connectListModel(listModel);
// now start it working
QCOMPARE(listModel->rowCount(), 0);
-
+ mWaitingForStateChanged = true;
waitForStateOrTimeout();
+ QCOMPARE(mWaitingForStateChanged, false);
QCOMPARE(listModel->rowCount(), 1);
QCOMPARE(listModel->property("state").toInt(), 2);
item.clear();
item.insert("_type", __FUNCTION__);
item.insert("name", "Baker");
- id = mClient->create(item, "com.nokia.shared.1");
- waitForItemChanged();
+ mItemsCreated = 0;
+ id = create(item, "com.nokia.shared.1");
+ waitForResponse1(id);
+ while (!mItemsCreated) {
+ mWaitingForRowsInserted = true;
+ waitForExitOrTimeout();
+ }
+ QCOMPARE(mWaitingForRowsInserted, false);
QCOMPARE(listModel->rowCount(), 2);
deleteModel(listModel);
@@ -286,10 +245,11 @@ void TestJsonDbSortingListModel::createItem()
// Create an item and then update it.
void TestJsonDbSortingListModel::updateItemClient()
{
+ resetWaitFlags();
QVariantMap item;
item.insert("_type", __FUNCTION__);
item.insert("name", "Charlie");
- int id = mClient->create(item,"com.nokia.shared.1");
+ int id = create(item,"com.nokia.shared.1");
waitForResponse1(id);
QAbstractListModel *listModel = createModel();
@@ -301,20 +261,31 @@ void TestJsonDbSortingListModel::updateItemClient()
// now start it working
QCOMPARE(listModel->rowCount(), 0);
-
+ mWaitingForStateChanged = true;
waitForStateOrTimeout();
+ QCOMPARE(mWaitingForStateChanged, false);
QCOMPARE(listModel->rowCount(), 1);
- item.insert("_uuid", mLastUuid);
+ QString lastUuid,lastVersion;
+ QVariantMap lastItem;
+ if (lastResult.count()) {
+ lastItem = lastResult[0].toMap();
+ lastUuid = lastItem.value("_uuid").toString();
+ lastVersion = lastItem.value("_version").toString();
+ }
+ item.insert("_uuid", lastUuid);
+ item.insert("_version", lastVersion);
item.insert("name", "Baker");
-
- mWaitingForDataChange = true;
-
- id = mClient->update(item, "com.nokia.shared.1");
- waitForItemChanged();
+ id = update(item, "com.nokia.shared.1");
+ waitForResponse1(id);
+ while (!mItemsUpdated) {
+ mWaitingForChanged = true;
+ waitForExitOrTimeout();
+ }
+ QCOMPARE(mWaitingForChanged, false);
QCOMPARE(listModel->rowCount(), 1);
- QCOMPARE(get(listModel, 0, "_uuid").toString(), mLastUuid);
+ QCOMPARE(get(listModel, 0, "_uuid").toString(), lastUuid);
QCOMPARE(get(listModel, 0, "_type").toString(), QLatin1String(__FUNCTION__));
QCOMPARE(get(listModel,0, "name").toString(), QLatin1String("Baker"));
deleteModel(listModel);
@@ -322,10 +293,11 @@ void TestJsonDbSortingListModel::updateItemClient()
void TestJsonDbSortingListModel::deleteItem()
{
+ resetWaitFlags();
QVariantMap item;
item.insert("_type", __FUNCTION__);
item.insert("name", "Charlie");
- int id = mClient->create(item, "com.nokia.shared.1");
+ int id = create(item, "com.nokia.shared.1");
waitForResponse1(id);
QAbstractListModel *listModel = createModel();
@@ -336,19 +308,38 @@ void TestJsonDbSortingListModel::deleteItem()
connectListModel(listModel);
// now start it working
+ mWaitingForStateChanged = true;
waitForStateOrTimeout();
+ QCOMPARE(mWaitingForStateChanged, false);
QCOMPARE(listModel->rowCount(), 1);
item.insert("name", "Baker");
- id = mClient->create(item, "com.nokia.shared.2");
+ mItemsCreated = 0;
+ id = create(item, "com.nokia.shared.2");
waitForResponse1(id);
-
+ while (!mItemsCreated) {
+ mWaitingForRowsInserted = true;
+ waitForExitOrTimeout();
+ }
+ QCOMPARE(mWaitingForRowsInserted, false);
QCOMPARE(listModel->rowCount(), 2);
- mWaitingForRowsRemoved = true;
- item.insert("_uuid", mLastUuid);
- id = mClient->remove(item, "com.nokia.shared.2");
- waitForItemChanged(true);
+ QString lastUuid,lastVersion;
+ QVariantMap lastItem;
+ if (lastResult.count()) {
+ lastItem = lastResult[0].toMap();
+ lastUuid = lastItem.value("_uuid").toString();
+ lastVersion = lastItem.value("_version").toString();
+ }
+ item.insert("_uuid", lastUuid);
+ item.insert("_version", lastVersion);
+ id = remove(item, "com.nokia.shared.2");
+ waitForResponse1(id);
+ while (!mItemsRemoved) {
+ mWaitingForRemoved = true;
+ waitForExitOrTimeout();
+ }
+ QCOMPARE(mWaitingForRemoved, false);
QCOMPARE(listModel->rowCount(), 1);
QCOMPARE(get(listModel, 0, "_type").toString(), QLatin1String(__FUNCTION__));
@@ -358,12 +349,13 @@ void TestJsonDbSortingListModel::deleteItem()
void TestJsonDbSortingListModel::sortedQuery()
{
+ resetWaitFlags();
int id = 0;
for (int i = 0; i < 1000; i++) {
QVariantMap item;
item.insert("_type", "RandNumber");
item.insert("number", i);
- id = mClient->create(item,"com.nokia.shared.2");
+ id = create(item,"com.nokia.shared.2");
waitForResponse1(id);
}
@@ -377,7 +369,9 @@ void TestJsonDbSortingListModel::sortedQuery()
listModel->setProperty("roleNames", rolenames);
listModel->setProperty("sortOrder", "[/number]");
listModel->setProperty("query", "[?_type=\"RandNumber\"]");
+ mWaitingForStateChanged = true;
waitForStateOrTimeout();
+ QCOMPARE(mWaitingForStateChanged, false);
QCOMPARE(listModel->property("sortOrder").toString(), QString("[/number]"));
@@ -408,12 +402,13 @@ bool greaterThan(const QString &s1, const QString &s2)
void TestJsonDbSortingListModel::ordering()
{
+ resetWaitFlags();
for (int i = 9; i >= 1; --i) {
QVariantMap item;
item.insert("_type", __FUNCTION__);
item.insert("name", "Charlie");
item.insert("order", QString::number(i));
- int id = mClient->create(item, "com.nokia.shared.2");
+ int id = create(item, "com.nokia.shared.2");
waitForResponse1(id);
}
@@ -427,7 +422,9 @@ void TestJsonDbSortingListModel::ordering()
// now start it working
QCOMPARE(listModel->rowCount(), 0);
+ mWaitingForStateChanged = true;
waitForStateOrTimeout();
+ QCOMPARE(mWaitingForStateChanged, false);
QStringList expectedOrder = QStringList() << "1" << "2" << "3" << "4" <<
"5" << "6" << "7" << "8" << "9";
QCOMPARE(getOrderValues(listModel), expectedOrder);
@@ -440,13 +437,18 @@ void TestJsonDbSortingListModel::ordering()
item.insert("_type", __FUNCTION__);
item.insert("name", "Charlie");
item.insert("order", "99"); // move it to the end
- mClient->update(item, "com.nokia.shared.2");
+ update(item, "com.nokia.shared.2");
}
- waitForItemChanged();
+ while (!mItemsUpdated) {
+ mWaitingForChanged = true;
+ waitForExitOrTimeout();
+ }
+ QCOMPARE(mWaitingForChanged, false);
expectedOrder = QStringList() << "1" << "2" << "3" <<
"4" << "6" << "7" << "8" << "9" << "99";
QCOMPARE(getOrderValues(listModel), expectedOrder);
+ mItemsUpdated = 0;
{
QVariant uuid = get(listModel, 8, "_uuid");
QVERIFY(!uuid.toString().isEmpty());
@@ -456,13 +458,18 @@ void TestJsonDbSortingListModel::ordering()
item.insert("_type", __FUNCTION__);
item.insert("name", "Charlie");
item.insert("order", "22"); // move it after "2"
- mClient->update(item, "com.nokia.shared.2");
+ update(item, "com.nokia.shared.2");
+ }
+ while (!mItemsUpdated) {
+ mWaitingForChanged = true;
+ waitForExitOrTimeout();
}
- waitForItemChanged();
+ QCOMPARE(mWaitingForChanged, false);
expectedOrder = QStringList() << "1" << "2" << "22" << "3" <<
"4" << "6" << "7" << "8" << "9";
QCOMPARE(getOrderValues(listModel), expectedOrder);
+ mItemsUpdated = 0;
{
QVariant uuid = get(listModel, 5, "_uuid");
QVERIFY(!uuid.toString().isEmpty());
@@ -472,9 +479,13 @@ void TestJsonDbSortingListModel::ordering()
item.insert("_type", __FUNCTION__);
item.insert("name", "Charlie");
item.insert("order", "0"); // move it to the beginning
- mClient->update(item, "com.nokia.shared.2");
+ update(item, "com.nokia.shared.2");
}
- waitForItemChanged();
+ while (!mItemsUpdated) {
+ mWaitingForChanged = true;
+ waitForExitOrTimeout();
+ }
+ QCOMPARE(mWaitingForChanged, false);
// Check for order and togther with queryLimit
expectedOrder = QStringList() << "0" << "1" << "2" << "22" << "3" <<
@@ -489,23 +500,27 @@ void TestJsonDbSortingListModel::ordering()
QCOMPARE(getOrderValues(listModel), expectedOrder);
listModel->setProperty("queryLimit", 5);
+ mWaitingForStateChanged = true;
waitForStateOrTimeout();
+ QCOMPARE(mWaitingForStateChanged, false);
QCOMPARE(listModel->rowCount(), 5);
QCOMPARE(getOrderValues(listModel), QStringList(expectedOrder.mid(0, 5)));
listModel->setProperty("sortOrder", "[\\order]");
+ mWaitingForStateChanged = true;
waitForStateOrTimeout();
+ QCOMPARE(mWaitingForStateChanged, false);
QCOMPARE(listModel->rowCount(), 5);
QCOMPARE(getOrderValues(listModel), QStringList(reverseOrder.mid(0, 5)));
deleteModel(listModel);
-
}
void TestJsonDbSortingListModel::checkRemoveNotification()
{
+ resetWaitFlags();
QVariantList itemList;
for (int i = 0; i < 50; i++) {
QVariantMap item;
@@ -514,7 +529,7 @@ void TestJsonDbSortingListModel::checkRemoveNotification()
item.insert("order", i);
itemList << item;
}
- int id = mClient->create(itemList,"com.nokia.shared.2");
+ int id = create(itemList,"com.nokia.shared.2");
waitForResponse1(id);
{
@@ -526,9 +541,12 @@ void TestJsonDbSortingListModel::checkRemoveNotification()
listModel->setProperty("sortOrder", "[/order]");
QStringList roleNames = (QStringList() << "_type" << "_uuid" << "_version"<< "name" << "order");
listModel->setProperty("roleNames", roleNames);
- waitForStateOrTimeout();
+ mWaitingForStateChanged = true;
+ waitForStateOrTimeout();
+ QCOMPARE(mWaitingForStateChanged, false);
QCOMPARE(listModel->rowCount(), 10);
+
QVariant result = get(listModel, 0, "order");
QVERIFY(result.isValid());
QCOMPARE(result.toInt(), 0);
@@ -540,8 +558,10 @@ void TestJsonDbSortingListModel::checkRemoveNotification()
QVariantMap item;
item.insert("_uuid", get(listModel, 0, "_uuid"));
item.insert("_version", get(listModel, 0, "_version"));
- id = mClient->remove(item, "com.nokia.shared.2");
- waitForItemChanged();
+ id = remove(item, "com.nokia.shared.2");
+ waitForResponse1(id);
+ waitForStateChanged(listModel);
+
QCOMPARE(listModel->rowCount(), 10);
result = get(listModel, 9, "order");
QVERIFY(result.isValid());
@@ -550,8 +570,10 @@ void TestJsonDbSortingListModel::checkRemoveNotification()
//Remove item at 9
item.insert("_uuid", get(listModel, 9, "_uuid"));
item.insert("_version", get(listModel, 9, "_version"));
- id = mClient->remove(item, "com.nokia.shared.2");
- waitForItemChanged();
+ id = remove(item, "com.nokia.shared.2");
+ waitForResponse1(id);
+ waitForStateChanged(listModel);
+
QCOMPARE(listModel->rowCount(), 10);
result = get(listModel, 9, "order");
QVERIFY(result.isValid());
@@ -560,8 +582,10 @@ void TestJsonDbSortingListModel::checkRemoveNotification()
//Remove item at 4
item.insert("_uuid", get(listModel, 4, "_uuid"));
item.insert("_version", get(listModel, 4, "_version"));
- id = mClient->remove(item, "com.nokia.shared.2");
- waitForItemChanged();
+ id = remove(item, "com.nokia.shared.2");
+ waitForResponse1(id);
+ waitForStateChanged(listModel);
+
QCOMPARE(listModel->rowCount(), 10);
result = get(listModel, 4, "order");
QVERIFY(result.isValid());
@@ -583,7 +607,7 @@ void TestJsonDbSortingListModel::checkUpdateNotification()
item.insert("order", i);
itemList << item;
}
- int id = mClient->create(itemList, "com.nokia.shared.1");
+ int id = create(itemList, "com.nokia.shared.1");
waitForResponse1(id);
{
@@ -595,9 +619,12 @@ void TestJsonDbSortingListModel::checkUpdateNotification()
listModel->setProperty("sortOrder", "[/order]");
QStringList roleNames = (QStringList() << "_type" << "_uuid" << "_version"<< "name" << "order");
listModel->setProperty("roleNames", roleNames);
- waitForStateOrTimeout();
+ mWaitingForStateChanged = true;
+ waitForStateOrTimeout();
+ QCOMPARE(mWaitingForStateChanged, false);
QCOMPARE(listModel->rowCount(), 10);
+
QVariant result = get(listModel, 0, "order");
QVERIFY(result.isValid());
QCOMPARE(result.toInt(), 0);
@@ -611,8 +638,10 @@ void TestJsonDbSortingListModel::checkUpdateNotification()
item.insert("_type", get(listModel, 0, "_type"));
item.insert("name", get(listModel, 0, "name"));
item.insert("order", 1);
- id = mClient->update(item, "com.nokia.shared.1");
+ id = update(item, "com.nokia.shared.1");
+
waitForItemChanged();
+ QCOMPARE(mWaitingForChanged, false);
QCOMPARE(listModel->rowCount(), 10);
result = get(listModel, 0, "order");
@@ -628,16 +657,11 @@ void TestJsonDbSortingListModel::checkUpdateNotification()
item.insert("_type", get(listModel, 9, "_type"));
item.insert("name", get(listModel, 9, "name"));
item.insert("order", 19);
- id = mClient->update(item,"com.nokia.shared.1");
- waitForItemChanged();
+ id = update(item,"com.nokia.shared.1");
- item.clear();
- item.insert("_uuid", get(listModel, 9, "_uuid"));
- item.insert("_type", get(listModel, 9, "_type"));
- item.insert("name", get(listModel, 9, "name"));
- item.insert("order", 19);
- id = mClient->update(item,"com.nokia.shared.1");
waitForItemChanged();
+ QCOMPARE(mWaitingForStateChanged, false);
+ waitForStateChanged(listModel);
QCOMPARE(listModel->rowCount(), 10);
result = get(listModel, 0, "order");
@@ -652,8 +676,11 @@ void TestJsonDbSortingListModel::checkUpdateNotification()
item.insert("_type", get(listModel, 9, "_type"));
item.insert("name", get(listModel, 9, "name"));
item.insert("order", 59);
- id = mClient->update(item, "com.nokia.shared.1");
+ id = update(item, "com.nokia.shared.1");
+
waitForItemChanged();
+ QCOMPARE(mWaitingForStateChanged, false);
+ waitForStateChanged(listModel);
QCOMPARE(listModel->rowCount(), 10);
result = get(listModel, 0, "order");
@@ -668,8 +695,11 @@ void TestJsonDbSortingListModel::checkUpdateNotification()
item.insert("_type", get(listModel, 8, "_type"));
item.insert("name", get(listModel, 8, "name"));
item.insert("order", 17);
- id = mClient->update(item, "com.nokia.shared.1");
+ id = update(item, "com.nokia.shared.1");
+
waitForItemChanged();
+ QCOMPARE(mWaitingForStateChanged, false);
+ waitForStateChanged(listModel);
QCOMPARE(listModel->rowCount(), 10);
result = get(listModel, 8, "order");
@@ -688,15 +718,16 @@ void TestJsonDbSortingListModel::checkUpdateNotification()
void TestJsonDbSortingListModel::totalRowCount()
{
+ resetWaitFlags();
int id = 0;
QVariantList insertedItems;
for (int i = 0; i < 10; i++) {
QVariantMap item;
item.insert("_type", __FUNCTION__);
item.insert("order", i);
- id = mClient->create(item, "com.nokia.shared.1");
+ id = create(item, "com.nokia.shared.1");
waitForResponse1(id);
- insertedItems << mData;
+ insertedItems << lastResult;
}
QAbstractListModel *listModel = createModel();
@@ -704,34 +735,50 @@ void TestJsonDbSortingListModel::totalRowCount()
return;
connectListModel(listModel);
- listModel->setProperty("queryLimit", 50);
+ listModel->setProperty("queryLimit", 100);
listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__));
QStringList roleNames = (QStringList() << "_type" << "_uuid" << "order");
listModel->setProperty("roleNames", roleNames);
+ mWaitingForStateChanged = true;
waitForStateOrTimeout();
+ QCOMPARE(mWaitingForStateChanged, false);
QCOMPARE(listModel->rowCount(), 10);
+ mItemsCreated = 0;
for (int i = 10; i < 50; i++) {
QVariantMap item;
item.insert("_type", __FUNCTION__);
item.insert("order", i);
- mClient->create(item, "com.nokia.shared.2");
+ id = create(item, "com.nokia.shared.2");
+ waitForResponse1(id);
}
- waitForItemsCreated(40);
+ waitForItemsCreated(40); // will set mWaitingForRowsInserted = true for you
+ if (id != lastRequestId)
+ waitForResponse1(id);
+ QCOMPARE(mWaitingForRowsInserted, false);
+ QCOMPARE(mItemsCreated, 40);
QCOMPARE(listModel->rowCount(), 50);
// Change sort order
+ mWaitingForReadyState = true;
listModel->setProperty("sortOrder", "[\\order]");
- waitForStateOrTimeout();
+ QVariant state = listModel->property("state");
+ if (state.toInt() != 2) {
+ waitForReadyStateOrTimeout();
+ QCOMPARE(mWaitingForReadyState, false);
+ }
+ else
+ mWaitingForReadyState = false;
QCOMPARE(listModel->rowCount(), 50);
// Delete the first 10 items
foreach (QVariant item, insertedItems) {
- mWaitingForRowsRemoved = true;
- id = mClient->remove(item.toMap(), "com.nokia.shared.1");
- waitForItemChanged(true);
+ mItemsRemoved = 0;
+ id = remove(item.toMap(), "com.nokia.shared.1");
+ waitForResponse1(id);
+ waitForItemsRemoved(1);
}
QCOMPARE(listModel->rowCount(), 40);
@@ -741,15 +788,16 @@ void TestJsonDbSortingListModel::totalRowCount()
void TestJsonDbSortingListModel::listProperty()
{
- QVariant jsonData = readJsonFile("list-objects.json");
+ resetWaitFlags();
+ QVariant jsonData = readJsonFile(findFile("list-objects.json")).toVariant();
QVariantList itemList = jsonData.toList();
int id = 0;
for (int i = 0; i < itemList.count()/2; i++) {
- id = mClient->create(itemList[i].toMap(), "com.nokia.shared.1");
+ id = create(itemList[i].toMap(), "com.nokia.shared.1");
waitForResponse1(id);
}
for (int i = itemList.count()/2; i < itemList.count(); i++) {
- id = mClient->create(itemList[i].toMap(), "com.nokia.shared.2");
+ id = create(itemList[i].toMap(), "com.nokia.shared.2");
waitForResponse1(id);
}
@@ -763,13 +811,17 @@ void TestJsonDbSortingListModel::listProperty()
listModel->setProperty("sortOrder", "[/features.0.properties.0.description]");
QStringList roleNames = (QStringList() << "_type" << "_uuid" << "features.0.properties.0.description"<< "features.0.feature");
listModel->setProperty("roleNames", roleNames);
+ mWaitingForStateChanged = true;
waitForStateOrTimeout();
+ QCOMPARE(mWaitingForStateChanged, false);
QCOMPARE(listModel->rowCount(), itemList.count());
+
QCOMPARE(get(listModel, 0, "_type").toString(), type);
QCOMPARE(get(listModel, 0, "features.0.properties.0.description").toString(), QLatin1String("Facebook account provider"));
QCOMPARE(get(listModel, 0, "features.0.feature").toString(), QLatin1String("provide Facebook"));
- QCOMPARE(get(listModel, 1, "_uuid").toString(), mLastUuid);
+ //Liang: todo or not?
+ //QCOMPARE(get(listModel, 1, "_uuid").toString(), mLastUuid);
QCOMPARE(get(listModel, 1, "_type").toString(), type);
QCOMPARE(get(listModel, 1, "features.0.properties.0.description").toString(), QLatin1String("Gmail account provider"));
QCOMPARE(get(listModel, 1, "features.0.feature").toString(), QLatin1String("provide Gmail"));
@@ -787,7 +839,9 @@ void TestJsonDbSortingListModel::listProperty()
roleNames.clear();
roleNames = (QStringList() << "_type" << "_uuid" << "features[0].properties[0].description"<< "features[0].supported[0]");
listModel->setProperty("roleNames", roleNames);
+ mWaitingForStateChanged = true;
waitForStateOrTimeout();
+ QCOMPARE(mWaitingForStateChanged, false);
QCOMPARE(listModel->rowCount(), itemList.count());
QCOMPARE(get(listModel, 0, "_type").toString(), type);
@@ -800,23 +854,23 @@ void TestJsonDbSortingListModel::listProperty()
deleteModel(listModel);
}
-
// Populate model of 300 items two partitions.
void TestJsonDbSortingListModel::twoPartitions()
{
+ resetWaitFlags();
QVariantMap item;
for (int i=0; i < 300; i = i+2) {
item.insert("_type", __FUNCTION__);
item.insert("name", QString("Arnie_%1").arg(i));
- int id = mClient->create(item, "com.nokia.shared.1");
+ int id = create(item, "com.nokia.shared.1");
waitForResponse1(id);
}
for (int i=1; i < 300; i = i+2) {
item.insert("_type", __FUNCTION__);
item.insert("name", QString("Arnie_%1").arg(i));
- int id = mClient->create(item, "com.nokia.shared.2");
+ int id = create(item, "com.nokia.shared.2");
waitForResponse1(id);
}
@@ -829,7 +883,9 @@ void TestJsonDbSortingListModel::twoPartitions()
listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__));
connectListModel(listModel);
+ mWaitingForStateChanged = true;
waitForStateOrTimeout();
+ QCOMPARE(mWaitingForStateChanged, false);
QCOMPARE(listModel->rowCount(), 300);
QCOMPARE(get(listModel, 0, "name").toString(), QString("Arnie_0"));
@@ -842,12 +898,13 @@ void TestJsonDbSortingListModel::twoPartitions()
void TestJsonDbSortingListModel::changeQuery()
{
+ resetWaitFlags();
QVariantMap item;
for (int i=0; i < 10; i++) {
item.insert("_type", __FUNCTION__);
item.insert("name", QString("Arnie_%1").arg(i));
- int id = mClient->create(item, "com.nokia.shared.1");
+ int id = create(item, "com.nokia.shared.1");
waitForResponse1(id);
}
@@ -860,7 +917,9 @@ void TestJsonDbSortingListModel::changeQuery()
listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__));
connectListModel(listModel);
+ mWaitingForStateChanged = true;
waitForStateOrTimeout();
+ QCOMPARE(mWaitingForStateChanged, false);
QCOMPARE(listModel->rowCount(), 10);
QCOMPARE(listModel->property("query").toString(), QString("[?_type=\"%1\"]").arg(__FUNCTION__));
@@ -876,7 +935,10 @@ void TestJsonDbSortingListModel::changeQuery()
QCOMPARE(listModel->property("query").toString(), QString(""));
listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__));
+
+ mWaitingForStateChanged = true;
waitForStateOrTimeout();
+ QCOMPARE(mWaitingForStateChanged, false);
QCOMPARE(listModel->rowCount(), 10);
QCOMPARE(listModel->property("query").toString(), QString("[?_type=\"%1\"]").arg(__FUNCTION__));
@@ -886,12 +948,13 @@ void TestJsonDbSortingListModel::changeQuery()
void TestJsonDbSortingListModel::getQJSValue()
{
+ resetWaitFlags();
QVariantMap item;
for (int i=0; i < 10; i++) {
item.insert("_type", __FUNCTION__);
item.insert("name", QString("Arnie_%1").arg(i));
- int id = mClient->create(item, "com.nokia.shared.1");
+ int id = create(item, "com.nokia.shared.1");
waitForResponse1(id);
}
@@ -904,7 +967,9 @@ void TestJsonDbSortingListModel::getQJSValue()
listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__));
connectListModel(listModel);
+ mWaitingForStateChanged = true;
waitForStateOrTimeout();
+ QCOMPARE(mWaitingForStateChanged, false);
QCOMPARE(listModel->rowCount(), 10);
QCOMPARE(get(listModel, 0).property("object").property("name").toString(), QString("Arnie_0"));
@@ -913,13 +978,13 @@ void TestJsonDbSortingListModel::getQJSValue()
deleteModel(listModel);
}
-
void TestJsonDbSortingListModel::indexOfUuid()
{
+ resetWaitFlags();
QVariantMap item;
item.insert("_type", __FUNCTION__);
item.insert("name", QString("Arnie_0"));
- int id = mClient->create(item, "com.nokia.shared.1");
+ int id = create(item, "com.nokia.shared.1");
waitForResponse1(id);
QAbstractListModel *listModel = createModel();
@@ -931,7 +996,9 @@ void TestJsonDbSortingListModel::indexOfUuid()
listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__));
connectListModel(listModel);
+ mWaitingForStateChanged = true;
waitForStateOrTimeout();
+ QCOMPARE(mWaitingForStateChanged, false);
QCOMPARE(listModel->rowCount(), 1);
QCOMPARE(get(listModel, 0, "name").toString(), QString("Arnie_0"));
@@ -939,9 +1006,14 @@ void TestJsonDbSortingListModel::indexOfUuid()
item.insert("_type", __FUNCTION__);
item.insert("name", QString("Arnie_1"));
- id = mClient->create(item, "com.nokia.shared.1");
+ id = create(item, "com.nokia.shared.1");
+ waitForResponse1(id);
- waitForItemsCreated(1);
+ waitForItemsCreated(1); // will set mWaitingForRowsInserted = true for you
+ if (id != lastRequestId)
+ waitForResponse1(id);
+ QCOMPARE(mWaitingForRowsInserted, false);
+ QCOMPARE(mItemsCreated, 1);
QCOMPARE(listModel->rowCount(), 2);
QCOMPARE(get(listModel, 1, "name").toString(), QString("Arnie_1"));
@@ -953,12 +1025,13 @@ void TestJsonDbSortingListModel::indexOfUuid()
void TestJsonDbSortingListModel::queryLimit()
{
+ resetWaitFlags();
QVariantMap item;
for (int i=0; i < 300; i++) {
item.insert("_type", __FUNCTION__);
item.insert("name", QString("Arnie_%1").arg(i));
- int id = mClient->create(item, "com.nokia.shared.1");
+ int id = create(item, "com.nokia.shared.1");
waitForResponse1(id);
}
@@ -972,7 +1045,9 @@ void TestJsonDbSortingListModel::queryLimit()
listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__));
connectListModel(listModel);
+ mWaitingForStateChanged = true;
waitForStateOrTimeout();
+ QCOMPARE(mWaitingForStateChanged, false);
QCOMPARE(listModel->rowCount(), 100);
QCOMPARE(listModel->property("overflow").toBool(), true);
@@ -983,7 +1058,10 @@ void TestJsonDbSortingListModel::queryLimit()
listModel->setProperty("queryLimit", 500);
+ mWaitingForStateChanged = true;
waitForStateOrTimeout();
+ QCOMPARE(mWaitingForStateChanged, false);
+
QCOMPARE(listModel->rowCount(), 300);
QCOMPARE(listModel->property("overflow").toBool(), false);
@@ -992,15 +1070,15 @@ void TestJsonDbSortingListModel::queryLimit()
void TestJsonDbSortingListModel::roleNames()
{
+ resetWaitFlags();
QVariantMap item;
item.insert("_type", __FUNCTION__);
item.insert("name", QString("Arnie"));
item.insert("friend", QString("Bert"));
- int id = mClient->create(item, "com.nokia.shared.1");
+ int id = create(item, "com.nokia.shared.1");
waitForResponse1(id);
-
QAbstractListModel *listModel = createModel();
if (!listModel) return;
@@ -1009,7 +1087,9 @@ void TestJsonDbSortingListModel::roleNames()
listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__));
connectListModel(listModel);
+ mWaitingForStateChanged = true;
waitForStateOrTimeout();
+ QCOMPARE(mWaitingForStateChanged, false);
QCOMPARE(listModel->rowCount(), 1);
@@ -1031,7 +1111,6 @@ void TestJsonDbSortingListModel::roleNames()
deleteModel(listModel);
}
-
QStringList TestJsonDbSortingListModel::getOrderValues(QAbstractListModel *listModel)
{
QStringList vals;
@@ -1042,15 +1121,23 @@ QStringList TestJsonDbSortingListModel::getOrderValues(QAbstractListModel *listM
void TestJsonDbSortingListModel::modelReset()
{
- mWaitingForReset = false;
- mEventLoop2.exit(0);
+ //qDebug() << "modelReset";
+ if (mWaitingForReset) {
+ mWaitingForReset = false;
+ eventLoop1.exit(0);
+ }
}
void TestJsonDbSortingListModel::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
{
Q_UNUSED(topLeft);
Q_UNUSED(bottomRight);
- mWaitingForDataChange = false;
+ mItemsUpdated++;
+ //qDebug() << "mItemsUpdated++" << mItemsUpdated;
+ if (mWaitingForChanged) {
+ mWaitingForChanged = false;
+ eventLoop1.exit(0);
+ }
}
void TestJsonDbSortingListModel::rowsInserted(const QModelIndex &parent, int first, int last)
@@ -1059,7 +1146,11 @@ void TestJsonDbSortingListModel::rowsInserted(const QModelIndex &parent, int fir
Q_UNUSED(first);
Q_UNUSED(last);
mItemsCreated++;
- mEventLoop2.exit(0);
+ //qDebug() << "mItemsCreated++" << mItemsCreated;
+ if (mWaitingForRowsInserted) {
+ mWaitingForRowsInserted = false;
+ eventLoop1.exit(0);
+ }
}
void TestJsonDbSortingListModel::rowsRemoved(const QModelIndex &parent, int first, int last)
@@ -1067,95 +1158,176 @@ void TestJsonDbSortingListModel::rowsRemoved(const QModelIndex &parent, int firs
Q_UNUSED(parent);
Q_UNUSED(first);
Q_UNUSED(last);
- mWaitingForRowsRemoved = false;
+ mItemsRemoved++;
+ //qDebug() << "mItemsRemoved++" << mItemsRemoved;
+ if (mWaitingForRemoved) {
+ mWaitingForRemoved = false;
+ eventLoop1.exit(0);
+ }
}
void TestJsonDbSortingListModel::rowsMoved( const QModelIndex &parent, int start, int end, const QModelIndex &destination, int row )
{
Q_UNUSED(parent);
+
Q_UNUSED(start);
Q_UNUSED(end);
Q_UNUSED(destination);
Q_UNUSED(row);
}
-void TestJsonDbSortingListModel::stateChanged()
+void TestJsonDbSortingListModel::stateChanged(State state)
{
- mWaitingForStateChanged = false;
- mEventLoop2.exit(0);
+ if (mWaitingForStateChanged) {
+ mWaitingForStateChanged = false;
+ eventLoop1.exit(0);
+ }
+ else if (mWaitingForReadyState && state == Ready) {
+ mWaitingForReadyState = false;
+ eventLoop1.exit(0);
+ }
}
void TestJsonDbSortingListModel::waitForItemsCreated(int items)
{
- mTimeoutCalled = false;
+ mTimedOut = false;
QTimer timer;
QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout()));
- QObject::connect(&timer, SIGNAL(timeout()), &mEventLoop2, SLOT(quit()));
- timer.start(mClientTimeout);
- mElapsedTimer.start();
+ timer.start(clientTimeout);
+ elapsedTimer.start();
- mItemsCreated = 0;
- while (mItemsCreated != items && !mTimeoutCalled)
- mEventLoop2.processEvents(QEventLoop::AllEvents, mClientTimeout);
+ while (!mTimedOut && mItemsCreated != items) {
+ mWaitingForRowsInserted = true;
+ eventLoop1.exec(QEventLoop::AllEvents);
+ }
+}
+
+void TestJsonDbSortingListModel::waitForItemsRemoved(int items)
+{
+ mTimedOut = false;
+ QTimer timer;
+ QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout()));
+ timer.start(clientTimeout);
+ elapsedTimer.start();
+
+ while (!mTimedOut && mItemsRemoved != items) {
+ mWaitingForRemoved = true;
+ eventLoop1.exec(QEventLoop::AllEvents);
+ }
+ if (mTimedOut)
+ qDebug () << "waitForItemsRemoved Timed out";
}
void TestJsonDbSortingListModel::waitForExitOrTimeout()
{
- mTimeoutCalled = false;
QTimer timer;
QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout()));
- QObject::connect(&timer, SIGNAL(timeout()), &mEventLoop2, SLOT(quit()));
- timer.start(mClientTimeout);
- mElapsedTimer.start();
- mEventLoop2.exec(QEventLoop::AllEvents);
+ timer.start(clientTimeout);
+ elapsedTimer.start();
+ eventLoop1.exec(QEventLoop::AllEvents);
+}
+
+void TestJsonDbSortingListModel::waitForReadyStateOrTimeout()
+{
+ mTimedOut = false;
+ QTimer timer;
+ QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout()));
+ timer.start(clientTimeout);
+ elapsedTimer.start();
+
+ while (mWaitingForReadyState && !mTimedOut)
+ eventLoop1.exec(QEventLoop::AllEvents);
}
void TestJsonDbSortingListModel::waitForStateOrTimeout()
{
- mTimeoutCalled = false;
+ mTimedOut = false;
QTimer timer;
QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout()));
- QObject::connect(&timer, SIGNAL(timeout()), &mEventLoop2, SLOT(quit()));
- timer.start(mClientTimeout);
- mElapsedTimer.start();
+ timer.start(clientTimeout);
+ elapsedTimer.start();
- mWaitingForStateChanged = true;
- while (mWaitingForStateChanged && !mTimeoutCalled)
- mEventLoop2.processEvents(QEventLoop::AllEvents, mClientTimeout);
+ while (mWaitingForStateChanged && !mTimedOut)
+ eventLoop1.exec(QEventLoop::AllEvents);
}
void TestJsonDbSortingListModel::timeout()
{
- ClientWrapper::timeout();
- mTimeoutCalled = true;
+ RequestWrapper::timeout();
+ mTimedOut = true;
+ eventLoop1.quit();
+}
+
+void TestJsonDbSortingListModel::resetWaitFlags()
+{
+ mItemsCreated = 0;
+ mItemsUpdated = 0;
+ mItemsRemoved = 0;
+ mWaitingForRowsInserted = false;
+ mWaitingForReset = false;
+ mWaitingForChanged = false;
+ mWaitingForRemoved = false;
+ mWaitingForStateChanged = false;
+}
+
+void TestJsonDbSortingListModel::waitForStateChanged(QAbstractListModel *listModel)
+{
+ int currentState;
+ currentState = listModel->property("state").toInt();
+ //1: JsonDbSortingListModel::Querying
+ if (currentState != 1) {
+ mWaitingForStateChanged = true;
+ waitForStateOrTimeout();
+ QCOMPARE(mWaitingForStateChanged, false);
+ currentState = listModel->property("state").toInt();
+ }
+ if (currentState == 1) {
+ mWaitingForStateChanged = true;
+ waitForStateOrTimeout();
+ QCOMPARE(mWaitingForStateChanged, false);
+ currentState = listModel->property("state").toInt();
+ }
}
void TestJsonDbSortingListModel::waitForItemChanged(bool waitForRemove)
{
- mTimeoutCalled = false;
+ mTimedOut = false;
QTimer timer;
QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout()));
- QObject::connect(&timer, SIGNAL(timeout()), &mEventLoop2, SLOT(quit()));
- timer.start(mClientTimeout);
- mElapsedTimer.start();
+ timer.start(clientTimeout);
+ elapsedTimer.start();
- mWaitingForRowsRemoved = true;
- mWaitingForDataChange = true;
+ mWaitingForRemoved = true;
+ mWaitingForChanged = true;
mItemsCreated = 0;
mWaitingForReset = true;
+ mWaitingForStateChanged = true;
bool waitMore = true;
- while (waitMore && !mTimeoutCalled) {
- if (!mWaitingForDataChange)
+ while (waitMore && !mTimedOut) {
+ if (!mWaitingForChanged) {
+ //qDebug() << "waitForItemChanged: mWaitingForChanged";
+ break;
+ }
+ if (!mWaitingForStateChanged) {
+ //qDebug() << "waitForItemChanged: mWaitingForStateChanged";
break;
- if (mItemsCreated)
+ }
+ if (mItemsCreated){
+ //qDebug() << "waitForItemChanged: mItemsCreated";
break;
- if (!mWaitingForReset)
+ }
+ if (!mWaitingForReset){
+ //qDebug() << "waitForItemChanged: mWaitingForReset";
break;
- if (waitForRemove && !mWaitingForRowsRemoved)
+ }
+ if (waitForRemove && !mWaitingForRemoved){
+ //qDebug() << "waitForItemChanged: mWaitingForRemoved";
break;
- mEventLoop2.processEvents(QEventLoop::AllEvents);
+ }
+ eventLoop1.exec(QEventLoop::AllEvents);
}
}
+
QTEST_MAIN(TestJsonDbSortingListModel)
diff --git a/tests/auto/jsondbsortinglistmodel/testjsondbsortinglistmodel.h b/tests/auto/jsondbsortinglistmodel/testjsondbsortinglistmodel.h
index 752eb9a7..dcbad13b 100644
--- a/tests/auto/jsondbsortinglistmodel/testjsondbsortinglistmodel.h
+++ b/tests/auto/jsondbsortinglistmodel/testjsondbsortinglistmodel.h
@@ -41,22 +41,9 @@
#ifndef TestJsonDbListModel_H
#define TestJsonDbListModel_H
-#include <QCoreApplication>
-#include <QList>
-#include <QTest>
-#include <QFile>
-#include <QProcess>
-#include <QEventLoop>
-#include <QDebug>
-#include <QLocalSocket>
-#include <QTimer>
-
-#include <jsondb-client.h>
-#include <jsondb-error.h>
-
#include <QAbstractListModel>
-#include "clientwrapper.h"
-#include "../../shared/qmltestutil.h"
+#include "requestwrapper.h"
+#include "qmltestutil.h"
QT_BEGIN_NAMESPACE
class QQmlEngine;
@@ -65,7 +52,8 @@ QT_END_NAMESPACE
QT_USE_NAMESPACE_JSONDB
-class JsonDbListModel;
+//class JsonDbListModel;
+enum State { None, Querying, Ready };
class ModelData {
public:
@@ -73,14 +61,10 @@ public:
~ModelData();
QQmlEngine *engine;
QQmlComponent *component;
- QQmlComponent *partitionComponent1;
- QQmlComponent *partitionComponent2;
QObject *model;
- QObject *parttion1;
- QObject *parttion2;
};
-class TestJsonDbSortingListModel: public ClientWrapper
+class TestJsonDbSortingListModel: public RequestWrapper
{
Q_OBJECT
public:
@@ -96,12 +80,12 @@ public slots:
void rowsRemoved(const QModelIndex &parent, int first, int last);
void rowsMoved( const QModelIndex &parent, int start, int end, const QModelIndex &destination, int row );
void modelReset();
- void stateChanged();
- void timeout();
+ void stateChanged(State);
private slots:
void initTestCase();
void cleanupTestCase();
+
void createItem();
void updateItemClient();
void deleteItem();
@@ -117,33 +101,37 @@ private slots:
void indexOfUuid();
void queryLimit();
void roleNames();
-
+public:
+ void timeout();
private:
void waitForExitOrTimeout();
void waitForItemsCreated(int items);
+ void waitForItemsRemoved(int items);
void waitForStateOrTimeout();
+ void waitForReadyStateOrTimeout();
+ void waitForStateChanged(QAbstractListModel *listModel);
void waitForItemChanged(bool waitForRemove = false);
QStringList getOrderValues(QAbstractListModel *listModel);
QAbstractListModel *createModel();
void deleteModel(QAbstractListModel *model);
- QVariant readJsonFile(const QString &filename);
+ void resetWaitFlags();
private:
QProcess *mProcess;
- QStringList mNotificationsReceived;
QList<ModelData*> mModels;
QString mPluginPath;
- QEventLoop mEventLoop2; // for all listmodel slots
// Response values
+ bool mTimedOut;
int mItemsCreated;
- bool mWaitingForNotification;
- bool mWaitingForDataChange;
- bool mWaitingForRowsRemoved;
- bool mTimeoutCalled;
+ int mItemsUpdated;
+ int mItemsRemoved;
+ bool mWaitingForRowsInserted;
bool mWaitingForReset;
+ bool mWaitingForChanged;
+ bool mWaitingForRemoved;
bool mWaitingForStateChanged;
-
+ bool mWaitingForReadyState;
};
#endif
diff --git a/tests/auto/jsonstream/jsonstream.pro b/tests/auto/jsonstream/jsonstream.pro
index 172fc7b2..f2f75c2f 100644
--- a/tests/auto/jsonstream/jsonstream.pro
+++ b/tests/auto/jsonstream/jsonstream.pro
@@ -4,7 +4,7 @@ QT = qml network testlib
CONFIG -= app_bundle
CONFIG += testcase
-include($$PWD/../../../src/common/common.pri)
+include($$PWD/../../../src/jsonstream/jsonstream.pri)
SOURCES += \
test-jsonstream.cpp
diff --git a/tests/auto/jsonstream/test-jsonstream.cpp b/tests/auto/jsonstream/test-jsonstream.cpp
index 4eac182e..15639241 100644
--- a/tests/auto/jsonstream/test-jsonstream.cpp
+++ b/tests/auto/jsonstream/test-jsonstream.cpp
@@ -40,14 +40,15 @@
****************************************************************************/
#include <QtTest/QtTest>
-#include <jsonstream.h>
+#include "jsonstream.h"
+
#include <QLocalServer>
#include <QLocalSocket>
#include <QBuffer>
#include <QDebug>
-QT_ADDON_JSONDB_USE_NAMESPACE
+using QtJsonDbJsonStream::JsonStream;
class TestJsonStream: public QObject
{
@@ -81,10 +82,9 @@ void TestJsonStream::testJsonStream()
QVERIFY(device->waitForConnected());
QVERIFY(device->state() == QLocalSocket::ConnectedState);
- JsonStream *stream = new JsonStream(device, this);
-
- connect(stream, SIGNAL(receive(QJsonObject)),
- this, SLOT(receiveStream(QJsonObject)));
+ JsonStream *stream = new JsonStream(this);
+ stream->setDevice(device);
+ connect(stream, SIGNAL(receive(QJsonObject)), this, SLOT(receiveStream(QJsonObject)));
qApp->processEvents();
qApp->processEvents();
@@ -99,7 +99,8 @@ void TestJsonStream::handleSocketConnection()
{
qDebug() << "handleSocketConnection";
serverOk = true;
- JsonStream sender(server->nextPendingConnection());
+ JsonStream sender;
+ sender.setDevice(server->nextPendingConnection());
QJsonObject json1;
json1.insert("hello", QString("world"));
diff --git a/tests/auto/daemon/json-validation.qrc b/tests/auto/partition/json-validation.qrc
index 5153c741..5153c741 100644
--- a/tests/auto/daemon/json-validation.qrc
+++ b/tests/auto/partition/json-validation.qrc
diff --git a/tests/auto/daemon/json-validation/array-boundaries-schema.json b/tests/auto/partition/json-validation/array-boundaries-schema.json
index 59f001b9..59f001b9 100644
--- a/tests/auto/daemon/json-validation/array-boundaries-schema.json
+++ b/tests/auto/partition/json-validation/array-boundaries-schema.json
diff --git a/tests/auto/daemon/json-validation/array-boundaries-twoOrLess-empty-valid.json b/tests/auto/partition/json-validation/array-boundaries-twoOrLess-empty-valid.json
index 0b99c24e..0b99c24e 100644
--- a/tests/auto/daemon/json-validation/array-boundaries-twoOrLess-empty-valid.json
+++ b/tests/auto/partition/json-validation/array-boundaries-twoOrLess-empty-valid.json
diff --git a/tests/auto/daemon/json-validation/array-boundaries-twoOrLess-five-invalid.json b/tests/auto/partition/json-validation/array-boundaries-twoOrLess-five-invalid.json
index 93d0ec31..93d0ec31 100644
--- a/tests/auto/daemon/json-validation/array-boundaries-twoOrLess-five-invalid.json
+++ b/tests/auto/partition/json-validation/array-boundaries-twoOrLess-five-invalid.json
diff --git a/tests/auto/daemon/json-validation/array-boundaries-twoOrLess-two-valid.json b/tests/auto/partition/json-validation/array-boundaries-twoOrLess-two-valid.json
index 697c5bed..697c5bed 100644
--- a/tests/auto/daemon/json-validation/array-boundaries-twoOrLess-two-valid.json
+++ b/tests/auto/partition/json-validation/array-boundaries-twoOrLess-two-valid.json
diff --git a/tests/auto/daemon/json-validation/array-boundaries-twoOrMore-empty-invalid.json b/tests/auto/partition/json-validation/array-boundaries-twoOrMore-empty-invalid.json
index b5f2d19b..b5f2d19b 100644
--- a/tests/auto/daemon/json-validation/array-boundaries-twoOrMore-empty-invalid.json
+++ b/tests/auto/partition/json-validation/array-boundaries-twoOrMore-empty-invalid.json
diff --git a/tests/auto/daemon/json-validation/array-boundaries-twoOrMore-five-valid.json b/tests/auto/partition/json-validation/array-boundaries-twoOrMore-five-valid.json
index 133961dd..133961dd 100644
--- a/tests/auto/daemon/json-validation/array-boundaries-twoOrMore-five-valid.json
+++ b/tests/auto/partition/json-validation/array-boundaries-twoOrMore-five-valid.json
diff --git a/tests/auto/daemon/json-validation/array-boundaries-twoOrMore-one-invalid.json b/tests/auto/partition/json-validation/array-boundaries-twoOrMore-one-invalid.json
index 62a898f6..62a898f6 100644
--- a/tests/auto/daemon/json-validation/array-boundaries-twoOrMore-one-invalid.json
+++ b/tests/auto/partition/json-validation/array-boundaries-twoOrMore-one-invalid.json
diff --git a/tests/auto/daemon/json-validation/array-boundaries-twoOrMore-two-valid.json b/tests/auto/partition/json-validation/array-boundaries-twoOrMore-two-valid.json
index 4547d4cb..4547d4cb 100644
--- a/tests/auto/daemon/json-validation/array-boundaries-twoOrMore-two-valid.json
+++ b/tests/auto/partition/json-validation/array-boundaries-twoOrMore-two-valid.json
diff --git a/tests/auto/daemon/json-validation/array-items-empty-empty-valid.json b/tests/auto/partition/json-validation/array-items-empty-empty-valid.json
index 49950992..49950992 100644
--- a/tests/auto/daemon/json-validation/array-items-empty-empty-valid.json
+++ b/tests/auto/partition/json-validation/array-items-empty-empty-valid.json
diff --git a/tests/auto/daemon/json-validation/array-items-empty-mixed-valid.json b/tests/auto/partition/json-validation/array-items-empty-mixed-valid.json
index e1a0d8f3..e1a0d8f3 100644
--- a/tests/auto/daemon/json-validation/array-items-empty-mixed-valid.json
+++ b/tests/auto/partition/json-validation/array-items-empty-mixed-valid.json
diff --git a/tests/auto/daemon/json-validation/array-items-empty-numbers-valid.json b/tests/auto/partition/json-validation/array-items-empty-numbers-valid.json
index 712e146e..712e146e 100644
--- a/tests/auto/daemon/json-validation/array-items-empty-numbers-valid.json
+++ b/tests/auto/partition/json-validation/array-items-empty-numbers-valid.json
diff --git a/tests/auto/daemon/json-validation/array-items-number-empty-valid.json b/tests/auto/partition/json-validation/array-items-number-empty-valid.json
index 5ffae678..5ffae678 100644
--- a/tests/auto/daemon/json-validation/array-items-number-empty-valid.json
+++ b/tests/auto/partition/json-validation/array-items-number-empty-valid.json
diff --git a/tests/auto/daemon/json-validation/array-items-number-highnumbers-invalid.json b/tests/auto/partition/json-validation/array-items-number-highnumbers-invalid.json
index fc2347e4..fc2347e4 100644
--- a/tests/auto/daemon/json-validation/array-items-number-highnumbers-invalid.json
+++ b/tests/auto/partition/json-validation/array-items-number-highnumbers-invalid.json
diff --git a/tests/auto/daemon/json-validation/array-items-number-mixed-invalid.json b/tests/auto/partition/json-validation/array-items-number-mixed-invalid.json
index 2b7d65e2..2b7d65e2 100644
--- a/tests/auto/daemon/json-validation/array-items-number-mixed-invalid.json
+++ b/tests/auto/partition/json-validation/array-items-number-mixed-invalid.json
diff --git a/tests/auto/daemon/json-validation/array-items-number-numbers-valid.json b/tests/auto/partition/json-validation/array-items-number-numbers-valid.json
index 00986d93..00986d93 100644
--- a/tests/auto/daemon/json-validation/array-items-number-numbers-valid.json
+++ b/tests/auto/partition/json-validation/array-items-number-numbers-valid.json
diff --git a/tests/auto/daemon/json-validation/array-items-number-object-invalid.json b/tests/auto/partition/json-validation/array-items-number-object-invalid.json
index 3dd8b867..3dd8b867 100644
--- a/tests/auto/daemon/json-validation/array-items-number-object-invalid.json
+++ b/tests/auto/partition/json-validation/array-items-number-object-invalid.json
diff --git a/tests/auto/daemon/json-validation/array-items-number-string-invalid.json b/tests/auto/partition/json-validation/array-items-number-string-invalid.json
index d5ccf425..d5ccf425 100644
--- a/tests/auto/daemon/json-validation/array-items-number-string-invalid.json
+++ b/tests/auto/partition/json-validation/array-items-number-string-invalid.json
diff --git a/tests/auto/daemon/json-validation/array-items-object-empty-valid.json b/tests/auto/partition/json-validation/array-items-object-empty-valid.json
index 9a2f07d9..9a2f07d9 100644
--- a/tests/auto/daemon/json-validation/array-items-object-empty-valid.json
+++ b/tests/auto/partition/json-validation/array-items-object-empty-valid.json
diff --git a/tests/auto/daemon/json-validation/array-items-object-missingfoo-valid.json b/tests/auto/partition/json-validation/array-items-object-missingfoo-valid.json
index 94ee005f..94ee005f 100644
--- a/tests/auto/daemon/json-validation/array-items-object-missingfoo-valid.json
+++ b/tests/auto/partition/json-validation/array-items-object-missingfoo-valid.json
diff --git a/tests/auto/daemon/json-validation/array-items-object-missingid-invalid.json b/tests/auto/partition/json-validation/array-items-object-missingid-invalid.json
index e1f13cdc..e1f13cdc 100644
--- a/tests/auto/daemon/json-validation/array-items-object-missingid-invalid.json
+++ b/tests/auto/partition/json-validation/array-items-object-missingid-invalid.json
diff --git a/tests/auto/daemon/json-validation/array-items-object-numbers-invalid.json b/tests/auto/partition/json-validation/array-items-object-numbers-invalid.json
index 98949560..98949560 100644
--- a/tests/auto/daemon/json-validation/array-items-object-numbers-invalid.json
+++ b/tests/auto/partition/json-validation/array-items-object-numbers-invalid.json
diff --git a/tests/auto/daemon/json-validation/array-items-object-std-valid.json b/tests/auto/partition/json-validation/array-items-object-std-valid.json
index b8d3ffe2..b8d3ffe2 100644
--- a/tests/auto/daemon/json-validation/array-items-object-std-valid.json
+++ b/tests/auto/partition/json-validation/array-items-object-std-valid.json
diff --git a/tests/auto/daemon/json-validation/array-items-object-strings-invalid.json b/tests/auto/partition/json-validation/array-items-object-strings-invalid.json
index 35c1a0c4..35c1a0c4 100644
--- a/tests/auto/daemon/json-validation/array-items-object-strings-invalid.json
+++ b/tests/auto/partition/json-validation/array-items-object-strings-invalid.json
diff --git a/tests/auto/daemon/json-validation/array-items-schema.json b/tests/auto/partition/json-validation/array-items-schema.json
index c155ccd9..c155ccd9 100644
--- a/tests/auto/daemon/json-validation/array-items-schema.json
+++ b/tests/auto/partition/json-validation/array-items-schema.json
diff --git a/tests/auto/daemon/json-validation/integer-boundaries-lessThenOne-one-invalid.json b/tests/auto/partition/json-validation/integer-boundaries-lessThenOne-one-invalid.json
index 929d80a1..929d80a1 100644
--- a/tests/auto/daemon/json-validation/integer-boundaries-lessThenOne-one-invalid.json
+++ b/tests/auto/partition/json-validation/integer-boundaries-lessThenOne-one-invalid.json
diff --git a/tests/auto/daemon/json-validation/integer-boundaries-lessThenOne-two-invalid.json b/tests/auto/partition/json-validation/integer-boundaries-lessThenOne-two-invalid.json
index fb694b0b..fb694b0b 100644
--- a/tests/auto/daemon/json-validation/integer-boundaries-lessThenOne-two-invalid.json
+++ b/tests/auto/partition/json-validation/integer-boundaries-lessThenOne-two-invalid.json
diff --git a/tests/auto/daemon/json-validation/integer-boundaries-lessThenOne-zero-valid.json b/tests/auto/partition/json-validation/integer-boundaries-lessThenOne-zero-valid.json
index 8ab8beea..8ab8beea 100644
--- a/tests/auto/daemon/json-validation/integer-boundaries-lessThenOne-zero-valid.json
+++ b/tests/auto/partition/json-validation/integer-boundaries-lessThenOne-zero-valid.json
diff --git a/tests/auto/daemon/json-validation/integer-boundaries-moreThenOne-one-invalid.json b/tests/auto/partition/json-validation/integer-boundaries-moreThenOne-one-invalid.json
index 9197c7df..9197c7df 100644
--- a/tests/auto/daemon/json-validation/integer-boundaries-moreThenOne-one-invalid.json
+++ b/tests/auto/partition/json-validation/integer-boundaries-moreThenOne-one-invalid.json
diff --git a/tests/auto/daemon/json-validation/integer-boundaries-moreThenOne-two-valid.json b/tests/auto/partition/json-validation/integer-boundaries-moreThenOne-two-valid.json
index 4eeb4bbc..4eeb4bbc 100644
--- a/tests/auto/daemon/json-validation/integer-boundaries-moreThenOne-two-valid.json
+++ b/tests/auto/partition/json-validation/integer-boundaries-moreThenOne-two-valid.json
diff --git a/tests/auto/daemon/json-validation/integer-boundaries-moreThenOne-zero-invalid.json b/tests/auto/partition/json-validation/integer-boundaries-moreThenOne-zero-invalid.json
index c60214f4..c60214f4 100644
--- a/tests/auto/daemon/json-validation/integer-boundaries-moreThenOne-zero-invalid.json
+++ b/tests/auto/partition/json-validation/integer-boundaries-moreThenOne-zero-invalid.json
diff --git a/tests/auto/daemon/json-validation/integer-boundaries-oneOrLess-one-valid.json b/tests/auto/partition/json-validation/integer-boundaries-oneOrLess-one-valid.json
index c18da6ca..c18da6ca 100644
--- a/tests/auto/daemon/json-validation/integer-boundaries-oneOrLess-one-valid.json
+++ b/tests/auto/partition/json-validation/integer-boundaries-oneOrLess-one-valid.json
diff --git a/tests/auto/daemon/json-validation/integer-boundaries-oneOrLess-two-invalid.json b/tests/auto/partition/json-validation/integer-boundaries-oneOrLess-two-invalid.json
index 27468647..27468647 100644
--- a/tests/auto/daemon/json-validation/integer-boundaries-oneOrLess-two-invalid.json
+++ b/tests/auto/partition/json-validation/integer-boundaries-oneOrLess-two-invalid.json
diff --git a/tests/auto/daemon/json-validation/integer-boundaries-oneOrMore-one-valid.json b/tests/auto/partition/json-validation/integer-boundaries-oneOrMore-one-valid.json
index 1eecd48a..1eecd48a 100644
--- a/tests/auto/daemon/json-validation/integer-boundaries-oneOrMore-one-valid.json
+++ b/tests/auto/partition/json-validation/integer-boundaries-oneOrMore-one-valid.json
diff --git a/tests/auto/daemon/json-validation/integer-boundaries-oneOrMore-two-valid.json b/tests/auto/partition/json-validation/integer-boundaries-oneOrMore-two-valid.json
index e1bbfe04..e1bbfe04 100644
--- a/tests/auto/daemon/json-validation/integer-boundaries-oneOrMore-two-valid.json
+++ b/tests/auto/partition/json-validation/integer-boundaries-oneOrMore-two-valid.json
diff --git a/tests/auto/daemon/json-validation/integer-boundaries-oneOrMore-zero-invalid.json b/tests/auto/partition/json-validation/integer-boundaries-oneOrMore-zero-invalid.json
index 848f6dc5..848f6dc5 100644
--- a/tests/auto/daemon/json-validation/integer-boundaries-oneOrMore-zero-invalid.json
+++ b/tests/auto/partition/json-validation/integer-boundaries-oneOrMore-zero-invalid.json
diff --git a/tests/auto/daemon/json-validation/integer-boundaries-schema.json b/tests/auto/partition/json-validation/integer-boundaries-schema.json
index 5575d28e..5575d28e 100644
--- a/tests/auto/daemon/json-validation/integer-boundaries-schema.json
+++ b/tests/auto/partition/json-validation/integer-boundaries-schema.json
diff --git a/tests/auto/daemon/json-validation/numbers-boundaries-lessThenOne-one-invalid.json b/tests/auto/partition/json-validation/numbers-boundaries-lessThenOne-one-invalid.json
index 515feadc..515feadc 100644
--- a/tests/auto/daemon/json-validation/numbers-boundaries-lessThenOne-one-invalid.json
+++ b/tests/auto/partition/json-validation/numbers-boundaries-lessThenOne-one-invalid.json
diff --git a/tests/auto/daemon/json-validation/numbers-boundaries-lessThenOne-two-invalid.json b/tests/auto/partition/json-validation/numbers-boundaries-lessThenOne-two-invalid.json
index b353576e..b353576e 100644
--- a/tests/auto/daemon/json-validation/numbers-boundaries-lessThenOne-two-invalid.json
+++ b/tests/auto/partition/json-validation/numbers-boundaries-lessThenOne-two-invalid.json
diff --git a/tests/auto/daemon/json-validation/numbers-boundaries-lessThenOne-zero-valid.json b/tests/auto/partition/json-validation/numbers-boundaries-lessThenOne-zero-valid.json
index c3dc2ed0..c3dc2ed0 100644
--- a/tests/auto/daemon/json-validation/numbers-boundaries-lessThenOne-zero-valid.json
+++ b/tests/auto/partition/json-validation/numbers-boundaries-lessThenOne-zero-valid.json
diff --git a/tests/auto/daemon/json-validation/numbers-boundaries-moreThenOne-one-invalid.json b/tests/auto/partition/json-validation/numbers-boundaries-moreThenOne-one-invalid.json
index 16d07ce9..16d07ce9 100644
--- a/tests/auto/daemon/json-validation/numbers-boundaries-moreThenOne-one-invalid.json
+++ b/tests/auto/partition/json-validation/numbers-boundaries-moreThenOne-one-invalid.json
diff --git a/tests/auto/daemon/json-validation/numbers-boundaries-moreThenOne-two-valid.json b/tests/auto/partition/json-validation/numbers-boundaries-moreThenOne-two-valid.json
index bdc4068f..bdc4068f 100644
--- a/tests/auto/daemon/json-validation/numbers-boundaries-moreThenOne-two-valid.json
+++ b/tests/auto/partition/json-validation/numbers-boundaries-moreThenOne-two-valid.json
diff --git a/tests/auto/daemon/json-validation/numbers-boundaries-moreThenOne-zero-invalid.json b/tests/auto/partition/json-validation/numbers-boundaries-moreThenOne-zero-invalid.json
index 5e5d8962..5e5d8962 100644
--- a/tests/auto/daemon/json-validation/numbers-boundaries-moreThenOne-zero-invalid.json
+++ b/tests/auto/partition/json-validation/numbers-boundaries-moreThenOne-zero-invalid.json
diff --git a/tests/auto/daemon/json-validation/numbers-boundaries-oneOrLess-one-valid.json b/tests/auto/partition/json-validation/numbers-boundaries-oneOrLess-one-valid.json
index 42600228..42600228 100644
--- a/tests/auto/daemon/json-validation/numbers-boundaries-oneOrLess-one-valid.json
+++ b/tests/auto/partition/json-validation/numbers-boundaries-oneOrLess-one-valid.json
diff --git a/tests/auto/daemon/json-validation/numbers-boundaries-oneOrLess-two-invalid.json b/tests/auto/partition/json-validation/numbers-boundaries-oneOrLess-two-invalid.json
index 2ebecfcf..2ebecfcf 100644
--- a/tests/auto/daemon/json-validation/numbers-boundaries-oneOrLess-two-invalid.json
+++ b/tests/auto/partition/json-validation/numbers-boundaries-oneOrLess-two-invalid.json
diff --git a/tests/auto/daemon/json-validation/numbers-boundaries-oneOrLess-zero-valid.json b/tests/auto/partition/json-validation/numbers-boundaries-oneOrLess-zero-valid.json
index e554507a..e554507a 100644
--- a/tests/auto/daemon/json-validation/numbers-boundaries-oneOrLess-zero-valid.json
+++ b/tests/auto/partition/json-validation/numbers-boundaries-oneOrLess-zero-valid.json
diff --git a/tests/auto/daemon/json-validation/numbers-boundaries-oneOrMore-one-valid.json b/tests/auto/partition/json-validation/numbers-boundaries-oneOrMore-one-valid.json
index f7ce9d88..f7ce9d88 100644
--- a/tests/auto/daemon/json-validation/numbers-boundaries-oneOrMore-one-valid.json
+++ b/tests/auto/partition/json-validation/numbers-boundaries-oneOrMore-one-valid.json
diff --git a/tests/auto/daemon/json-validation/numbers-boundaries-oneOrMore-two-valid.json b/tests/auto/partition/json-validation/numbers-boundaries-oneOrMore-two-valid.json
index 5ef0d9e3..5ef0d9e3 100644
--- a/tests/auto/daemon/json-validation/numbers-boundaries-oneOrMore-two-valid.json
+++ b/tests/auto/partition/json-validation/numbers-boundaries-oneOrMore-two-valid.json
diff --git a/tests/auto/daemon/json-validation/numbers-boundaries-oneOrMore-zero-invalid.json b/tests/auto/partition/json-validation/numbers-boundaries-oneOrMore-zero-invalid.json
index 4730c400..4730c400 100644
--- a/tests/auto/daemon/json-validation/numbers-boundaries-oneOrMore-zero-invalid.json
+++ b/tests/auto/partition/json-validation/numbers-boundaries-oneOrMore-zero-invalid.json
diff --git a/tests/auto/daemon/json-validation/numbers-boundaries-schema.json b/tests/auto/partition/json-validation/numbers-boundaries-schema.json
index 74c02d96..74c02d96 100644
--- a/tests/auto/daemon/json-validation/numbers-boundaries-schema.json
+++ b/tests/auto/partition/json-validation/numbers-boundaries-schema.json
diff --git a/tests/auto/daemon/json-validation/required-missing-invalid.json b/tests/auto/partition/json-validation/required-missing-invalid.json
index b4453061..b4453061 100644
--- a/tests/auto/daemon/json-validation/required-missing-invalid.json
+++ b/tests/auto/partition/json-validation/required-missing-invalid.json
diff --git a/tests/auto/daemon/json-validation/required-nested-valid.json b/tests/auto/partition/json-validation/required-nested-valid.json
index f7571492..f7571492 100644
--- a/tests/auto/daemon/json-validation/required-nested-valid.json
+++ b/tests/auto/partition/json-validation/required-nested-valid.json
diff --git a/tests/auto/daemon/json-validation/required-notimportent-number-invalid.json b/tests/auto/partition/json-validation/required-notimportent-number-invalid.json
index a7325db0..a7325db0 100644
--- a/tests/auto/daemon/json-validation/required-notimportent-number-invalid.json
+++ b/tests/auto/partition/json-validation/required-notimportent-number-invalid.json
diff --git a/tests/auto/daemon/json-validation/required-number-valid.json b/tests/auto/partition/json-validation/required-number-valid.json
index 78b039a7..78b039a7 100644
--- a/tests/auto/daemon/json-validation/required-number-valid.json
+++ b/tests/auto/partition/json-validation/required-number-valid.json
diff --git a/tests/auto/daemon/json-validation/required-object-valid.json b/tests/auto/partition/json-validation/required-object-valid.json
index 6acfbdc1..6acfbdc1 100644
--- a/tests/auto/daemon/json-validation/required-object-valid.json
+++ b/tests/auto/partition/json-validation/required-object-valid.json
diff --git a/tests/auto/daemon/json-validation/required-schema.json b/tests/auto/partition/json-validation/required-schema.json
index 881e295b..881e295b 100644
--- a/tests/auto/daemon/json-validation/required-schema.json
+++ b/tests/auto/partition/json-validation/required-schema.json
diff --git a/tests/auto/daemon/json-validation/string-boundaries-max5chars-silo-valid.json b/tests/auto/partition/json-validation/string-boundaries-max5chars-silo-valid.json
index 368f132f..368f132f 100644
--- a/tests/auto/daemon/json-validation/string-boundaries-max5chars-silo-valid.json
+++ b/tests/auto/partition/json-validation/string-boundaries-max5chars-silo-valid.json
diff --git a/tests/auto/daemon/json-validation/string-boundaries-max5chars-silos-valid.json b/tests/auto/partition/json-validation/string-boundaries-max5chars-silos-valid.json
index d1c98da8..d1c98da8 100644
--- a/tests/auto/daemon/json-validation/string-boundaries-max5chars-silos-valid.json
+++ b/tests/auto/partition/json-validation/string-boundaries-max5chars-silos-valid.json
diff --git a/tests/auto/daemon/json-validation/string-boundaries-max5chars-toolong-invalid.json b/tests/auto/partition/json-validation/string-boundaries-max5chars-toolong-invalid.json
index c7bdfe18..c7bdfe18 100644
--- a/tests/auto/daemon/json-validation/string-boundaries-max5chars-toolong-invalid.json
+++ b/tests/auto/partition/json-validation/string-boundaries-max5chars-toolong-invalid.json
diff --git a/tests/auto/daemon/json-validation/string-boundaries-min5chars-silo-invalid.json b/tests/auto/partition/json-validation/string-boundaries-min5chars-silo-invalid.json
index dc085e9b..dc085e9b 100644
--- a/tests/auto/daemon/json-validation/string-boundaries-min5chars-silo-invalid.json
+++ b/tests/auto/partition/json-validation/string-boundaries-min5chars-silo-invalid.json
diff --git a/tests/auto/daemon/json-validation/string-boundaries-min5chars-silos-valid.json b/tests/auto/partition/json-validation/string-boundaries-min5chars-silos-valid.json
index 6663c273..6663c273 100644
--- a/tests/auto/daemon/json-validation/string-boundaries-min5chars-silos-valid.json
+++ b/tests/auto/partition/json-validation/string-boundaries-min5chars-silos-valid.json
diff --git a/tests/auto/daemon/json-validation/string-boundaries-min5chars-toolong-valid.json b/tests/auto/partition/json-validation/string-boundaries-min5chars-toolong-valid.json
index f1d60b45..f1d60b45 100644
--- a/tests/auto/daemon/json-validation/string-boundaries-min5chars-toolong-valid.json
+++ b/tests/auto/partition/json-validation/string-boundaries-min5chars-toolong-valid.json
diff --git a/tests/auto/daemon/json-validation/string-boundaries-pattern-a-valid.json b/tests/auto/partition/json-validation/string-boundaries-pattern-a-valid.json
index 1231c734..1231c734 100644
--- a/tests/auto/daemon/json-validation/string-boundaries-pattern-a-valid.json
+++ b/tests/auto/partition/json-validation/string-boundaries-pattern-a-valid.json
diff --git a/tests/auto/daemon/json-validation/string-boundaries-pattern-aaa-valid.json b/tests/auto/partition/json-validation/string-boundaries-pattern-aaa-valid.json
index 8dc140af..8dc140af 100644
--- a/tests/auto/daemon/json-validation/string-boundaries-pattern-aaa-valid.json
+++ b/tests/auto/partition/json-validation/string-boundaries-pattern-aaa-valid.json
diff --git a/tests/auto/daemon/json-validation/string-boundaries-pattern-ab-invalid.json b/tests/auto/partition/json-validation/string-boundaries-pattern-ab-invalid.json
index 253168fd..253168fd 100644
--- a/tests/auto/daemon/json-validation/string-boundaries-pattern-ab-invalid.json
+++ b/tests/auto/partition/json-validation/string-boundaries-pattern-ab-invalid.json
diff --git a/tests/auto/daemon/json-validation/string-boundaries-schema.json b/tests/auto/partition/json-validation/string-boundaries-schema.json
index 3aea2432..3aea2432 100644
--- a/tests/auto/daemon/json-validation/string-boundaries-schema.json
+++ b/tests/auto/partition/json-validation/string-boundaries-schema.json
diff --git a/tests/auto/daemon/json-validation/type-array-array-valid.json b/tests/auto/partition/json-validation/type-array-array-valid.json
index 34425f30..34425f30 100644
--- a/tests/auto/daemon/json-validation/type-array-array-valid.json
+++ b/tests/auto/partition/json-validation/type-array-array-valid.json
diff --git a/tests/auto/daemon/json-validation/type-array-bool-invalid.json b/tests/auto/partition/json-validation/type-array-bool-invalid.json
index 437a46bc..437a46bc 100644
--- a/tests/auto/daemon/json-validation/type-array-bool-invalid.json
+++ b/tests/auto/partition/json-validation/type-array-bool-invalid.json
diff --git a/tests/auto/daemon/json-validation/type-array-integer-invalid.json b/tests/auto/partition/json-validation/type-array-integer-invalid.json
index 41f67e4b..41f67e4b 100644
--- a/tests/auto/daemon/json-validation/type-array-integer-invalid.json
+++ b/tests/auto/partition/json-validation/type-array-integer-invalid.json
diff --git a/tests/auto/daemon/json-validation/type-array-number-invalid.json b/tests/auto/partition/json-validation/type-array-number-invalid.json
index 15fca625..15fca625 100644
--- a/tests/auto/daemon/json-validation/type-array-number-invalid.json
+++ b/tests/auto/partition/json-validation/type-array-number-invalid.json
diff --git a/tests/auto/daemon/json-validation/type-array-object-invalid.json b/tests/auto/partition/json-validation/type-array-object-invalid.json
index af4ab14d..af4ab14d 100644
--- a/tests/auto/daemon/json-validation/type-array-object-invalid.json
+++ b/tests/auto/partition/json-validation/type-array-object-invalid.json
diff --git a/tests/auto/daemon/json-validation/type-array-string-invalid.json b/tests/auto/partition/json-validation/type-array-string-invalid.json
index 01fb9038..01fb9038 100644
--- a/tests/auto/daemon/json-validation/type-array-string-invalid.json
+++ b/tests/auto/partition/json-validation/type-array-string-invalid.json
diff --git a/tests/auto/daemon/json-validation/type-bool-array-invalid.json b/tests/auto/partition/json-validation/type-bool-array-invalid.json
index c9bb7920..c9bb7920 100644
--- a/tests/auto/daemon/json-validation/type-bool-array-invalid.json
+++ b/tests/auto/partition/json-validation/type-bool-array-invalid.json
diff --git a/tests/auto/daemon/json-validation/type-bool-false-valid.json b/tests/auto/partition/json-validation/type-bool-false-valid.json
index 7f809e1a..7f809e1a 100644
--- a/tests/auto/daemon/json-validation/type-bool-false-valid.json
+++ b/tests/auto/partition/json-validation/type-bool-false-valid.json
diff --git a/tests/auto/daemon/json-validation/type-bool-integer-invalid.json b/tests/auto/partition/json-validation/type-bool-integer-invalid.json
index 1f6e88c5..1f6e88c5 100644
--- a/tests/auto/daemon/json-validation/type-bool-integer-invalid.json
+++ b/tests/auto/partition/json-validation/type-bool-integer-invalid.json
diff --git a/tests/auto/daemon/json-validation/type-bool-number-invalid.json b/tests/auto/partition/json-validation/type-bool-number-invalid.json
index 2943012f..2943012f 100644
--- a/tests/auto/daemon/json-validation/type-bool-number-invalid.json
+++ b/tests/auto/partition/json-validation/type-bool-number-invalid.json
diff --git a/tests/auto/daemon/json-validation/type-bool-object-invalid.json b/tests/auto/partition/json-validation/type-bool-object-invalid.json
index c763630d..c763630d 100644
--- a/tests/auto/daemon/json-validation/type-bool-object-invalid.json
+++ b/tests/auto/partition/json-validation/type-bool-object-invalid.json
diff --git a/tests/auto/daemon/json-validation/type-bool-string-invalid.json b/tests/auto/partition/json-validation/type-bool-string-invalid.json
index 678468c0..678468c0 100644
--- a/tests/auto/daemon/json-validation/type-bool-string-invalid.json
+++ b/tests/auto/partition/json-validation/type-bool-string-invalid.json
diff --git a/tests/auto/daemon/json-validation/type-bool-true-valid.json b/tests/auto/partition/json-validation/type-bool-true-valid.json
index a65bb225..a65bb225 100644
--- a/tests/auto/daemon/json-validation/type-bool-true-valid.json
+++ b/tests/auto/partition/json-validation/type-bool-true-valid.json
diff --git a/tests/auto/daemon/json-validation/type-integer-array-invalid.json b/tests/auto/partition/json-validation/type-integer-array-invalid.json
index 75046728..75046728 100644
--- a/tests/auto/daemon/json-validation/type-integer-array-invalid.json
+++ b/tests/auto/partition/json-validation/type-integer-array-invalid.json
diff --git a/tests/auto/daemon/json-validation/type-integer-bool-invalid.json b/tests/auto/partition/json-validation/type-integer-bool-invalid.json
index c5c25ed9..c5c25ed9 100644
--- a/tests/auto/daemon/json-validation/type-integer-bool-invalid.json
+++ b/tests/auto/partition/json-validation/type-integer-bool-invalid.json
diff --git a/tests/auto/daemon/json-validation/type-integer-double-invalid.json b/tests/auto/partition/json-validation/type-integer-double-invalid.json
index 50c93d7a..50c93d7a 100644
--- a/tests/auto/daemon/json-validation/type-integer-double-invalid.json
+++ b/tests/auto/partition/json-validation/type-integer-double-invalid.json
diff --git a/tests/auto/daemon/json-validation/type-integer-integer-valid.json b/tests/auto/partition/json-validation/type-integer-integer-valid.json
index f6922f01..f6922f01 100644
--- a/tests/auto/daemon/json-validation/type-integer-integer-valid.json
+++ b/tests/auto/partition/json-validation/type-integer-integer-valid.json
diff --git a/tests/auto/daemon/json-validation/type-integer-object-invalid.json b/tests/auto/partition/json-validation/type-integer-object-invalid.json
index a3f1ee6a..a3f1ee6a 100644
--- a/tests/auto/daemon/json-validation/type-integer-object-invalid.json
+++ b/tests/auto/partition/json-validation/type-integer-object-invalid.json
diff --git a/tests/auto/daemon/json-validation/type-integer-string-invalid.json b/tests/auto/partition/json-validation/type-integer-string-invalid.json
index 4fcdc391..4fcdc391 100644
--- a/tests/auto/daemon/json-validation/type-integer-string-invalid.json
+++ b/tests/auto/partition/json-validation/type-integer-string-invalid.json
diff --git a/tests/auto/daemon/json-validation/type-mixed-array-invalid.json b/tests/auto/partition/json-validation/type-mixed-array-invalid.json
index 0214a9bf..0214a9bf 100644
--- a/tests/auto/daemon/json-validation/type-mixed-array-invalid.json
+++ b/tests/auto/partition/json-validation/type-mixed-array-invalid.json
diff --git a/tests/auto/daemon/json-validation/type-mixed-double-invalid.json b/tests/auto/partition/json-validation/type-mixed-double-invalid.json
index 98683900..98683900 100644
--- a/tests/auto/daemon/json-validation/type-mixed-double-invalid.json
+++ b/tests/auto/partition/json-validation/type-mixed-double-invalid.json
diff --git a/tests/auto/daemon/json-validation/type-mixed-number-valid.json b/tests/auto/partition/json-validation/type-mixed-number-valid.json
index 8a5ff6a7..8a5ff6a7 100644
--- a/tests/auto/daemon/json-validation/type-mixed-number-valid.json
+++ b/tests/auto/partition/json-validation/type-mixed-number-valid.json
diff --git a/tests/auto/daemon/json-validation/type-mixed-object-invalid.json b/tests/auto/partition/json-validation/type-mixed-object-invalid.json
index 87597e2d..87597e2d 100644
--- a/tests/auto/daemon/json-validation/type-mixed-object-invalid.json
+++ b/tests/auto/partition/json-validation/type-mixed-object-invalid.json
diff --git a/tests/auto/daemon/json-validation/type-mixed-string-valid.json b/tests/auto/partition/json-validation/type-mixed-string-valid.json
index abc8f382..abc8f382 100644
--- a/tests/auto/daemon/json-validation/type-mixed-string-valid.json
+++ b/tests/auto/partition/json-validation/type-mixed-string-valid.json
diff --git a/tests/auto/daemon/json-validation/type-number-array-invalid.json b/tests/auto/partition/json-validation/type-number-array-invalid.json
index 8afa6212..8afa6212 100644
--- a/tests/auto/daemon/json-validation/type-number-array-invalid.json
+++ b/tests/auto/partition/json-validation/type-number-array-invalid.json
diff --git a/tests/auto/daemon/json-validation/type-number-bool-invalid.json b/tests/auto/partition/json-validation/type-number-bool-invalid.json
index f1407060..f1407060 100644
--- a/tests/auto/daemon/json-validation/type-number-bool-invalid.json
+++ b/tests/auto/partition/json-validation/type-number-bool-invalid.json
diff --git a/tests/auto/daemon/json-validation/type-number-double-valid.json b/tests/auto/partition/json-validation/type-number-double-valid.json
index 74b549a2..74b549a2 100644
--- a/tests/auto/daemon/json-validation/type-number-double-valid.json
+++ b/tests/auto/partition/json-validation/type-number-double-valid.json
diff --git a/tests/auto/daemon/json-validation/type-number-number-valid.json b/tests/auto/partition/json-validation/type-number-number-valid.json
index 27a667fa..27a667fa 100644
--- a/tests/auto/daemon/json-validation/type-number-number-valid.json
+++ b/tests/auto/partition/json-validation/type-number-number-valid.json
diff --git a/tests/auto/daemon/json-validation/type-number-object-invalid.json b/tests/auto/partition/json-validation/type-number-object-invalid.json
index 68c2e512..68c2e512 100644
--- a/tests/auto/daemon/json-validation/type-number-object-invalid.json
+++ b/tests/auto/partition/json-validation/type-number-object-invalid.json
diff --git a/tests/auto/daemon/json-validation/type-number-string-invalid.json b/tests/auto/partition/json-validation/type-number-string-invalid.json
index e19b9c88..e19b9c88 100644
--- a/tests/auto/daemon/json-validation/type-number-string-invalid.json
+++ b/tests/auto/partition/json-validation/type-number-string-invalid.json
diff --git a/tests/auto/daemon/json-validation/type-object-array-invalid.json b/tests/auto/partition/json-validation/type-object-array-invalid.json
index 69e69855..69e69855 100644
--- a/tests/auto/daemon/json-validation/type-object-array-invalid.json
+++ b/tests/auto/partition/json-validation/type-object-array-invalid.json
diff --git a/tests/auto/daemon/json-validation/type-object-bool-invalid.json b/tests/auto/partition/json-validation/type-object-bool-invalid.json
index 1ee40176..1ee40176 100644
--- a/tests/auto/daemon/json-validation/type-object-bool-invalid.json
+++ b/tests/auto/partition/json-validation/type-object-bool-invalid.json
diff --git a/tests/auto/daemon/json-validation/type-object-double-invalid.json b/tests/auto/partition/json-validation/type-object-double-invalid.json
index 5728ac01..5728ac01 100644
--- a/tests/auto/daemon/json-validation/type-object-double-invalid.json
+++ b/tests/auto/partition/json-validation/type-object-double-invalid.json
diff --git a/tests/auto/daemon/json-validation/type-object-number-invalid.json b/tests/auto/partition/json-validation/type-object-number-invalid.json
index bd527110..bd527110 100644
--- a/tests/auto/daemon/json-validation/type-object-number-invalid.json
+++ b/tests/auto/partition/json-validation/type-object-number-invalid.json
diff --git a/tests/auto/daemon/json-validation/type-object-object-valid.json b/tests/auto/partition/json-validation/type-object-object-valid.json
index f6b61530..f6b61530 100644
--- a/tests/auto/daemon/json-validation/type-object-object-valid.json
+++ b/tests/auto/partition/json-validation/type-object-object-valid.json
diff --git a/tests/auto/daemon/json-validation/type-object-string-invalid.json b/tests/auto/partition/json-validation/type-object-string-invalid.json
index 7f5a952a..7f5a952a 100644
--- a/tests/auto/daemon/json-validation/type-object-string-invalid.json
+++ b/tests/auto/partition/json-validation/type-object-string-invalid.json
diff --git a/tests/auto/daemon/json-validation/type-schema.json b/tests/auto/partition/json-validation/type-schema.json
index 4aad2acd..4aad2acd 100644
--- a/tests/auto/daemon/json-validation/type-schema.json
+++ b/tests/auto/partition/json-validation/type-schema.json
diff --git a/tests/auto/daemon/json-validation/type-string-array-invalid.json b/tests/auto/partition/json-validation/type-string-array-invalid.json
index 10c491d9..10c491d9 100644
--- a/tests/auto/daemon/json-validation/type-string-array-invalid.json
+++ b/tests/auto/partition/json-validation/type-string-array-invalid.json
diff --git a/tests/auto/daemon/json-validation/type-string-bool-invalid.json b/tests/auto/partition/json-validation/type-string-bool-invalid.json
index d19d1048..d19d1048 100644
--- a/tests/auto/daemon/json-validation/type-string-bool-invalid.json
+++ b/tests/auto/partition/json-validation/type-string-bool-invalid.json
diff --git a/tests/auto/daemon/json-validation/type-string-double-invalid.json b/tests/auto/partition/json-validation/type-string-double-invalid.json
index af4b6ed3..af4b6ed3 100644
--- a/tests/auto/daemon/json-validation/type-string-double-invalid.json
+++ b/tests/auto/partition/json-validation/type-string-double-invalid.json
diff --git a/tests/auto/daemon/json-validation/type-string-integer-invalid.json b/tests/auto/partition/json-validation/type-string-integer-invalid.json
index 681e09b6..681e09b6 100644
--- a/tests/auto/daemon/json-validation/type-string-integer-invalid.json
+++ b/tests/auto/partition/json-validation/type-string-integer-invalid.json
diff --git a/tests/auto/daemon/json-validation/type-string-object-invalid.json b/tests/auto/partition/json-validation/type-string-object-invalid.json
index 5f7702c5..5f7702c5 100644
--- a/tests/auto/daemon/json-validation/type-string-object-invalid.json
+++ b/tests/auto/partition/json-validation/type-string-object-invalid.json
diff --git a/tests/auto/daemon/json-validation/type-string-string-valid.json b/tests/auto/partition/json-validation/type-string-string-valid.json
index 5122b734..5122b734 100644
--- a/tests/auto/daemon/json-validation/type-string-string-valid.json
+++ b/tests/auto/partition/json-validation/type-string-string-valid.json
diff --git a/tests/auto/daemon/json/array.json b/tests/auto/partition/json/array.json
index 9eff59fa..9eff59fa 100644
--- a/tests/auto/daemon/json/array.json
+++ b/tests/auto/partition/json/array.json
diff --git a/tests/auto/daemon/json/index-casepreference.json b/tests/auto/partition/json/index-casepreference.json
index 42b811a8..42b811a8 100644
--- a/tests/auto/daemon/json/index-casepreference.json
+++ b/tests/auto/partition/json/index-casepreference.json
diff --git a/tests/auto/daemon/json/index-casesensitive.json b/tests/auto/partition/json/index-casesensitive.json
index bcccd562..bcccd562 100644
--- a/tests/auto/daemon/json/index-casesensitive.json
+++ b/tests/auto/partition/json/index-casesensitive.json
diff --git a/tests/auto/daemon/json/largeContactsTest.json b/tests/auto/partition/json/largeContactsTest.json
index 7666c68f..7666c68f 100644
--- a/tests/auto/daemon/json/largeContactsTest.json
+++ b/tests/auto/partition/json/largeContactsTest.json
diff --git a/tests/auto/daemon/json/largeContactsTest10k.json b/tests/auto/partition/json/largeContactsTest10k.json
index bd9f91f0..bd9f91f0 100644
--- a/tests/auto/daemon/json/largeContactsTest10k.json
+++ b/tests/auto/partition/json/largeContactsTest10k.json
diff --git a/tests/auto/daemon/json/largeContactsTest1k.json b/tests/auto/partition/json/largeContactsTest1k.json
index 7666c68f..7666c68f 100644
--- a/tests/auto/daemon/json/largeContactsTest1k.json
+++ b/tests/auto/partition/json/largeContactsTest1k.json
diff --git a/tests/auto/daemon/json/largeContactsTest33k.json b/tests/auto/partition/json/largeContactsTest33k.json
index 5c6d37b2..5c6d37b2 100644
--- a/tests/auto/daemon/json/largeContactsTest33k.json
+++ b/tests/auto/partition/json/largeContactsTest33k.json
diff --git a/tests/auto/daemon/json/map-array-conversion.json b/tests/auto/partition/json/map-array-conversion.json
index b51aab00..b51aab00 100644
--- a/tests/auto/daemon/json/map-array-conversion.json
+++ b/tests/auto/partition/json/map-array-conversion.json
diff --git a/tests/auto/daemon/json/map-join-sourceuuids.json b/tests/auto/partition/json/map-join-sourceuuids.json
index 24ad24e7..24ad24e7 100644
--- a/tests/auto/daemon/json/map-join-sourceuuids.json
+++ b/tests/auto/partition/json/map-join-sourceuuids.json
diff --git a/tests/auto/daemon/json/map-join.json b/tests/auto/partition/json/map-join.json
index 75d5fb28..75d5fb28 100644
--- a/tests/auto/daemon/json/map-join.json
+++ b/tests/auto/partition/json/map-join.json
diff --git a/tests/auto/daemon/json/map-reduce-schema.json b/tests/auto/partition/json/map-reduce-schema.json
index 726d0cc0..726d0cc0 100644
--- a/tests/auto/daemon/json/map-reduce-schema.json
+++ b/tests/auto/partition/json/map-reduce-schema.json
diff --git a/tests/auto/daemon/json/map-reduce.json b/tests/auto/partition/json/map-reduce.json
index 2736a9cd..2736a9cd 100644
--- a/tests/auto/daemon/json/map-reduce.json
+++ b/tests/auto/partition/json/map-reduce.json
diff --git a/tests/auto/daemon/json/map-sametarget.json b/tests/auto/partition/json/map-sametarget.json
index f94c7843..f94c7843 100644
--- a/tests/auto/daemon/json/map-sametarget.json
+++ b/tests/auto/partition/json/map-sametarget.json
diff --git a/tests/auto/daemon/json/pk-capability.json b/tests/auto/partition/json/pk-capability.json
index eea7caeb..eea7caeb 100644
--- a/tests/auto/daemon/json/pk-capability.json
+++ b/tests/auto/partition/json/pk-capability.json
diff --git a/tests/auto/daemon/json/reduce-array.json b/tests/auto/partition/json/reduce-array.json
index 144513a4..144513a4 100644
--- a/tests/auto/daemon/json/reduce-array.json
+++ b/tests/auto/partition/json/reduce-array.json
diff --git a/tests/auto/daemon/json/reduce-data.json b/tests/auto/partition/json/reduce-data.json
index 810bf973..810bf973 100644
--- a/tests/auto/daemon/json/reduce-data.json
+++ b/tests/auto/partition/json/reduce-data.json
diff --git a/tests/auto/daemon/json/reduce-subprop.json b/tests/auto/partition/json/reduce-subprop.json
index a5002853..a5002853 100644
--- a/tests/auto/daemon/json/reduce-subprop.json
+++ b/tests/auto/partition/json/reduce-subprop.json
diff --git a/tests/auto/daemon/json/reduce.json b/tests/auto/partition/json/reduce.json
index 5939fb71..5939fb71 100644
--- a/tests/auto/daemon/json/reduce.json
+++ b/tests/auto/partition/json/reduce.json
diff --git a/tests/auto/partition/partition.pro b/tests/auto/partition/partition.pro
new file mode 100644
index 00000000..36bd18b7
--- /dev/null
+++ b/tests/auto/partition/partition.pro
@@ -0,0 +1,32 @@
+TARGET = tst_partition
+CONFIG += debug
+
+QT = network qml testlib jsondbpartition
+CONFIG -= app_bundle
+CONFIG += testcase
+
+LIBS += -L$$QT.jsondb.libs
+
+DEFINES += SRCDIR=\\\"$$PWD/\\\"
+
+RESOURCES += json-validation.qrc partition.qrc
+
+unix:!mac:contains(QT_CONFIG,icu) {
+ LIBS += -licuuc -licui18n
+} else {
+ DEFINES += NO_COLLATION_SUPPORT
+}
+
+# HACK, remove when jsondbpartition separates private api from public api
+include(../../../src/3rdparty/btree/btree.pri)
+include(../../../src/hbtree/hbtree.pri)
+
+SOURCES += \
+ testpartition.cpp \
+
+contains(config_test_icu, yes) {
+ LIBS += -licuuc -licui18n
+} else {
+ DEFINES += NO_COLLATION_SUPPORT
+}
+
diff --git a/tests/auto/daemon/daemon.qrc b/tests/auto/partition/partition.qrc
index 5ee38b61..a4332b49 100644
--- a/tests/auto/daemon/daemon.qrc
+++ b/tests/auto/partition/partition.qrc
@@ -1,5 +1,5 @@
<RCC>
- <qresource prefix="/daemon">
+ <qresource prefix="/partition">
<file>json</file>
<file>schemas</file>
</qresource>
diff --git a/tests/auto/daemon/schemas/TestView.json b/tests/auto/partition/schemas/TestView.json
index 9f37750e..9f37750e 100644
--- a/tests/auto/daemon/schemas/TestView.json
+++ b/tests/auto/partition/schemas/TestView.json
diff --git a/tests/auto/daemon/schemas/address.json b/tests/auto/partition/schemas/address.json
index 76f5bdce..76f5bdce 100644
--- a/tests/auto/daemon/schemas/address.json
+++ b/tests/auto/partition/schemas/address.json
diff --git a/tests/auto/daemon/schemas/contact.json b/tests/auto/partition/schemas/contact.json
index 168ef20b..168ef20b 100644
--- a/tests/auto/daemon/schemas/contact.json
+++ b/tests/auto/partition/schemas/contact.json
diff --git a/tests/auto/daemon/schemas/ephemeral.json b/tests/auto/partition/schemas/ephemeral.json
index a065a976..a065a976 100644
--- a/tests/auto/daemon/schemas/ephemeral.json
+++ b/tests/auto/partition/schemas/ephemeral.json
diff --git a/tests/auto/daemon/testjsondb.cpp b/tests/auto/partition/testpartition.cpp
index ce2781ed..f08fb1e1 100644
--- a/tests/auto/daemon/testjsondb.cpp
+++ b/tests/auto/partition/testpartition.cpp
@@ -45,18 +45,17 @@
#include <QFile>
#include <QFileInfo>
#include <QDir>
+#include <QMessageHandler>
#include <QTime>
#include <QUuid>
-#include "json.h"
-
#include "jsondbbtree.h"
#include "jsondbobjecttable.h"
#include "jsondbpartition.h"
#include "jsondbindex.h"
#include "jsondbsettings.h"
-#include "jsondb-strings.h"
-#include "jsondb-error.h"
+#include "jsondbstrings.h"
+#include "jsondberrors.h"
#include <qjsonobject.h>
@@ -68,7 +67,7 @@
#define DBG() if (0) qDebug()
#endif
-QT_USE_NAMESPACE_JSONDB
+QT_USE_NAMESPACE_JSONDB_PARTITION
static QString kContactStr = "com.example.unittest.contact";
@@ -116,12 +115,11 @@ private:
T mValue;
};
-class TestJsonDb: public QObject
+class TestPartition: public QObject
{
Q_OBJECT
public:
- TestJsonDb();
-
+ TestPartition();
private slots:
void initTestCase();
@@ -175,6 +173,7 @@ private slots:
void mapSchemaViolation();
void mapMultipleEmitNoTargetKeyName();
void mapArrayConversion();
+ void mapConsole();
void reduce();
void reduceFlattened();
void reduceSourceKeyFunction();
@@ -234,6 +233,13 @@ private slots:
void settings();
+ void typeChangeIndex();
+ void typeChangeMap();
+ void typeChangeReduce();
+ void typeChangeMapSource();
+ void typeChangeReduceSource();
+ void typeChangeSchema();
+
private:
void createContacts();
JsonDbQueryResult find(JsonDbOwner *owner, const QString &query, const QJsonObject bindings = QJsonObject());
@@ -245,8 +251,6 @@ private:
void addSchema(const QString &schemaName, JsonDbObject &schemaObject);
void addIndex(const QString &propertyName, const QString &propertyType=QString(), const QString &objectType=QString());
- QJsonValue readJsonFile(const QString &filename);
- QJsonValue readJson(const QByteArray& json);
void removeDbFiles();
private:
@@ -261,13 +265,13 @@ const QString kReplica1Name = QString("replica1");
const QString kReplica2Name = QString("replica2");
const QStringList kReplicaNames = (QStringList() << kReplica1Name << kReplica2Name);
-TestJsonDb::TestJsonDb() :
+TestPartition::TestPartition() :
mJsonDbPartition(0)
, mOwner(0)
{
}
-void TestJsonDb::removeDbFiles()
+void TestPartition::removeDbFiles()
{
QStringList filters;
filters << QLatin1String("*.db")
@@ -277,7 +281,7 @@ void TestJsonDb::removeDbFiles()
QFile::remove(fileName);
}
-void TestJsonDb::initTestCase()
+void TestPartition::initTestCase()
{
qsrand(QDateTime::currentDateTime().toTime_t());
QCoreApplication::setOrganizationName("Example");
@@ -294,22 +298,26 @@ void TestJsonDb::initTestCase()
mJsonDbPartition->open();
}
-void TestJsonDb::cleanupTestCase()
+void TestPartition::cleanupTestCase()
{
if (mJsonDbPartition) {
mJsonDbPartition->close();
delete mJsonDbPartition;
mJsonDbPartition = 0;
}
+ if (mOwner) {
+ delete mOwner;
+ mOwner = 0;
+ }
removeDbFiles();
}
-void TestJsonDb::cleanup()
+void TestPartition::cleanup()
{
QCOMPARE(mJsonDbPartition->mTransactionDepth, 0);
}
-void TestJsonDb::reopen()
+void TestPartition::reopen()
{
int counter = 1;
for (int i = 0; i < 10; ++i, ++counter) {
@@ -324,27 +332,19 @@ void TestJsonDb::reopen()
mJsonDbPartition = new JsonDbPartition(kFilename, QStringLiteral("com.example.JsonDbTest"), mOwner, this);
mJsonDbPartition->open();
- JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner,
- JsonDbQuery::parse(QLatin1String("[?_type=\"reopentest\"]")));
+ JsonDbQuery *parsedQuery = JsonDbQuery::parse(QLatin1String("[?_type=\"reopentest\"]"));
+ JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, parsedQuery);
+ delete parsedQuery;
QCOMPARE(queryResult.data.size(), counter);
}
}
-void TestJsonDb::createContacts()
+void TestPartition::createContacts()
{
if (!mContactList.isEmpty())
return;
- QFile contactsFile(":/daemon/json/largeContactsTest.json");
- QVERIFY2(contactsFile.exists(), "Err: largeContactsTest.json doesn't exist!");
-
- contactsFile.open(QIODevice::ReadOnly);
- QByteArray json = contactsFile.readAll();
- JsonReader parser;
- bool ok = parser.parse(json);
- if (!ok)
- qDebug() << parser.errorString();
- QVariantList contactList = parser.result().toList();
+ QVariantList contactList = readJsonFile(":/partition/json/largeContactsTest.json").toArray().toVariantList();
QList<JsonDbObject> newContactList;
foreach (QVariant v, contactList) {
JsonDbObject contact(JsonDbObject::fromVariantMap(v.toMap()));
@@ -367,12 +367,15 @@ void TestJsonDb::createContacts()
}
-JsonDbQueryResult TestJsonDb::find(JsonDbOwner *owner, const QString &query, const QJsonObject bindings)
+JsonDbQueryResult TestPartition::find(JsonDbOwner *owner, const QString &query, const QJsonObject bindings)
{
- return mJsonDbPartition->queryObjects(owner, JsonDbQuery::parse(query, bindings));
+ JsonDbQuery *parsedQuery = JsonDbQuery::parse(query, bindings);
+ JsonDbQueryResult result = mJsonDbPartition->queryObjects(owner, parsedQuery);
+ delete parsedQuery;
+ return result;
}
-JsonDbWriteResult TestJsonDb::create(JsonDbOwner *owner, JsonDbObject &object, JsonDbPartition::WriteMode mode)
+JsonDbWriteResult TestPartition::create(JsonDbOwner *owner, JsonDbObject &object, JsonDbPartition::WriteMode mode)
{
JsonDbWriteResult result = mJsonDbPartition->updateObject(owner, object, mode);
if (result.code == JsonDbError::NoError) {
@@ -382,7 +385,7 @@ JsonDbWriteResult TestJsonDb::create(JsonDbOwner *owner, JsonDbObject &object, J
return result;
}
-JsonDbWriteResult TestJsonDb::update(JsonDbOwner *owner, JsonDbObject &object, JsonDbPartition::WriteMode mode)
+JsonDbWriteResult TestPartition::update(JsonDbOwner *owner, JsonDbObject &object, JsonDbPartition::WriteMode mode)
{
JsonDbWriteResult result = mJsonDbPartition->updateObject(owner, object, mode);
if (result.code == JsonDbError::NoError)
@@ -390,7 +393,7 @@ JsonDbWriteResult TestJsonDb::update(JsonDbOwner *owner, JsonDbObject &object, J
return result;
}
-JsonDbWriteResult TestJsonDb::remove(JsonDbOwner *owner, JsonDbObject &object, JsonDbPartition::WriteMode mode)
+JsonDbWriteResult TestPartition::remove(JsonDbOwner *owner, JsonDbObject &object, JsonDbPartition::WriteMode mode)
{
JsonDbObject toDelete = object;
toDelete.insert(JsonDbString::kDeletedStr, true);
@@ -403,16 +406,16 @@ JsonDbWriteResult TestJsonDb::remove(JsonDbOwner *owner, JsonDbObject &object, J
/*
* const version for all the cleanup code that doesn't care about updated properties
*/
-JsonDbWriteResult TestJsonDb::remove(JsonDbOwner *owner, const JsonDbObject &object, JsonDbPartition::WriteMode mode)
+JsonDbWriteResult TestPartition::remove(JsonDbOwner *owner, const JsonDbObject &object, JsonDbPartition::WriteMode mode)
{
JsonDbObject toDelete = object;
toDelete.insert(JsonDbString::kDeletedStr, true);
return mJsonDbPartition->updateObject(owner, toDelete, mode);
}
-void TestJsonDb::addSchema(const QString &schemaName, JsonDbObject &schemaObject)
+void TestPartition::addSchema(const QString &schemaName, JsonDbObject &schemaObject)
{
- QJsonValue schema = readJsonFile(QString(":/daemon/schemas/%1.json").arg(schemaName));
+ QJsonValue schema = readJsonFile(QString(":/partition/schemas/%1.json").arg(schemaName));
schemaObject = JsonDbObject();
schemaObject.insert(JsonDbString::kTypeStr, JsonDbString::kSchemaTypeStr);
schemaObject.insert("name", schemaName);
@@ -421,7 +424,7 @@ void TestJsonDb::addSchema(const QString &schemaName, JsonDbObject &schemaObject
verifyGoodResult(create(mOwner, schemaObject));
}
-void TestJsonDb::addIndex(const QString &propertyName, const QString &propertyType, const QString &objectType)
+void TestPartition::addIndex(const QString &propertyName, const QString &propertyType, const QString &objectType)
{
JsonDbObject index;
index.insert(JsonDbString::kTypeStr, JsonDbString::kIndexTypeStr);
@@ -433,7 +436,7 @@ void TestJsonDb::addIndex(const QString &propertyName, const QString &propertyTy
verifyGoodResult(create(mOwner, index));
}
-void TestJsonDb::computeVersion()
+void TestPartition::computeVersion()
{
JsonDbObject item0;
QCOMPARE(item0.version(), QString());
@@ -588,7 +591,7 @@ void TestJsonDb::computeVersion()
QCOMPARE(item9.version().mid(1), item1.version().mid(1));
}
-void TestJsonDb::updateVersionOptimistic()
+void TestPartition::updateVersionOptimistic()
{
JsonDbObject master;
master.generateUuid();
@@ -636,7 +639,7 @@ void TestJsonDb::updateVersionOptimistic()
}
-void TestJsonDb::updateVersionReplicating()
+void TestPartition::updateVersionReplicating()
{
JsonDbObject master;
master.generateUuid();
@@ -747,7 +750,7 @@ void TestJsonDb::updateVersionReplicating()
/*
* Create an item
*/
-void TestJsonDb::create()
+void TestPartition::create()
{
JsonDbObject item;
item.insert(JsonDbString::kTypeStr, QString("create-test-type"));
@@ -778,7 +781,7 @@ void TestJsonDb::create()
* Insert an item and then update it.
*/
-void TestJsonDb::update()
+void TestPartition::update()
{
JsonDbObject item;
item.insert(JsonDbString::kTypeStr, QLatin1String("update-test-type"));
@@ -801,7 +804,7 @@ void TestJsonDb::update()
* Update an item which doesn't exist
*/
-void TestJsonDb::update2()
+void TestPartition::update2()
{
JsonDbObject item;
item.insert("update2-test", 100);
@@ -817,7 +820,7 @@ void TestJsonDb::update2()
* Update an item which doesn't have a "uuid" field
*/
-void TestJsonDb::update3()
+void TestPartition::update3()
{
JsonDbObject item;
item.insert("update2-test", 100);
@@ -830,7 +833,7 @@ void TestJsonDb::update3()
* Update a stale copy of an item
*/
-void TestJsonDb::update4()
+void TestPartition::update4()
{
JsonDbObject item;
item.insert(JsonDbString::kTypeStr, QLatin1String("update-test-type"));
@@ -891,7 +894,7 @@ void TestJsonDb::update4()
* Create an item and immediately remove it
*/
-void TestJsonDb::remove()
+void TestPartition::remove()
{
JsonDbObject item;
item.insert(JsonDbString::kTypeStr, QLatin1String("remove-test-type"));
@@ -918,7 +921,7 @@ void TestJsonDb::remove()
* Try to remove an item which doesn't exist
*/
-void TestJsonDb::remove2()
+void TestPartition::remove2()
{
JsonDbObject item;
item.insert("remove2-test", 100);
@@ -933,7 +936,7 @@ void TestJsonDb::remove2()
* Don't include a 'uuid' field
*/
-void TestJsonDb::remove3()
+void TestPartition::remove3()
{
JsonDbObject item;
item.insert("remove3-test", 100);
@@ -945,7 +948,7 @@ void TestJsonDb::remove3()
/*
* Try to remove an item which existed before but was removed
*/
-void TestJsonDb::remove4()
+void TestPartition::remove4()
{
JsonDbObject item;
item.insert(JsonDbString::kTypeStr, QLatin1String("remove-test-type"));
@@ -969,7 +972,7 @@ void TestJsonDb::remove4()
/*
* Remove a stale version of the object
*/
-void TestJsonDb::remove5()
+void TestPartition::remove5()
{
jsondbSettings->setRejectStaleUpdates(true);
@@ -990,7 +993,7 @@ void TestJsonDb::remove5()
jsondbSettings->setRejectStaleUpdates(false);
}
-void TestJsonDb::schemaValidation_data()
+void TestPartition::schemaValidation_data()
{
QTest::addColumn<QByteArray>("schema");
QTest::addColumn<QByteArray>("object");
@@ -1024,7 +1027,7 @@ void TestJsonDb::schemaValidation_data()
}
}
-void TestJsonDb::schemaValidation()
+void TestPartition::schemaValidation()
{
jsondbSettings->setValidateSchemas(true);
@@ -1036,7 +1039,7 @@ void TestJsonDb::schemaValidation()
id++;
QString schemaName = QLatin1String("schemaValidationSchema") + QString::number(id);
- QJsonObject schemaBody = readJson(schema).toObject();
+ QJsonObject schemaBody = QJsonDocument::fromJson(schema).object();
JsonDbObject schemaObject;
schemaObject.insert(JsonDbString::kTypeStr, JsonDbString::kSchemaTypeStr);
schemaObject.insert("name", schemaName);
@@ -1045,7 +1048,7 @@ void TestJsonDb::schemaValidation()
JsonDbWriteResult qResult = create(mOwner, schemaObject);
verifyGoodResult(qResult);
- JsonDbObject item = readJson(object).toObject();
+ JsonDbObject item = QJsonDocument::fromJson(object).object();
item.insert(JsonDbString::kTypeStr, schemaName);
// Create an item that matches the schema
@@ -1066,7 +1069,7 @@ void TestJsonDb::schemaValidation()
jsondbSettings->setValidateSchemas(false);
}
-void TestJsonDb::schemaValidationExtends_data()
+void TestPartition::schemaValidationExtends_data()
{
QTest::addColumn<QByteArray>("item");
QTest::addColumn<bool>("isPerson");
@@ -1086,7 +1089,7 @@ void TestJsonDb::schemaValidationExtends_data()
<< QByteArray("{ \"name\":\"Alice's great-grandmother\", \"age\": 130}") << false << false;
}
-void TestJsonDb::schemaValidationExtends()
+void TestPartition::schemaValidationExtends()
{
jsondbSettings->setValidateSchemas(true);
@@ -1117,8 +1120,8 @@ void TestJsonDb::schemaValidationExtends()
" \"properties\": {\"age\": {\"minimum\": 18}},"
" \"extends\": {\"$ref\":\"person%1\"}"
"}").arg(QString::number(id)).toLatin1();
- QJsonObject personSchemaBody = readJson(person).toObject();
- QJsonObject adultSchemaBody = readJson(adult).toObject();
+ QJsonObject personSchemaBody = QJsonDocument::fromJson(person).object();
+ QJsonObject adultSchemaBody = QJsonDocument::fromJson(adult).object();
JsonDbObject personSchemaObject;
personSchemaObject.insert(JsonDbString::kTypeStr, JsonDbString::kSchemaTypeStr);
@@ -1137,7 +1140,7 @@ void TestJsonDb::schemaValidationExtends()
}
{
- JsonDbObject object = readJson(item).toObject();
+ JsonDbObject object = QJsonDocument::fromJson(item).object();
object.insert("testingForPerson", isPerson);
object.insert(JsonDbString::kTypeStr, personSchemaName);
qResult = create(mOwner, object);
@@ -1149,7 +1152,7 @@ void TestJsonDb::schemaValidationExtends()
}
{
- JsonDbObject object = readJson(item).toObject();
+ JsonDbObject object = QJsonDocument::fromJson(item).object();
object.insert("testingForAdult", isAdult);
object.insert(JsonDbString::kTypeStr, adultSchemaName);
qResult = create(mOwner, object);
@@ -1164,7 +1167,7 @@ void TestJsonDb::schemaValidationExtends()
}
-void TestJsonDb::schemaValidationExtendsArray_data()
+void TestPartition::schemaValidationExtendsArray_data()
{
QTest::addColumn<QByteArray>("item");
QTest::addColumn<bool>("isValid");
@@ -1181,7 +1184,7 @@ void TestJsonDb::schemaValidationExtendsArray_data()
<< QByteArray("{ \"waterSpeed\":100, \"landSpeed\": 100, \"airSpeed\": 100}") << true;
}
-void TestJsonDb::schemaValidationExtendsArray()
+void TestPartition::schemaValidationExtendsArray()
{
jsondbSettings->setValidateSchemas(true);
@@ -1215,9 +1218,9 @@ void TestJsonDb::schemaValidationExtendsArray()
" \"extends\": [{\"$ref\":\"car%1\"}, {\"$ref\":\"boat%1\"}]"
"}").arg(QString::number(id)).toLatin1();
- QJsonObject amphibiousSchemaBody = readJson(amphibious).toObject();
- QJsonObject carSchemaBody = readJson(car).toObject();
- QJsonObject boatSchemaBody = readJson(boat).toObject();
+ QJsonObject amphibiousSchemaBody = QJsonDocument::fromJson(amphibious).object();
+ QJsonObject carSchemaBody = QJsonDocument::fromJson(car).object();
+ QJsonObject boatSchemaBody = QJsonDocument::fromJson(boat).object();
JsonDbObject carSchemaObject;
@@ -1244,7 +1247,7 @@ void TestJsonDb::schemaValidationExtendsArray()
}
{
- JsonDbObject object = readJson(item).toObject();
+ JsonDbObject object = QJsonDocument::fromJson(item).object();
object.insert("testingForAmphibious", isValid);
object.insert(JsonDbString::kTypeStr, amphibiousSchemaName);
qResult = create(mOwner, object);
@@ -1258,7 +1261,7 @@ void TestJsonDb::schemaValidationExtendsArray()
jsondbSettings->setValidateSchemas(false);
}
-void TestJsonDb::schemaValidationLazyInit()
+void TestPartition::schemaValidationLazyInit()
{
jsondbSettings->setValidateSchemas(true);
@@ -1281,8 +1284,8 @@ void TestJsonDb::schemaValidationLazyInit()
const QString personSchemaName = QString::fromLatin1("personLazyInit");
const QString adultSchemaName = QString::fromLatin1("adultLazyInit");
- QJsonObject personSchemaBody = readJson(person).toObject();
- QJsonObject adultSchemaBody = readJson(adult).toObject();
+ QJsonObject personSchemaBody = QJsonDocument::fromJson(person).object();
+ QJsonObject adultSchemaBody = QJsonDocument::fromJson(adult).object();
JsonDbObject personSchemaObject;
personSchemaObject.insert(JsonDbString::kTypeStr, JsonDbString::kSchemaTypeStr);
@@ -1305,35 +1308,35 @@ void TestJsonDb::schemaValidationLazyInit()
// Insert some objects to force full schema compilation
{
const QByteArray item = "{ \"name\":\"Nierob\", \"age\":99 }";
- JsonDbObject object = readJson(item).toObject();
+ JsonDbObject object = QJsonDocument::fromJson(item).object();
object.insert(JsonDbString::kTypeStr, adultSchemaName);
qResult = create(mOwner, object);
verifyGoodResult(qResult);
}
{
const QByteArray item = "{ \"name\":\"Nierob\", \"age\":12 }";
- JsonDbObject object = readJson(item).toObject();
+ JsonDbObject object = QJsonDocument::fromJson(item).object();
object.insert(JsonDbString::kTypeStr, adultSchemaName);
qResult = create(mOwner, object);
verifyErrorResult(qResult);
}
{
const QByteArray item = "{ \"age\":19 }";
- JsonDbObject object = readJson(item).toObject();
+ JsonDbObject object = QJsonDocument::fromJson(item).object();
object.insert(JsonDbString::kTypeStr, adultSchemaName);
qResult = create(mOwner, object);
verifyErrorResult(qResult);
}
{
const QByteArray item = "{ \"name\":\"Nierob\", \"age\":12 }";
- JsonDbObject object = readJson(item).toObject();
+ JsonDbObject object = QJsonDocument::fromJson(item).object();
object.insert(JsonDbString::kTypeStr, personSchemaName);
qResult = create(mOwner, object);
verifyGoodResult(qResult);
}
{
const QByteArray item = "{ \"age\":12 }";
- JsonDbObject object = readJson(item).toObject();
+ JsonDbObject object = QJsonDocument::fromJson(item).object();
object.insert(JsonDbString::kTypeStr, personSchemaName);
qResult = create(mOwner, object);
verifyErrorResult(qResult);
@@ -1349,7 +1352,7 @@ void TestJsonDb::schemaValidationLazyInit()
#define LIST_TEST_ITEMS 6
-void TestJsonDb::createList()
+void TestPartition::createList()
{
JsonDbObjectList list;
for (int i = 0 ; i < LIST_TEST_ITEMS ; i++ ) {
@@ -1367,7 +1370,7 @@ void TestJsonDb::createList()
* Create a list of items and then update them
*/
-void TestJsonDb::updateList()
+void TestPartition::updateList()
{
JsonDbObjectList list;
for (int i = 0 ; i < LIST_TEST_ITEMS ; i++ ) {
@@ -1387,7 +1390,7 @@ void TestJsonDb::updateList()
QCOMPARE(result.objectsWritten.count(), LIST_TEST_ITEMS);
}
-void TestJsonDb::mapDefinition()
+void TestPartition::mapDefinition()
{
// we need a schema that extends View for our targetType
JsonDbObject schema;
@@ -1413,7 +1416,7 @@ void TestJsonDb::mapDefinition()
verifyGoodResult(remove(mOwner, schema));
}
-void TestJsonDb::mapDefinitionInvalid()
+void TestPartition::mapDefinitionInvalid()
{
// we need a schema that extends View for our targetType
JsonDbObject schema;
@@ -1461,7 +1464,7 @@ void TestJsonDb::mapDefinitionInvalid()
verifyGoodResult(res);
}
-void TestJsonDb::reduceDefinition()
+void TestPartition::reduceDefinition()
{
// we need a schema that extends View for our targetType
JsonDbObject schema;
@@ -1488,7 +1491,7 @@ void TestJsonDb::reduceDefinition()
verifyGoodResult(remove(mOwner, schema));
}
-void TestJsonDb::reduceDefinitionInvalid()
+void TestPartition::reduceDefinitionInvalid()
{
// we need a schema that extends View for our targetType
JsonDbObject schema;
@@ -1573,7 +1576,7 @@ void TestJsonDb::reduceDefinitionInvalid()
verifyGoodResult(remove(mOwner, schema));
}
-void TestJsonDb::mapInvalidMapFunc()
+void TestPartition::mapInvalidMapFunc()
{
JsonDbObject schema;
schema.insert(JsonDbString::kTypeStr, QLatin1String("_schemaType"));
@@ -1599,7 +1602,7 @@ void TestJsonDb::mapInvalidMapFunc()
verifyGoodResult(remove(mOwner, schema));
}
-void TestJsonDb::reduceInvalidAddSubtractFuncs()
+void TestPartition::reduceInvalidAddSubtractFuncs()
{
JsonDbObject schema;
schema.insert(JsonDbString::kTypeStr, QLatin1String("_schemaType"));
@@ -1624,11 +1627,10 @@ void TestJsonDb::reduceInvalidAddSubtractFuncs()
verifyGoodResult(remove(mOwner, schema));
}
-void TestJsonDb::map()
+void TestPartition::map()
{
addIndex(QLatin1String("phoneNumber"));
-
- QJsonArray objects(readJsonFile(":/daemon/json/map-reduce.json").toArray());
+ QJsonArray objects(readJsonFile(":/partition/json/map-reduce.json").toArray());
JsonDbObjectList mapsReduces;
JsonDbObjectList schemas;
@@ -1662,12 +1664,12 @@ void TestJsonDb::map()
// get results with getObjects()
GetObjectsResult getObjectsResult = mJsonDbPartition->getObjects(JsonDbString::kTypeStr, QLatin1String("Phone"));
- QCOMPARE(getObjectsResult.data.size(), 3);
if (jsondbSettings->verbose()) {
JsonDbObjectList vs = getObjectsResult.data;
for (int i = 0; i < vs.size(); i++)
qDebug() << " " << vs[i];
}
+ QCOMPARE(getObjectsResult.data.size(), 3);
// query for results
queryResult = find(mOwner, QLatin1String("[?_type=\"Phone\"]"));
@@ -1728,9 +1730,9 @@ void TestJsonDb::map()
}
-void TestJsonDb::mapDuplicateSourceAndTarget()
+void TestPartition::mapDuplicateSourceAndTarget()
{
- QJsonArray objects(readJsonFile(":/daemon/json/map-sametarget.json").toArray());
+ QJsonArray objects(readJsonFile(":/partition/json/map-sametarget.json").toArray());
JsonDbObjectList toDelete;
JsonDbObjectList maps;
@@ -1762,9 +1764,9 @@ void TestJsonDb::mapDuplicateSourceAndTarget()
mJsonDbPartition->removeIndex("ContactView");
}
-void TestJsonDb::mapRemoval()
+void TestPartition::mapRemoval()
{
- QJsonArray objects(readJsonFile(":/daemon/json/map-sametarget.json").toArray());
+ QJsonArray objects(readJsonFile(":/partition/json/map-sametarget.json").toArray());
QList<JsonDbObject> maps;
QList<JsonDbObject> toDelete;
@@ -1804,9 +1806,9 @@ void TestJsonDb::mapRemoval()
verifyGoodResult(remove(mOwner, toDelete.at(ii)));
}
-void TestJsonDb::mapUpdate()
+void TestPartition::mapUpdate()
{
- QJsonArray objects(readJsonFile(":/daemon/json/map-sametarget.json").toArray());
+ QJsonArray objects(readJsonFile(":/partition/json/map-sametarget.json").toArray());
JsonDbObjectList maps;
JsonDbObjectList toDelete;
@@ -1868,9 +1870,9 @@ void TestJsonDb::mapUpdate()
}
-void TestJsonDb::mapJoin()
+void TestPartition::mapJoin()
{
- QJsonArray objects(readJsonFile(":/daemon/json/map-join.json").toArray());
+ QJsonArray objects(readJsonFile(":/partition/json/map-join.json").toArray());
JsonDbObject join;
JsonDbObject schema;
@@ -1971,11 +1973,11 @@ void TestJsonDb::mapJoin()
mJsonDbPartition->removeIndex("value.foaf", "FoafPerson");
}
-void TestJsonDb::mapSelfJoinSourceUuids()
+void TestPartition::mapSelfJoinSourceUuids()
{
addIndex("magic", "string");
- QJsonArray objects(readJsonFile(":/daemon/json/map-join-sourceuuids.json").toArray());
+ QJsonArray objects(readJsonFile(":/partition/json/map-join-sourceuuids.json").toArray());
JsonDbObjectList toDelete;
JsonDbObject toUpdate;
@@ -2012,7 +2014,7 @@ void TestJsonDb::mapSelfJoinSourceUuids()
mJsonDbPartition->removeIndex("magic", "string");
}
-void TestJsonDb::mapMapFunctionError()
+void TestPartition::mapMapFunctionError()
{
JsonDbObject schema;
schema.insert(JsonDbString::kTypeStr, QString("_schemaType"));
@@ -2051,7 +2053,7 @@ void TestJsonDb::mapMapFunctionError()
verifyGoodResult(remove(mOwner, schema));
}
-void TestJsonDb::mapSchemaViolation()
+void TestPartition::mapSchemaViolation()
{
jsondbSettings->setValidateSchemas(true);
@@ -2061,7 +2063,7 @@ void TestJsonDb::mapSchemaViolation()
remove(mOwner, toRemove);
}
- QJsonArray objects(readJsonFile(":/daemon/json/map-reduce-schema.json").toArray());
+ QJsonArray objects(readJsonFile(":/partition/json/map-reduce-schema.json").toArray());
JsonDbObjectList toDelete;
QJsonValue workingMap;
JsonDbObject map;
@@ -2130,7 +2132,7 @@ void TestJsonDb::mapSchemaViolation()
}
// verify that only one target object per source object is allowed without targetKeyName
-void TestJsonDb::mapMultipleEmitNoTargetKeyName()
+void TestPartition::mapMultipleEmitNoTargetKeyName()
{
jsondbSettings->setValidateSchemas(true);
@@ -2140,7 +2142,7 @@ void TestJsonDb::mapMultipleEmitNoTargetKeyName()
remove(mOwner, toRemove);
}
- QJsonArray objects(readJsonFile(":/daemon/json/map-reduce-schema.json").toArray());
+ QJsonArray objects(readJsonFile(":/partition/json/map-reduce-schema.json").toArray());
JsonDbObjectList toDelete;
JsonDbObject map;
@@ -2178,15 +2180,19 @@ void TestJsonDb::mapMultipleEmitNoTargetKeyName()
jsondbSettings->setValidateSchemas(false);
}
-void TestJsonDb::mapArrayConversion()
+void TestPartition::mapArrayConversion()
{
- QJsonArray objects(readJsonFile(":/daemon/json/map-array-conversion.json").toArray());
+ QJsonArray objects(readJsonFile(":/partition/json/map-array-conversion.json").toArray());
JsonDbObjectList toDelete;
+ JsonDbObject mapDefinition;
for (int i = 0; i < objects.size(); i++) {
JsonDbObject object(objects.at(i).toObject());
JsonDbWriteResult result = create(mOwner, object);
verifyGoodResult(result);
- toDelete.append(object);
+ if (object.value(JsonDbString::kTypeStr) == JsonDbString::kMapTypeStr)
+ mapDefinition = object;
+ else
+ toDelete.append(object);
}
JsonDbObject testObject;
@@ -2199,11 +2205,99 @@ void TestJsonDb::mapArrayConversion()
QCOMPARE(queryResult.data.size(), 1);
JsonDbObject o = queryResult.data.at(0);
QVERIFY(o.value("result").isArray());
+
+ verifyGoodResult(remove(mOwner, mapDefinition));
+ for (int ii = 0; ii < toDelete.size(); ii++)
+ verifyGoodResult(remove(mOwner, toDelete.at(ii)));
}
-void TestJsonDb::reduce()
+static QHash<QString, QList<QString> > sDebugMessages;
+void logMessageOutput(QtMsgType type, const QMessageLogContext &context, const char *msg)
{
- QJsonArray objects(readJsonFile(":/daemon/json/reduce-data.json").toArray());
+ Q_UNUSED(context);
+ switch (type) {
+ case QtDebugMsg:
+ sDebugMessages[QLatin1Literal("Debug")].append(msg);
+ break;
+ case QtWarningMsg:
+ sDebugMessages[QLatin1Literal("Warning")].append(msg);
+ break;
+ case QtCriticalMsg:
+ sDebugMessages[QLatin1Literal("Critical")].append(msg);
+ break;
+ case QtFatalMsg:
+ sDebugMessages[QLatin1Literal("Fatal")].append(msg);
+ break;
+ }
+}
+
+void TestPartition::mapConsole()
+{
+ bool wasVerbose = jsondbSettings->verbose();
+ bool wasDebug = jsondbSettings->debug();
+ sDebugMessages.clear();
+ QMessageHandler oldMessageHandler = qInstallMessageHandler(logMessageOutput);
+ jsondbSettings->setVerbose(true);
+ jsondbSettings->setDebug(true);
+
+ QJsonArray objects(readJsonFile(":/partition/json/map-array-conversion.json").toArray());
+ JsonDbObjectList toDelete;
+ JsonDbObject mapDefinition;
+ QLatin1Literal sourceType("com.test.Test");
+ for (int i = 0; i < objects.size(); i++) {
+ JsonDbObject object(objects.at(i).toObject());
+ if (object.value(JsonDbString::kTypeStr) == JsonDbString::kMapTypeStr) {
+ QJsonObject map = object.value(QLatin1Literal("map")).toObject();
+ // replace with a map that just calls console functions
+ map.insert(sourceType, QLatin1String("function(test) { console.warn('testing'); for (var i in test) { if (i.indexOf('_') < 0) console[i](test[i]); } }"));
+ object.insert(QLatin1Literal("map"), map);
+ }
+ JsonDbWriteResult result = create(mOwner, object);
+ verifyGoodResult(result);
+ if (object.value(JsonDbString::kTypeStr) == JsonDbString::kMapTypeStr)
+ mapDefinition = object;
+ else
+ toDelete.append(object);
+ }
+
+ QMap<QString,QString> levelMapping;
+ levelMapping["log"] = "Debug";
+ levelMapping["debug"] = "Debug";
+ levelMapping["info"] = "Debug";
+ levelMapping["warn"] = "Warning";
+ levelMapping["error"] = "Critical";
+
+ QStringList consoleMethods = levelMapping.keys();
+ JsonDbObject testObject;
+ testObject.insert(JsonDbString::kTypeStr, QLatin1String("com.test.Test"));
+ foreach (const QString &method, consoleMethods)
+ testObject.insert(method, QString("%1 message").arg(method));
+ JsonDbWriteResult result = create(mOwner, testObject);
+ verifyGoodResult(result);
+
+ JsonDbQueryResult queryResult = find(mOwner, QLatin1String("[?_type=\"com.test.TestView\"]"));
+ verifyGoodQueryResult(queryResult);
+ QCOMPARE(queryResult.data.size(), 0);
+
+ // revert to original settings
+ jsondbSettings->setVerbose(wasVerbose);
+ jsondbSettings->setDebug(wasDebug);
+ qInstallMessageHandler(oldMessageHandler);
+
+ // verify each method was invoked
+ foreach (const QString &method, consoleMethods) {
+ QVERIFY(sDebugMessages.contains(levelMapping[method]));
+ QVERIFY(sDebugMessages[levelMapping[method]].contains(QString("\"%1 message\" ").arg(method)));
+ }
+
+ verifyGoodResult(remove(mOwner, mapDefinition));
+ for (int ii = 0; ii < toDelete.size(); ii++)
+ verifyGoodResult(remove(mOwner, toDelete.at(ii)));
+}
+
+void TestPartition::reduce()
+{
+ QJsonArray objects(readJsonFile(":/partition/json/reduce-data.json").toArray());
JsonDbObjectList toDelete;
JsonDbObjectList reduces;
@@ -2217,7 +2311,7 @@ void TestJsonDb::reduce()
toDelete.append(object);
}
- objects = readJsonFile(":/daemon/json/reduce.json").toArray();
+ objects = readJsonFile(":/partition/json/reduce.json").toArray();
for (int ii = 0; ii < objects.size(); ii++) {
JsonDbObject object(objects.at(ii).toObject());
JsonDbWriteResult result = create(mOwner, object);
@@ -2244,9 +2338,9 @@ void TestJsonDb::reduce()
mJsonDbPartition->removeIndex("MyContactCount");
}
-void TestJsonDb::reduceFlattened()
+void TestPartition::reduceFlattened()
{
- QJsonArray objects(readJsonFile(":/daemon/json/reduce-data.json").toArray());
+ QJsonArray objects(readJsonFile(":/partition/json/reduce-data.json").toArray());
JsonDbObjectList toDelete;
JsonDbObjectList reduces;
@@ -2260,7 +2354,7 @@ void TestJsonDb::reduceFlattened()
toDelete.append(object);
}
- objects = readJsonFile(":/daemon/json/reduce.json").toArray();
+ objects = readJsonFile(":/partition/json/reduce.json").toArray();
for (int ii = 0; ii < objects.size(); ii++) {
JsonDbObject object(objects.at(ii).toObject());
if (object.value(JsonDbString::kTypeStr).toString() == JsonDbString::kReduceTypeStr) {
@@ -2293,9 +2387,9 @@ void TestJsonDb::reduceFlattened()
mJsonDbPartition->removeIndex("MyContactCount");
}
-void TestJsonDb::reduceSourceKeyFunction()
+void TestPartition::reduceSourceKeyFunction()
{
- QJsonArray objects(readJsonFile(":/daemon/json/reduce-data.json").toArray());
+ QJsonArray objects(readJsonFile(":/partition/json/reduce-data.json").toArray());
JsonDbObjectList toDelete;
JsonDbObjectList reduces;
@@ -2309,7 +2403,7 @@ void TestJsonDb::reduceSourceKeyFunction()
toDelete.append(object);
}
- objects = readJsonFile(":/daemon/json/reduce.json").toArray();
+ objects = readJsonFile(":/partition/json/reduce.json").toArray();
for (int ii = 0; ii < objects.size(); ii++) {
JsonDbObject object(objects.at(ii).toObject());
if (object.value(JsonDbString::kTypeStr).toString() == JsonDbString::kReduceTypeStr) {
@@ -2342,9 +2436,9 @@ void TestJsonDb::reduceSourceKeyFunction()
mJsonDbPartition->removeIndex("MyContactCount");
}
-void TestJsonDb::reduceRemoval()
+void TestPartition::reduceRemoval()
{
- QJsonArray objects(readJsonFile(":/daemon/json/reduce-data.json").toArray());
+ QJsonArray objects(readJsonFile(":/partition/json/reduce-data.json").toArray());
QJsonArray toDelete;
QHash<QString, int> firstNameCount;
@@ -2356,7 +2450,7 @@ void TestJsonDb::reduceRemoval()
toDelete.append(object);
}
- objects = readJsonFile(":/daemon/json/reduce.json").toArray();
+ objects = readJsonFile(":/partition/json/reduce.json").toArray();
JsonDbObject reduce;
for (int ii = 0; ii < objects.size(); ii++) {
JsonDbObject object(objects.at(ii).toObject());
@@ -2384,9 +2478,9 @@ void TestJsonDb::reduceRemoval()
mJsonDbPartition->removeIndex("MyContactCount");
}
-void TestJsonDb::reduceUpdate()
+void TestPartition::reduceUpdate()
{
- QJsonArray objects(readJsonFile(":/daemon/json/reduce-data.json").toArray());
+ QJsonArray objects(readJsonFile(":/partition/json/reduce-data.json").toArray());
QJsonArray toDelete;
QHash<QString, int> firstNameCount;
@@ -2400,7 +2494,7 @@ void TestJsonDb::reduceUpdate()
toDelete.append(object);
}
- objects = readJsonFile(":/daemon/json/reduce.json").toArray();
+ objects = readJsonFile(":/partition/json/reduce.json").toArray();
JsonDbObject reduce;
JsonDbObject schema;
for (int ii = 0; ii < objects.size(); ii++) {
@@ -2447,9 +2541,9 @@ void TestJsonDb::reduceUpdate()
mJsonDbPartition->removeIndex("MyContactCount");
}
-void TestJsonDb::reduceDuplicate()
+void TestPartition::reduceDuplicate()
{
- QJsonArray objects(readJsonFile(":/daemon/json/reduce-data.json").toArray());
+ QJsonArray objects(readJsonFile(":/partition/json/reduce-data.json").toArray());
JsonDbObjectList toDelete;
QHash<QString, int> firstNameCount;
@@ -2463,7 +2557,7 @@ void TestJsonDb::reduceDuplicate()
toDelete.append(object);
}
- objects = readJsonFile(":/daemon/json/reduce.json").toArray();
+ objects = readJsonFile(":/partition/json/reduce.json").toArray();
JsonDbObject reduce;
for (int ii = 0; ii < objects.size(); ii++) {
JsonDbObject object(objects.at(ii).toObject());
@@ -2518,7 +2612,7 @@ void TestJsonDb::reduceDuplicate()
mJsonDbPartition->removeIndex("MyContactCount");
}
-void TestJsonDb::reduceFunctionError()
+void TestPartition::reduceFunctionError()
{
JsonDbObject schema;
QString viewTypeStr("ReduceFunctionErrorView");
@@ -2557,11 +2651,11 @@ void TestJsonDb::reduceFunctionError()
verifyGoodResult(remove(mOwner, schema));
}
-void TestJsonDb::reduceSchemaViolation()
+void TestPartition::reduceSchemaViolation()
{
jsondbSettings->setValidateSchemas(true);
- QJsonArray objects(readJsonFile(":/daemon/json/map-reduce-schema.json").toArray());
+ QJsonArray objects(readJsonFile(":/partition/json/map-reduce-schema.json").toArray());
QJsonArray toDelete;
JsonDbObject map;
@@ -2632,9 +2726,9 @@ void TestJsonDb::reduceSchemaViolation()
jsondbSettings->setValidateSchemas(false);
}
-void TestJsonDb::reduceSubObjectProp()
+void TestPartition::reduceSubObjectProp()
{
- QJsonArray objects(readJsonFile(":/daemon/json/reduce-subprop.json").toArray());
+ QJsonArray objects(readJsonFile(":/partition/json/reduce-subprop.json").toArray());
QJsonArray toDelete;
JsonDbObject reduce;
@@ -2672,9 +2766,9 @@ void TestJsonDb::reduceSubObjectProp()
mJsonDbPartition->removeIndex("NameCount");
}
-void TestJsonDb::reduceArray()
+void TestPartition::reduceArray()
{
- QJsonArray objects(readJsonFile(":/daemon/json/reduce-array.json").toArray());
+ QJsonArray objects(readJsonFile(":/partition/json/reduce-array.json").toArray());
QJsonArray toDelete;
JsonDbObject human;
@@ -2720,7 +2814,7 @@ void TestJsonDb::reduceArray()
mJsonDbPartition->removeIndex("ArrayView");
}
-void TestJsonDb::changesSinceCreate()
+void TestPartition::changesSinceCreate()
{
QJsonObject csRes = mJsonDbPartition->changesSince(0);
QVERIFY(csRes.value(JsonDbString::kErrorStr).isNull());
@@ -2748,7 +2842,7 @@ void TestJsonDb::changesSinceCreate()
QCOMPARE(after.value("lastName").toString(), toCreate.value("lastName").toString());
}
-void TestJsonDb::addIndex()
+void TestPartition::addIndex()
{
addIndex(QLatin1String("subject"));
@@ -2763,16 +2857,16 @@ void TestJsonDb::addIndex()
remove(mOwner, indexObject);
}
-void TestJsonDb::addSchema()
+void TestPartition::addSchema()
{
JsonDbObject s;
addSchema("contact", s);
verifyGoodResult(remove(mOwner, s));
}
-void TestJsonDb::duplicateSchema()
+void TestPartition::duplicateSchema()
{
- QJsonValue schema = readJsonFile(":/daemon/schemas/address.json");
+ QJsonValue schema = readJsonFile(":/partition/schemas/address.json");
JsonDbObject schemaObject;
schemaObject.insert(JsonDbString::kTypeStr, JsonDbString::kSchemaTypeStr);
schemaObject.insert("name", QLatin1String("Address"));
@@ -2792,9 +2886,9 @@ void TestJsonDb::duplicateSchema()
verifyGoodResult(result);
}
-void TestJsonDb::removeSchema()
+void TestPartition::removeSchema()
{
- QJsonValue schema = readJsonFile(":/daemon/schemas/address.json");
+ QJsonValue schema = readJsonFile(":/partition/schemas/address.json");
JsonDbObject schemaObject;
schemaObject.insert(JsonDbString::kTypeStr, JsonDbString::kSchemaTypeStr);
schemaObject.insert("name", QLatin1String("Address"));
@@ -2821,9 +2915,9 @@ void TestJsonDb::removeSchema()
verifyGoodResult(result);
}
-void TestJsonDb::removeViewSchema()
+void TestPartition::removeViewSchema()
{
- QJsonArray objects = readJsonFile(":/daemon/json/reduce.json").toArray();
+ QJsonArray objects = readJsonFile(":/partition/json/reduce.json").toArray();
JsonDbObject schema;
JsonDbObject reduce;
for (int i = 0; i < objects.size(); ++i) {
@@ -2848,9 +2942,9 @@ void TestJsonDb::removeViewSchema()
verifyGoodResult(result);
}
-void TestJsonDb::updateSchema()
+void TestPartition::updateSchema()
{
- QJsonObject schema = readJsonFile(":/daemon/schemas/address.json").toObject();
+ QJsonObject schema = readJsonFile(":/partition/schemas/address.json").toObject();
QVERIFY(!schema.isEmpty());
JsonDbObject schemaObject;
schemaObject.insert(JsonDbString::kTypeStr, JsonDbString::kSchemaTypeStr);
@@ -2883,7 +2977,7 @@ void TestJsonDb::updateSchema()
verifyGoodResult(result);
}
-void TestJsonDb::unindexedFind()
+void TestPartition::unindexedFind()
{
JsonDbObject item;
item.insert("_type", QLatin1String("unindexedFind"));
@@ -2911,7 +3005,7 @@ void TestJsonDb::unindexedFind()
remove(mOwner, item);
}
-void TestJsonDb::find1()
+void TestPartition::find1()
{
JsonDbObject item;
item.insert(JsonDbString::kTypeStr, QString("Find1Type"));
@@ -2924,7 +3018,7 @@ void TestJsonDb::find1()
QVERIFY(queryResult.data.size() >= 1);
}
-void TestJsonDb::find2()
+void TestPartition::find2()
{
addIndex(QLatin1String("name"));
addIndex(QLatin1String("_type"));
@@ -3007,7 +3101,7 @@ QStringList strings = (QStringList()
QStringList patterns = (QStringList()
);
-void TestJsonDb::findLikeRegexp_data()
+void TestPartition::findLikeRegexp_data()
{
QTest::addColumn<QString>("pattern");
QTest::addColumn<QString>("modifiers");
@@ -3040,7 +3134,7 @@ void TestJsonDb::findLikeRegexp_data()
}
}
-void TestJsonDb::findLikeRegexp()
+void TestPartition::findLikeRegexp()
{
QFETCH(QString, pattern);
QFETCH(QString, modifiers);
@@ -3074,7 +3168,7 @@ void TestJsonDb::findLikeRegexp()
QCOMPARE(length, expectedMatches.size());
}
-void TestJsonDb::findInContains()
+void TestPartition::findInContains()
{
QList<QStringList> stringLists;
stringLists << (QStringList() << "fred" << "barney");
@@ -3112,7 +3206,7 @@ void TestJsonDb::findInContains()
mJsonDbPartition->removeIndex("i");
}
-void TestJsonDb::findFields()
+void TestPartition::findFields()
{
addIndex(QLatin1String("name"));
addIndex(QLatin1String("_type"));
@@ -3131,22 +3225,16 @@ void TestJsonDb::findFields()
QJsonObject query, result, map;
- JsonDbQueryResult queryResult = find(mOwner, QLatin1String("[?firstName=\"Wilma\"][=firstName]"));
- verifyGoodQueryResult(queryResult);
- QCOMPARE(queryResult.values.at(0).toString(), QString("Wilma"));
-
- queryResult = find(mOwner, QLatin1String("[?firstName=\"Wilma\"][= [firstName,lastName]]"));
+ JsonDbQueryResult queryResult = find(mOwner, QLatin1String("[?firstName=\"Wilma\"][= {firstName:firstName,lastName:lastName}]"));
verifyGoodQueryResult(queryResult);
- QCOMPARE(queryResult.values.size(), 1);
- QJsonArray data = queryResult.values.at(0).toArray();
- QCOMPARE(data.at(0).toString(), QString("Wilma"));
- QCOMPARE(data.at(1).toString(), QString("Flintstone"));
+ QCOMPARE(queryResult.data.size(), 1);
+ QJsonObject data = queryResult.data.at(0);
+ QCOMPARE(data.value(QLatin1String("firstName")).toString(), QString("Wilma"));
+ QCOMPARE(data.value(QLatin1String("lastName")).toString(), QString("Flintstone"));
mJsonDbPartition->removeIndex(QLatin1String("firstName"));
- //mJsonDbPartition->removeIndex(QLatin1String("name"));
- //mJsonDbPartition->removeIndex(QLatin1String("_type")); //crash here
}
-void TestJsonDb::orderedFind1_data()
+void TestPartition::orderedFind1_data()
{
QTest::addColumn<QString>("order");
QTest::newRow("asc") << "/";
@@ -3171,7 +3259,7 @@ void TestJsonDb::orderedFind1_data()
create(mOwner, item3);
}
-void TestJsonDb::orderedFind1()
+void TestPartition::orderedFind1()
{
QFETCH(QString, order);
@@ -3200,7 +3288,7 @@ void TestJsonDb::orderedFind1()
mJsonDbPartition->removeIndex(QLatin1String("_type"));
}
-void TestJsonDb::orderedFind2_data()
+void TestPartition::orderedFind2_data()
{
QTest::addColumn<QString>("order");
QTest::addColumn<QString>("field");
@@ -3217,7 +3305,7 @@ void TestJsonDb::orderedFind2_data()
}
}
-void TestJsonDb::orderedFind2()
+void TestPartition::orderedFind2()
{
QFETCH(QString, order);
QFETCH(QString, field);
@@ -3250,7 +3338,7 @@ void TestJsonDb::orderedFind2()
}
}
-void TestJsonDb::wildcardIndex()
+void TestPartition::wildcardIndex()
{
addIndex("telephoneNumbers.*.number");
JsonDbObject item;
@@ -3270,12 +3358,12 @@ void TestJsonDb::wildcardIndex()
JsonDbQueryResult queryResult = find(mOwner, QString("[?telephoneNumbers.*.number=\"%1\"]").arg(mobileNumberString));
verifyGoodQueryResult(queryResult);
- queryResult = find(mOwner, QString("[?%1=\"%2\"][= .telephoneNumbers[*].number]").arg(JsonDbString::kTypeStr).arg(kContactStr));
+ queryResult = find(mOwner, QString("[?%1=\"%2\"][? telephoneNumbers[*].number exists ]").arg(JsonDbString::kTypeStr).arg(kContactStr));
verifyGoodQueryResult(queryResult);
mJsonDbPartition->removeIndex("telephoneNumbers.*.number");
}
-void TestJsonDb::uuidJoin()
+void TestPartition::uuidJoin()
{
addIndex("name");
addIndex("thumbnailUuid");
@@ -3324,22 +3412,9 @@ void TestJsonDb::uuidJoin()
QVERIFY(queryResult.data.size() > 0);
QCOMPARE(queryResult.data.at(0).value("thumbnailUuid").toString(), thumbnailUuid);
- queryResult = find(mOwner, QLatin1String("[?name=\"Betty\"][= [ name, thumbnailUuid->url ]]"));
- verifyGoodQueryResult(queryResult);
- QCOMPARE(queryResult.values.at(0).toArray().at(1).toString(), thumbnailUrl);
-
- queryResult = find(mOwner, QString("[?_type=\"%1\"][= [ name, thumbnailUuid->url ]]").arg(__FUNCTION__));
+ queryResult = find(mOwner, QLatin1String("[?name=\"Betty\"][= { name:name, url:thumbnailUuid->url }]"));
verifyGoodQueryResult(queryResult);
- QJsonArray values = queryResult.values;
- for (int ii = 0; ii < values.size(); ii++) {
- QJsonArray item = values.at(ii).toArray();
- QString name = item.at(0).toString();
- QString url = item.at(1).toString();
- if (name == "Pebbles")
- QVERIFY(url.isEmpty());
- else
- QCOMPARE(url, thumbnailUrl);
- }
+ QCOMPARE(queryResult.data.at(0).value(QLatin1String("url")).toString(), thumbnailUrl);
queryResult = find(mOwner, QString("[?_type=\"%1\"][= { name: name, url: thumbnailUuid->url } ]").arg(__FUNCTION__));
verifyGoodQueryResult(queryResult);
@@ -3355,22 +3430,22 @@ void TestJsonDb::uuidJoin()
QCOMPARE(url, thumbnailUrl);
}
-
- queryResult = find(mOwner, QLatin1String("[?bettyUuid exists][= bettyUuid->thumbnailUuid]"));
+ queryResult = find(mOwner, QLatin1String("[?bettyUuid exists][= { thumbnailUuid : bettyUuid->thumbnailUuid }]"));
verifyGoodQueryResult(queryResult);
- QCOMPARE(queryResult.values.at(0).toString(),
+ QCOMPARE(queryResult.data.at(0).value(QLatin1String("thumbnailUuid")).toString(),
thumbnailUuid);
- queryResult = find(mOwner, QLatin1String("[?bettyUuid exists][= bettyUuid->thumbnailUuid->url]"));
+ queryResult = find(mOwner, QLatin1String("[?bettyUuid exists][= { thumbnailUuid : bettyUuid->thumbnailUuid->url }]"));
verifyGoodQueryResult(queryResult);
- QCOMPARE(queryResult.values.at(0).toString(), thumbnail.value("url").toString());
+ QCOMPARE(queryResult.data.at(0).value(QLatin1String("thumbnailUuid")).toString(),
+ thumbnail.value("url").toString());
mJsonDbPartition->removeIndex("name");
mJsonDbPartition->removeIndex("thumbnailUuid");
mJsonDbPartition->removeIndex("url");
mJsonDbPartition->removeIndex("bettyUuid");
}
-void TestJsonDb::orQuery_data()
+void TestPartition::orQuery_data()
{
QTest::addColumn<QString>("field1");
QTest::addColumn<QString>("value1");
@@ -3423,7 +3498,7 @@ void TestJsonDb::orQuery_data()
mJsonDbPartition->removeIndex(QLatin1String("key2"));
}
-void TestJsonDb::orQuery()
+void TestPartition::orQuery()
{
QFETCH(QString, field1);
QFETCH(QString, value1);
@@ -3449,7 +3524,7 @@ void TestJsonDb::orQuery()
mJsonDbPartition->removeIndex("key2");
}
-void TestJsonDb::findByName()
+void TestPartition::findByName()
{
createContacts();
int count = mContactList.size();
@@ -3469,7 +3544,7 @@ void TestJsonDb::findByName()
verifyGoodQueryResult(queryResult);
}
-void TestJsonDb::findEQ()
+void TestPartition::findEQ()
{
createContacts();
int count = mContactList.size();
@@ -3488,7 +3563,7 @@ void TestJsonDb::findEQ()
mJsonDbPartition->removeIndex("name.last");
}
-void TestJsonDb::find10()
+void TestPartition::find10()
{
createContacts();
int count = mContactList.size();
@@ -3502,40 +3577,16 @@ void TestJsonDb::find10()
QString query = QString("[?name.first<=\"%1\"][?_type=\"contact\"]")
.arg(item.propertyLookup("name.first").toString());
- JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, JsonDbQuery::parse(query), 10);
- verifyGoodQueryResult(queryResult);
+ JsonDbQuery *parsedQuery = JsonDbQuery::parse(query);
+ JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, parsedQuery, 10);
+ delete parsedQuery;
+ verifyGoodQueryResult(queryResult);
QCOMPARE(queryResult.data.size(), 10);
mJsonDbPartition->removeIndex("name.first");
mJsonDbPartition->removeIndex("contact");
}
-QJsonValue TestJsonDb::readJsonFile(const QString& filename)
-{
- QString filepath = filename;
- QFile jsonFile(filepath);
- jsonFile.open(QIODevice::ReadOnly);
- QByteArray json = jsonFile.readAll();
- JsonReader parser;
- bool ok = parser.parse(json);
- if (!ok) {
- qDebug() << filepath << parser.errorString();
- }
- QVariant v = parser.result();
- return QJsonValue::fromVariant(v);
-}
-
-QJsonValue TestJsonDb::readJson(const QByteArray& json)
-{
- JsonReader parser;
- bool ok = parser.parse(json);
- if (!ok) {
- qDebug() << parser.errorString();
- }
- QVariant v = parser.result();
- return QJsonObject::fromVariantMap(v.toMap());
-}
-
-void TestJsonDb::startsWith()
+void TestPartition::startsWith()
{
addIndex(QLatin1String("name"));
@@ -3578,11 +3629,11 @@ void TestJsonDb::startsWith()
queryResult = find(mOwner, QLatin1String("[?_type startsWith \"startsWith\"][/name]"));
QCOMPARE(queryResult.data.size(), 4);
- queryResult = find(mOwner, QLatin1String("[?_type startsWith \"startsWith\"][= _type ]"));
- QCOMPARE(queryResult.values.size(), 4);
+ queryResult = find(mOwner, QLatin1String("[?_type startsWith \"startsWith\"][= { _type: _type } ]"));
+ QCOMPARE(queryResult.data.size(), 4);
}
-void TestJsonDb::comparison()
+void TestPartition::comparison()
{
addIndex(QLatin1String("latitude"), QLatin1String("number"));
@@ -3625,7 +3676,7 @@ void TestJsonDb::comparison()
mJsonDbPartition->removeIndex(QLatin1String("latitude"));
}
-void TestJsonDb::removedObjects()
+void TestPartition::removedObjects()
{
addIndex(QLatin1String("foo"));
addIndex(QLatin1String("name"));
@@ -3671,11 +3722,11 @@ void TestJsonDb::removedObjects()
mJsonDbPartition->removeIndex(QLatin1String("name"));
}
-void TestJsonDb::arrayIndexQuery()
+void TestPartition::arrayIndexQuery()
{
addIndex(QLatin1String("phoneNumber"));
- QJsonArray objects(readJsonFile(":/daemon/json/array.json").toArray());
+ QJsonArray objects(readJsonFile(":/partition/json/array.json").toArray());
QMap<QString, JsonDbObject> toDelete;
for (int i = 0; i < objects.size(); ++i) {
JsonDbObject object = objects.at(i).toObject();
@@ -3728,7 +3779,7 @@ void TestJsonDb::arrayIndexQuery()
verifyGoodResult(remove(mOwner, object));
}
-void TestJsonDb::deindexError()
+void TestPartition::deindexError()
{
JsonDbWriteResult result;
@@ -3770,7 +3821,7 @@ void TestJsonDb::deindexError()
}
}
-void TestJsonDb::expectedOrder()
+void TestPartition::expectedOrder()
{
QStringList list;
QStringList uuids;
@@ -3813,7 +3864,7 @@ void TestJsonDb::expectedOrder()
}
}
-void TestJsonDb::indexQueryOnCommonValues()
+void TestPartition::indexQueryOnCommonValues()
{
// Specific indexing bug when you have records inserted that only differ
// by their _type
@@ -3853,7 +3904,7 @@ void TestJsonDb::indexQueryOnCommonValues()
QCOMPARE(queryResult.data.size(), 1);
}
-void TestJsonDb::removeIndexes()
+void TestPartition::removeIndexes()
{
addIndex("wacky_index");
QVERIFY(mJsonDbPartition->findObjectTable(JsonDbString::kSchemaTypeStr)->indexSpec("wacky_index") != 0);
@@ -3879,7 +3930,7 @@ void TestJsonDb::removeIndexes()
QVERIFY(mJsonDbPartition->findObjectTable("Index")->indexSpec("predicate") == 0);
}
-void TestJsonDb::setOwner()
+void TestPartition::setOwner()
{
jsondbSettings->setEnforceAccessControl(true);
@@ -3898,7 +3949,7 @@ void TestJsonDb::setOwner()
result = remove(mOwner, item);
verifyGoodResult(result);
- JsonDbOwner *unauthOwner = new JsonDbOwner(this);
+ QScopedPointer<JsonDbOwner> unauthOwner(new JsonDbOwner(this));
unauthOwner->setOwnerId("com.example.OtherOwner");
unauthOwner->setAllowAll(false);
unauthOwner->setAllowedObjects(QLatin1String("all"), "write", (QStringList() << QLatin1String("[*]")));
@@ -3907,19 +3958,19 @@ void TestJsonDb::setOwner()
item = JsonDbObject();
item.insert(JsonDbString::kTypeStr, QLatin1String("SetOwnerType2"));
item.insert(JsonDbString::kOwnerStr, fooOwnerStr);
- result = create(unauthOwner, item);
+ result = create(unauthOwner.data(), item);
verifyGoodResult(result);
getObjects = mJsonDbPartition->getObjects(JsonDbString::kTypeStr, QLatin1String("SetOwnerType2"));
QVERIFY(getObjects.data.at(0).value(JsonDbString::kOwnerStr).toString()
!= fooOwnerStr);
- result = remove(unauthOwner, item);
+ result = remove(unauthOwner.data(), item);
verifyGoodResult(result);
jsondbSettings->setEnforceAccessControl(false);
}
-void TestJsonDb::indexPropertyFunction()
+void TestPartition::indexPropertyFunction()
{
JsonDbObject index;
index.insert(JsonDbString::kTypeStr, QLatin1String("Index"));
@@ -3967,9 +4018,27 @@ void TestJsonDb::indexPropertyFunction()
queryResult = find(mOwner, QLatin1String("[?_type=\"IndexPropertyFunction\"][?propertyFunctionIndex < 0]"));
QCOMPARE(queryResult.data.size(), 1);
QCOMPARE(queryResult.data.at(0).value("to").toDouble(), (double)-64);
+
+ // verify we can fetch the index values
+ queryResult = find(mOwner, QLatin1String("[?_type=\"IndexPropertyFunction\"][/propertyFunctionIndex]"));
+ QCOMPARE(queryResult.data.size(), 4);
+ JsonDbObjectList data = queryResult.data;
+ for (int i = 0; i < data.size(); i++) {
+ JsonDbObject o = queryResult.data.at(i);
+ QVERIFY(o.contains("_indexValue"));
+ QCOMPARE(o.value("_indexValue").toDouble(), (o.contains("to") ? o.value("to").toDouble() : o.value("from").toDouble()));
+ }
+
+ // verify we can fetch the index values
+ queryResult = find(mOwner, QLatin1String("[?_type=\"IndexPropertyFunction\"][?propertyFunctionIndex > 10][/propertyFunctionIndex][= { _uuid: _uuid, indexValue: propertyFunctionIndex }]"));
+ QCOMPARE(queryResult.data.size(), 1);
+ QCOMPARE(queryResult.data.at(0).value("to").toDouble(), (double)42);
+ QVERIFY(queryResult.data.at(0).contains("_indexValue"));
+ QCOMPARE(queryResult.data.at(0).value("_indexValue").toDouble(), (double)42);
+
}
-void TestJsonDb::indexCollation()
+void TestPartition::indexCollation()
{
#ifndef NO_COLLATION_SUPPORT
JsonDbObject item;
@@ -4066,9 +4135,9 @@ void TestJsonDb::indexCollation()
#endif
}
-void TestJsonDb::indexCaseSensitive()
+void TestPartition::indexCaseSensitive()
{
- QJsonArray objects(readJsonFile(":/daemon/json/index-casesensitive.json").toArray());
+ QJsonArray objects(readJsonFile(":/partition/json/index-casesensitive.json").toArray());
for (int ii = 0; ii < objects.size(); ii++) {
JsonDbObject object(objects.at(ii).toObject());
JsonDbWriteResult result = create(mOwner, object);
@@ -4092,10 +4161,10 @@ void TestJsonDb::indexCaseSensitive()
QCOMPARE(queryResult2.data.at(6).value("field").toString(), QLatin1String("aBB"));
}
-void TestJsonDb::indexCasePreference()
+void TestPartition::indexCasePreference()
{
#ifndef NO_COLLATION_SUPPORT
- QJsonArray objects(readJsonFile(":/daemon/json/index-casepreference.json").toArray());
+ QJsonArray objects(readJsonFile(":/partition/json/index-casepreference.json").toArray());
for (int ii = 0; ii < objects.size(); ii++) {
JsonDbObject object(objects.at(ii).toObject());
JsonDbWriteResult result = create(mOwner, object);
@@ -4134,8 +4203,15 @@ void TestJsonDb::indexCasePreference()
#endif
}
-void TestJsonDb::settings()
+void TestPartition::settings()
{
+ JsonDbSettings currentSettings;
+ const QMetaObject *metaObject = jsondbSettings->metaObject();
+ for (int i = metaObject->propertyOffset(); i < metaObject->propertyCount(); ++i) {
+ QByteArray property = metaObject->property(i).name();
+ currentSettings.setProperty(property, jsondbSettings->property(property));
+ }
+
// first explicitly set the values
jsondbSettings->setRejectStaleUpdates(true);
jsondbSettings->setDebug(true);
@@ -4198,7 +4274,388 @@ void TestJsonDb::settings()
QCOMPARE(jsondbSettings->syncInterval(), 6000);
QCOMPARE(jsondbSettings->indexSyncInterval(), 17000);
QVERIFY(jsondbSettings->debugQuery());
+
+ // restore settings
+ for (int i = metaObject->propertyOffset(); i < metaObject->propertyCount(); ++i) {
+ QByteArray property = metaObject->property(i).name();
+ jsondbSettings->setProperty(property, currentSettings.property(property));
+ }
+}
+
+void TestPartition::typeChangeIndex()
+{
+ JsonDbObject test1;
+ test1.insert(JsonDbString::kTypeStr, QLatin1String("TestContactTCI"));
+ test1.insert(QLatin1String("firstName"), QLatin1String("adam"));
+ verifyGoodResult(create(mOwner, test1));
+
+ JsonDbObject test2;
+ test2.insert(JsonDbString::kTypeStr, QLatin1String("TestContactTCI"));
+ test2.insert(QLatin1String("firstName"), QLatin1String("Betty"));
+ verifyGoodResult(create(mOwner, test2));
+
+ // create an object that's not an index
+ QString uuid = QUuid::createUuid().toString();
+ JsonDbObject changing;
+ changing.insert(JsonDbString::kUuidStr, uuid);
+ changing.insert(JsonDbString::kTypeStr, QLatin1String("not.an.index"));
+ verifyGoodResult(create(mOwner, changing));
+
+ // FIXME: I think this only works currently because we auto-create the index
+ JsonDbQueryResult queryResult = find(mOwner, QLatin1String("[?_type=\"TestContactTCI\"][/firstName]"));
+ verifyGoodQueryResult(queryResult);
+ QCOMPARE(queryResult.data.count(), 2);
+ QCOMPARE(queryResult.data.at(0).value(JsonDbString::kUuidStr).toString(),
+ test2.value(JsonDbString::kUuidStr).toString());
+ QCOMPARE(queryResult.data.at(1).value(JsonDbString::kUuidStr).toString(),
+ test1.value(JsonDbString::kUuidStr).toString());
+
+ // change the object into an Index
+ changing.insert(JsonDbString::kTypeStr, JsonDbString::kIndexTypeStr);
+ changing.insert(JsonDbString::kNameStr, QLatin1String("firstName"));
+ changing.insert(JsonDbString::kPropertyNameStr, QLatin1String("firstName"));
+ changing.insert(JsonDbString::kCaseSensitiveStr, false);
+ verifyGoodResult(update(mOwner, changing));
+
+ queryResult = find(mOwner, QLatin1String("[?_type=\"TestContactTCI\"][/firstName]"));
+ verifyGoodQueryResult(queryResult);
+ QCOMPARE(queryResult.data.count(), 2);
+ QCOMPARE(queryResult.data.at(0).value(JsonDbString::kUuidStr).toString(),
+ test1.value(JsonDbString::kUuidStr).toString());
+ QCOMPARE(queryResult.data.at(1).value(JsonDbString::kUuidStr).toString(),
+ test2.value(JsonDbString::kUuidStr).toString());
+
+ // change it back into a non-Index
+ changing.insert(JsonDbString::kTypeStr, QLatin1String("not.an.index"));
+ verifyGoodResult(update(mOwner, changing));
+
+ // make sure the old ordering is back
+ queryResult = find(mOwner, QLatin1String("[?_type=\"TestContactTCI\"][/firstName]"));
+ verifyGoodQueryResult(queryResult);
+ QCOMPARE(queryResult.data.count(), 2);
+ QCOMPARE(queryResult.data.at(0).value(JsonDbString::kUuidStr).toString(),
+ test2.value(JsonDbString::kUuidStr).toString());
+ QCOMPARE(queryResult.data.at(1).value(JsonDbString::kUuidStr).toString(),
+ test1.value(JsonDbString::kUuidStr).toString());
+
+ verifyGoodResult(remove(mOwner, changing));
+ verifyGoodResult(remove(mOwner, test1));
+ verifyGoodResult(remove(mOwner, test2));
+}
+
+void TestPartition::typeChangeMap()
+{
+ QJsonArray objects(readJsonFile(":/partition/json/map-reduce.json").toArray());
+
+ JsonDbObjectList schemas;
+ JsonDbObject map;
+
+ QMap<QString, JsonDbObject> toDelete;
+
+ for (int i = 0; i < objects.size(); ++i) {
+ QJsonObject object(objects.at(i).toObject());
+ JsonDbObject doc(object);
+
+ if (doc.type() == JsonDbString::kMapTypeStr)
+ doc.insert(JsonDbString::kTypeStr, QLatin1String("not.a.Map"));
+
+ if (doc.type() != JsonDbString::kReduceTypeStr) {
+ JsonDbWriteResult result = create(mOwner, doc);
+ verifyGoodResult(result);
+
+ if (doc.value(JsonDbString::kTypeStr).toString() == QLatin1String("not.a.Map"))
+ map = doc;
+ else if (object.value(JsonDbString::kTypeStr).toString() == JsonDbString::kSchemaTypeStr)
+ schemas.append(doc);
+ else
+ toDelete.insert(doc.value("_uuid").toString(), doc);
+ }
+ }
+
+ JsonDbQueryResult queryResult = find(mOwner, QLatin1String("[?_type=\"Phone\"]"));
+ verifyGoodQueryResult(queryResult);
+ QCOMPARE(queryResult.data.size(), 0);
+
+ // change the object into a Map and test the result
+ map.insert(JsonDbString::kTypeStr, JsonDbString::kMapTypeStr);
+ verifyGoodResult(update(mOwner, map));
+
+ queryResult = find(mOwner, QLatin1String("[?_type=\"Phone\"]"));
+ verifyGoodQueryResult(queryResult);
+ QCOMPARE(queryResult.data.size(), 5);
+
+ // make it not a Map again and test the result
+ map.insert(JsonDbString::kTypeStr, QLatin1String("not.a.Map"));
+ verifyGoodResult(update(mOwner, map));
+
+ queryResult = find(mOwner, QLatin1String("[?_type=\"Phone\"]"));
+ verifyGoodQueryResult(queryResult);
+ QCOMPARE(queryResult.data.size(), 0);
+
+ verifyGoodResult(remove(mOwner, map));
+ foreach (JsonDbObject schema, schemas)
+ verifyGoodResult(remove(mOwner, schema));
+
+ foreach (JsonDbObject del, toDelete.values())
+ verifyGoodResult(remove(mOwner, del));
+}
+
+void TestPartition::typeChangeReduce()
+{
+ JsonDbObject test1;
+ test1.insert(JsonDbString::kTypeStr, QLatin1String("MyContact"));
+ test1.insert(QLatin1String("firstName"), QLatin1String("Bill"));
+ verifyGoodResult(create(mOwner, test1));
+
+ JsonDbObject test2;
+ test2.insert(JsonDbString::kTypeStr, QLatin1String("MyContact"));
+ test2.insert(QLatin1String("firstName"), QLatin1String("Alice"));
+ verifyGoodResult(create(mOwner, test2));
+
+ QJsonArray objects(readJsonFile(":/partition/json/reduce.json").toArray());
+
+ JsonDbObject reduce;
+ JsonDbObject schema;
+
+ for (int i = 0; i < objects.size(); ++i) {
+ QJsonObject object(objects.at(i).toObject());
+ JsonDbObject doc(object);
+
+ if (doc.type() == JsonDbString::kReduceTypeStr)
+ doc.insert(JsonDbString::kTypeStr, QLatin1String("not.a.Reduce"));
+
+ JsonDbWriteResult result = create(mOwner, doc);
+ verifyGoodResult(result);
+
+ if (doc.value(JsonDbString::kTypeStr).toString() == QLatin1String("not.a.Reduce"))
+ reduce = doc;
+ else if (object.value(JsonDbString::kTypeStr).toString() == JsonDbString::kSchemaTypeStr)
+ schema = doc;
+ }
+
+ JsonDbQueryResult queryResult = find(mOwner, QLatin1String("[?_type=\"MyContactCount\"]"));
+ verifyGoodQueryResult(queryResult);
+ QCOMPARE(queryResult.data.size(), 0);
+
+ // make it into a Reduce and check the result
+ reduce.insert(JsonDbString::kTypeStr, JsonDbString::kReduceTypeStr);
+ verifyGoodResult(update(mOwner, reduce));
+
+ queryResult = find(mOwner, QLatin1String("[?_type=\"MyContactCount\"]"));
+ verifyGoodQueryResult(queryResult);
+ QCOMPARE(queryResult.data.size(), 2);
+
+ // make it not a Reduce again and check the result
+ reduce.insert(JsonDbString::kTypeStr, QLatin1String("not.a.Reduce"));
+ verifyGoodResult(update(mOwner, reduce));
+
+ queryResult = find(mOwner, QLatin1String("[?_type=\"MyContactCount\"]"));
+ verifyGoodQueryResult(queryResult);
+ QCOMPARE(queryResult.data.size(), 0);
+
+ verifyGoodResult(remove(mOwner, reduce));
+ verifyGoodResult(remove(mOwner, schema));
+ verifyGoodResult(remove(mOwner, test1));
+ verifyGoodResult(remove(mOwner, test2));
+}
+
+void TestPartition::typeChangeMapSource()
+{
+ QJsonArray objects(readJsonFile(":/partition/json/map-reduce.json").toArray());
+
+ JsonDbObject map;
+ JsonDbObject schema;
+ QMap<QString, JsonDbObject> toDelete;
+
+ for (int i = 0; i < objects.size(); ++i) {
+ QJsonObject object(objects.at(i).toObject());
+ JsonDbObject doc(object);
+
+ if (doc.type() != JsonDbString::kReduceTypeStr) {
+ JsonDbWriteResult result = create(mOwner, doc);
+ verifyGoodResult(result);
+
+ if (object.value(JsonDbString::kTypeStr).toString() == JsonDbString::kMapTypeStr)
+ map = doc;
+ else if (object.value(JsonDbString::kTypeStr).toString() == JsonDbString::kSchemaTypeStr)
+ schema = doc;
+ else
+ toDelete.insert(doc.value("_uuid").toString(), doc);
+ }
+ }
+
+ JsonDbObject changing;
+ changing.insert(JsonDbString::kTypeStr, QLatin1String("not.a.Contact"));
+ QJsonObject phoneNumber1;
+ phoneNumber1.insert(QLatin1String("type"), QLatin1String("home"));
+ phoneNumber1.insert(QLatin1String("number"), QLatin1String("+4700112233"));
+ QJsonObject phoneNumber2;
+ phoneNumber2.insert(QLatin1String("type"), QLatin1String("work"));
+ phoneNumber2.insert(QLatin1String("number"), QLatin1String("+4711223344"));
+ QJsonArray phoneNumbers;
+ phoneNumbers.append(phoneNumber1);
+ phoneNumbers.append(phoneNumber2);
+ changing.insert(QLatin1String("phoneNumbers"), phoneNumbers);
+
+ verifyGoodResult(create(mOwner, changing));
+
+ JsonDbQueryResult queryResult = find(mOwner, QLatin1String("[?_type=\"Phone\"]"));
+ verifyGoodQueryResult(queryResult);
+ QCOMPARE(queryResult.data.size(), 5);
+
+ // change the _type to a source type of the Map
+ changing.insert(JsonDbString::kTypeStr, QLatin1String("Contact"));
+ verifyGoodResult(update(mOwner, changing));
+
+ queryResult = find(mOwner, QLatin1String("[?_type=\"Phone\"]"));
+ verifyGoodQueryResult(queryResult);
+ QCOMPARE(queryResult.data.size(), 7);
+
+ // change it back to a non-source type
+ changing.insert(JsonDbString::kTypeStr, QLatin1String("not.a.Contact"));
+ verifyGoodResult(update(mOwner, changing));
+
+ queryResult = find(mOwner, QLatin1String("[?_type=\"Phone\"]"));
+ verifyGoodQueryResult(queryResult);
+ QCOMPARE(queryResult.data.size(), 5);
+
+ verifyGoodResult(remove(mOwner, map));
+ verifyGoodResult(remove(mOwner, schema));
+
+ foreach (JsonDbObject del, toDelete.values())
+ verifyGoodResult(remove(mOwner, del));
+}
+
+void TestPartition::typeChangeReduceSource()
+{
+ JsonDbObject test1;
+ test1.insert(JsonDbString::kTypeStr, QLatin1String("MyContact"));
+ test1.insert(QLatin1String("firstName"), QLatin1String("Bill"));
+ verifyGoodResult(create(mOwner, test1));
+
+ JsonDbObject test2;
+ test2.insert(JsonDbString::kTypeStr, QLatin1String("MyContact"));
+ test2.insert(QLatin1String("firstName"), QLatin1String("Alice"));
+ verifyGoodResult(create(mOwner, test2));
+
+ QJsonArray objects(readJsonFile(":/partition/json/reduce.json").toArray());
+
+ JsonDbObject reduce;
+ JsonDbObject schema;
+
+ for (int i = 0; i < objects.size(); ++i) {
+ QJsonObject object(objects.at(i).toObject());
+ JsonDbObject doc(object);
+
+ JsonDbWriteResult result = create(mOwner, doc);
+ verifyGoodResult(result);
+
+ if (object.value(JsonDbString::kTypeStr).toString() == JsonDbString::kReduceTypeStr)
+ reduce = doc;
+ else if (object.value(JsonDbString::kTypeStr).toString() == JsonDbString::kSchemaTypeStr)
+ schema = doc;
+ }
+
+ JsonDbObject changing;
+ changing.insert(JsonDbString::kTypeStr, QLatin1String("not.a.MyContact"));
+ changing.insert(QLatin1String("firstName"), QLatin1String("Bob"));
+ verifyGoodResult(create(mOwner, changing));
+
+ JsonDbQueryResult queryResult = find(mOwner, QLatin1String("[?_type=\"MyContactCount\"]"));
+ verifyGoodQueryResult(queryResult);
+ QCOMPARE(queryResult.data.size(), 2);
+
+ // change the object so it's the source type of the Reduce
+ changing.insert(JsonDbString::kTypeStr, QLatin1String("MyContact"));
+ verifyGoodResult(update(mOwner, changing));
+
+ // re-query to see if the Reduce picked it up
+ queryResult = find(mOwner, QLatin1String("[?_type=\"MyContactCount\"]"));
+ verifyGoodQueryResult(queryResult);
+ QCOMPARE(queryResult.data.size(), 3);
+
+ // change the object back to not being a source type of the Reduce
+ changing.insert(JsonDbString::kTypeStr, QLatin1String("not.a.MyContact"));
+ verifyGoodResult(update(mOwner, changing));
+
+ // re-query to see if the Reduce picked it up
+ queryResult = find(mOwner, QLatin1String("[?_type=\"MyContactCount\"]"));
+ verifyGoodQueryResult(queryResult);
+ QCOMPARE(queryResult.data.size(), 2);
+
+ // one more time, but this time adding to an existing Reduce target object
+ changing.insert(JsonDbString::kTypeStr, QLatin1String("MyContact"));
+ changing.insert(QLatin1String("firstName"), QLatin1String("Alice"));
+ verifyGoodResult(update(mOwner, changing));
+
+ queryResult = find(mOwner, QLatin1String("[?_type=\"MyContactCount\"]"));
+ verifyGoodQueryResult(queryResult);
+ QCOMPARE(queryResult.data.size(), 2);
+
+ foreach (const JsonDbObject &object, queryResult.data) {
+ if (object.value(QLatin1String("firstName")).toString() == QLatin1String("Alice")) {
+ QCOMPARE(static_cast<int>(object.value(QLatin1String("count")).toDouble()), 2);
+ } else {
+ QVERIFY(object.value(QLatin1String("firstName")).toString() == QLatin1String("Bill"));
+ QCOMPARE(static_cast<int>(object.value(QLatin1String("count")).toDouble()), 1);
+ }
+ }
+
+ // change the type again and make sure the count goes back down
+ changing.insert(JsonDbString::kTypeStr, QLatin1String("not.a.MyContact"));
+ verifyGoodResult(update(mOwner, changing));
+
+ queryResult = find(mOwner, QLatin1String("[?_type=\"MyContactCount\"]"));
+ verifyGoodQueryResult(queryResult);
+ QCOMPARE(queryResult.data.size(), 2);
+
+ foreach (const JsonDbObject &object, queryResult.data)
+ QCOMPARE(static_cast<int>(object.value(QLatin1String("count")).toDouble()), 1);
+
+ verifyGoodResult(remove(mOwner, reduce));
+ verifyGoodResult(remove(mOwner, schema));
+ verifyGoodResult(remove(mOwner, test1));
+ verifyGoodResult(remove(mOwner, test2));
+ verifyGoodResult(remove(mOwner, changing));
+}
+
+void TestPartition::typeChangeSchema()
+{
+ bool currentValidateSchemas = jsondbSettings->validateSchemas();
+ jsondbSettings->setValidateSchemas(true);
+ QJsonObject schemaDef(readJsonFile(":/json-validation/required-schema.json").toObject());
+ JsonDbObject schema;
+ schema.insert(JsonDbString::kTypeStr, QLatin1String("not.a._schemaType"));
+ schema.insert(JsonDbString::kSchemaStr, schemaDef);
+ schema.insert(JsonDbString::kNameStr, QLatin1String("TestObject"));
+ verifyGoodResult(create(mOwner, schema));
+
+ // test object which is missing the required "important" field
+ JsonDbObject test;
+ test.insert(JsonDbString::kTypeStr, QLatin1String("TestObject"));
+ verifyGoodResult(create(mOwner, test));
+
+ // change the object into a schema and try the invalid update
+ schema.insert(JsonDbString::kTypeStr, JsonDbString::kSchemaTypeStr);
+ verifyGoodResult(update(mOwner, schema));
+
+ test.insert(QLatin1String("notimportant"), QLatin1String("foo"));
+ JsonDbWriteResult result = update(mOwner, test);
+ verifyErrorResult(result);
+ QCOMPARE(result.code, JsonDbError::FailedSchemaValidation);
+ verifyGoodResult(remove(mOwner, test));
+
+ // change it back into a non-schema and make sure the update goes through
+ schema.insert(JsonDbString::kTypeStr, QLatin1String("not.a._schemaType"));
+ verifyGoodResult(update(mOwner, schema));
+
+ test.remove(JsonDbString::kDeletedStr);
+ verifyGoodResult(update(mOwner, test));
+
+ verifyGoodResult(remove(mOwner, test));
+ verifyGoodResult(remove(mOwner, schema));
+ jsondbSettings->setValidateSchemas(currentValidateSchemas);
}
-QTEST_MAIN(TestJsonDb)
-#include "testjsondb.moc"
+QTEST_MAIN(TestPartition)
+#include "testpartition.moc"
diff --git a/tests/auto/qjsondbflushrequest/qjsondbflushrequest.pro b/tests/auto/qjsondbflushrequest/qjsondbflushrequest.pro
new file mode 100644
index 00000000..f144050e
--- /dev/null
+++ b/tests/auto/qjsondbflushrequest/qjsondbflushrequest.pro
@@ -0,0 +1,13 @@
+TARGET = tst_qjsondbflushrequest
+
+QT = network testlib jsondb-private
+CONFIG -= app_bundle
+CONFIG += testcase
+
+include($$PWD/../../shared/shared.pri)
+
+DEFINES += SRCDIR=\\\"$$PWD/\\\"
+
+RESOURCES += ../partition/partition.qrc
+
+SOURCES += testqjsondbflushrequest.cpp
diff --git a/tests/auto/qjsondbflushrequest/testqjsondbflushrequest.cpp b/tests/auto/qjsondbflushrequest/testqjsondbflushrequest.cpp
new file mode 100644
index 00000000..929e0420
--- /dev/null
+++ b/tests/auto/qjsondbflushrequest/testqjsondbflushrequest.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+ **
+ ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+ ** Contact: http://www.qt-project.org/
+ **
+ ** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
+ **
+ ** $QT_BEGIN_LICENSE:LGPL$
+ ** GNU Lesser General Public License Usage
+ ** This file may be used under the terms of the GNU Lesser General Public
+ ** License version 2.1 as published by the Free Software Foundation and
+ ** appearing in the file LICENSE.LGPL included in the packaging of this
+ ** file. Please review the following information to ensure the GNU Lesser
+ ** General Public License version 2.1 requirements will be met:
+ ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+ **
+ ** In addition, as a special exception, Nokia gives you certain additional
+ ** rights. These rights are described in the Nokia Qt LGPL Exception
+ ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+ **
+ ** GNU General Public License Usage
+ ** Alternatively, this file may be used under the terms of the GNU General
+ ** Public License version 3.0 as published by the Free Software Foundation
+ ** and appearing in the file LICENSE.GPL included in the packaging of this
+ ** file. Please review the following information to ensure the GNU General
+ ** Public License version 3.0 requirements will be met:
+ ** http://www.gnu.org/copyleft/gpl.html.
+ **
+ ** Other Usage
+ ** Alternatively, this file may be used in accordance with the terms and
+ ** conditions contained in a signed written agreement between you and Nokia.
+ **
+ **
+ **
+ **
+ **
+ **
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************/
+
+#include "qjsondbconnection.h"
+#include "testhelper.h"
+
+#include <QTest>
+
+QT_USE_NAMESPACE_JSONDB
+
+static const char dbfileprefix[] = "test-jsondb-flushrequest";
+
+class TestQJsonDbFlushRequest: public TestHelper
+{
+ Q_OBJECT
+
+private slots:
+ void initTestCase();
+ void cleanupTestCase();
+ void init();
+ void cleanup();
+};
+
+void TestQJsonDbFlushRequest::initTestCase()
+{
+ removeDbFiles();
+
+ QStringList arg_list = QStringList() << "-validate-schemas";
+ launchJsonDbDaemon(QString::fromLatin1(dbfileprefix), arg_list, __FILE__);
+}
+
+void TestQJsonDbFlushRequest::cleanupTestCase()
+{
+ removeDbFiles();
+ stopDaemon();
+}
+
+void TestQJsonDbFlushRequest::init()
+{
+ connectToServer();
+}
+
+void TestQJsonDbFlushRequest::cleanup()
+{
+ disconnectFromServer();
+}
+
+QTEST_MAIN(TestQJsonDbFlushRequest)
+
+#include "testqjsondbflushrequest.moc"
diff --git a/tests/auto/qjsondbrequest/partitions.json b/tests/auto/qjsondbrequest/partitions.json
new file mode 100644
index 00000000..56139e6a
--- /dev/null
+++ b/tests/auto/qjsondbrequest/partitions.json
@@ -0,0 +1,3 @@
+[
+ { "name" :"com.qt-project.shared", "default" : true }
+]
diff --git a/tests/auto/qjsondbrequest/qjsondbrequest.pro b/tests/auto/qjsondbrequest/qjsondbrequest.pro
new file mode 100644
index 00000000..9ac6f240
--- /dev/null
+++ b/tests/auto/qjsondbrequest/qjsondbrequest.pro
@@ -0,0 +1,17 @@
+TARGET = tst_qjsondbrequest
+
+QT = network testlib jsondb-private
+CONFIG -= app_bundle
+CONFIG += testcase
+
+include($$PWD/../../shared/shared.pri)
+
+DEFINES += JSONDB_DAEMON_BASE=\\\"$$QT.jsondb.bins\\\"
+DEFINES += SRCDIR=\\\"$$PWD/\\\"
+
+RESOURCES += ../partition/partition.qrc
+
+SOURCES += testqjsondbrequest.cpp
+
+OTHER_FILES += \
+ partitions.json
diff --git a/tests/auto/qjsondbrequest/testqjsondbrequest.cpp b/tests/auto/qjsondbrequest/testqjsondbrequest.cpp
new file mode 100644
index 00000000..2699d62d
--- /dev/null
+++ b/tests/auto/qjsondbrequest/testqjsondbrequest.cpp
@@ -0,0 +1,197 @@
+/****************************************************************************
+ **
+ ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+ ** Contact: http://www.qt-project.org/
+ **
+ ** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
+ **
+ ** $QT_BEGIN_LICENSE:LGPL$
+ ** GNU Lesser General Public License Usage
+ ** This file may be used under the terms of the GNU Lesser General Public
+ ** License version 2.1 as published by the Free Software Foundation and
+ ** appearing in the file LICENSE.LGPL included in the packaging of this
+ ** file. Please review the following information to ensure the GNU Lesser
+ ** General Public License version 2.1 requirements will be met:
+ ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+ **
+ ** In addition, as a special exception, Nokia gives you certain additional
+ ** rights. These rights are described in the Nokia Qt LGPL Exception
+ ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+ **
+ ** GNU General Public License Usage
+ ** Alternatively, this file may be used under the terms of the GNU General
+ ** Public License version 3.0 as published by the Free Software Foundation
+ ** and appearing in the file LICENSE.GPL included in the packaging of this
+ ** file. Please review the following information to ensure the GNU General
+ ** Public License version 3.0 requirements will be met:
+ ** http://www.gnu.org/copyleft/gpl.html.
+ **
+ ** Other Usage
+ ** Alternatively, this file may be used in accordance with the terms and
+ ** conditions contained in a signed written agreement between you and Nokia.
+ **
+ **
+ **
+ **
+ **
+ **
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************/
+
+#include "qjsondbconnection.h"
+#include "qjsondbobject.h"
+#include "qjsondbreadrequest.h"
+#include "qjsondbwriterequest.h"
+#include "testhelper.h"
+
+#include <QDebug>
+#include <QJsonArray>
+#include <QJsonDocument>
+#include <QProcess>
+#include <QTest>
+#include <QFile>
+
+#include <signal.h>
+
+QT_USE_NAMESPACE_JSONDB
+
+static const char dbfileprefix[] = "test-jsondb-request";
+
+class TestQJsonDbRequest: public TestHelper
+{
+ Q_OBJECT
+
+private slots:
+ void initTestCase();
+ void cleanupTestCase();
+ void init();
+ void cleanup();
+
+ void modifyPartitions();
+};
+
+void TestQJsonDbRequest::initTestCase()
+{
+ removeDbFiles();
+
+ QStringList arg_list = QStringList() << "-validate-schemas";
+ launchJsonDbDaemon(QString::fromLatin1(dbfileprefix), arg_list, __FILE__);
+}
+
+void TestQJsonDbRequest::cleanupTestCase()
+{
+ removeDbFiles();
+ stopDaemon();
+}
+
+void TestQJsonDbRequest::init()
+{
+ connectToServer();
+}
+
+void TestQJsonDbRequest::cleanup()
+{
+ disconnectFromServer();
+}
+
+void TestQJsonDbRequest::modifyPartitions()
+{
+ // create a notification on Partitions
+ QJsonDbWatcher watcher;
+ watcher.setPartition(QLatin1String("Ephemeral"));
+ watcher.setQuery("[?_type=\"Partition\"]");
+ mConnection->addWatcher(&watcher);
+
+ // ensure that there's only one partition defined and that it's the default
+ QLatin1String defaultPartition("com.qt-project.shared");
+
+ QJsonDbReadRequest partitionQuery;
+ partitionQuery.setPartition(QLatin1String("Ephemeral"));
+ partitionQuery.setQuery(QLatin1String("[?_type=%type]"));
+ partitionQuery.bindValue(QLatin1String("type"), QLatin1String("Partition"));
+
+ mConnection->send(&partitionQuery);
+ waitForResponse(&partitionQuery);
+
+ QList<QJsonObject> results = partitionQuery.takeResults();
+ QCOMPARE(results.count(), 1);
+ QCOMPARE(results[0].value(QLatin1String("name")).toString(), defaultPartition);
+ QVERIFY(results[0].value(QLatin1String("default")).toBool());
+
+ // write a new partitions file
+ QJsonObject def1;
+ def1.insert(QLatin1String("name"), QLatin1String("com.qt-project.test1"));
+ QJsonObject def2;
+ def2.insert(QLatin1String("name"), QLatin1String("com.qt-project.test2"));
+ QJsonArray defs;
+ defs.append(def1);
+ defs.append(def2);
+
+ QFile partitionsFile(QLatin1String("partitions-test.json"));
+ partitionsFile.open(QFile::WriteOnly);
+ partitionsFile.write(QJsonDocument(defs).toJson());
+ partitionsFile.close();
+
+ // send the daemon a SIGHUP to get it to reload the partitions
+ kill(mProcess->pid(), SIGHUP);
+ waitForResponseAndNotifications(0, &watcher, 2);
+
+ // query for the new partitions
+ mConnection->send(&partitionQuery);
+ waitForResponse(&partitionQuery);
+
+ results = partitionQuery.takeResults();
+ QCOMPARE(results.count(), 3);
+
+ // operate on the new partition to make sure it works
+ QJsonDbWriteRequest writeRequest;
+ QUuid testUuid = QJsonDbObject::createUuidFromString(QLatin1String("testobject1"));
+ QJsonDbObject toWrite;
+ toWrite.setUuid(testUuid);
+ toWrite.insert(QLatin1String("_type"), QLatin1String("TestObject"));
+ writeRequest.setObjects(QList<QJsonObject>() << toWrite);
+ mConnection->send(&writeRequest);
+ waitForResponse(&writeRequest);
+ QVERIFY(!mRequestErrors.contains(&writeRequest));
+
+ QJsonDbReadObjectRequest readRequest(testUuid);
+ mConnection->send(&readRequest);
+ waitForResponse(&readRequest);
+ QVERIFY(!mRequestErrors.contains(&readRequest));
+ results = readRequest.takeResults();
+ QCOMPARE(results.count(), 1);
+ QCOMPARE(results[0].value(QLatin1String("_type")).toString(), QLatin1String("TestObject"));
+
+ // remove the new partitions file
+ partitionsFile.remove();
+
+ // send the daemon a SIGHUP to get it to unload the partitions
+ kill(mProcess->pid(), SIGHUP);
+ waitForResponseAndNotifications(0, &watcher, 2);
+
+ // verify that we're back to just the origin partition
+ mConnection->send(&partitionQuery);
+ waitForResponse(&partitionQuery);
+
+ results = partitionQuery.takeResults();
+ QCOMPARE(results.count(), 1);
+ QCOMPARE(results[0].value(QLatin1String("name")).toString(), defaultPartition);
+ QVERIFY(results[0].value(QLatin1String("default")).toBool());
+
+ // query one of the test partitions to ensure we get an InvalidPartition error
+ QJsonDbReadRequest failingRequest;
+ failingRequest.setPartition(QLatin1String("com.qt-project.test1"));
+ failingRequest.setQuery(QLatin1String("[*]"));
+ mConnection->send(&failingRequest);
+ waitForResponse(&failingRequest);
+
+ QVERIFY(mRequestErrors.contains(&failingRequest));
+ QCOMPARE(mRequestErrors[&failingRequest], QJsonDbRequest::InvalidPartition);
+
+ mConnection->removeWatcher(&watcher);
+}
+
+QTEST_MAIN(TestQJsonDbRequest)
+
+#include "testqjsondbrequest.moc"
diff --git a/tests/auto/qjsondbwatcher/qjsondbwatcher.pro b/tests/auto/qjsondbwatcher/qjsondbwatcher.pro
index 008fb2c5..344b9414 100644
--- a/tests/auto/qjsondbwatcher/qjsondbwatcher.pro
+++ b/tests/auto/qjsondbwatcher/qjsondbwatcher.pro
@@ -9,6 +9,6 @@ include($$PWD/../../shared/shared.pri)
DEFINES += JSONDB_DAEMON_BASE=\\\"$$QT.jsondb.bins\\\"
DEFINES += SRCDIR=\\\"$$PWD/\\\"
-RESOURCES += ../daemon/daemon.qrc
+RESOURCES += ../partition/partition.qrc
SOURCES += testqjsondbwatcher.cpp
diff --git a/tests/auto/qjsondbwatcher/testqjsondbwatcher.cpp b/tests/auto/qjsondbwatcher/testqjsondbwatcher.cpp
index 61d4bc0c..06593c7e 100644
--- a/tests/auto/qjsondbwatcher/testqjsondbwatcher.cpp
+++ b/tests/auto/qjsondbwatcher/testqjsondbwatcher.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include <QCoreApplication>
+#include <QFile>
#include <QList>
#include <QTest>
#include <QProcess>
@@ -54,19 +55,19 @@
#include "qjsondocument.h"
#include "qjsondbconnection.h"
+#include "qjsondbobject.h"
+#include "qjsondbreadrequest.h"
#include "qjsondbwatcher.h"
#include "qjsondbwriterequest.h"
#include "private/qjsondbstrings_p.h"
-#include "util.h"
+#include "testhelper.h"
QT_USE_NAMESPACE_JSONDB
// #define EXTRA_DEBUG
-// #define DONT_START_SERVER
-
-class TestQJsonDbWatcher: public QObject
+class TestQJsonDbWatcher: public TestHelper
{
Q_OBJECT
public:
@@ -76,63 +77,24 @@ class TestQJsonDbWatcher: public QObject
private slots:
void initTestCase();
void cleanupTestCase();
+ void init();
+ void cleanup();
+ void createAndRemove_data();
void createAndRemove();
+ void indexValue_data();
+ void indexValue();
void history();
void currentState();
void notificationTriggersView();
-
-public slots:
- // from mConnection
- void error(QtJsonDb::QJsonDbConnection::ErrorCode c, QString msg);
- void statusChanged(QtJsonDb::QJsonDbConnection::Status status);
- void disconnected();
-
- // from a request
- void onRequestFinished();
- void onRequestError(QtJsonDb::QJsonDbRequest::ErrorCode,QString);
- void onRequestStatusChanged(QtJsonDb::QJsonDbRequest::Status);
- // from a watcher
- void onWatcherNotificationsAvailable(int);
- void onWatcherStatusChanged(QtJsonDb::QJsonDbWatcher::Status);
- void onWatcherError(QtJsonDb::QJsonDbWatcher::ErrorCode,QString);
-private:
- void removeDbFiles();
-
-private:
-#ifndef DONT_START_SERVER
- QProcess *mProcess;
-#endif
- QJsonDbConnection *mConnection;
- QEventLoop mEventLoop;
- // what we're waiting for
- QJsonDbRequest *mRequest;
- int mNotificationCount;
- int mNotificationsReceived;
-
+ void notificationTriggersMapReduce();
+ void typeChangeEagerViewSource();
};
-#ifndef DONT_START_SERVER
static const char dbfileprefix[] = "test-jsondb-watcher";
-#endif
-
-// this should go into a new version of clientwrapper.h
-#define waitForResponseAndNotification(_request, _count) \
- { \
- mRequest = _request; \
- mNotificationCount = _count; \
- mNotificationsReceived = 0; \
- mEventLoop.exec(QEventLoop::AllEvents); \
- }
-#define waitForWatcherStatus(_watcher, _status) \
- { \
- while (_watcher.status() != _status) \
- mEventLoop.processEvents(QEventLoop::AllEvents); \
- }
TestQJsonDbWatcher::TestQJsonDbWatcher()
- : mProcess(0)
{
}
@@ -140,142 +102,138 @@ TestQJsonDbWatcher::~TestQJsonDbWatcher()
{
}
-void TestQJsonDbWatcher::error(QtJsonDb::QJsonDbConnection::ErrorCode c, QString msg)
+void TestQJsonDbWatcher::initTestCase()
{
- qCritical() << "Error from connection" << c << msg;
-}
+ removeDbFiles();
-void TestQJsonDbWatcher::statusChanged(QtJsonDb::QJsonDbConnection::Status status)
-{
- Q_UNUSED(status);
+ QStringList arg_list = QStringList() << "-validate-schemas";
+ launchJsonDbDaemon(QString::fromLatin1(dbfileprefix), arg_list, __FILE__);
}
-void TestQJsonDbWatcher::disconnected()
+void TestQJsonDbWatcher::cleanupTestCase()
{
- qCritical() << "Disconnected from jsondb";
+ removeDbFiles();
+ stopDaemon();
}
-// this should go into a new version of clientwrapper.h
-void TestQJsonDbWatcher::onRequestFinished()
+void TestQJsonDbWatcher::init()
{
- mRequest = 0;
- if (mNotificationCount <= mNotificationsReceived)
- mEventLoop.quit();
+ connectToServer();
}
-// this should go into a new version of clientwrapper.h
-void TestQJsonDbWatcher::onRequestError(QtJsonDb::QJsonDbRequest::ErrorCode code, QString msg)
-{
- qCritical() << "onRequestError" << code << msg;
- mEventLoop.quit();
-}
-void TestQJsonDbWatcher::onRequestStatusChanged(QtJsonDb::QJsonDbRequest::Status status)
+void TestQJsonDbWatcher::cleanup()
{
- Q_UNUSED(status);
- //qDebug() << "onRequestStatusChanged" << status;
+ disconnectFromServer();
}
-// this should go into a new version of clientwrapper.h
-void TestQJsonDbWatcher::onWatcherNotificationsAvailable(int count)
+void TestQJsonDbWatcher::createAndRemove_data()
{
- mNotificationsReceived = count;
- if (mRequest == 0 && mNotificationCount <= mNotificationsReceived)
- mEventLoop.quit();
-}
+ QTest::addColumn<QString>("partition");
-void TestQJsonDbWatcher::onWatcherStatusChanged(QtJsonDb::QJsonDbWatcher::Status status)
-{
- Q_UNUSED(status);
+ QTest::newRow("persistent") << "";
+ QTest::newRow("ephemeral") << "Ephemeral";
}
-// this should go into a new version of clientwrapper.h
-void TestQJsonDbWatcher::onWatcherError(QtJsonDb::QJsonDbWatcher::ErrorCode code, QString message)
-{
- qCritical() << "onWatcherError" << code << message;
- mEventLoop.quit();
-}
+/*
+ * Watch for an item creation
+ */
-void TestQJsonDbWatcher::removeDbFiles()
+void TestQJsonDbWatcher::createAndRemove()
{
-#ifndef DONT_START_SERVER
- QStringList lst = QDir().entryList(QStringList() << QLatin1String("*.db"));
- lst << "objectFile.bin" << "objectFile2.bin";
- foreach (const QString &fileName, lst)
- QFile::remove(fileName);
-#else
- qDebug("Don't forget to clean database files before running the test!");
-#endif
-}
+ QVERIFY(mConnection);
+ QFETCH(QString, partition);
-void TestQJsonDbWatcher::initTestCase()
-{
- removeDbFiles();
+ // create a watcher
+ QJsonDbWatcher watcher;
+ watcher.setWatchedActions(QJsonDbWatcher::All);
+ watcher.setQuery(QLatin1String("[?_type=\"com.test.qjsondbwatcher-test\"]"));
+ watcher.setPartition(partition);
+ mConnection->addWatcher(&watcher);
+ waitForStatus(&watcher, QJsonDbWatcher::Active);
+
+ QJsonObject item;
+ item.insert(JsonDbStrings::Property::type(), QLatin1String("com.test.qjsondbwatcher-test"));
+ item.insert(QLatin1String("create-test"), 22);
+
+ // Create an item
+ QJsonDbCreateRequest request(item);
+ request.setPartition(partition);
+ mConnection->send(&request);
+ waitForResponseAndNotifications(&request, &watcher, 1);
+
+ QList<QJsonObject> results = request.takeResults();
+ QCOMPARE(results.size(), 1);
+ QJsonObject info = results.at(0);
+ item.insert(JsonDbStrings::Property::uuid(), info.value(JsonDbStrings::Property::uuid()));
+ item.insert(JsonDbStrings::Property::version(), info.value(JsonDbStrings::Property::version()));
+
+ QList<QJsonDbNotification> notifications = watcher.takeNotifications();
+ QCOMPARE(notifications.size(), 1);
+
+ // remove the object
+ item.remove(QLatin1String("create-test"));
+ QJsonDbRemoveRequest remove(item);
+ remove.setPartition(partition);
+ mConnection->send(&remove);
+ waitForResponseAndNotifications(&remove, &watcher, 1);
-#ifndef DONT_START_SERVER
- QStringList arg_list = (QStringList()
- << "-validate-schemas");
- arg_list << "-base-name";
- arg_list << QString::fromLatin1(dbfileprefix);
- mProcess = launchJsonDbDaemon(JSONDB_DAEMON_BASE, QString("testjsondb_%1").arg(getpid()), arg_list);
-#endif
- mConnection = new QJsonDbConnection(this);
- connect(mConnection, SIGNAL(disconnected()), this, SLOT(disconnected()));
- connect(mConnection, SIGNAL(statusChanged(QtJsonDb::QJsonDbConnection::Status)),
- this, SLOT(statusChanged(QtJsonDb::QJsonDbConnection::Status)));
+ notifications = watcher.takeNotifications();
+ QCOMPARE(notifications.size(), 1);
+ QJsonDbNotification n = notifications[0];
+ QJsonObject o = n.object();
- connect(mConnection, SIGNAL(error(QtJsonDb::QJsonDbConnection::ErrorCode,QString)),
- this, SLOT(error(QtJsonDb::QJsonDbConnection::ErrorCode,QString)));
+ // make sure we got notified on the right object
+ QCOMPARE(o.value(JsonDbStrings::Property::uuid()), info.value(JsonDbStrings::Property::uuid()));
+ QCOMPARE(o.value(QLatin1String("create-test")).toDouble(), 22.);
- mConnection->connectToServer();
+ // we do now expect a tombstone
+ QVERIFY(o.contains(JsonDbStrings::Property::deleted()));
+ mConnection->removeWatcher(&watcher);
}
-void TestQJsonDbWatcher::cleanupTestCase()
+void TestQJsonDbWatcher::indexValue_data()
{
- if (mConnection) {
- delete mConnection;
- mConnection = NULL;
- }
+ QTest::addColumn<QString>("partition");
-#ifndef DONT_START_SERVER
- if (mProcess) {
- mProcess->close();
- delete mProcess;
- }
- removeDbFiles();
-#endif
+ QTest::newRow("persistent") << "";
+ QTest::newRow("ephemeral") << "Ephemeral";
}
-/*
- * Watch for an item creation
- */
-
-void TestQJsonDbWatcher::createAndRemove()
+void TestQJsonDbWatcher::indexValue()
{
QVERIFY(mConnection);
+ QFETCH(QString, partition);
+
+ // create an index
+ QJsonObject index;
+ index.insert(JsonDbStrings::Property::type(), QLatin1String("Index"));
+ index.insert(QLatin1String("name"), QLatin1String("create-test"));
+ index.insert(QLatin1String("propertyName"), QLatin1String("create-test"));
+ index.insert(QLatin1String("propertyType"), QLatin1String("string"));
+ index.insert(QLatin1String("objectType"), QLatin1String("com.test.qjsondbwatcher-test"));
+ QJsonDbCreateRequest create(index);
+ mConnection->send(&create);
+ waitForResponse(&create);
+ QList<QJsonObject> toDelete = create.takeResults();
// create a watcher
QJsonDbWatcher watcher;
watcher.setWatchedActions(QJsonDbWatcher::All);
- watcher.setQuery(QLatin1String("[?_type=\"com.test.qjsondbwatcher-test\"]"));
- connect(&watcher, SIGNAL(notificationsAvailable(int)),
- this, SLOT(onWatcherNotificationsAvailable(int)));
- connect(&watcher, SIGNAL(statusChanged(QtJsonDb::QJsonDbWatcher::Status)),
- this, SLOT(onWatcherStatusChanged(QtJsonDb::QJsonDbWatcher::Status)));
- connect(&watcher, SIGNAL(error(QtJsonDb::QJsonDbWatcher::ErrorCode,QString)), this, SLOT(onWatcherError(QtJsonDb::QJsonDbWatcher::ErrorCode,QString)));
+ watcher.setQuery(QLatin1String("[?_type=\"com.test.qjsondbwatcher-test\"][/create-test]"));
+ watcher.setPartition(partition);
mConnection->addWatcher(&watcher);
+ waitForStatus(&watcher, QJsonDbWatcher::Active);
QJsonObject item;
item.insert(JsonDbStrings::Property::type(), QLatin1String("com.test.qjsondbwatcher-test"));
- item.insert("create-test", 22);
+ item.insert(QLatin1String("create-test"), 22);
// Create an item
QJsonDbCreateRequest request(item);
- connect(&request, SIGNAL(finished()), this, SLOT(onRequestFinished()));
- connect(&request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
- this, SLOT(onRequestError(QtJsonDb::QJsonDbRequest::ErrorCode,QString)));
+ request.setPartition(partition);
mConnection->send(&request);
- waitForResponseAndNotification(&request, 1);
+ waitForResponseAndNotifications(&request, &watcher, 1);
QList<QJsonObject> results = request.takeResults();
QCOMPARE(results.size(), 1);
@@ -285,21 +243,34 @@ void TestQJsonDbWatcher::createAndRemove()
QList<QJsonDbNotification> notifications = watcher.takeNotifications();
QCOMPARE(notifications.size(), 1);
+ QJsonDbNotification n = notifications[0];
+ QJsonObject o = n.object();
+ // verify _indexValue was set unless partition was Ephemeral
+ if (partition != QLatin1String("Ephemeral")) {
+ QVERIFY(o.contains(QLatin1String("_indexValue")));
+ QCOMPARE(o.value(QLatin1String("_indexValue")), item.value(QLatin1String("create-test")));
+ }
// remove the object
QJsonDbRemoveRequest remove(item);
- connect(&remove, SIGNAL(finished()), this, SLOT(onRequestFinished()));
- connect(&remove, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
- this, SLOT(onRequestError(QtJsonDb::QJsonDbRequest::ErrorCode,QString)));
+ remove.setPartition(partition);
mConnection->send(&remove);
- waitForResponseAndNotification(&remove, 1);
+ waitForResponseAndNotifications(&remove, &watcher, 1);
notifications = watcher.takeNotifications();
QCOMPARE(notifications.size(), 1);
- QJsonDbNotification n = notifications[0];
- QJsonObject o = n.object();
+ n = notifications[0];
+ o = n.object();
+
// make sure we got notified on the right object
QCOMPARE(o.value(JsonDbStrings::Property::uuid()), info.value(JsonDbStrings::Property::uuid()));
+ QCOMPARE(o.value(QLatin1String("create-test")).toDouble(), 22.);
+
+ // verify the index value was set unless partition was Ephemeral
+ if (partition != QLatin1String("Ephemeral")) {
+ QVERIFY(o.contains(QLatin1String("_indexValue")));
+ QCOMPARE(o.value(QLatin1String("_indexValue")), item.value(QLatin1String("create-test")));
+ }
// we do now expect a tombstone
QVERIFY(o.contains(JsonDbStrings::Property::deleted()));
@@ -311,7 +282,7 @@ void TestQJsonDbWatcher::history()
{
QVERIFY(mConnection);
- QFile dataFile(":/daemon/json/largeContactsTest.json");
+ QFile dataFile(":/partition/json/largeContactsTest.json");
QVERIFY(dataFile.exists());
dataFile.open(QIODevice::ReadOnly);
QByteArray json = dataFile.readAll();
@@ -322,21 +293,14 @@ void TestQJsonDbWatcher::history()
QJsonArray array = doc.array();
// make a request and connect it
quint32 firstStateNumber = 0;
- quint32 lastStateNumber = 0;
// pass the empty object list to make the constructor happy
QList<QJsonObject> objects;
QJsonDbCreateRequest request(objects);
- connect(&request, SIGNAL(finished()), this, SLOT(onRequestFinished()));
- connect(&request, SIGNAL(statusChanged(QtJsonDb::QJsonDbRequest::Status)),
- this, SLOT(onRequestStatusChanged(QtJsonDb::QJsonDbRequest::Status)));
- connect(&request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
- this, SLOT(onRequestError(QtJsonDb::QJsonDbRequest::ErrorCode,QString)));
for (int i = 0; i < qMin(100, array.size()); i++) {
QJsonObject item = array.at(i).toObject();
- // why does QJsonDbCreate request require me to set the Uuid? /me thinks it's a bug
item.insert(JsonDbStrings::Property::uuid(), QUuid::createUuid().toString());
item.insert(JsonDbStrings::Property::type(), QLatin1String("com.test.qjsondbwatcher-test"));
objects.append(item);
@@ -345,10 +309,9 @@ void TestQJsonDbWatcher::history()
// Create the item
mConnection->send(&request);
- waitForResponseAndNotification(&request, 0);
+ waitForResponse(&request);
if (!firstStateNumber)
firstStateNumber = request.stateNumber();
- lastStateNumber = request.stateNumber();
}
QVERIFY(firstStateNumber);
@@ -356,27 +319,22 @@ void TestQJsonDbWatcher::history()
QJsonDbWatcher watcher;
watcher.setWatchedActions(QJsonDbWatcher::All);
watcher.setQuery(QLatin1String("[?_type=\"com.test.qjsondbwatcher-test\"]"));
- connect(&watcher, SIGNAL(notificationsAvailable(int)),
- this, SLOT(onWatcherNotificationsAvailable(int)));
- connect(&watcher, SIGNAL(statusChanged(QtJsonDb::QJsonDbWatcher::Status)),
- this, SLOT(onWatcherStatusChanged(QtJsonDb::QJsonDbWatcher::Status)));
- connect(&watcher, SIGNAL(error(QtJsonDb::QJsonDbWatcher::ErrorCode,QString)), this, SLOT(onWatcherError(QtJsonDb::QJsonDbWatcher::ErrorCode,QString)));
// set the starting state
watcher.setInitialStateNumber(firstStateNumber-1);
mConnection->addWatcher(&watcher);
- // expecting one notification per create and one state change
- waitForResponseAndNotification(0, objects.size()+1);
- waitForWatcherStatus(watcher, QJsonDbWatcher::Active);
+ // expecting one notification per create
+ waitForResponseAndNotifications(0, &watcher, objects.size());
+ waitForStatus(&watcher, QJsonDbWatcher::Active);
QList<QJsonDbNotification> notifications = watcher.takeNotifications();
- QCOMPARE(notifications.size(), objects.size()+1);
+ QCOMPARE(notifications.size(), objects.size());
// we received one Create notification per object
- foreach (const QJsonDbNotification n, notifications.mid(0, objects.size()))
+ foreach (const QJsonDbNotification n, notifications.mid(0, objects.size())) {
QCOMPARE(n.action(), QJsonDbWatcher::Created);
- // we received one StateChanged notification
- QCOMPARE(notifications.at(objects.size()).action(), QJsonDbWatcher::StateChanged);
+ QVERIFY(n.stateNumber() >= firstStateNumber);
+ }
mConnection->removeWatcher(&watcher);
@@ -384,81 +342,77 @@ void TestQJsonDbWatcher::history()
QJsonDbWatcher watcher2;
watcher2.setWatchedActions(QJsonDbWatcher::All);
watcher2.setQuery(QLatin1String("[?_type=\"com.test.qjsondbwatcher-test\"]"));
- connect(&watcher2, SIGNAL(notificationsAvailable(int)),
- this, SLOT(onWatcherNotificationsAvailable(int)));
- connect(&watcher2, SIGNAL(statusChanged(QtJsonDb::QJsonDbWatcher::Status)),
- this, SLOT(onWatcherStatusChanged(QtJsonDb::QJsonDbWatcher::Status)));
- connect(&watcher2, SIGNAL(error(QtJsonDb::QJsonDbWatcher::ErrorCode,QString)), this, SLOT(onWatcherError(QtJsonDb::QJsonDbWatcher::ErrorCode,QString)));
- watcher2.setInitialStateNumber(-1);
+ watcher2.setInitialStateNumber(0);
mConnection->addWatcher(&watcher2);
- waitForResponseAndNotification(0, objects.size() + 1);
- waitForWatcherStatus(watcher2, QJsonDbWatcher::Active);
+ waitForResponseAndNotifications(0, &watcher2, objects.size());
QList<QJsonDbNotification> notifications2 = watcher2.takeNotifications();
- QCOMPARE(notifications2.size(), objects.size()+1);
+ QCOMPARE(notifications2.size(), objects.size());
// we received one Create notification per object
foreach (const QJsonDbNotification n, notifications2.mid(0, objects.size()))
QCOMPARE(n.action(), QJsonDbWatcher::Created);
- // we received one StateChanged notification
- QCOMPARE(notifications2.at(objects.size()).action(), QJsonDbWatcher::StateChanged);
+ // create another one
+ {
+ QJsonObject item;
+ item.insert(JsonDbStrings::Property::uuid(), QUuid::createUuid().toString());
+ item.insert(JsonDbStrings::Property::type(), QLatin1String("com.test.qjsondbwatcher-test"));
+ item.insert("another one", true);
+ QJsonDbCreateRequest request(item);
+ mConnection->send(&request);
+ // wait for response from request, one create notification
+ waitForResponseAndNotifications(&request, &watcher2, 1);
+ }
mConnection->removeWatcher(&watcher2);
+
+ QJsonDbRemoveRequest remove(objects);
+ mConnection->send(&remove);
+ waitForResponse(&remove);
}
+
void TestQJsonDbWatcher::currentState()
{
QJsonDbWatcher watcher;
watcher.setWatchedActions(QJsonDbWatcher::All);
watcher.setQuery(QLatin1String("[?_type=\"com.test.qjsondbwatcher-test\"]"));
- connect(&watcher, SIGNAL(notificationsAvailable(int)),
- this, SLOT(onWatcherNotificationsAvailable(int)));
- connect(&watcher, SIGNAL(statusChanged(QtJsonDb::QJsonDbWatcher::Status)),
- this, SLOT(onWatcherStatusChanged(QtJsonDb::QJsonDbWatcher::Status)));
- connect(&watcher, SIGNAL(error(QtJsonDb::QJsonDbWatcher::ErrorCode,QString)), this, SLOT(onWatcherError(QtJsonDb::QJsonDbWatcher::ErrorCode,QString)));
-
- // set the starting state to -1 to get the current state
- watcher.setInitialStateNumber(static_cast<quint32>(-1));
+
+ // set the starting state to 0 to get the current state
+ watcher.setInitialStateNumber(0);
mConnection->addWatcher(&watcher);
- // expecting one notification per create and one state change
- bool stateChanged = false;
- while (!stateChanged) {
- // wait for a notification
- waitForResponseAndNotification(0, 1);
- QList<QJsonDbNotification> notifications = watcher.takeNotifications();
- foreach (const QJsonDbNotification n, notifications)
- if (n.action() == QJsonDbWatcher::StateChanged)
- stateChanged = true;
- }
+ // expecting one notification per create
+ waitForResponseAndNotifications(0, &watcher, 1, 1);
+ watcher.takeNotifications();
// now create another object
- {
- QJsonObject item;
- item.insert(JsonDbStrings::Property::type(), QLatin1String("com.test.qjsondbwatcher-test"));
- item.insert("create-test", 22);
+ QJsonObject item;
+ item.insert(JsonDbStrings::Property::type(), QLatin1String("com.test.qjsondbwatcher-test"));
+ item.insert("create-test", 22);
+
+ // Create an item
+ QJsonDbCreateRequest request(item);
+ mConnection->send(&request);
+ waitForResponseAndNotifications(&request, &watcher, 1);
- // Create an item
- QJsonDbCreateRequest request(item);
- connect(&request, SIGNAL(finished()), this, SLOT(onRequestFinished()));
- connect(&request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
- this, SLOT(onRequestError(QtJsonDb::QJsonDbRequest::ErrorCode,QString)));
- mConnection->send(&request);
- waitForResponseAndNotification(&request, 1);
- }
QList<QJsonDbNotification> notifications = watcher.takeNotifications();
QCOMPARE(notifications.size(), 1);
mConnection->removeWatcher(&watcher);
+
+ QJsonDbRemoveRequest remove(request.takeResults());
+ mConnection->send(&remove);
+ waitForResponse(&remove);
}
void TestQJsonDbWatcher::notificationTriggersView()
{
QVERIFY(mConnection);
- QJsonParseError error;
- QJsonArray array(readJsonFile(":/daemon/json/map-array-conversion.json", &error).array());
- QVERIFY(error.error == QJsonParseError::NoError);
+ QLatin1String query("[?_type=\"com.test.TestView\"]");
+ QJsonArray array(readJsonFile(":/partition/json/map-array-conversion.json").array());
+
QList<QJsonObject> objects;
foreach (const QJsonValue v, array)
objects.append(v.toObject());
@@ -468,32 +422,215 @@ void TestQJsonDbWatcher::notificationTriggersView()
// create the objects
QJsonDbCreateRequest request(objects);
- connect(&request, SIGNAL(finished()), this, SLOT(onRequestFinished()));
- connect(&request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
- this, SLOT(onRequestError(QtJsonDb::QJsonDbRequest::ErrorCode,QString)));
mConnection->send(&request);
- waitForResponseAndNotification(&request, 0);
+ waitForResponse(&request);
+ QList<QJsonObject> toDelete;
+ foreach (const QJsonObject result, request.takeResults())
+ toDelete.prepend(result);
+
+ {
+ QJsonDbReadRequest read(query);
+ mConnection->send(&read);
+ waitForResponse(&read);
+ QList<QJsonObject> objects = read.takeResults();
+ int numObjects = objects.size();
+ QCOMPARE(numObjects, 1);
+ }
+
+ // create a watcher
+ QJsonDbWatcher watcher;
+ watcher.setWatchedActions(QJsonDbWatcher::All);
+ watcher.setQuery(QLatin1String(query));
+ mConnection->addWatcher(&watcher);
+ waitForStatus(&watcher, QJsonDbWatcher::Active);
+
+ {
+ QJsonObject item;
+ item.insert(JsonDbStrings::Property::type(), QLatin1String("com.test.Test"));
+ QJsonDbCreateRequest request(item);
+ mConnection->send(&request);
+ waitForResponseAndNotifications(&request, &watcher, 1);
+
+ QList<QJsonDbNotification> notifications = watcher.takeNotifications();
+ QCOMPARE(notifications.size(), 1);
+ QJsonDbNotification n = notifications[0];
+ QJsonObject o = n.object();
+ // make sure we got notified on the right object
+ //QCOMPARE(o.value(JsonDbStrings::Property::uuid()), info.value(JsonDbStrings::Property::uuid()));
+ }
+ mConnection->removeWatcher(&watcher);
+
+ foreach (const QJsonObject &object, request.takeResults())
+ toDelete.prepend(object);
+
+ QJsonDbRemoveRequest remove(toDelete);
+ mConnection->send(&remove);
+ waitForResponse(&remove);
+}
+
+void TestQJsonDbWatcher::notificationTriggersMapReduce()
+{
+ QVERIFY(mConnection);
+
+ QJsonParseError error;
+ QJsonArray array(readJsonFile(":/partition/json/map-reduce.json", &error).array());
+ QVERIFY(error.error == QJsonParseError::NoError);
+ QList<QJsonObject> objects;
+ foreach (const QJsonValue v, array)
+ objects.append(v.toObject());
+
+ // create the objects
+ QJsonDbCreateRequest request(objects);
+ mConnection->send(&request);
+ waitForResponse(&request);
+ QList<QJsonObject> toDelete;
+ foreach (const QJsonObject result, request.takeResults())
+ toDelete.prepend(result);
+
+ QString query = QLatin1String("[?_type=\"PhoneCount\"]");
+
+ {
+ QJsonDbReadRequest read(query);
+ mConnection->send(&read);
+ waitForResponse(&read);
+ int numObjects = read.takeResults().size();
+ QCOMPARE(numObjects, 5);
+ }
+
+ {
+ const char json[] = "{\"_type\":\"Contact\",\"displayName\":\"Will Robinson\",\"phoneNumbers\":[{\"type\":\"satellite\",\"number\":\"+614159\"}]}";
+ QJsonObject object(QJsonDocument::fromJson(json).object());
+
+ QJsonDbCreateRequest write(object);
+ mConnection->send(&write);
+ waitForResponse(&write);
+ }
+
+ // create a watcher
+ QJsonDbWatcher watcher;
+ watcher.setWatchedActions(QJsonDbWatcher::All);
+ watcher.setQuery(query);
+ mConnection->addWatcher(&watcher);
+
+ waitForResponseAndNotifications(0, &watcher, 1);
+ int numNotifications = watcher.takeNotifications().size();
+ QCOMPARE(numNotifications, 1);
+
+ {
+ QJsonDbReadRequest read(query);
+ mConnection->send(&read);
+ waitForResponse(&read);
+
+ QList<QJsonObject> results = read.takeResults();
+ QCOMPARE(results.size(), 6);
+ }
+
+ // now write another one
+ {
+ const char json[] = "{\"_type\":\"Contact\",\"displayName\":\"Jeffrey Goines\",\"phoneNumbers\":[{\"type\":\"satellite\",\"number\":\"+2718281828\"}]}";
+ QJsonObject object(QJsonDocument::fromJson(json).object());
+
+ QJsonDbCreateRequest write(object);
+ mConnection->send(&write);
+ waitForResponseAndNotifications(&write, &watcher, 1);
+
+ int numNotifications = watcher.takeNotifications().size();
+ QCOMPARE(numNotifications, 1);
+ }
+
+ mConnection->removeWatcher(&watcher);
+ {
+ QJsonDbReadRequest read("[?_type=\"Contact\"]");
+ mConnection->send(&read);
+ waitForResponse(&read);
+ QJsonDbRemoveRequest remove(read.takeResults());
+ mConnection->send(&remove);
+ waitForResponse(&remove);
+ }
+
+ QJsonDbRemoveRequest remove(toDelete);
+ mConnection->send(&remove);
+ waitForResponse(&remove);
+}
+
+void TestQJsonDbWatcher::typeChangeEagerViewSource()
+{
+ QVERIFY(mConnection);
+
+ QJsonParseError error;
+ QJsonArray array(readJsonFile(":/partition/json/map-reduce.json", &error).array());
+ QVERIFY(error.error == QJsonParseError::NoError);
+ QList<QJsonObject> objects;
+ foreach (const QJsonValue v, array)
+ objects.append(v.toObject());
+
+ // create the objects
+ QJsonDbCreateRequest request(objects);
+ mConnection->send(&request);
+ waitForResponse(&request);
+ QList<QJsonObject> toDelete;
+ foreach (const QJsonObject result, request.takeResults())
+ toDelete.prepend(result);
+
+ QString query = QLatin1String("[?_type=\"PhoneCount\"]");
+
+ // verify that we get what we expect
+ {
+ QJsonDbReadRequest read(query);
+ mConnection->send(&read);
+ waitForResponse(&read);
+ int numObjects = read.takeResults().size();
+ QCOMPARE(numObjects, 5);
+ }
+
+ // create an object that's not of the source type of the view
+ const char json[] = "{\"_type\":\"not.a.Contact\",\"displayName\":\"Will Robinson\",\"phoneNumbers\":[{\"type\":\"satellite\",\"number\":\"+614159\"}]}";
+ QJsonDbObject object(QJsonDocument::fromJson(json).object());
+ object.setUuid(QJsonDbObject::createUuidFromString("typeChangeEagerViewSource"));
+
+ QJsonDbWriteRequest write;
+ write.setObjects(QList<QJsonObject>() << object);
+ mConnection->send(&write);
+ waitForResponse(&write);
+
+ // verify that the view didn't change
+ {
+ QJsonDbReadRequest read(query);
+ mConnection->send(&read);
+ waitForResponse(&read);
+ int numObjects = read.takeResults().size();
+ QCOMPARE(numObjects, 5);
+ }
// create a watcher
QJsonDbWatcher watcher;
watcher.setWatchedActions(QJsonDbWatcher::All);
- watcher.setQuery(QLatin1String("[?_type=\"com.test.TestView\"]"));
- connect(&watcher, SIGNAL(notificationsAvailable(int)),
- this, SLOT(onWatcherNotificationsAvailable(int)));
- connect(&watcher, SIGNAL(statusChanged(QtJsonDb::QJsonDbWatcher::Status)),
- this, SLOT(onWatcherStatusChanged(QtJsonDb::QJsonDbWatcher::Status)));
- connect(&watcher, SIGNAL(error(int,QString)), this, SLOT(onWatcherError(int,QString)));
+ watcher.setQuery(query);
mConnection->addWatcher(&watcher);
- waitForResponseAndNotification(0, 1);
+ waitForStatus(&watcher, QJsonDbWatcher::Active);
+ // change the object so that it's now a source type of the view
+ object.insert(QLatin1String("_type"), QLatin1String("Contact"));
+ write.setObjects(QList<QJsonObject>() << object);
+ mConnection->send(&write);
+ waitForResponseAndNotifications(&write, &watcher, 1);
QList<QJsonDbNotification> notifications = watcher.takeNotifications();
- QCOMPARE(notifications.size(), 1);
- QJsonDbNotification n = notifications[0];
- QJsonObject o = n.object();
- // make sure we got notified on the right object
- //QCOMPARE(o.value(JsonDbStrings::Property::uuid()), info.value(JsonDbStrings::Property::uuid()));
+ QCOMPARE(notifications.count(), 1);
+ QCOMPARE(notifications[0].action(), QJsonDbWatcher::Created);
+
+ // change it back, which should result in a remove notification
+ object.insert(QLatin1String("_type"), QLatin1String("not.a.Contact"));
+ write.setObjects(QList<QJsonObject>() << object);
+ mConnection->send(&write);
+ waitForResponseAndNotifications(&write, &watcher, 1);
+ notifications = watcher.takeNotifications();
+ QCOMPARE(notifications.count(), 1);
+ QCOMPARE(notifications[0].action(), QJsonDbWatcher::Removed);
mConnection->removeWatcher(&watcher);
+ QJsonDbRemoveRequest remove(toDelete);
+ mConnection->send(&remove);
+ waitForResponse(&remove);
}
QTEST_MAIN(TestQJsonDbWatcher)
diff --git a/tests/auto/queries/queries.pro b/tests/auto/queries/queries.pro
index 620406bc..7a3a89ac 100644
--- a/tests/auto/queries/queries.pro
+++ b/tests/auto/queries/queries.pro
@@ -1,16 +1,13 @@
TARGET = tst_queries
-QT = network qml testlib
+QT = network qml testlib jsondbpartition
CONFIG -= app_bundle
CONFIG += testcase
-INCLUDEPATH += $$PWD/../../../src/daemon
LIBS += -L$$QT.jsondb.libs
DEFINES += SRCDIR=\\\"$$PWD/\\\"
-include($$PWD/../../../src/daemon/daemon.pri)
-
RESOURCES = queries.qrc
SOURCES += \
diff --git a/tests/auto/queries/testjsondbqueries.cpp b/tests/auto/queries/testjsondbqueries.cpp
index d5218b6d..3e9837c8 100644
--- a/tests/auto/queries/testjsondbqueries.cpp
+++ b/tests/auto/queries/testjsondbqueries.cpp
@@ -48,12 +48,11 @@
#include <QTime>
#include <QUuid>
-#include "json.h"
#include "jsondbowner.h"
#include "jsondbpartition.h"
#include "jsondbquery.h"
-#include "jsondb-strings.h"
-#include "jsondb-error.h"
+#include "jsondbstrings.h"
+#include "jsondberrors.h"
#include "../../shared/util.h"
@@ -71,7 +70,7 @@
__result.error.toObject().value("message").toString().toLocal8Bit()); \
}
-QT_USE_NAMESPACE_JSONDB
+QT_USE_NAMESPACE_JSONDB_PARTITION
class TestJsonDbQueries: public QObject
{
@@ -100,6 +99,7 @@ private slots:
void querySortedByIndexName();
void queryContains();
void queryInvalid();
+ void queryRegExp();
private:
void removeDbFiles();
@@ -199,7 +199,8 @@ void TestJsonDbQueries::removeDbFiles()
JsonDbQueryResult TestJsonDbQueries::find(JsonDbOwner *owner, const QString &query, const QJsonObject bindings)
{
- return mJsonDbPartition->queryObjects(owner, JsonDbQuery::parse(query, bindings));
+ QScopedPointer<JsonDbQuery> parsedQuery(JsonDbQuery::parse(query, bindings));
+ return mJsonDbPartition->queryObjects(owner, parsedQuery.data());
}
void TestJsonDbQueries::initTestCase()
@@ -216,15 +217,7 @@ void TestJsonDbQueries::initTestCase()
mJsonDbPartition = new JsonDbPartition(kFilename, QStringLiteral("com.example.JsonDbTestQueries"), mOwner, this);
mJsonDbPartition->open();
- QFile contactsFile(":/queries/dataset.json");
- QVERIFY2(contactsFile.exists(), "Err: dataset.json doesn't exist!");
-
- contactsFile.open(QIODevice::ReadOnly);
- QByteArray json = contactsFile.readAll();
- JsonReader parser;
- bool ok = parser.parse(json);
- QVERIFY2(ok, parser.errorString().toAscii());
- QVariantList contactList = parser.result().toList();
+ QVariantList contactList = readJsonFile(":/queries/dataset.json").toArray().toVariantList();
foreach (QVariant v, contactList) {
JsonDbObject object(QJsonObject::fromVariantMap(v.toMap()));
QString type = object.value("_type").toString();
@@ -381,14 +374,20 @@ void TestJsonDbQueries::queryQuotedProperties()
QVERIFY(confirmEachObject(queryResult.data, CheckObjectFieldEqualTo<QString>("_type", "dragon")));
queryResult = find(mOwner, QLatin1String("[?_type = \"dragon\"][?\"eye-color\" = \"red\"][= \"eye-color\"]"));
- // single values are returned in queryResult.values
- QCOMPARE(queryResult.values.size(), mDataStats["num-red-eyes"].toInt());
- QCOMPARE(queryResult.values.at(0).toString(), QString("red"));
-
- queryResult = find(mOwner, QLatin1String("[?\"eye-color\" = \"red\"][= [\"eye-color\", age ]]"));
- // array values are returned in queryResult.values
- QCOMPARE(queryResult.values.size(), mDataStats["num-red-eyes"].toInt());
- QCOMPARE(queryResult.values.at(0).toArray().at(0).toString(), QString("red"));
+ // no longer supported
+ QCOMPARE(queryResult.data.size(), 0);
+ QVERIFY(queryResult.error.isObject());
+ QVERIFY(queryResult.error.toObject().contains(QLatin1String("code")));
+ QCOMPARE((int)queryResult.error.toObject().value(QLatin1String("code")).toDouble(),
+ (int)JsonDbError::MissingQuery);
+
+ queryResult = find(mOwner, QLatin1String("[?\"eye-color\" = \"red\"][= [\"eye-color\", age ]]"));
+ // no longer supported
+ QCOMPARE(queryResult.data.size(), 0);
+ QVERIFY(queryResult.error.isObject());
+ QVERIFY(queryResult.error.toObject().contains(QLatin1String("code")));
+ QCOMPARE((int)queryResult.error.toObject().value(QLatin1String("code")).toDouble(),
+ (int)JsonDbError::MissingQuery);
queryResult = find(mOwner, QLatin1String("[?_type=\"dragon\"][/_type][?\"eye-color\" = \"red\"][= {\"color-of-eyes\": \"eye-color\" }]"));
// object values are returned in queryResult.data
@@ -455,5 +454,18 @@ void TestJsonDbQueries::queryInvalid()
QVERIFY(!queryResult.error.isNull());
}
+void TestJsonDbQueries::queryRegExp()
+{
+ JsonDbQueryResult queryResult = find(mOwner, QLatin1String("[?_type = \"dog\"][?name =~ \"/*ov*/w\" ]"));
+ QVERIFY(queryResult.error.isNull());
+ QCOMPARE(queryResult.data.count(), 1);
+
+ QJsonObject bindings;
+ bindings.insert(QLatin1String("regexp"), QLatin1String("/*ov*/w"));
+ queryResult = find(mOwner, QLatin1String("[?_type = \"dog\"][?name =~ %regexp ]"), bindings);
+ QVERIFY(queryResult.error.isNull());
+ QCOMPARE(queryResult.data.count(), 1);
+}
+
QTEST_MAIN(TestJsonDbQueries)
#include "testjsondbqueries.moc"
diff --git a/tests/auto/tests.xml b/tests/auto/tests.xml
index 56c2a6bf..fc9061e6 100644
--- a/tests/auto/tests.xml
+++ b/tests/auto/tests.xml
@@ -1,14 +1,14 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<testdefinition version="0.1">
<suite domain="Functional" name="jsondb-autotests" timeout="2000">
- <set description=" Simple JSON DB auto tests " feature="JSONDB" level="System" name="jsondb-autotests" type="Functional" timeout="2000">
+ <set description=" Simple JSON DB auto tests " feature="JSONDB" level="Auto" name="jsondb-autotests" type="Functional" timeout="2000">
<case name="tst_client" requirement="BAT,CST" component="qt5jsondb" timeout="100">
<description>Client library tests: C++ APIs testcases.</description>
<step>cd /usr/lib/qt5jsondb-tests/auto/client;date &amp;&amp; ./tst_client&amp;&amp; date</step>
</case>
- <case name="tst_daemon" requirement="BAT" component="qt5jsondb" timeout="2000">
- <description> JsonDb daemon tests: This testcase tests server behavior.</description>
- <step>cd /usr/lib/qt5jsondb-tests/auto/daemon;date &amp;&amp; ./tst_daemon &amp;&amp; date</step>
+ <case name="tst_partition" requirement="BAT" component="qt5jsondb" timeout="2000">
+ <description> JsonDb partition tests: This testcase tests server behavior.</description>
+ <step>cd /usr/lib/qt5jsondb-tests/auto/partition;date &amp;&amp; ./tst_partition &amp;&amp; date</step>
</case>
<case name="tst_accesscontrol" requirement="BAT,CST" type="Security" component="qt5jsondb" timeout="600">
<description> JsonDb security tests</description>
@@ -42,6 +42,18 @@
<description>Btree tests</description>
<step>cd /usr/lib/qt5jsondb-tests/auto/qbtree;date &amp;&amp; ./tst_qbtree&amp;&amp; date</step>
</case>
+ <case name="tst_qjsondbrequest" component="qt5jsondb" timeout="600">
+ <description>QJsonDbRequest Class tests</description>
+ <step>cd /usr/lib/qt5jsondb-tests/auto/qjsondbrequest;date &amp;&amp; ./tst_qjsondbrequest &amp;&amp; date</step>
+ </case>
+ <case name="tst_qjsondbflushrequest" component="qt5jsondb" timeout="600">
+ <description>QJsonDbFlushRequest Class tests</description>
+ <step>cd /usr/lib/qt5jsondb-tests/auto/qjsondbflushrequest;date &amp;&amp; ./tst_qjsondbflushrequest &amp;&amp; date</step>
+ </case>
+ <case name="tst_qjsondbwatcher" component="qt5jsondb" timeout="600">
+ <description>QJsonDbWatcher Class tests</description>
+ <step>cd /usr/lib/qt5jsondb-tests/auto/qjsondbwatcher;date &amp;&amp; ./tst_qjsondbwatcher &amp;&amp; date</step>
+ </case>
</set>
</suite>
</testdefinition>
diff --git a/tests/benchmarks/benchmarks.pro b/tests/benchmarks/benchmarks.pro
index 4e840fea..298d99d7 100644
--- a/tests/benchmarks/benchmarks.pro
+++ b/tests/benchmarks/benchmarks.pro
@@ -1,2 +1,2 @@
TEMPLATE = subdirs
-SUBDIRS += daemon jsondb-listmodel client jsondbcachinglistmodel jsondbsortinglistmodel btrees
+SUBDIRS += partition client jsondbcachinglistmodel jsondbsortinglistmodel btrees
diff --git a/tests/benchmarks/client/client-benchmark.cpp b/tests/benchmarks/client/client-benchmark.cpp
index 4134d907..fc8e0b75 100644
--- a/tests/benchmarks/client/client-benchmark.cpp
+++ b/tests/benchmarks/client/client-benchmark.cpp
@@ -42,7 +42,6 @@
#include <QtTest/QtTest>
#include "client-benchmark.h"
#include "private/jsondb-connection_p.h"
-#include <json.h>
#include "util.h"
@@ -93,20 +92,17 @@ void TestJson::initTestCase()
#ifndef DONT_START_SERVER
removeDbFiles();
QString socketName = QString("testjsondb_%1").arg(getpid());
- mProcess = launchJsonDbDaemon(JSONDB_DAEMON_BASE, socketName, QStringList() << "-base-name" << dbfile);
+ mProcess = launchJsonDbDaemon(JSONDB_DAEMON_BASE, socketName, QStringList() << "-base-name" << dbfile, __FILE__);
#endif
connectToServer();
QByteArray friendJson("{\"type\": \"object\", \"properties\": {\"name\": {\"type\": \"string\", \"indexed\": true}}}");
- JsonReader reader;
-
// Create schemas for the items
- reader.parse(friendJson);
QVariantMap friendSchema;
friendSchema.insert("name", "Friends");
- friendSchema.insert("schema", reader.result());
+ friendSchema.insert("schema", QJsonDocument::fromJson(friendJson).object().toVariantMap());
friendSchema.insert("_type", "_schemaType");
int id = mClient->create(friendSchema);
waitForResponse1(id);
@@ -271,7 +267,6 @@ void TestJson::queryThousandItems_data()
{
QTest::addColumn<QString>("queryString");
QTest::newRow("Friends") << QString("[?_type=\"Friends\"]");
- QTest::newRow("Friends[=_uuid]") << QString("[?_type=\"Friends\"][=_uuid]");
QTest::newRow("Friends[={_uuid:_uuid}]") << QString("[?_type=\"Friends\"][={_uuid:_uuid}]");
}
diff --git a/tests/benchmarks/client/client.pro b/tests/benchmarks/client/client.pro
index 0ae1dd8a..44c55ad0 100644
--- a/tests/benchmarks/client/client.pro
+++ b/tests/benchmarks/client/client.pro
@@ -5,10 +5,6 @@ QT = core network testlib jsondb jsondbcompat-private
DEFINES += JSONDB_DAEMON_BASE=\\\"$$QT.jsondb.bins\\\"
-INCLUDEPATH += "../../../src/common"
-INCLUDEPATH += "../../../src/3rdparty/qjson/src"
-SOURCES += ../../../src/3rdparty/qjson/src/json.cpp
-
CONFIG += qtestlib
CONFIG -= app_bundle
diff --git a/tests/benchmarks/daemon/daemon.pro b/tests/benchmarks/daemon/daemon.pro
deleted file mode 100644
index a76caafa..00000000
--- a/tests/benchmarks/daemon/daemon.pro
+++ /dev/null
@@ -1,14 +0,0 @@
-TARGET = tst_bench_daemon
-
-QT = network qml testlib
-CONFIG -= app_bundle
-CONFIG += testcase
-
-INCLUDEPATH += $$PWD/../../../src/daemon
-LIBS += -L$$QT.jsondb.libs
-
-DEFINES += SRCDIR=\\\"$$PWD/\\\"
-include($$PWD/../../../src/daemon/daemon.pri)
-RESOURCES+=../../json.qrc daemon.qrc
-SOURCES += \
- bench_daemon.cpp \
diff --git a/tests/benchmarks/daemon/daemon.qrc b/tests/benchmarks/daemon/daemon.qrc
deleted file mode 100644
index 8e10790c..00000000
--- a/tests/benchmarks/daemon/daemon.qrc
+++ /dev/null
@@ -1,6 +0,0 @@
-<RCC>
- <qresource prefix="/daemon">
- <file alias="json">../../auto/daemon/json</file>
- <file alias="schemas">../../auto/daemon/schemas</file>
- </qresource>
-</RCC>
diff --git a/tests/benchmarks/jsondb-listmodel/jsondb-listmodel.pro b/tests/benchmarks/jsondb-listmodel/jsondb-listmodel.pro
deleted file mode 100644
index 3a8098f8..00000000
--- a/tests/benchmarks/jsondb-listmodel/jsondb-listmodel.pro
+++ /dev/null
@@ -1,17 +0,0 @@
-TEMPLATE = app
-TARGET = tst_bench_listmodel
-
-QT = core network testlib gui qml jsondbcompat-private
-CONFIG -= app_bundle
-
-include($$PWD/../../shared/shared.pri)
-include($$PWD/../../../src/3rdparty/qjson/qjson.pri)
-
-DEFINES += JSONDB_DAEMON_BASE=\\\"$$QT.jsondb.bins\\\"
-
-INCLUDEPATH += $$PWD/../../../src/imports/jsondb-listmodel
-HEADERS += $$PWD/../../../src/imports/jsondb-listmodel/jsondb-listmodel.h
-SOURCES += $$PWD/../../../src/imports/jsondb-listmodel/jsondb-listmodel.cpp
-
-HEADERS += listmodel-benchmark.h
-SOURCES += listmodel-benchmark.cpp
diff --git a/tests/benchmarks/jsondb-listmodel/listmodel-benchmark.cpp b/tests/benchmarks/jsondb-listmodel/listmodel-benchmark.cpp
deleted file mode 100644
index a0eb763a..00000000
--- a/tests/benchmarks/jsondb-listmodel/listmodel-benchmark.cpp
+++ /dev/null
@@ -1,564 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-#include <QJSEngine>
-#include "listmodel-benchmark.h"
-
-#include "../../shared/util.h"
-#include <QQmlEngine>
-#include <QQmlComponent>
-#include <QQmlContext>
-
-static const char dbfile[] = "dbFile-test-jsondb";
-ModelData::ModelData(): engine(0), component(0), model(0)
-{
-}
-
-ModelData::~ModelData()
-{
- if (model)
- delete model;
- if (component)
- delete component;
- if (engine)
- delete engine;
-}
-
-TestListModel::TestListModel()
- : mProcess(0)
-{
-}
-
-TestListModel::~TestListModel()
-{
-}
-
-void TestListModel::connectListModel(JsonDbListModel *model)
-{
- connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this , SLOT(dataChanged(QModelIndex,QModelIndex)));
- connect(model, SIGNAL(modelReset()), this, SLOT(modelReset()));
- connect(model, SIGNAL(layoutChanged()), this, SLOT(layoutChanged()));
- connect(model, SIGNAL(rowsInserted(QModelIndex, int, int)), this, SLOT(rowsInserted(QModelIndex, int, int)));
- connect(model, SIGNAL(rowsRemoved(QModelIndex, int, int)), this, SLOT(rowsRemoved(QModelIndex, int, int)));
- connect(model, SIGNAL(rowsMoved(QModelIndex, int, int, QModelIndex, int)), this, SLOT(rowsMoved(QModelIndex, int, int, QModelIndex, int)));
-}
-
-void TestListModel::deleteDbFiles()
-{
- // remove all the test files.
- QDir currentDir;
- QStringList nameFilter;
- nameFilter << QString("*.db");
- QFileInfoList databaseFiles = currentDir.entryInfoList(nameFilter, QDir::Files);
- foreach (QFileInfo fileInfo, databaseFiles) {
- //qDebug() << "Deleted : " << fileInfo.fileName();
- QFile file(fileInfo.fileName());
- file.remove();
- }
-}
-
-void TestListModel::initTestCase()
-{
- // make sure there is no old db files.
- deleteDbFiles();
-
- QString socketName = QString("testjsondb_%1").arg(getpid());
- mProcess = launchJsonDbDaemon(JSONDB_DAEMON_BASE, socketName, QStringList() << "-base-name" << dbfile);
-
- mClient = new JsonDbClient(this);
- QVERIFY(mClient!= 0);
- connectToServer();
-
- QQmlEngine *engine = new QQmlEngine();
- QStringList pluginPaths = engine->importPathList();
- for (int i=0; (i<pluginPaths.count() && mPluginPath.isEmpty()); i++) {
- QDir dir(pluginPaths[i]+"/QtAddOn/JsonDb");
- dir.setFilter(QDir::Files | QDir::NoSymLinks);
- QFileInfoList list = dir.entryInfoList();
- for (int i = 0; i < list.size(); ++i) {
- QString error;
- if (engine->importPlugin(list.at(i).absoluteFilePath(), QString("QtAddOn.JsonDb"), &error)) {
- mPluginPath = list.at(i).absoluteFilePath();
- break;
- }
- }
- }
- delete engine;
-
- // Create alot of items in the database
- QVariantList friendsList;
- for (int i=0; i<1000; i++) {
- QVariantMap item;
- item.insert("_type", "Friends");
- item.insert("name", QString("Name-%1").arg(i));
- item.insert("phone",QString("%1").arg(qrand()));
- friendsList << item;
- }
- mId = mClient->create(friendsList);
-
- QVariantList ImageList;
- for (int i=0; i<1000; i++) {
- QVariantMap item;
- item.insert("_type", "Image");
- item.insert("name", QString("Name-%1.jpg").arg(i));
- item.insert("location",QString("/home/qt/Pictures/Myfolder-%1").arg(i));
- ImageList << item;
- }
- mId = mClient->create(ImageList);
-
- QVariantList numberList;
- for (int i=0; i<1000; i++) {
- QVariantMap item;
- item.insert("_type", "RandNumber");
- item.insert("number", qrand()%100);
- numberList << item;
- }
- mId = mClient->create(numberList);
-
- QVariantList trollList;
- for (int i=0; i<100; i++) {
- QVariantMap item;
- item.insert("_type", "Troll");
- item.insert("age", i);
- item.insert("name", QString("Troll-%1").arg(i));
- trollList << item;
- }
- mId = mClient->create(trollList);
-
- mEventLoop.exec(QEventLoop::AllEvents);
-}
-
-JsonDbListModel *TestListModel::createModel()
-{
- ModelData *newModel = new ModelData();
- newModel->engine = new QQmlEngine();
- QString error;
- if (!newModel->engine->importPlugin(mPluginPath, QString("QtAddOn.JsonDb"), &error)) {
- qDebug()<<"Unable to load the plugin :"<<error;
- delete newModel->engine;
- return 0;
- }
- newModel->component = new QQmlComponent(newModel->engine);
- newModel->component->setData("import QtQuick 2.0\nimport QtAddOn.JsonDb 1.0 \n JsonDbListModel {id: contactsModel}", QUrl());
- newModel->model = newModel->component->create();
- mModels.append(newModel);
- return (JsonDbListModel*)(newModel->model);
-}
-
-void TestListModel::deleteModel(JsonDbListModel *model)
-{
- for (int i = 0; i < mModels.count(); i++) {
- if (mModels[i]->model == model) {
- ModelData *modelData = mModels.takeAt(i);
- delete modelData;
- return;
- }
- }
-}
-
-void TestListModel::cleanupTestCase()
-{
- if (mClient) {
- delete mClient;
- mClient = NULL;
- }
-
- if (mProcess) {
- mProcess->kill();
- mProcess->waitForFinished();
- delete mProcess;
- mProcess = NULL;
- }
- deleteDbFiles();
-}
-
-void TestListModel::notified(const QString& notifyUuid, const QVariant& object, const QString& action)
-{
- Q_UNUSED(notifyUuid);
- Q_UNUSED(object);
- Q_UNUSED(action);
- //qDebug() << Q_FUNC_INFO << "notifyUuid=" << notifyUuid << "action=" << action << "object=" << object;
- //mEventLoop.exit(0);
-}
-
-void TestListModel::response(int id, const QVariant& data)
-{
- //qDebug() << Q_FUNC_INFO << "id: " << id << data;
- QMap<QString,QVariant> map = data.toMap();
- mLastUuid = map.value("_uuid").toString();
- mLastResponseData = data;
- if (mId == id)
- mEventLoop.exit(0);
-}
-
-void TestListModel::error(int id, int code, const QString& message)
-{
- qDebug() << Q_FUNC_INFO << "id:" << id << "code:" << code << "message:" << message;
- if (mId == id)
- mEventLoop.exit(0);
-}
-
-void TestListModel::dataChanged(QModelIndex, QModelIndex)
-{
- //qDebug() << "dataChanged(QModelIndex,QModelIndex)";
- mEventLoop.exit(0);
-}
-
-void TestListModel::modelReset()
-{
- //qDebug() << "modelReset()";
- mEventLoop.exit(0);
-}
-
-void TestListModel::layoutChanged()
-{
- //qDebug() << "layoutChanged()";
- mEventLoop.exit(0);
-}
-
-void TestListModel::rowsInserted(QModelIndex parent, int start , int end)
-{
- Q_UNUSED(parent);
- qDebug() << QString("rowsInserted(QModelIndex, %1, %2)").arg(start).arg(end);
- mEventLoop.exit(0);
-}
-
-void TestListModel::rowsRemoved(QModelIndex parent, int start, int end)
-{
- Q_UNUSED(parent);
- qDebug() << QString("rowsRemoved(QModelIndex, %1, %2)").arg(start).arg(end);
- mEventLoop.exit(0);
-}
-
-void TestListModel::rowsMoved(QModelIndex sourceParent, int sourceStart, int sourceEnd, QModelIndex destinationParent, int destinationRow)
-{
- Q_UNUSED(sourceParent);
- Q_UNUSED(destinationParent);
- qDebug() << QString("rowsMoved(QModelIndex, %1, %2, QModelIndex, %3)").arg(sourceStart).arg(sourceEnd).arg(destinationRow);
- mEventLoop.exit(0);
-}
-
-void TestListModel::createListModelHundredItems()
-{
- JsonDbListModel *listModel = createModel();
- if (!listModel) return;
-
- connectListModel(listModel);
- QStringList rolenames;
- rolenames << "age" << "name" << "_type";
- listModel->setScriptableRoleNames(rolenames);
-
- QBENCHMARK {
- listModel->setQuery("[?_type=\"Troll\"]");
- mEventLoop.exec(QEventLoop::AllEvents);
- }
- QCoreApplication::instance()->processEvents();
- deleteModel(listModel);
-}
-
-
-void TestListModel::createListModelThousandItems()
-{
- JsonDbListModel *listModel = createModel();
-
- connectListModel(listModel);
- QStringList rolenames;
- rolenames << "name" << "phone" << "_uuid" << "_type";
- listModel->setScriptableRoleNames(rolenames);
-
- QBENCHMARK {
- listModel->setQuery("[?_type=\"Friends\"]");
- mEventLoop.exec(QEventLoop::AllEvents);
- }
- QCoreApplication::instance()->processEvents();
- deleteModel(listModel);
-}
-
-void TestListModel::createListModelGroupedQuery()
-{
- JsonDbListModel *listModel = createModel();
- if (!listModel) return;
-
- connectListModel(listModel);
- QStringList rolenames;
- rolenames << "_uuid" << "_type" << "number";
- listModel->setScriptableRoleNames(rolenames);
-
- QBENCHMARK {
- listModel->setQuery("[?_type=\"RandNumber\"][?number=77]");
- mEventLoop.exec(QEventLoop::AllEvents);
- }
- QCoreApplication::instance()->processEvents();
- deleteModel(listModel);
-}
-
-
-void TestListModel::createListModelSortedQuery()
-{
- JsonDbListModel *listModel = createModel();
- if (!listModel) return;
-
- connectListModel(listModel);
-
- QStringList rolenames;
- rolenames << "_uuid" << "_type" << "number";
- listModel->setScriptableRoleNames(rolenames);
-
- QBENCHMARK {
- listModel->setQuery("[?_type=\"RandNumber\"][/number]");
- mEventLoop.exec(QEventLoop::AllEvents);
- }
- QCoreApplication::instance()->processEvents();
- deleteModel(listModel);
-}
-
-void TestListModel::changeOneItemClient()
-{
-
- QString queryString("[?_type=\"Friends\"][?name=\"Name-1\"]");
- mId = mClient->query(queryString);
- mEventLoop.exec(QEventLoop::AllEvents);
-
- QVariantMap mapResponse = mLastResponseData.toMap();
- QVariantMap item = mapResponse.value("data").toList().at(0).toMap();
- int i = mapResponse.value("length").toInt();
- QVERIFY(i == 1);
- item.insert("phone","111122223");
-
- // Make sure that we only exit the eventloop
- // on listmodel updates.
- disconnect(mClient, 0, this, 0);
-
- JsonDbListModel *listModel = createModel();
- if (!listModel) return;
- QStringList rolenames;
- rolenames << "name" << "phone" << "_uuid" << "_type";
- listModel->setScriptableRoleNames(rolenames);
- listModel->setQuery("[?_type=\"Friends\"][/name]");
- connectListModel(listModel);
-
- mEventLoop.exec(QEventLoop::AllEvents);
-
- QBENCHMARK {
- mId = mClient->update(item);
- mEventLoop.exec(QEventLoop::AllEvents);
- }
-
- connectToServer();
-
- mEventLoop.processEvents();
- QCoreApplication::instance()->processEvents();
- deleteModel(listModel);
-}
-
-void TestListModel::changeOneItemSet()
-{
- // Make sure that we only exit the eventloop
- // on listmodel updates.
- disconnect(mClient, 0, this, 0);
- mEventLoop.processEvents();
-
- JsonDbListModel *listModel = createModel();
- if (!listModel) return;
- QStringList rolenames;
- rolenames << "name" << "phone" << "_uuid" << "_type";
- listModel->setScriptableRoleNames(rolenames);
- listModel->setQuery("[?_type=\"Friends\"][/name]");
- connectListModel(listModel);
-
- mEventLoop.exec(QEventLoop::AllEvents);
-
- QJSEngine engine;
- QJSValue value = engine.newObject();
- value.setProperty("phone", "987654321");
-
- QBENCHMARK {
- listModel->set(0,value);
- mEventLoop.exec(QEventLoop::AllEvents);
- }
-
- QVERIFY(listModel->get(0, "phone") == "987654321");
- deleteModel(listModel);
-}
-
-void TestListModel::changeOneItemSetProperty()
-{
- // Make sure that we only exit the eventloop
- // on listmodel updates.
- disconnect(mClient, 0, this, 0);
- mEventLoop.processEvents();
-
- JsonDbListModel *listModel = createModel();
- if (!listModel) return;
- QStringList rolenames;
- rolenames << "name" << "phone" << "_uuid" << "_type";
- listModel->setScriptableRoleNames(rolenames);
- listModel->setQuery("[?_type=\"Friends\"]");
- connectListModel(listModel);
-
- mEventLoop.exec(QEventLoop::AllEvents);
-
- QBENCHMARK {
- listModel->setProperty(1, "phone", "111122223");
- mEventLoop.exec(QEventLoop::AllEvents);
- }
-
- connectToServer();
-
- mEventLoop.processEvents();
- QCoreApplication::instance()->processEvents();
- deleteModel(listModel);
-}
-
-void TestListModel::getOneItemInCache()
-{
- disconnect(mClient, 0, this, 0);
-
- JsonDbListModel *listModel = createModel();
- if (!listModel) return;
- connectListModel(listModel);
- QStringList rolenames;
- rolenames << "name" << "phone" << "_uuid" << "_type" ;
- listModel->setScriptableRoleNames(rolenames);
- listModel->setQuery("[?_type=\"Friends\"]");
- mEventLoop.exec(QEventLoop::AllEvents);
-
- QBENCHMARK {
- QVariant res = listModel->data(listModel->index(10,0), listModel->roleFromString("name"));
- // Since it is in the cache the fetch value should be valid at this point.
- QVERIFY(res.isValid());
- }
-
- QCoreApplication::instance()->processEvents();
- deleteModel(listModel);
-}
-
-void TestListModel::getOneItemNotInCache()
-{
- disconnect(mClient, 0, this, 0);
-
- JsonDbListModel *listModel = createModel();
- if (!listModel) return;
- connectListModel(listModel);
- listModel->setLimit(80);
- QStringList rolenames;
- rolenames << "name" << "phone" << "_uuid" << "_type";
- listModel->setScriptableRoleNames(rolenames);
- listModel->setQuery("[?_type=\"Friends\"][/name]");
- mEventLoop.exec(QEventLoop::AllEvents);
-
- bool flip = true; // so we can run multiple benchmarks
-
- QBENCHMARK {
- QVariant res;
- if (flip)
- res = listModel->data(listModel->index(960,0), listModel->roleFromString("name"));
- else
- res = listModel->data(listModel->index(10,0), listModel->roleFromString("name"));
-
- flip = !flip;
- }
-
- QCoreApplication::instance()->processEvents();
- deleteModel(listModel);
-}
-
-void TestListModel::getOneItemNotInCacheThousandItems()
-{
- disconnect(mClient, 0, this, 0);
-
- JsonDbListModel *listModel = createModel();
- if (!listModel) return;
- connectListModel(listModel);
- listModel->setLimit(80);
- QStringList rolenames;
- rolenames << "name" << "location" << "_type";
- listModel->setScriptableRoleNames(rolenames);
- listModel->setQuery("[?_type=\"Image\"][/name]");
- mEventLoop.exec(QEventLoop::AllEvents);
-
- QVERIFY(listModel->count() == 1000);
-
- bool flip = true; // so we can run multiple benchmarks
-
- QBENCHMARK {
- QVariant res;
- if (flip)
- res = listModel->data(listModel->index(980,0), listModel->roleFromString("name"));
- else
- res = listModel->data(listModel->index(10,0), listModel->roleFromString("name"));
-
- flip = !flip;
- }
-
- QCoreApplication::instance()->processEvents();
- deleteModel(listModel);
-}
-
-void TestListModel::scrollThousandItems()
-{
- disconnect(mClient, 0, this, 0);
- mEventLoop.processEvents();
-
- JsonDbListModel *listModel = createModel();
- if (!listModel) return;
- QStringList rolenames;
- rolenames << "name" << "phone" << "_uuid" << "_type";
- listModel->setScriptableRoleNames(rolenames);
- listModel->setQuery("[?_type=\"Friends\"][/name]");
- listModel->setLimit(80);
- connectListModel(listModel);
-
- mEventLoop.exec(QEventLoop::AllEvents);
-
- int rowCount = listModel->rowCount();
-
- QBENCHMARK {
- for( int i=0 ; i<rowCount; i++)
- foreach(QString role, rolenames)
- listModel->data(listModel->index(i,0), listModel->roleFromString(role));
- }
- deleteModel(listModel);
-}
-
-
-QTEST_MAIN(TestListModel)
diff --git a/tests/benchmarks/jsondb-listmodel/listmodel-benchmark.h b/tests/benchmarks/jsondb-listmodel/listmodel-benchmark.h
deleted file mode 100644
index b0a0d9f8..00000000
--- a/tests/benchmarks/jsondb-listmodel/listmodel-benchmark.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef LISTMODEL_BENCHMARK_H
-#define LISTMODEL_BENCHMARK_H
-
-#include <QCoreApplication>
-#include <QProcess>
-#include <QTest>
-#include <QDebug>
-
-#include <QEventLoop>
-#include <QLocalSocket>
-
-#include <jsondb-client.h>
-#include <jsondb-error.h>
-
-#include "clientwrapper.h"
-#include "jsondb-listmodel.h"
-
-QT_BEGIN_NAMESPACE
-class QQmlEngine;
-class QQmlComponent;
-QT_END_NAMESPACE
-
-QT_USE_NAMESPACE_JSONDB
-class JsonDbListModel;
-
-class ModelData {
-public:
- ModelData();
- ~ModelData();
- QQmlEngine *engine;
- QQmlComponent *component;
- QObject *model;
-};
-
-class TestListModel: public ClientWrapper
-{
- Q_OBJECT
-public:
- TestListModel();
- ~TestListModel();
-
- void deleteDbFiles();
- void connectListModel(JsonDbListModel *model);
-
-public slots:
- void notified(const QString& notifyUuid, const QVariant& object, const QString& action);
- void response(int id, const QVariant& data);
- void error(int id, int code, const QString& message);
-
- void dataChanged(QModelIndex,QModelIndex);
- void modelReset();
- void layoutChanged();
- void rowsInserted(QModelIndex, int, int);
- void rowsRemoved(QModelIndex, int, int);
- void rowsMoved(QModelIndex, int, int, QModelIndex, int);
-
-private slots:
- void initTestCase();
- void cleanupTestCase();
-
- void createListModelHundredItems();
- void createListModelThousandItems();
- void createListModelGroupedQuery();
- void createListModelSortedQuery();
- void changeOneItemClient();
- void changeOneItemSet();
- void changeOneItemSetProperty();
- void getOneItemInCache();
- void getOneItemNotInCache();
- void getOneItemNotInCacheThousandItems();
- void scrollThousandItems();
-private:
- JsonDbListModel *createModel();
- void deleteModel(JsonDbListModel *model);
-private:
- QProcess *mProcess;
- QVariant mLastResponseData;
- QList<ModelData*> mModels;
- QString mPluginPath;
-};
-
-#endif
diff --git a/tests/benchmarks/jsondbcachinglistmodel/jsondbcachinglistmodel-bench.cpp b/tests/benchmarks/jsondbcachinglistmodel/jsondbcachinglistmodel-bench.cpp
index 68c64854..9a3e430a 100644
--- a/tests/benchmarks/jsondbcachinglistmodel/jsondbcachinglistmodel-bench.cpp
+++ b/tests/benchmarks/jsondbcachinglistmodel/jsondbcachinglistmodel-bench.cpp
@@ -41,11 +41,10 @@
#include <QtTest/QtTest>
#include <QJSEngine>
+#include <QQmlListReference>
#include "jsondbcachinglistmodel-bench.h"
-#include "../../shared/util.h"
-#include <QQmlListReference>
-#include "json.h"
+#include "util.h"
static const char dbfile[] = "dbFile-jsondb-cached-listmodel";
ModelData::ModelData(): engine(0), component(0), model(0)
@@ -56,25 +55,26 @@ ModelData::~ModelData()
{
if (model)
delete model;
- if (partition1)
- delete partition1;
- if (partition2)
- delete partition2;
-
if (component)
delete component;
- if (partitionComponent1)
- delete partitionComponent1;
- if (partitionComponent2)
- delete partitionComponent2;
-
if (engine)
delete engine;
}
+const QString qmlProgram = QLatin1String(
+ "import QtQuick 2.0 \n"
+ "import QtJsonDb 1.0 as JsonDb \n"
+ "JsonDb.JsonDbCachingListModel {"
+ "signal callbackSignal(variant index, variant response);"
+ "id: contactsModel; cacheSize: 75;"
+ "partitions: ["
+ "JsonDb.Partition {name: \"com.nokia.shared.1\"},"
+ "JsonDb.Partition {name: \"com.nokia.shared.2\"}"
+ "]"
+ "}");
+
JsonDbCachingListModelBench::JsonDbCachingListModelBench()
- : mWaitingForNotification(false), mWaitingForDataChange(false), mWaitingForRowsRemoved(false)
{
}
@@ -97,20 +97,6 @@ void JsonDbCachingListModelBench::deleteDbFiles()
}
}
-QVariant JsonDbCachingListModelBench::readJsonFile(const QString& filename)
-{
- QString filepath = findFile(filename);
- QFile jsonFile(filepath);
- jsonFile.open(QIODevice::ReadOnly);
- QByteArray json = jsonFile.readAll();
- JsonReader parser;
- bool ok = parser.parse(json);
- if (!ok) {
- qDebug() << filepath << parser.errorString();
- }
- return parser.result();
-}
-
void JsonDbCachingListModelBench::connectListModel(QAbstractListModel *model)
{
connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(dataChanged(QModelIndex,QModelIndex)));
@@ -129,29 +115,26 @@ void JsonDbCachingListModelBench::initTestCase()
deleteDbFiles();
QString socketName = QString("testjsondb_%1").arg(getpid());
- mProcess = launchJsonDbDaemon(JSONDB_DAEMON_BASE, socketName, QStringList() << "-base-name" << dbfile);
+ mProcess = launchJsonDbDaemon(JSONDB_DAEMON_BASE, socketName, QStringList() << "-base-name" << dbfile, __FILE__);
- mClient = new JsonDbClient(this);
- connect(mClient, SIGNAL(notified(QString,QtAddOn::JsonDb::JsonDbNotification)),
- this, SLOT(notified(QString,QtAddOn::JsonDb::JsonDbNotification)));
- connect( mClient, SIGNAL(response(int, const QVariant&)),
- this, SLOT(response(int, const QVariant&)));
- connect( mClient, SIGNAL(error(int, int, const QString&)),
- this, SLOT(error(int, int, const QString&)));
+ connection = new QJsonDbConnection();
+ connection->connectToServer();
mPluginPath = findQMLPluginPath("QtJsonDb");
+ if (mPluginPath.isEmpty())
+ qDebug() << "Couldn't find the plugin path for the plugin QtJsonDb";
// Create the shared Partitions
QVariantMap item;
item.insert("_type", "Partition");
item.insert("name", "com.nokia.shared.1");
- int id = mClient->create(item);
+ int id = create(item);
waitForResponse1(id);
item.clear();
item.insert("_type", "Partition");
item.insert("name", "com.nokia.shared.2");
- id = mClient->create(item);
+ id = create(item);
waitForResponse1(id);
}
@@ -167,9 +150,8 @@ QAbstractListModel *JsonDbCachingListModelBench::createModel()
return 0;
}
newModel->component = new QQmlComponent(newModel->engine);
- newModel->component->setData("import QtQuick 2.0\nimport QtJsonDb 1.0 as JsonDb \n"
- "JsonDb.JsonDbCachingListModel {signal callbackSignal(variant index, variant response); id: contactsModel; cacheSize: 200;}",
- QUrl());
+ newModel->component->setData(qmlProgram.toLocal8Bit(), QUrl());
+
newModel->model = newModel->component->create();
if (newModel->component->isError())
qDebug() << newModel->component->errors();
@@ -177,27 +159,6 @@ QAbstractListModel *JsonDbCachingListModelBench::createModel()
QObject::connect(newModel->model, SIGNAL(callbackSignal(QVariant, QVariant)),
this, SLOT(callbackSlot(QVariant, QVariant)));
- newModel->partitionComponent1 = new QQmlComponent(newModel->engine);
- newModel->partitionComponent1->setData("import QtQuick 2.0\nimport QtJsonDb 1.0 as JsonDb \n"
- "JsonDb.Partition {name: \"com.nokia.shared.1\"}",
- QUrl());
- newModel->partition1 = newModel->partitionComponent1->create();
- if (newModel->partitionComponent1->isError())
- qDebug() << newModel->partitionComponent1->errors();
-
-
- newModel->partitionComponent2 = new QQmlComponent(newModel->engine);
- newModel->partitionComponent2->setData("import QtQuick 2.0\nimport QtJsonDb 1.0 as JsonDb \n"
- "JsonDb.Partition {name: \"com.nokia.shared.2\"}",
- QUrl());
- newModel->partition2 = newModel->partitionComponent2->create();
- if (newModel->partitionComponent2->isError())
- qDebug() << newModel->partitionComponent2->errors();
-
- QQmlListReference partitions(newModel->model, "partitions", newModel->engine);
- partitions.append(newModel->partition1);
- partitions.append(newModel->partition2);
-
mModels.append(newModel);
return (QAbstractListModel*)(newModel->model);
}
@@ -216,9 +177,9 @@ void JsonDbCachingListModelBench::deleteModel(QAbstractListModel *model)
// Delete all the items of this type from JsonDb
void JsonDbCachingListModelBench::deleteItems(const QString &type, const QString &partition)
{
- int id = mClient->query(QString("[?_type=\"%1\"]").arg(type), 0, -1, partition);
+ int id = query(QString("[?_type=\"%1\"]").arg(type), partition);
waitForResponse1(id);
- id = mClient->remove(mData.toMap().value("data"), partition);
+ id = remove(lastResult, partition);
waitForResponse1(id);
}
@@ -239,20 +200,26 @@ void JsonDbCachingListModelBench::callbackSlot(QVariant error, QVariant response
callbackError = error.isValid();
callbackMeta = response;
callbackResponse = response.toMap().value("object");
- mEventLoop.quit();
+ eventLoop1.quit();
}
void JsonDbCachingListModelBench::getIndex(int index)
{
mCallbackReceived = false;
- const QString createString = QString("get(%1, function (error, response) {callbackSignal(error, response);});");
+ const QString createString = QString("get(%1, function (error, response) { callbackSignal(error, response);});");
const QString getString = QString(createString).arg(index);
QQmlExpression expr(mModels.last()->engine->rootContext(), mModels.last()->model, getString);
expr.evaluate().toInt();
if (!mCallbackReceived)
- waitForCallback();
+ waitForCallback1();
+}
+
+QVariant JsonDbCachingListModelBench::getIndexRaw(QAbstractListModel *model, int index, int role)
+{
+ QVariant val = model->data(model->index(index), role);
+ return val;
}
void JsonDbCachingListModelBench::createIndex(const QString &property, const QString &propertyType)
@@ -263,10 +230,10 @@ void JsonDbCachingListModelBench::createIndex(const QString &property, const QSt
item.insert("propertyName", property);
item.insert("propertyType", propertyType);
- int id = mClient->create(item, "com.nokia.shared.1");
+ int id = create(item, "com.nokia.shared.1");
waitForResponse1(id);
- id = mClient->create(item, "com.nokia.shared.2");
+ id = create(item, "com.nokia.shared.2");
waitForResponse1(id);
}
@@ -274,12 +241,13 @@ void JsonDbCachingListModelBench::createIndex(const QString &property, const QSt
// Populate model of 300 items.
void JsonDbCachingListModelBench::ModelStartup()
{
+ resetWaitFlags();
QVariantMap item;
for (int i=0; i < 300; i++) {
item.insert("_type", __FUNCTION__);
item.insert("name", QString("Arnie_%1").arg(i));
- int id = mClient->create(item, "com.nokia.shared.1");
+ int id = create(item, "com.nokia.shared.1");
waitForResponse1(id);
}
@@ -297,9 +265,11 @@ void JsonDbCachingListModelBench::ModelStartup()
QCOMPARE(listModel->rowCount(), 0);
QBENCHMARK_ONCE {
- waitForStateOrTimeout();
+ mWaitingForReset = true;
+ waitForExitOrTimeout();
}
+ QCOMPARE(mWaitingForReset, false);
QCOMPARE(listModel->rowCount(), 300);
deleteItems(__FUNCTION__, "com.nokia.shared.1");
@@ -309,19 +279,20 @@ void JsonDbCachingListModelBench::ModelStartup()
// Populate model of 300 items two partitions.
void JsonDbCachingListModelBench::ModelStartupTwoPartitions()
{
+ resetWaitFlags();
QVariantMap item;
for (int i=0; i < 300; i = i+2) {
item.insert("_type", __FUNCTION__);
item.insert("name", QString("Arnie_%1").arg(i));
- int id = mClient->create(item, "com.nokia.shared.1");
+ int id = create(item, "com.nokia.shared.1");
waitForResponse1(id);
}
for (int i=1; i < 300; i = i+2) {
item.insert("_type", __FUNCTION__);
item.insert("name", QString("Arnie_%1").arg(i));
- int id = mClient->create(item, "com.nokia.shared.2");
+ int id = create(item, "com.nokia.shared.2");
waitForResponse1(id);
}
@@ -339,7 +310,8 @@ void JsonDbCachingListModelBench::ModelStartupTwoPartitions()
QCOMPARE(listModel->rowCount(), 0);
QBENCHMARK_ONCE {
- waitForStateOrTimeout();
+ mWaitingForReset = true;
+ waitForExitOrTimeout();
}
QCOMPARE(listModel->rowCount(), 300);
@@ -353,12 +325,13 @@ void JsonDbCachingListModelBench::ModelStartupTwoPartitions()
// Populate model of 300 items sorted.
void JsonDbCachingListModelBench::ModelStartupSorted()
{
+ resetWaitFlags();
QVariantMap item;
for (int i=0; i < 300; i++) {
item.insert("_type", __FUNCTION__);
item.insert("name", QString("Arnie_%1").arg(i));
- int id = mClient->create(item, "com.nokia.shared.1");
+ int id = create(item, "com.nokia.shared.1");
waitForResponse1(id);
}
@@ -377,7 +350,8 @@ void JsonDbCachingListModelBench::ModelStartupSorted()
QCOMPARE(listModel->rowCount(), 0);
QBENCHMARK_ONCE {
- waitForStateOrTimeout();
+ mWaitingForReset = true;
+ waitForExitOrTimeout();
}
QCOMPARE(listModel->rowCount(), 300);
@@ -389,11 +363,12 @@ void JsonDbCachingListModelBench::ModelStartupSorted()
void JsonDbCachingListModelBench::getItemNotInCache()
{
+ resetWaitFlags();
QVariantMap item;
for (int i=0; i < 300; i++) {
item.insert("_type", __FUNCTION__);
item.insert("name", QString("Arnie_%1").arg(i));
- int id = mClient->create(item, "com.nokia.shared.1");
+ int id = create(item, "com.nokia.shared.1");
waitForResponse1(id);
}
@@ -411,9 +386,9 @@ void JsonDbCachingListModelBench::getItemNotInCache()
// now start it working
QCOMPARE(listModel->rowCount(), 0);
- waitForStateOrTimeout();
+ mWaitingForReset = true;
+ waitForExitOrTimeout();
QCOMPARE(listModel->rowCount(), 300);
-
// Now get some items so we know that index 20 is not in the cache
getIndex(100);
getIndex(151);
@@ -430,11 +405,12 @@ void JsonDbCachingListModelBench::getItemNotInCache()
void JsonDbCachingListModelBench::deleteItem()
{
+ resetWaitFlags();
QVariantMap item;
for (int i=0; i < 300; i++) {
item.insert("_type", __FUNCTION__);
item.insert("name", QString("Arnie_%1").arg(i));
- int id = mClient->create(item, "com.nokia.shared.1");
+ int id = create(item, "com.nokia.shared.1");
waitForResponse1(id);
}
@@ -450,7 +426,8 @@ void JsonDbCachingListModelBench::deleteItem()
connectListModel(listModel);
// now start it working
- waitForStateOrTimeout();
+ mWaitingForReset = true;
+ waitForExitOrTimeout();
QCOMPARE(listModel->rowCount(), 300);
QVariantMap itemToRemove;
@@ -466,11 +443,13 @@ void JsonDbCachingListModelBench::deleteItem()
getIndex(255);
// Delete the item
- mClient->remove(itemToRemove, "com.nokia.shared.1");
+ int id = remove(itemToRemove, "com.nokia.shared.1");
QBENCHMARK_ONCE {
waitForItemChanged(true);
}
+ while (lastRequestId < id)
+ waitForResponse1(id);
QCOMPARE(listModel->rowCount(), 299);
@@ -478,18 +457,77 @@ void JsonDbCachingListModelBench::deleteItem()
deleteModel(listModel);
}
+void JsonDbCachingListModelBench::flicking()
+{
+ resetWaitFlags();
+ QVariantList items;
+ QVariantMap item;
+ for (int i=0; i < 300; i++) {
+ item.insert("_type", __FUNCTION__);
+ item.insert("name", QString("Arnie_%1").arg(i));
+ items.append(item);
+ }
+ int id = create(items, "com.nokia.shared.1");
+ waitForResponse1(id);
+
+ items.clear();
+ for (int i=0; i < 300; i++) {
+ item.insert("_type", __FUNCTION__);
+ item.insert("name", QString("Bertta_%1").arg(i));
+ items.append(item);
+ }
+ id = create(items, "com.nokia.shared.2");
+ waitForResponse1(id);
+
+ createIndex("name", "string");
+
+ QAbstractListModel *listModel = createModel();
+ if (!listModel) return;
+ listModel->setProperty("cacheSize", 75);
+ listModel->setProperty("sortOrder", "[/name]");
+ QStringList roleNames = (QStringList() << "_type" << "_uuid" << "name");
+ listModel->setProperty("roleNames", roleNames);
+ listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__));
+ connectListModel(listModel);
+
+ // now start it working
+ mWaitingForReset = true;
+ waitForExitOrTimeout();
+ QCOMPARE(listModel->rowCount(), 600);
+
+ int noOfCacheMisses = 0;
+ mItemsUpdated = 0;
+ // simulate flicking through lhe list
+ for (int i = 0; i < 600; i++) {
+ QVariant nameVariant = getIndexRaw (listModel, i, 2);
+ if (nameVariant.isNull())
+ noOfCacheMisses++;
+ waitForMs(10, 6);
+ }
+
+ deleteItems(__FUNCTION__, "com.nokia.shared.1");
+ deleteItems(__FUNCTION__, "com.nokia.shared.2");
+ deleteModel(listModel);
+}
+
void JsonDbCachingListModelBench::modelReset()
{
- mWaitingForReset = false;
- mEventLoop2.exit(0);
+ if (mWaitingForReset) {
+ mWaitingForReset = false;
+ eventLoop1.exit(0);
+ }
}
void JsonDbCachingListModelBench::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
{
Q_UNUSED(topLeft);
Q_UNUSED(bottomRight);
- mWaitingForDataChange = false;
+ mItemsUpdated++;
+ if (mWaitingForChanged) {
+ mWaitingForChanged = false;
+ eventLoop1.exit(0);
+ }
}
void JsonDbCachingListModelBench::rowsInserted(const QModelIndex &parent, int first, int last)
@@ -497,8 +535,11 @@ void JsonDbCachingListModelBench::rowsInserted(const QModelIndex &parent, int fi
Q_UNUSED(parent);
Q_UNUSED(first);
Q_UNUSED(last);
- mItemsCreated++;
- mEventLoop2.exit(0);
+ mItemsCreated += last-first+1;
+ if (mWaitingForRowsInserted) {
+ mWaitingForRowsInserted = false;
+ eventLoop1.exit(0);
+ }
}
void JsonDbCachingListModelBench::rowsRemoved(const QModelIndex &parent, int first, int last)
@@ -506,7 +547,11 @@ void JsonDbCachingListModelBench::rowsRemoved(const QModelIndex &parent, int fir
Q_UNUSED(parent);
Q_UNUSED(first);
Q_UNUSED(last);
- mWaitingForRowsRemoved = false;
+ mItemsRemoved += last-first+1;
+ if (mWaitingForRemoved) {
+ mWaitingForRemoved = false;
+ eventLoop1.exit(0);
+ }
}
void JsonDbCachingListModelBench::rowsMoved( const QModelIndex &parent, int start, int end, const QModelIndex &destination, int row )
@@ -522,83 +567,143 @@ void JsonDbCachingListModelBench::stateChanged()
{
// only exit on ready state.
QAbstractListModel *model = qobject_cast<QAbstractListModel *>(sender());
- if (model->property("state") == 2) {
+ if (model->property("state").toInt() == 2 && mWaitingForStateChanged) {
mWaitingForStateChanged = false;
- mEventLoop2.exit(0);
+ eventLoop1.exit(0);
}
}
void JsonDbCachingListModelBench::waitForItemsCreated(int items)
{
- mTimeoutCalled = false;
+ mTimedOut = false;
QTimer timer;
QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout()));
- QObject::connect(&timer, SIGNAL(timeout()), &mEventLoop2, SLOT(quit()));
- timer.start(mClientTimeout);
- mElapsedTimer.start();
+ timer.start(clientTimeout);
+ elapsedTimer.start();
- mItemsCreated = 0;
- while (mItemsCreated != items && !mTimeoutCalled)
- mEventLoop2.processEvents(QEventLoop::AllEvents, mClientTimeout);
+ while (!mTimedOut && mItemsCreated != items) {
+ mWaitingForRowsInserted = true;
+ eventLoop1.exec(QEventLoop::AllEvents);
+ }
+ if (mTimedOut)
+ qDebug () << "waitForItemsCreated Timed out";
+}
+
+void JsonDbCachingListModelBench::waitForItemsUpdated(int items)
+{
+ mTimedOut = false;
+ QTimer timer;
+ QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout()));
+ timer.start(clientTimeout);
+ elapsedTimer.start();
+
+ while (!mTimedOut && mItemsUpdated != items) {
+ mWaitingForChanged = true;
+ eventLoop1.exec(QEventLoop::AllEvents);
+ }
+ if (mTimedOut)
+ qDebug () << "waitForItemsUpdated Timed out";
}
void JsonDbCachingListModelBench::waitForExitOrTimeout()
{
- mTimeoutCalled = false;
QTimer timer;
QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout()));
- QObject::connect(&timer, SIGNAL(timeout()), &mEventLoop2, SLOT(quit()));
- timer.start(mClientTimeout);
- mElapsedTimer.start();
- mEventLoop2.exec(QEventLoop::AllEvents);
+ timer.start(clientTimeout);
+ elapsedTimer.start();
+ eventLoop1.exec(QEventLoop::AllEvents);
+}
+
+void JsonDbCachingListModelBench::waitForMs(int ms, int warningThreshold)
+{
+ QTimer timer;
+ QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(silentTimeout()));
+ timer.start(ms);
+ qint64 elap;
+ QElapsedTimer elt;
+ elt.start();
+ eventLoop1.exec(QEventLoop::AllEvents);
+ if ((elap = elt.elapsed()) > ms+warningThreshold)
+ qDebug() << "Some event took more than " << warningThreshold << "ms" << "(" << elap-ms << "ms )";
}
void JsonDbCachingListModelBench::waitForStateOrTimeout()
{
- mTimeoutCalled = false;
+ mTimedOut = false;
QTimer timer;
QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout()));
- QObject::connect(&timer, SIGNAL(timeout()), &mEventLoop2, SLOT(quit()));
- timer.start(mClientTimeout);
- mElapsedTimer.start();
+ timer.start(clientTimeout);
+ elapsedTimer.start();
- mWaitingForStateChanged = true;
- while (mWaitingForStateChanged && !mTimeoutCalled)
- mEventLoop2.processEvents(QEventLoop::AllEvents, mClientTimeout);
+ while (mWaitingForStateChanged && !mTimedOut) {
+ eventLoop1.exec(QEventLoop::AllEvents);
+ }
+ if (mTimedOut)
+ qDebug () << "waitForStateOrTimeout Timed out";
}
void JsonDbCachingListModelBench::timeout()
{
- ClientWrapper::timeout();
- mTimeoutCalled = true;
+ qDebug () << "JsonDbCachingListModelBench::timeout()";
+ RequestWrapper::timeout();
mTimedOut = true;
+ eventLoop1.quit();
+}
+
+void JsonDbCachingListModelBench::silentTimeout()
+{
+ eventLoop1.quit();
+}
+
+void JsonDbCachingListModelBench::resetWaitFlags()
+{
+ mItemsCreated = 0;
+ mItemsUpdated = 0;
+ mItemsRemoved = 0;
+ mWaitingForStateChanged = false;
+ mWaitingForRowsInserted = false;
+ mWaitingForReset = false;
+ mWaitingForChanged = false;
+ mWaitingForRemoved = false;
}
void JsonDbCachingListModelBench::waitForItemChanged(bool waitForRemove)
{
- mTimeoutCalled = false;
+ mTimedOut = false;
QTimer timer;
QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout()));
- QObject::connect(&timer, SIGNAL(timeout()), &mEventLoop2, SLOT(quit()));
- timer.start(mClientTimeout);
- mElapsedTimer.start();
+ timer.start(clientTimeout);
+ elapsedTimer.start();
- mWaitingForRowsRemoved = true;
- mWaitingForDataChange = true;
+ mWaitingForRemoved = true;
+ mWaitingForChanged = true;
mItemsCreated = 0;
mWaitingForReset = true;
+ mWaitingForStateChanged = true;
bool waitMore = true;
- while (waitMore && !mTimeoutCalled) {
- if (!mWaitingForDataChange)
+ while (waitMore && !mTimedOut) {
+ if (!mWaitingForChanged) {
+ //qDebug() << "waitForItemChanged: mWaitingForChanged";
+ break;
+ }
+ if (!mWaitingForStateChanged) {
+ //qDebug() << "waitForItemChanged: mWaitingForStateChanged";
break;
- if (mItemsCreated)
+ }
+ if (mItemsCreated){
+ //qDebug() << "waitForItemChanged: mItemsCreated";
break;
- if (!mWaitingForReset)
+ }
+ if (!mWaitingForReset){
+ //qDebug() << "waitForItemChanged: mWaitingForReset";
break;
- if (waitForRemove && !mWaitingForRowsRemoved)
+ }
+ if (waitForRemove && !mWaitingForRemoved){
+ //qDebug() << "waitForItemChanged: mWaitingForRemoved";
break;
- mEventLoop2.processEvents(QEventLoop::AllEvents);
+ }
+ eventLoop1.exec(QEventLoop::AllEvents);
}
}
QTEST_MAIN(JsonDbCachingListModelBench)
diff --git a/tests/benchmarks/jsondbcachinglistmodel/jsondbcachinglistmodel-bench.h b/tests/benchmarks/jsondbcachinglistmodel/jsondbcachinglistmodel-bench.h
index cfac030d..2096dcdd 100644
--- a/tests/benchmarks/jsondbcachinglistmodel/jsondbcachinglistmodel-bench.h
+++ b/tests/benchmarks/jsondbcachinglistmodel/jsondbcachinglistmodel-bench.h
@@ -41,22 +41,9 @@
#ifndef JsonDbCachingListModel_Bench_H
#define JsonDbCachingListModel_Bench_H
-#include <QCoreApplication>
-#include <QList>
-#include <QTest>
-#include <QFile>
-#include <QProcess>
-#include <QEventLoop>
-#include <QDebug>
-#include <QLocalSocket>
-#include <QTimer>
-
-#include <jsondb-client.h>
-#include <jsondb-error.h>
-
#include <QAbstractListModel>
-#include "clientwrapper.h"
-#include "../../shared/qmltestutil.h"
+#include "requestwrapper.h"
+#include "qmltestutil.h"
QT_BEGIN_NAMESPACE
class QQmlEngine;
@@ -65,22 +52,16 @@ QT_END_NAMESPACE
QT_USE_NAMESPACE_JSONDB
-class JsonDbListModel;
-
class ModelData {
public:
ModelData();
~ModelData();
QQmlEngine *engine;
QQmlComponent *component;
- QQmlComponent *partitionComponent1;
- QQmlComponent *partitionComponent2;
QObject *model;
- QObject *partition1;
- QObject *partition2;
};
-class JsonDbCachingListModelBench: public ClientWrapper
+class JsonDbCachingListModelBench: public RequestWrapper
{
Q_OBJECT
public:
@@ -97,12 +78,11 @@ public slots:
void rowsMoved( const QModelIndex &parent, int start, int end, const QModelIndex &destination, int row );
void modelReset();
void stateChanged();
-
void callbackSlot(QVariant error, QVariant response);
-
protected slots:
void timeout();
+ void silentTimeout();
private slots:
void initTestCase();
@@ -112,41 +92,39 @@ private slots:
void ModelStartupSorted();
void getItemNotInCache();
void deleteItem();
+ void flicking();
private:
void waitForExitOrTimeout();
void waitForItemsCreated(int items);
+ void waitForItemsUpdated(int items);
void waitForStateOrTimeout();
+ void waitForMs(int ms, int warningThreshold);
void waitForItemChanged(bool waitForRemove = false);
QStringList getOrderValues(QAbstractListModel *listModel);
void getIndex(int index);
+ QVariant getIndexRaw(QAbstractListModel *model, int index, int role);
void createIndex(const QString &property, const QString &propertyType);
QAbstractListModel *createModel();
void deleteModel(QAbstractListModel *model);
void deleteItems(const QString &type, const QString &partition);
- QVariant readJsonFile(const QString &filename);
+ void resetWaitFlags();
private:
QProcess *mProcess;
- QStringList mNotificationsReceived;
QList<ModelData*> mModels;
QString mPluginPath;
- QEventLoop mEventLoop2; // for all listmodel slots
// Response values
+ bool mTimedOut;
int mItemsCreated;
- bool mWaitingForNotification;
- bool mWaitingForDataChange;
- bool mWaitingForRowsRemoved;
- bool mTimeoutCalled;
- bool mWaitingForReset;
+ int mItemsUpdated;
+ int mItemsRemoved;
bool mWaitingForStateChanged;
-
- bool mTimedOut;
- bool callbackError;
- bool mCallbackReceived;
- QVariant callbackMeta;
- QVariant callbackResponse;
+ bool mWaitingForRowsInserted;
+ bool mWaitingForReset;
+ bool mWaitingForChanged;
+ bool mWaitingForRemoved;
};
diff --git a/tests/benchmarks/jsondbcachinglistmodel/jsondbcachinglistmodel.pro b/tests/benchmarks/jsondbcachinglistmodel/jsondbcachinglistmodel.pro
index 1c0d1aeb..0e69fcb7 100644
--- a/tests/benchmarks/jsondbcachinglistmodel/jsondbcachinglistmodel.pro
+++ b/tests/benchmarks/jsondbcachinglistmodel/jsondbcachinglistmodel.pro
@@ -3,15 +3,15 @@ TARGET = tst_bench_jsondbcachinglistmodel
DEPENDPATH += .
INCLUDEPATH += .
-QT = core network testlib gui qml jsondbcompat-private
+QT = core network testlib gui qml jsondb
CONFIG -= app_bundle
CONFIG += testcase
include($$PWD/../../shared/shared.pri)
-include($$PWD/../../../src/3rdparty/qjson/qjson.pri)
DEFINES += JSONDB_DAEMON_BASE=\\\"$$QT.jsondb.bins\\\"
DEFINES += SRCDIR=\\\"$$PWD/\\\"
-HEADERS += jsondbcachinglistmodel-bench.h
+HEADERS += jsondbcachinglistmodel-bench.h \
+ $$PWD/../../shared/requestwrapper.h
SOURCES += jsondbcachinglistmodel-bench.cpp
diff --git a/tests/benchmarks/jsondbcachinglistmodel/partitions.json b/tests/benchmarks/jsondbcachinglistmodel/partitions.json
new file mode 100644
index 00000000..1cdd0fa5
--- /dev/null
+++ b/tests/benchmarks/jsondbcachinglistmodel/partitions.json
@@ -0,0 +1,4 @@
+[
+ { "name" :"com.nokia.shared.1" },
+ { "name" :"com.nokia.shared.2" }
+]
diff --git a/tests/benchmarks/jsondbsortinglistmodel/jsondbsortinglistmodel-bench.cpp b/tests/benchmarks/jsondbsortinglistmodel/jsondbsortinglistmodel-bench.cpp
index 9691f2b8..1e993060 100644
--- a/tests/benchmarks/jsondbsortinglistmodel/jsondbsortinglistmodel-bench.cpp
+++ b/tests/benchmarks/jsondbsortinglistmodel/jsondbsortinglistmodel-bench.cpp
@@ -43,9 +43,8 @@
#include <QJSEngine>
#include "jsondbsortinglistmodel-bench.h"
-#include "../../shared/util.h"
+#include "util.h"
#include <QQmlListReference>
-#include "json.h"
static const char dbfile[] = "dbFile-jsondb-cached-listmodel";
ModelData::ModelData(): engine(0), component(0), model(0)
@@ -56,25 +55,21 @@ ModelData::~ModelData()
{
if (model)
delete model;
- if (partition1)
- delete partition1;
- if (partition2)
- delete partition2;
-
if (component)
delete component;
- if (partitionComponent1)
- delete partitionComponent1;
- if (partitionComponent2)
- delete partitionComponent2;
-
if (engine)
delete engine;
}
+const QString qmlProgram = QLatin1String(
+ "import QtQuick 2.0\n"
+ "import QtJsonDb 1.0 as JsonDb \n"
+ "JsonDb.JsonDbSortingListModel {"
+ "id: contactsModel;"
+ "partitions: [JsonDb.Partition {name: \"com.nokia.shared.1\"}, JsonDb.Partition {name: \"com.nokia.shared.2\"}]"
+ "}");
JsonDbSortingListModelBench::JsonDbSortingListModelBench()
- : mWaitingForNotification(false), mWaitingForDataChange(false), mWaitingForRowsRemoved(false)
{
}
@@ -97,20 +92,6 @@ void JsonDbSortingListModelBench::deleteDbFiles()
}
}
-QVariant JsonDbSortingListModelBench::readJsonFile(const QString& filename)
-{
- QString filepath = findFile(filename);
- QFile jsonFile(filepath);
- jsonFile.open(QIODevice::ReadOnly);
- QByteArray json = jsonFile.readAll();
- JsonReader parser;
- bool ok = parser.parse(json);
- if (!ok) {
- qDebug() << filepath << parser.errorString();
- }
- return parser.result();
-}
-
void JsonDbSortingListModelBench::connectListModel(QAbstractListModel *model)
{
connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(dataChanged(QModelIndex,QModelIndex)));
@@ -129,29 +110,26 @@ void JsonDbSortingListModelBench::initTestCase()
deleteDbFiles();
QString socketName = QString("testjsondb_%1").arg(getpid());
- mProcess = launchJsonDbDaemon(JSONDB_DAEMON_BASE, socketName, QStringList() << "-base-name" << dbfile);
+ mProcess = launchJsonDbDaemon(JSONDB_DAEMON_BASE, socketName, QStringList() << "-base-name" << dbfile, __FILE__);
- mClient = new JsonDbClient(this);
- connect(mClient, SIGNAL(notified(QString,QtAddOn::JsonDb::JsonDbNotification)),
- this, SLOT(notified(QString,QtAddOn::JsonDb::JsonDbNotification)));
- connect( mClient, SIGNAL(response(int, const QVariant&)),
- this, SLOT(response(int, const QVariant&)));
- connect( mClient, SIGNAL(error(int, int, const QString&)),
- this, SLOT(error(int, int, const QString&)));
+ connection = new QJsonDbConnection();
+ connection->connectToServer();
mPluginPath = findQMLPluginPath("QtJsonDb");
+ if (mPluginPath.isEmpty())
+ qDebug() << "Couldn't find the plugin path for the plugin QtJsonDb";
// Create the shared Partitions
QVariantMap item;
item.insert("_type", "Partition");
item.insert("name", "com.nokia.shared.1");
- int id = mClient->create(item);
+ int id = create(item);
waitForResponse1(id);
item.clear();
item.insert("_type", "Partition");
item.insert("name", "com.nokia.shared.2");
- id = mClient->create(item);
+ id = create(item);
waitForResponse1(id);
}
@@ -167,37 +145,12 @@ QAbstractListModel *JsonDbSortingListModelBench::createModel()
return 0;
}
newModel->component = new QQmlComponent(newModel->engine);
- newModel->component->setData("import QtQuick 2.0\nimport QtJsonDb 1.0 as JsonDb \n"
- "JsonDb.JsonDbCachingListModel {signal callbackSignal(variant index, variant response); id: contactsModel;}",
- QUrl());
+ newModel->component->setData(qmlProgram.toLocal8Bit(), QUrl());
+
newModel->model = newModel->component->create();
if (newModel->component->isError())
qDebug() << newModel->component->errors();
- QObject::connect(newModel->model, SIGNAL(callbackSignal(QVariant, QVariant)),
- this, SLOT(callbackSlot(QVariant, QVariant)));
-
- newModel->partitionComponent1 = new QQmlComponent(newModel->engine);
- newModel->partitionComponent1->setData("import QtQuick 2.0\nimport QtJsonDb 1.0 as JsonDb \n"
- "JsonDb.Partition {name: \"com.nokia.shared.1\"}",
- QUrl());
- newModel->partition1 = newModel->partitionComponent1->create();
- if (newModel->partitionComponent1->isError())
- qDebug() << newModel->partitionComponent1->errors();
-
-
- newModel->partitionComponent2 = new QQmlComponent(newModel->engine);
- newModel->partitionComponent2->setData("import QtQuick 2.0\nimport QtJsonDb 1.0 as JsonDb \n"
- "JsonDb.Partition {name: \"com.nokia.shared.2\"}",
- QUrl());
- newModel->partition2 = newModel->partitionComponent2->create();
- if (newModel->partitionComponent2->isError())
- qDebug() << newModel->partitionComponent2->errors();
-
- QQmlListReference partitions(newModel->model, "partitions", newModel->engine);
- partitions.append(newModel->partition1);
- partitions.append(newModel->partition2);
-
mModels.append(newModel);
return (QAbstractListModel*)(newModel->model);
}
@@ -216,9 +169,9 @@ void JsonDbSortingListModelBench::deleteModel(QAbstractListModel *model)
// Delete all the items of this type from JsonDb
void JsonDbSortingListModelBench::deleteItems(const QString &type, const QString &partition)
{
- int id = mClient->query(QString("[?_type=\"%1\"]").arg(type), 0, -1, partition);
+ int id = query(QString("[?_type=\"%1\"]").arg(type), partition);
waitForResponse1(id);
- id = mClient->remove(mData.toMap().value("data"), partition);
+ id = remove(lastResult, partition);
waitForResponse1(id);
}
@@ -233,26 +186,12 @@ void JsonDbSortingListModelBench::cleanupTestCase()
deleteDbFiles();
}
-void JsonDbSortingListModelBench::callbackSlot(QVariant error, QVariant response)
-{
- mCallbackReceived = true;
- callbackError = error.isValid();
- callbackMeta = response;
- callbackResponse = response.toMap().value("object");
- mEventLoop.quit();
-}
-
void JsonDbSortingListModelBench::getIndex(int index)
{
- mCallbackReceived = false;
-
- const QString createString = QString("get(%1, function (error, response) {callbackSignal(error, response);});");
+ const QString createString = QString("get(%1);");
const QString getString = QString(createString).arg(index);
QQmlExpression expr(mModels.last()->engine->rootContext(), mModels.last()->model, getString);
- expr.evaluate().toInt();
-
- if (!mCallbackReceived)
- waitForCallback();
+ callbackResponse = expr.evaluate();
}
void JsonDbSortingListModelBench::createIndex(const QString &property, const QString &propertyType)
@@ -263,10 +202,10 @@ void JsonDbSortingListModelBench::createIndex(const QString &property, const QSt
item.insert("propertyName", property);
item.insert("propertyType", propertyType);
- int id = mClient->create(item, "com.nokia.shared.1");
+ int id = create(item, "com.nokia.shared.1");
waitForResponse1(id);
- id = mClient->create(item, "com.nokia.shared.2");
+ id = create(item, "com.nokia.shared.2");
waitForResponse1(id);
}
@@ -274,12 +213,13 @@ void JsonDbSortingListModelBench::createIndex(const QString &property, const QSt
// Populate model of 300 items.
void JsonDbSortingListModelBench::ModelStartup()
{
+ resetWaitFlags();
QVariantMap item;
for (int i=0; i < 300; i++) {
item.insert("_type", __FUNCTION__);
item.insert("name", QString("Arnie_%1").arg(i));
- int id = mClient->create(item, "com.nokia.shared.1");
+ int id = create(item, "com.nokia.shared.1");
waitForResponse1(id);
}
@@ -295,8 +235,8 @@ void JsonDbSortingListModelBench::ModelStartup()
// now start it working
QCOMPARE(listModel->rowCount(), 0);
-
QBENCHMARK_ONCE {
+ mWaitingForStateChanged = true;
waitForStateOrTimeout();
}
@@ -309,19 +249,20 @@ void JsonDbSortingListModelBench::ModelStartup()
// Populate model of 300 items two partitions.
void JsonDbSortingListModelBench::ModelStartupTwoPartitions()
{
+ resetWaitFlags();
QVariantMap item;
for (int i=0; i < 300; i = i+2) {
item.insert("_type", __FUNCTION__);
item.insert("name", QString("Arnie_%1").arg(i));
- int id = mClient->create(item, "com.nokia.shared.1");
+ int id = create(item, "com.nokia.shared.1");
waitForResponse1(id);
}
for (int i=1; i < 300; i = i+2) {
item.insert("_type", __FUNCTION__);
item.insert("name", QString("Arnie_%1").arg(i));
- int id = mClient->create(item, "com.nokia.shared.2");
+ int id = create(item, "com.nokia.shared.2");
waitForResponse1(id);
}
@@ -339,9 +280,11 @@ void JsonDbSortingListModelBench::ModelStartupTwoPartitions()
QCOMPARE(listModel->rowCount(), 0);
QBENCHMARK_ONCE {
+ mWaitingForStateChanged = true;
waitForStateOrTimeout();
}
+ QCOMPARE(mWaitingForReset, false);
QCOMPARE(listModel->rowCount(), 300);
deleteItems(__FUNCTION__, "com.nokia.shared.1");
@@ -353,12 +296,13 @@ void JsonDbSortingListModelBench::ModelStartupTwoPartitions()
// Populate model of 300 items sorted.
void JsonDbSortingListModelBench::ModelStartupSorted()
{
+ resetWaitFlags();
QVariantMap item;
for (int i=0; i < 300; i++) {
item.insert("_type", __FUNCTION__);
item.insert("name", QString("Arnie_%1").arg(i));
- int id = mClient->create(item, "com.nokia.shared.1");
+ int id = create(item, "com.nokia.shared.1");
waitForResponse1(id);
}
@@ -377,9 +321,11 @@ void JsonDbSortingListModelBench::ModelStartupSorted()
QCOMPARE(listModel->rowCount(), 0);
QBENCHMARK_ONCE {
+ mWaitingForStateChanged = true;
waitForStateOrTimeout();
}
+ QCOMPARE(mWaitingForReset, false);
QCOMPARE(listModel->rowCount(), 300);
deleteItems(__FUNCTION__, "com.nokia.shared.1");
@@ -387,13 +333,14 @@ void JsonDbSortingListModelBench::ModelStartupSorted()
}
-void JsonDbSortingListModelBench::getItemNotInCache()
+void JsonDbSortingListModelBench::getItems()
{
+ resetWaitFlags();
QVariantMap item;
for (int i=0; i < 300; i++) {
item.insert("_type", __FUNCTION__);
item.insert("name", QString("Arnie_%1").arg(i));
- int id = mClient->create(item, "com.nokia.shared.1");
+ int id = create(item, "com.nokia.shared.1");
waitForResponse1(id);
}
@@ -409,8 +356,10 @@ void JsonDbSortingListModelBench::getItemNotInCache()
// now start it working
QCOMPARE(listModel->rowCount(), 0);
-
+ mWaitingForStateChanged = true;
waitForStateOrTimeout();
+
+ QCOMPARE(mWaitingForReset, false);
QCOMPARE(listModel->rowCount(), 300);
// Now get some items so we know that index 20 is not in the cache
@@ -429,11 +378,12 @@ void JsonDbSortingListModelBench::getItemNotInCache()
void JsonDbSortingListModelBench::deleteItem()
{
+ resetWaitFlags();
QVariantMap item;
for (int i=0; i < 300; i++) {
item.insert("_type", __FUNCTION__);
item.insert("name", QString("Arnie_%1").arg(i));
- int id = mClient->create(item, "com.nokia.shared.1");
+ int id = create(item, "com.nokia.shared.1");
waitForResponse1(id);
}
@@ -448,14 +398,16 @@ void JsonDbSortingListModelBench::deleteItem()
connectListModel(listModel);
// now start it working
+ mWaitingForStateChanged = true;
waitForStateOrTimeout();
QCOMPARE(listModel->rowCount(), 300);
QVariantMap itemToRemove;
// get the item that we shall remove
getIndex(20);
- itemToRemove.insert("_uuid", callbackResponse.toMap().value("_uuid").toString());
- itemToRemove.insert("_version", callbackResponse.toMap().value("_version").toString());
+ QVariantMap retrievedItem = callbackResponse.toMap().value("object").toMap();
+ itemToRemove.insert("_uuid", retrievedItem.value("_uuid").toString());
+ itemToRemove.insert("_version", retrievedItem.value("_version").toString());
// Now get some items so we know that index 20 is not in the cache
getIndex(100);
@@ -464,11 +416,13 @@ void JsonDbSortingListModelBench::deleteItem()
getIndex(255);
// Delete the item
- mClient->remove(itemToRemove, "com.nokia.shared.1");
+ int id = remove(itemToRemove, "com.nokia.shared.1");
QBENCHMARK_ONCE {
waitForItemChanged(true);
}
+ while (lastRequestId < id)
+ waitForResponse1(id);
QCOMPARE(listModel->rowCount(), 299);
@@ -479,11 +433,12 @@ void JsonDbSortingListModelBench::deleteItem()
void JsonDbSortingListModelBench::scrollThousandItems()
{
+ resetWaitFlags();
QVariantMap item;
for (int i=0; i < 1000; i++) {
item.insert("_type", __FUNCTION__);
item.insert("name", QString("Arnie_%1").arg(i));
- int id = mClient->create(item, "com.nokia.shared.1");
+ int id = create(item, "com.nokia.shared.1");
waitForResponse1(id);
}
@@ -498,6 +453,7 @@ void JsonDbSortingListModelBench::scrollThousandItems()
connectListModel(listModel);
// now start it working
+ mWaitingForStateChanged = true;
waitForStateOrTimeout();
QCOMPARE(listModel->rowCount(), 1000);
@@ -515,15 +471,21 @@ void JsonDbSortingListModelBench::scrollThousandItems()
void JsonDbSortingListModelBench::modelReset()
{
- mWaitingForReset = false;
- mEventLoop2.exit(0);
+ if (mWaitingForReset) {
+ mWaitingForReset = false;
+ eventLoop1.exit(0);
+ }
}
void JsonDbSortingListModelBench::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
{
Q_UNUSED(topLeft);
Q_UNUSED(bottomRight);
- mWaitingForDataChange = false;
+ mItemsUpdated++;
+ if (mWaitingForChanged) {
+ mWaitingForChanged = false;
+ eventLoop1.exit(0);
+ }
}
void JsonDbSortingListModelBench::rowsInserted(const QModelIndex &parent, int first, int last)
@@ -531,8 +493,11 @@ void JsonDbSortingListModelBench::rowsInserted(const QModelIndex &parent, int fi
Q_UNUSED(parent);
Q_UNUSED(first);
Q_UNUSED(last);
- mItemsCreated++;
- mEventLoop2.exit(0);
+ mItemsCreated += last-first+1;
+ if (mWaitingForRowsInserted) {
+ mWaitingForRowsInserted = false;
+ eventLoop1.exit(0);
+ }
}
void JsonDbSortingListModelBench::rowsRemoved(const QModelIndex &parent, int first, int last)
@@ -540,7 +505,11 @@ void JsonDbSortingListModelBench::rowsRemoved(const QModelIndex &parent, int fir
Q_UNUSED(parent);
Q_UNUSED(first);
Q_UNUSED(last);
- mWaitingForRowsRemoved = false;
+ mItemsRemoved += last-first+1;
+ if (mWaitingForRemoved) {
+ mWaitingForRemoved = false;
+ eventLoop1.exit(0);
+ }
}
void JsonDbSortingListModelBench::rowsMoved( const QModelIndex &parent, int start, int end, const QModelIndex &destination, int row )
@@ -556,83 +525,109 @@ void JsonDbSortingListModelBench::stateChanged()
{
// only exit on ready state.
QAbstractListModel *model = qobject_cast<QAbstractListModel *>(sender());
- if (model->property("state") == 2) {
+ if (model->property("state").toInt() == 2 && mWaitingForStateChanged) {
mWaitingForStateChanged = false;
- mEventLoop2.exit(0);
+ eventLoop1.exit(0);
}
}
void JsonDbSortingListModelBench::waitForItemsCreated(int items)
{
- mTimeoutCalled = false;
+ mTimedOut = false;
QTimer timer;
QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout()));
- QObject::connect(&timer, SIGNAL(timeout()), &mEventLoop2, SLOT(quit()));
- timer.start(mClientTimeout);
- mElapsedTimer.start();
+ timer.start(clientTimeout);
+ elapsedTimer.start();
- mItemsCreated = 0;
- while (mItemsCreated != items && !mTimeoutCalled)
- mEventLoop2.processEvents(QEventLoop::AllEvents, mClientTimeout);
+ while (!mTimedOut && mItemsCreated != items) {
+ mWaitingForRowsInserted = true;
+ eventLoop1.exec(QEventLoop::AllEvents);
+ }
+ if (mTimedOut)
+ qDebug () << "waitForItemsCreated Timed out";
}
void JsonDbSortingListModelBench::waitForExitOrTimeout()
{
- mTimeoutCalled = false;
QTimer timer;
QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout()));
- QObject::connect(&timer, SIGNAL(timeout()), &mEventLoop2, SLOT(quit()));
- timer.start(mClientTimeout);
- mElapsedTimer.start();
- mEventLoop2.exec(QEventLoop::AllEvents);
+ timer.start(clientTimeout);
+ elapsedTimer.start();
+ eventLoop1.exec(QEventLoop::AllEvents);
}
void JsonDbSortingListModelBench::waitForStateOrTimeout()
{
- mTimeoutCalled = false;
+ mTimedOut = false;
QTimer timer;
QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout()));
- QObject::connect(&timer, SIGNAL(timeout()), &mEventLoop2, SLOT(quit()));
- timer.start(mClientTimeout);
- mElapsedTimer.start();
+ timer.start(clientTimeout);
+ elapsedTimer.start();
- mWaitingForStateChanged = true;
- while (mWaitingForStateChanged && !mTimeoutCalled)
- mEventLoop2.processEvents(QEventLoop::AllEvents, mClientTimeout);
+ while (mWaitingForStateChanged && !mTimedOut) {
+ eventLoop1.exec(QEventLoop::AllEvents);
+ }
+ if (mTimedOut)
+ qDebug () << "waitForStateOrTimeout Timed out";
}
void JsonDbSortingListModelBench::timeout()
{
- ClientWrapper::timeout();
- mTimeoutCalled = true;
+ qDebug () << "JsonDbSortingListModelBench::timeout()";
+ RequestWrapper::timeout();
mTimedOut = true;
+ eventLoop1.quit();
+}
+
+void JsonDbSortingListModelBench::resetWaitFlags()
+{
+ mItemsCreated = 0;
+ mItemsUpdated = 0;
+ mItemsRemoved = 0;
+ mWaitingForStateChanged = false;
+ mWaitingForRowsInserted = false;
+ mWaitingForReset = false;
+ mWaitingForChanged = false;
+ mWaitingForRemoved = false;
}
void JsonDbSortingListModelBench::waitForItemChanged(bool waitForRemove)
{
- mTimeoutCalled = false;
+ mTimedOut = false;
QTimer timer;
QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout()));
- QObject::connect(&timer, SIGNAL(timeout()), &mEventLoop2, SLOT(quit()));
- timer.start(mClientTimeout);
- mElapsedTimer.start();
+ timer.start(clientTimeout);
+ elapsedTimer.start();
- mWaitingForRowsRemoved = true;
- mWaitingForDataChange = true;
+ mWaitingForRemoved = true;
+ mWaitingForChanged = true;
mItemsCreated = 0;
mWaitingForReset = true;
+ mWaitingForStateChanged = true;
bool waitMore = true;
- while (waitMore && !mTimeoutCalled) {
- if (!mWaitingForDataChange)
+ while (waitMore && !mTimedOut) {
+ if (!mWaitingForChanged) {
+ //qDebug() << "waitForItemChanged: mWaitingForChanged";
break;
- if (mItemsCreated)
+ }
+ if (!mWaitingForStateChanged) {
+ //qDebug() << "waitForItemChanged: mWaitingForStateChanged";
break;
- if (!mWaitingForReset)
+ }
+ if (mItemsCreated){
+ //qDebug() << "waitForItemChanged: mItemsCreated";
break;
- if (waitForRemove && !mWaitingForRowsRemoved)
+ }
+ if (!mWaitingForReset){
+ //qDebug() << "waitForItemChanged: mWaitingForReset";
break;
- mEventLoop2.processEvents(QEventLoop::AllEvents);
+ }
+ if (waitForRemove && !mWaitingForRemoved){
+ //qDebug() << "waitForItemChanged: mWaitingForRemoved";
+ break;
+ }
+ eventLoop1.exec(QEventLoop::AllEvents);
}
}
QTEST_MAIN(JsonDbSortingListModelBench)
diff --git a/tests/benchmarks/jsondbsortinglistmodel/jsondbsortinglistmodel-bench.h b/tests/benchmarks/jsondbsortinglistmodel/jsondbsortinglistmodel-bench.h
index 68ae04f8..e28a6453 100644
--- a/tests/benchmarks/jsondbsortinglistmodel/jsondbsortinglistmodel-bench.h
+++ b/tests/benchmarks/jsondbsortinglistmodel/jsondbsortinglistmodel-bench.h
@@ -41,22 +41,9 @@
#ifndef JsonDbSortingListModel_Bench_H
#define JsonDbSortingListModel_Bench_H
-#include <QCoreApplication>
-#include <QList>
-#include <QTest>
-#include <QFile>
-#include <QProcess>
-#include <QEventLoop>
-#include <QDebug>
-#include <QLocalSocket>
-#include <QTimer>
-
-#include <jsondb-client.h>
-#include <jsondb-error.h>
-
#include <QAbstractListModel>
-#include "clientwrapper.h"
-#include "../../shared/qmltestutil.h"
+#include "requestwrapper.h"
+#include "qmltestutil.h"
QT_BEGIN_NAMESPACE
class QQmlEngine;
@@ -65,22 +52,16 @@ QT_END_NAMESPACE
QT_USE_NAMESPACE_JSONDB
-class JsonDbListModel;
-
class ModelData {
public:
ModelData();
~ModelData();
QQmlEngine *engine;
QQmlComponent *component;
- QQmlComponent *partitionComponent1;
- QQmlComponent *partitionComponent2;
QObject *model;
- QObject *partition1;
- QObject *partition2;
};
-class JsonDbSortingListModelBench: public ClientWrapper
+class JsonDbSortingListModelBench: public RequestWrapper
{
Q_OBJECT
public:
@@ -98,9 +79,6 @@ public slots:
void modelReset();
void stateChanged();
- void callbackSlot(QVariant error, QVariant response);
-
-
protected slots:
void timeout();
@@ -110,7 +88,7 @@ private slots:
void ModelStartup();
void ModelStartupTwoPartitions();
void ModelStartupSorted();
- void getItemNotInCache();
+ void getItems();
void deleteItem();
void scrollThousandItems();
@@ -125,29 +103,23 @@ private:
QAbstractListModel *createModel();
void deleteModel(QAbstractListModel *model);
void deleteItems(const QString &type, const QString &partition);
- QVariant readJsonFile(const QString &filename);
+ void resetWaitFlags();
private:
QProcess *mProcess;
- QStringList mNotificationsReceived;
QList<ModelData*> mModels;
QString mPluginPath;
- QEventLoop mEventLoop2; // for all listmodel slots
// Response values
+ bool mTimedOut;
int mItemsCreated;
- bool mWaitingForNotification;
- bool mWaitingForDataChange;
- bool mWaitingForRowsRemoved;
- bool mTimeoutCalled;
- bool mWaitingForReset;
+ int mItemsUpdated;
+ int mItemsRemoved;
bool mWaitingForStateChanged;
-
- bool mTimedOut;
- bool callbackError;
- bool mCallbackReceived;
- QVariant callbackMeta;
- QVariant callbackResponse;
+ bool mWaitingForRowsInserted;
+ bool mWaitingForReset;
+ bool mWaitingForChanged;
+ bool mWaitingForRemoved;
};
diff --git a/tests/benchmarks/jsondbsortinglistmodel/jsondbsortinglistmodel.pro b/tests/benchmarks/jsondbsortinglistmodel/jsondbsortinglistmodel.pro
index f1fe37ea..60b03207 100644
--- a/tests/benchmarks/jsondbsortinglistmodel/jsondbsortinglistmodel.pro
+++ b/tests/benchmarks/jsondbsortinglistmodel/jsondbsortinglistmodel.pro
@@ -3,15 +3,15 @@ TARGET = tst_bench_jsondbsortinglistmodel
DEPENDPATH += .
INCLUDEPATH += .
-QT = core network testlib gui qml jsondbcompat-private
+QT = core network testlib gui qml jsondb
CONFIG -= app_bundle
CONFIG += testcase
include($$PWD/../../shared/shared.pri)
-include($$PWD/../../../src/3rdparty/qjson/qjson.pri)
DEFINES += JSONDB_DAEMON_BASE=\\\"$$QT.jsondb.bins\\\"
DEFINES += SRCDIR=\\\"$$PWD/\\\"
-HEADERS += jsondbsortinglistmodel-bench.h
+HEADERS += jsondbsortinglistmodel-bench.h \
+ $$PWD/../../shared/requestwrapper.h
SOURCES += jsondbsortinglistmodel-bench.cpp
diff --git a/tests/benchmarks/jsondbsortinglistmodel/partitions.json b/tests/benchmarks/jsondbsortinglistmodel/partitions.json
new file mode 100644
index 00000000..1cdd0fa5
--- /dev/null
+++ b/tests/benchmarks/jsondbsortinglistmodel/partitions.json
@@ -0,0 +1,4 @@
+[
+ { "name" :"com.nokia.shared.1" },
+ { "name" :"com.nokia.shared.2" }
+]
diff --git a/tests/benchmarks/daemon/bench_daemon.cpp b/tests/benchmarks/partition/bench_partition.cpp
index f880af85..cae5fc0b 100644
--- a/tests/benchmarks/daemon/bench_daemon.cpp
+++ b/tests/benchmarks/partition/bench_partition.cpp
@@ -47,36 +47,34 @@
#include <QDir>
#include <QTime>
-#include "json.h"
-
#include "jsondbpartition.h"
#include "jsondbindex.h"
#include "jsondbindexquery.h"
#include "jsondbsettings.h"
-#include "jsondb-strings.h"
-#include "jsondb-error.h"
+#include "jsondbstrings.h"
+#include "jsondberrors.h"
#include <qjsonobject.h>
#include "../../shared/util.h"
-QT_USE_NAMESPACE_JSONDB
+QT_USE_NAMESPACE_JSONDB_PARTITION
Q_DECLARE_METATYPE(QJsonArray)
Q_DECLARE_METATYPE(QJsonObject)
-class TestJsonDb: public QObject
+class TestPartition: public QObject
{
Q_OBJECT
public:
- TestJsonDb();
+ TestPartition();
private slots:
void init();
void initTestCase();
void cleanupTestCase();
void cleanup();
- void contactListChaff();//moved from auto/daemon
+ void contactListChaff();
void compact();
void jsonArrayCreate();
void jsonObjectCreate();
@@ -119,17 +117,13 @@ private slots:
void benchmarkFindUnindexed();
void benchmarkFindReindexed();
void benchmarkFindNames();
- void findNamesMapL();
- void benchmarkFindNamesMapL();
- void findNamesMapO();
- void benchmarkFindNamesMapO();
+ void findNamesMapObject();
+ void benchmarkFindNamesMapObject();
void benchmarkCursorCount();
void benchmarkQueryCount();
void benchmarkScriptEngineCreation();
private:
- QJsonValue readJsonFile(const QString &filename);
- QJsonValue readJson(const QByteArray &json);
void removeDbFiles();
void addSchema(const QString &schemaName);
void addIndex(const QString &propertyName, const QString &propertyType=QString(), const QString &objectType=QString());
@@ -156,13 +150,13 @@ private:
const char *kFilename = "testdatabase";
-TestJsonDb::TestJsonDb() :
+TestPartition::TestPartition() :
mJsonDbPartition(0)
, mOwner(0)
{
}
-void TestJsonDb::removeDbFiles()
+void TestPartition::removeDbFiles()
{
QStringList filters;
filters << QString::fromLatin1(kFilename)+QLatin1Char('*');
@@ -172,11 +166,11 @@ void TestJsonDb::removeDbFiles()
QFile::remove(fileName);
}
-void TestJsonDb::initTestCase()
+void TestPartition::initTestCase()
{
QCoreApplication::setOrganizationName("Example");
QCoreApplication::setOrganizationDomain("example.com");
- QCoreApplication::setApplicationName("TestJsonDb");
+ QCoreApplication::setApplicationName("TestPartition");
QCoreApplication::setApplicationVersion("1.0");
removeDbFiles();
@@ -185,7 +179,7 @@ void TestJsonDb::initTestCase()
mJsonDbPartition = new JsonDbPartition(kFilename, QStringLiteral("com.example.JsonDbTest"), mOwner, this);
mJsonDbPartition->open();
- QFile contactsFile(":/daemon/json/largeContactsTest.json");
+ QFile contactsFile(":/partition/json/largeContactsTest.json");
QVERIFY(contactsFile.exists());
contactsFile.open(QIODevice::ReadOnly);
QByteArray json = contactsFile.readAll();
@@ -234,28 +228,32 @@ void TestJsonDb::initTestCase()
qDebug() << "done. Time per item (ms):" << (double)elapsed / count << "count" << count << "elapsed" << elapsed << "ms";
}
-void TestJsonDb::init()
+void TestPartition::init()
{
}
-void TestJsonDb::cleanupTestCase()
+void TestPartition::cleanupTestCase()
{
if (mJsonDbPartition) {
mJsonDbPartition->close();
delete mJsonDbPartition;
mJsonDbPartition = 0;
}
+ if (mOwner) {
+ delete mOwner;
+ mOwner = 0;
+ }
removeDbFiles();
}
-void TestJsonDb::cleanup()
+void TestPartition::cleanup()
{
QCOMPARE(mJsonDbPartition->mTransactionDepth, 0);
}
-void TestJsonDb::addSchema(const QString &schemaName)
+void TestPartition::addSchema(const QString &schemaName)
{
- QJsonValue schema = readJsonFile(QString(":/daemon/schemas/%1.json").arg(schemaName)).toArray();
+ QJsonValue schema = readJsonFile(QString(":/partition/schemas/%1.json").arg(schemaName)).toArray();
JsonDbObject schemaDocument;
schemaDocument.insert(JsonDbString::kTypeStr, JsonDbString::kSchemaTypeStr);
schemaDocument.insert("name", schemaName);
@@ -265,7 +263,7 @@ void TestJsonDb::addSchema(const QString &schemaName)
verifyGoodResult(result);
}
-void TestJsonDb::addIndex(const QString &propertyName, const QString &propertyType, const QString &objectType)
+void TestPartition::addIndex(const QString &propertyName, const QString &propertyType, const QString &objectType)
{
QJsonObject index;
index.insert(JsonDbString::kTypeStr, JsonDbString::kIndexTypeStr);
@@ -278,26 +276,26 @@ void TestJsonDb::addIndex(const QString &propertyName, const QString &propertyTy
QVERIFY(result.code == JsonDbError::NoError);
}
-void TestJsonDb::compact()
+void TestPartition::compact()
{
mJsonDbPartition->compact();
}
-void TestJsonDb::jsonArrayCreate()
+void TestPartition::jsonArrayCreate()
{
QBENCHMARK {
QJsonArray list;
}
}
-void TestJsonDb::jsonObjectCreate()
+void TestPartition::jsonObjectCreate()
{
QBENCHMARK {
QJsonObject map;
}
}
-void TestJsonDb::jsonArrayReadValue_data()
+void TestPartition::jsonArrayReadValue_data()
{
QTest::addColumn<QJsonArray>("list");
QTest::addColumn<int>("index");
@@ -315,7 +313,7 @@ void TestJsonDb::jsonArrayReadValue_data()
QTest::newRow("large list") << data3 << 12 << 12;
}
-void TestJsonDb::jsonArrayReadValue()
+void TestPartition::jsonArrayReadValue()
{
QFETCH(QJsonArray, list);
QFETCH(int, index);
@@ -326,7 +324,7 @@ void TestJsonDb::jsonArrayReadValue()
}
}
-void TestJsonDb::jsonObjectReadValue_data()
+void TestPartition::jsonObjectReadValue_data()
{
QTest::addColumn<QJsonObject>("map");
QTest::addColumn<QString>("property");
@@ -344,7 +342,7 @@ void TestJsonDb::jsonObjectReadValue_data()
QTest::newRow("large map") << data2 << QString::number(12) << 12;
}
-void TestJsonDb::jsonObjectReadValue()
+void TestPartition::jsonObjectReadValue()
{
QFETCH(QJsonObject, map);
QFETCH(QString, property);
@@ -355,7 +353,7 @@ void TestJsonDb::jsonObjectReadValue()
}
}
-void TestJsonDb::jsonArrayInsertValue()
+void TestPartition::jsonArrayInsertValue()
{
QBENCHMARK {
QJsonArray list;
@@ -364,7 +362,7 @@ void TestJsonDb::jsonArrayInsertValue()
}
}
-void TestJsonDb::jsonObjectInsertValue()
+void TestPartition::jsonObjectInsertValue()
{
const int iterations = 1024;
QVarLengthArray<QString, iterations> names;
@@ -379,18 +377,18 @@ void TestJsonDb::jsonObjectInsertValue()
}
}
-void TestJsonDb::benchmarkCreate()
+void TestPartition::benchmarkCreate()
{
- QJsonArray contacts(readJsonFile(":/daemon/json/largeContactsTest.json").toArray());
+ QJsonArray contacts(readJsonFile(":/partition/json/largeContactsTest.json").toArray());
QBENCHMARK {
JsonDbObject contact(contacts.at(0).toObject());
mJsonDbPartition->updateObject(mOwner, contact);
}
}
-void TestJsonDb::benchmarkFileAppend()
+void TestPartition::benchmarkFileAppend()
{
- QJsonArray contacts(readJsonFile(":/daemon/json/largeContactsTest.json").toArray());
+ QJsonArray contacts(readJsonFile(":/partition/json/largeContactsTest.json").toArray());
QFile objectFile("objectFile.bin");
objectFile.open(QIODevice::ReadWrite);
@@ -401,9 +399,9 @@ void TestJsonDb::benchmarkFileAppend()
}
}
-void TestJsonDb::benchmarkFileAppend2()
+void TestPartition::benchmarkFileAppend2()
{
- QJsonValue bson(readJsonFile(":/daemon/json/largeContactsTest.json"));
+ QJsonValue bson(readJsonFile(":/partition/json/largeContactsTest.json"));
QJsonArray contacts(bson.toArray());
QFile objectFile("objectFile.bin");
objectFile.open(QIODevice::ReadWrite);
@@ -420,7 +418,7 @@ void TestJsonDb::benchmarkFileAppend2()
}
}
-void TestJsonDb::benchmarkParseQuery_data()
+void TestPartition::benchmarkParseQuery_data()
{
QTest::addColumn<QString>("query");
QTest::newRow("1") << "[?foo exists]";
@@ -432,32 +430,25 @@ void TestJsonDb::benchmarkParseQuery_data()
QTest::newRow("7") << "[?foo=%bar]";
QTest::newRow("8") << "[?foo=\"bar\" | foo=\"baz\"]";
QTest::newRow("9") << "[?foo=\"bar\"][/foo]";
- QTest::newRow("10") << "[?foo=\"bar\"][= a ]";
QTest::newRow("11") << "[?foo =~ \"/a\\//\"]";
- QTest::newRow("12") << "[?foo=\"bar\"][= a,b,c]";
- QTest::newRow("13") << "[?foo=\"bar\"][= a->foreign,b,c]";
- QTest::newRow("14") << "[?foo=\"bar\"][=[ a,b,c]]";
QTest::newRow("15") << "[?foo=\"bar\"][={ a:x, b:y, c:z}]";
QTest::newRow("16") << "[?foo=\"bar\"][={ a:x->foreign, b:y, c:z}]";
- QTest::newRow("17") << "[?foo=\"bar\"][= _uuid, name.first, name.last ]";
QTest::newRow("18") << "[?_type=\"contact\"][= { uuid: _uuid, first: name.first, last: name.last } ]";
QTest::newRow("19") << "[?telephoneNumbers.*.number=\"6175551212\"]";
- QTest::newRow("20") << "[?_type=\"contact\"][= .telephoneNumbers[*].number]";
QTest::newRow("21") << "[?_type=\"contact\"][?foo startsWith \"bar\"]";
}
-void TestJsonDb::benchmarkParseQuery()
+void TestPartition::benchmarkParseQuery()
{
QFETCH(QString, query);
QJsonObject bindings;
bindings.insert("bar", QString("barValue"));
QBENCHMARK {
- JsonDbQuery *jq = JsonDbQuery::parse(query, bindings);
- delete jq;
+ QScopedPointer<JsonDbQuery> jq(JsonDbQuery::parse(query, bindings));
}
}
-void TestJsonDb::benchmarkFieldMatch()
+void TestPartition::benchmarkFieldMatch()
{
int count = mContactList.size();
if (!count)
@@ -475,7 +466,7 @@ void TestJsonDb::benchmarkFieldMatch()
}
}
-void TestJsonDb::benchmarkTokenizer()
+void TestPartition::benchmarkTokenizer()
{
QStringList queries = (QStringList()
<< "[?abc=\"def\"]"
@@ -484,10 +475,6 @@ void TestJsonDb::benchmarkTokenizer()
<< "[?abc->def=\"ghi\"]"
<< "[?abc.def=\"ghi\"][/abc.def]"
<< "[?abc.def=\"ghi\"][\\foo]"
- << "[?abc.def=\"ghi\"][=foo]"
- << "[?abc.def=\"ghi\"][=foo,bar]"
- << "[?abc.def=\"ghi\"][=.foo,.bar]"
- << "[?abc.def=\"ghi\"][=[.foo,.bar]]"
<< "[?abc.def=\"ghi\"][={foo:Foo,bar:Bar}][/foo]"
);
foreach (QString query, queries) {
@@ -508,7 +495,7 @@ QByteArray makeForwardKey(const QJsonValue &fieldValue, const ObjectKey &objectK
int forwardKeyCmp(const QByteArray &, const QByteArray &);
} } // end namespace QtAddOn::JsonDb
-void TestJsonDb::benchmarkForwardKeyCmp()
+void TestPartition::benchmarkForwardKeyCmp()
{
int count = mContactList.size();
@@ -538,7 +525,7 @@ void TestJsonDb::benchmarkForwardKeyCmp()
}
}
-void TestJsonDb::benchmarkParsedQuery()
+void TestPartition::benchmarkParsedQuery()
{
int count = mContactList.size();
if (!count)
@@ -573,7 +560,7 @@ void TestJsonDb::benchmarkParsedQuery()
}
}
-void TestJsonDb::benchmarkSchemaValidation_data()
+void TestPartition::benchmarkSchemaValidation_data()
{
QTest::addColumn<QByteArray>("item");
QTest::addColumn<bool>("isPerson");
@@ -593,7 +580,7 @@ void TestJsonDb::benchmarkSchemaValidation_data()
<< QByteArray("{ \"name\":\"Alice's great-grandmother\", \"age\": 130}") << false << false;
}
-void TestJsonDb::benchmarkSchemaValidation()
+void TestPartition::benchmarkSchemaValidation()
{
bool validate = jsondbSettings->validateSchemas();
jsondbSettings->setValidateSchemas(true);
@@ -615,7 +602,7 @@ void TestJsonDb::benchmarkSchemaValidation()
static int schemaId = 0;
const QString personSchemaName = QString::fromLatin1("personBenchmark") + QString::number(++schemaId);
- QJsonObject personSchemaBody = readJson(person).toObject();
+ QJsonObject personSchemaBody = QJsonDocument::fromJson(person).object();
JsonDbObject personSchemaObject;
personSchemaObject.insert(JsonDbString::kTypeStr, JsonDbString::kSchemaTypeStr);
personSchemaObject.insert("name", personSchemaName);
@@ -628,7 +615,7 @@ void TestJsonDb::benchmarkSchemaValidation()
QList<QJsonObject> objects;
objects.reserve(numberOfIterations);
for (uint i = 0; i < numberOfIterations; ++i) {
- QJsonObject object = readJson(item).toObject();
+ QJsonObject object = QJsonDocument::fromJson(item).object();
object.insert("testingForAdult", (int)i);
object.insert(JsonDbString::kTypeStr, personSchemaName);
objects.append(object);
@@ -650,7 +637,7 @@ void TestJsonDb::benchmarkSchemaValidation()
jsondbSettings->setValidateSchemas(validate);
}
-void TestJsonDb::benchmarkFind()
+void TestPartition::benchmarkFind()
{
int count = mContactList.size();
if (!count)
@@ -663,12 +650,13 @@ void TestJsonDb::benchmarkFind()
.arg(JsonDbString::kTypeStr)
.arg("contact")
.arg(item.value("name").toString());
- JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, JsonDbQuery::parse(query), 1);
+ QScopedPointer<JsonDbQuery> parsedQuery(JsonDbQuery::parse(query));
+ JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, parsedQuery.data(), 1);
verifyGoodQueryResult(queryResult);
}
}
-void TestJsonDb::benchmarkFindByName()
+void TestPartition::benchmarkFindByName()
{
int count = mContactList.size();
if (!count)
@@ -679,12 +667,13 @@ void TestJsonDb::benchmarkFindByName()
.arg(JsonDbString::kTypeStr)
.arg("contact")
.arg(mFirstNames[mFirstNames.size()-1]);
- JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, JsonDbQuery::parse(query), 1);
+ QScopedPointer<JsonDbQuery> parsedQuery(JsonDbQuery::parse(query));
+ JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, parsedQuery.data(), 1);
verifyGoodQueryResult(queryResult);
}
}
-void TestJsonDb::benchmarkFindByUuid()
+void TestPartition::benchmarkFindByUuid()
{
int count = mContactList.size();
if (!count)
@@ -695,12 +684,13 @@ void TestJsonDb::benchmarkFindByUuid()
QString query = QString("[?%1=\"%2\"]")
.arg(JsonDbString::kUuidStr)
.arg(uuid);
- JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, JsonDbQuery::parse(query));
+ QScopedPointer<JsonDbQuery> parsedQuery(JsonDbQuery::parse(query));
+ JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, parsedQuery.data());
verifyGoodQueryResult(queryResult);
}
}
-void TestJsonDb::benchmarkFindEQ()
+void TestPartition::benchmarkFindEQ()
{
int count = mContactList.size();
if (!count)
@@ -713,12 +703,13 @@ void TestJsonDb::benchmarkFindEQ()
.arg("contact")
.arg(item.propertyLookup("name.first").toString());
QBENCHMARK {
- JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, JsonDbQuery::parse(query));
- verifyGoodQueryResult(queryResult);
+ QScopedPointer<JsonDbQuery> parsedQuery(JsonDbQuery::parse(query));
+ JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, parsedQuery.data());
+ verifyGoodQueryResult(queryResult);
}
}
-void TestJsonDb::benchmarkFindLE()
+void TestPartition::benchmarkFindLE()
{
int count = mContactList.size();
if (!count)
@@ -731,12 +722,13 @@ void TestJsonDb::benchmarkFindLE()
.arg(JsonDbString::kTypeStr)
.arg("contact")
.arg(item.propertyLookup("name.first").toString());
- JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, JsonDbQuery::parse(query), 1);
+ QScopedPointer<JsonDbQuery> parsedQuery(JsonDbQuery::parse(query));
+ JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, parsedQuery.data(), 1);
verifyGoodQueryResult(queryResult);
}
}
-void TestJsonDb::benchmarkFirst()
+void TestPartition::benchmarkFirst()
{
int count = mContactList.size();
if (!count)
@@ -746,12 +738,13 @@ void TestJsonDb::benchmarkFirst()
QString query = QString("[?%1=\"%2\"][?name.last exists][/name.first]")
.arg(JsonDbString::kTypeStr)
.arg("contact");
- JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, JsonDbQuery::parse(query), 1);
+ QScopedPointer<JsonDbQuery> parsedQuery(JsonDbQuery::parse(query));
+ JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, parsedQuery.data(), 1);
verifyGoodQueryResult(queryResult);
}
}
-void TestJsonDb::benchmarkLast()
+void TestPartition::benchmarkLast()
{
int count = mContactList.size();
if (!count)
@@ -761,12 +754,13 @@ void TestJsonDb::benchmarkLast()
QString query = QString("[?%1=\"%2\"][?name.last exists][\\name.first]")
.arg(JsonDbString::kTypeStr)
.arg("contact");
- JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, JsonDbQuery::parse(query), 1);
+ QScopedPointer<JsonDbQuery> parsedQuery(JsonDbQuery::parse(query));
+ JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, parsedQuery.data(), 1);
verifyGoodQueryResult(queryResult);
}
}
-void TestJsonDb::benchmarkFirst10()
+void TestPartition::benchmarkFirst10()
{
int count = mContactList.size();
if (!count)
@@ -776,12 +770,13 @@ void TestJsonDb::benchmarkFirst10()
QString query = QString("[?%1=\"%2\"][?name.last exists][/name.first]")
.arg(JsonDbString::kTypeStr)
.arg("contact");
- JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, JsonDbQuery::parse(query), 10);
+ QScopedPointer<JsonDbQuery> parsedQuery(JsonDbQuery::parse(query));
+ JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, parsedQuery.data(), 10);
verifyGoodQueryResult(queryResult);
}
}
-void TestJsonDb::benchmarkFind10()
+void TestPartition::benchmarkFind10()
{
int count = mContactList.size();
if (!count)
@@ -794,11 +789,12 @@ void TestJsonDb::benchmarkFind10()
.arg(JsonDbString::kTypeStr)
.arg("contact")
.arg(mFirstNames[itemNumber]);
- JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, JsonDbQuery::parse(query), 10);
+ QScopedPointer<JsonDbQuery> parsedQuery(JsonDbQuery::parse(query));
+ JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, parsedQuery.data(), 10);
verifyGoodQueryResult(queryResult);
}
}
-void TestJsonDb::benchmarkFind20()
+void TestPartition::benchmarkFind20()
{
int count = mContactList.size();
if (!count)
@@ -812,12 +808,13 @@ void TestJsonDb::benchmarkFind20()
.arg(JsonDbString::kTypeStr)
.arg("contact")
.arg(item.propertyLookup("name.first").toString());
- JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, JsonDbQuery::parse(query), 20);
+ QScopedPointer<JsonDbQuery> parsedQuery(JsonDbQuery::parse(query));
+ JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, parsedQuery.data(), 20);
verifyGoodQueryResult(queryResult);
}
}
-void TestJsonDb::benchmarkFirstByUuid()
+void TestPartition::benchmarkFirstByUuid()
{
int count = mContactList.size();
if (!count)
@@ -827,12 +824,13 @@ void TestJsonDb::benchmarkFirstByUuid()
QString query = QString("[?%1=\"%2\"][?name.last exists][/_uuid]")
.arg(JsonDbString::kTypeStr)
.arg("contact");
- JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, JsonDbQuery::parse(query), 1);
+ QScopedPointer<JsonDbQuery> parsedQuery(JsonDbQuery::parse(query));
+ JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, parsedQuery.data(), 1);
verifyGoodQueryResult(queryResult);
}
}
-void TestJsonDb::benchmarkLastByUuid()
+void TestPartition::benchmarkLastByUuid()
{
int count = mContactList.size();
if (!count)
@@ -842,12 +840,13 @@ void TestJsonDb::benchmarkLastByUuid()
QString query = QString("[?%1=\"%2\"][?name.last exists][/_uuid]")
.arg(JsonDbString::kTypeStr)
.arg("contact");
- JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, JsonDbQuery::parse(query), 1);
+ QScopedPointer<JsonDbQuery> parsedQuery(JsonDbQuery::parse(query));
+ JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, parsedQuery.data(), 1);
verifyGoodQueryResult(queryResult);
}
}
-void TestJsonDb::benchmarkFirst10ByUuid()
+void TestPartition::benchmarkFirst10ByUuid()
{
int count = mContactList.size();
if (!count)
@@ -857,12 +856,13 @@ void TestJsonDb::benchmarkFirst10ByUuid()
QString query = QString("[?%1=\"%2\"][?name.last exists][/_uuid]")
.arg(JsonDbString::kTypeStr)
.arg("contact");
- JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, JsonDbQuery::parse(query), 10);
+ QScopedPointer<JsonDbQuery> parsedQuery(JsonDbQuery::parse(query));
+ JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, parsedQuery.data(), 10);
verifyGoodQueryResult(queryResult);
}
}
-void TestJsonDb::benchmarkFind10ByUuid()
+void TestPartition::benchmarkFind10ByUuid()
{
int count = mContactList.size();
if (!count)
@@ -874,12 +874,13 @@ void TestJsonDb::benchmarkFind10ByUuid()
.arg(JsonDbString::kTypeStr)
.arg("contact")
.arg(mUuids[itemNumber]);
- JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, JsonDbQuery::parse(query), 10);
+ QScopedPointer<JsonDbQuery> parsedQuery(JsonDbQuery::parse(query));
+ JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, parsedQuery.data(), 10);
verifyGoodQueryResult(queryResult);
}
}
-void TestJsonDb::benchmarkFindUnindexed()
+void TestPartition::benchmarkFindUnindexed()
{
int count = mContactList.size();
if (!count)
@@ -892,12 +893,13 @@ void TestJsonDb::benchmarkFindUnindexed()
.arg(JsonDbString::kTypeStr)
.arg("contact")
.arg(item.value("firstName").toString());
- JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, JsonDbQuery::parse(query));
+ QScopedPointer<JsonDbQuery> parsedQuery(JsonDbQuery::parse(query));
+ JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, parsedQuery.data());
verifyGoodQueryResult(queryResult);
}
}
-void TestJsonDb::benchmarkFindReindexed()
+void TestPartition::benchmarkFindReindexed()
{
int count = mContactList.size();
if (!count)
@@ -914,72 +916,51 @@ void TestJsonDb::benchmarkFindReindexed()
.arg(JsonDbString::kTypeStr)
.arg("contact")
.arg(item.value("lastName").toString());
- JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, JsonDbQuery::parse(query));
+ QScopedPointer<JsonDbQuery> parsedQuery(JsonDbQuery::parse(query));
+ JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, parsedQuery.data());
verifyGoodQueryResult(queryResult);
}
}
-void TestJsonDb::benchmarkFindNames()
+void TestPartition::benchmarkFindNames()
{
QBENCHMARK {
QString query = QString("[?%1=\"%2\"]")
.arg(JsonDbString::kTypeStr)
.arg("contact");
- JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, JsonDbQuery::parse(query), 1);
+ QScopedPointer<JsonDbQuery> parsedQuery(JsonDbQuery::parse(query));
+ JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, parsedQuery.data(), 1);
verifyGoodQueryResult(queryResult);
}
}
-void TestJsonDb::findNamesMapL()
-{
- QBENCHMARK_ONCE {
- QString query = QString("[?%1=\"%2\"][= [_uuid, name.first, name.last] ]")
- .arg(JsonDbString::kTypeStr)
- .arg("contact");
- JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, JsonDbQuery::parse(query));
- verifyGoodQueryResult(queryResult);
- QCOMPARE(queryResult.values.size(), mContactList.size());
- }
-}
-
-void TestJsonDb::benchmarkFindNamesMapL()
-{
- QBENCHMARK {
- QString query = QString("[?%1=\"%2\"][= [_uuid, name.first, name.last] ]")
- .arg(JsonDbString::kTypeStr)
- .arg("contact");
- JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, JsonDbQuery::parse(query), 1);
- verifyGoodQueryResult(queryResult);
- QCOMPARE(queryResult.values.size(), 1);
- }
-}
-
-
-void TestJsonDb::findNamesMapO()
+void TestPartition::findNamesMapObject()
{
QBENCHMARK_ONCE {
QString query = QString("[?%1=\"%2\"][= { uuid: _uuid, first: name.first, last: name.last } ]")
.arg(JsonDbString::kTypeStr)
.arg("contact");
- JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, JsonDbQuery::parse(query));
+ QScopedPointer<JsonDbQuery> parsedQuery(JsonDbQuery::parse(query));
+ JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, parsedQuery.data());
verifyGoodQueryResult(queryResult);
QCOMPARE(queryResult.data.size(), mContactList.size());
}
}
-void TestJsonDb::benchmarkFindNamesMapO()
+void TestPartition::benchmarkFindNamesMapObject()
{
QBENCHMARK {
QString query = QString("[?%1=\"%2\"][= { uuid: _uuid, first: name.first, last: name.last } ]")
.arg(JsonDbString::kTypeStr)
.arg("contact");
- JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, JsonDbQuery::parse(query), 1);
+ QScopedPointer<JsonDbQuery> parsedQuery(JsonDbQuery::parse(query));
+ JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, parsedQuery.data(), 1);
verifyGoodQueryResult(queryResult);
QCOMPARE(queryResult.data.size(), 1);
}
}
-void TestJsonDb::benchmarkCursorCount()
+void TestPartition::benchmarkCursorCount()
{
QStringList queries = (QStringList()
<< "[/name.first]"
@@ -1003,7 +984,7 @@ void TestJsonDb::benchmarkCursorCount()
}
}
-void TestJsonDb::benchmarkQueryCount()
+void TestPartition::benchmarkQueryCount()
{
QStringList queries = (QStringList()
<< "[/name.first]"
@@ -1011,39 +992,13 @@ void TestJsonDb::benchmarkQueryCount()
);
foreach (QString query, queries) {
QBENCHMARK {
- JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner,
- JsonDbQuery::parse(QString("%1[count]").arg(query)));
+ QScopedPointer<JsonDbQuery> parsedQuery(JsonDbQuery::parse(QString("%1[count]").arg(query)));
+ JsonDbQueryResult queryResult = mJsonDbPartition->queryObjects(mOwner, parsedQuery.data());
}
}
}
-QJsonValue TestJsonDb::readJsonFile(const QString& filename)
-{
- QString filepath = filename;
- QFile jsonFile(filepath);
- jsonFile.open(QIODevice::ReadOnly);
- QByteArray json = jsonFile.readAll();
- JsonReader parser;
- bool ok = parser.parse(json);
- if (!ok) {
- qDebug() << filepath << parser.errorString();
- }
- QVariant v = parser.result();
- return QJsonObject::fromVariantMap(v.toMap());
-}
-
-QJsonValue TestJsonDb::readJson(const QByteArray& json)
-{
- JsonReader parser;
- bool ok = parser.parse(json);
- if (!ok) {
- qDebug() << parser.errorString();
- }
- QVariant v = parser.result();
- return QJsonObject::fromVariantMap(v.toMap());
-}
-
-void TestJsonDb::benchmarkScriptEngineCreation()
+void TestPartition::benchmarkScriptEngineCreation()
{
QJSValue result;
QBENCHMARK {
@@ -1052,11 +1007,12 @@ void TestJsonDb::benchmarkScriptEngineCreation()
QJSValue globalObject = engine->globalObject();
result =
engine->evaluate(QString("var reduce = function(k, v, s) { s.count = s.count + v.count; return s; };"));
+ delete engine;
engine = 0;
}
}
-void TestJsonDb::contactListChaff()
+void TestPartition::contactListChaff()
{
QBENCHMARK {
for (int ii = 0; ii < mContactList.size(); ii++) {
@@ -1075,5 +1031,5 @@ void TestJsonDb::contactListChaff()
}
}
-QTEST_MAIN(TestJsonDb)
-#include "bench_daemon.moc"
+QTEST_MAIN(TestPartition)
+#include "bench_partition.moc"
diff --git a/tests/benchmarks/partition/partition.pro b/tests/benchmarks/partition/partition.pro
new file mode 100644
index 00000000..d09d2150
--- /dev/null
+++ b/tests/benchmarks/partition/partition.pro
@@ -0,0 +1,18 @@
+TARGET = tst_bench_partition
+
+QT = network qml testlib jsondbpartition
+CONFIG -= app_bundle
+CONFIG += testcase
+
+LIBS += -L$$QT.jsondb.libs
+
+DEFINES += SRCDIR=\\\"$$PWD/\\\"
+
+RESOURCES+=../../json.qrc partition.qrc
+
+# HACK, remove when jsondbpartition separates private api from public api
+include(../../../src/3rdparty/btree/btree.pri)
+include(../../../src/hbtree/hbtree.pri)
+
+SOURCES += \
+ bench_partition.cpp \
diff --git a/tests/benchmarks/partition/partition.qrc b/tests/benchmarks/partition/partition.qrc
new file mode 100644
index 00000000..f490be78
--- /dev/null
+++ b/tests/benchmarks/partition/partition.qrc
@@ -0,0 +1,6 @@
+<RCC>
+ <qresource prefix="/partition">
+ <file alias="json">../../auto/partition/json</file>
+ <file alias="schemas">../../auto/partition/schemas</file>
+ </qresource>
+</RCC>
diff --git a/tests/benchmarks/tests.xml b/tests/benchmarks/tests.xml
index 3f5eface..0d4cd1be 100644
--- a/tests/benchmarks/tests.xml
+++ b/tests/benchmarks/tests.xml
@@ -6,13 +6,9 @@
<description>Client API performance 01</description>
<step>cd /usr/lib/qt5jsondb-tests/benchmarks/client; date &amp;&amp; ./tst_bench_client &amp;&amp; date</step>
</case>
- <case name="tst_bench_daemon" timeout="5000" component="qt5jsondb">
+ <case name="tst_bench_partition" timeout="5000" component="qt5jsondb">
<description>Server-side performance</description>
- <step>cd /usr/lib/qt5jsondb-tests/benchmarks/daemon; date &amp;&amp; ./tst_bench_daemon &amp;&amp; date</step>
- </case>
- <case name="tst_bench_listmodel" timeout="5000" component="qt5jsondb">
- <description>JsonDbListModel performance</description>
- <step>cd /usr/lib/qt5jsondb-tests/benchmarks/jsondb-listmodel; date &amp;&amp; ./tst_bench_listmodel -platform minimal &amp;&amp; date</step>
+ <step>cd /usr/lib/qt5jsondb-tests/benchmarks/partition; date &amp;&amp; ./tst_bench_partition &amp;&amp; date</step>
</case>
<case name="tst_bench_jsondbcachinglistmodel" timeout="5000" component="qt5jsondb">
<description>JsonDbCachingListModel performance</description>
diff --git a/tests/json.qrc b/tests/json.qrc
index e3c3e82d..dc8a0d3a 100644
--- a/tests/json.qrc
+++ b/tests/json.qrc
@@ -6,6 +6,6 @@
<file>auto/jsondblistmodel/list-objects.json</file>
<file>auto/jsondbsortinglistmodel/list-objects.json</file>
<file alias="dataset.json">auto/queries/dataset.json</file>
- <file>auto/daemon/json/map-reduce.json</file>
+ <file>auto/partition/json/map-reduce.json</file>
</qresource>
</RCC>
diff --git a/tests/shared/clientwrapper.h b/tests/shared/clientwrapper.h
index 32e71db4..1fc5b929 100644
--- a/tests/shared/clientwrapper.h
+++ b/tests/shared/clientwrapper.h
@@ -45,6 +45,10 @@
#include <QEventLoop>
#include <QElapsedTimer>
#include <QDebug>
+#include <QJsonObject>
+#include <QJsonArray>
+#include <QJsonValue>
+#include <QJsonDocument>
#include "jsondb-client.h"
@@ -81,7 +85,8 @@ QT_USE_NAMESPACE_JSONDB
if ((result)->mNotificationId.isNull()) { \
QVERIFY2(false, "we expected notification but did not get it :("); \
} else { \
- QString data = JsonWriter().toString((result)->mNotifications.last().mObject); \
+ QJsonValue value = QJsonValue::fromVariant((result)->mNotifications.last().mObject); \
+ QString data = QString::fromUtf8(value.isArray() ? QJsonDocument(value.toArray()).toJson() : QJsonDocument(value.toObject()).toJson()); \
QByteArray ba = QString("we didn't expect notification but got it. %1").arg(data).toLatin1(); \
QVERIFY2(false, ba.constData()); \
} \
@@ -96,6 +101,22 @@ QT_USE_NAMESPACE_JSONDB
#define waitForResponse3(id, code, notificationId) waitForResponse(mEventLoop, this, id, code, notificationId, 0)
#define waitForResponse4(id, code, notificationId, count) waitForResponse(mEventLoop, this, id, code, notificationId, count)
+#define waitForCallbackGeneric(eventloop) \
+{ \
+ QTimer timer; \
+ QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout())); \
+ QObject::connect(&timer, SIGNAL(timeout()), &eventloop, SLOT(quit())); \
+ timer.start(mClientTimeout); \
+ mElapsedTimer.start(); \
+ mTimedOut = false;\
+ callbackError = false; \
+ eventloop.exec(QEventLoop::AllEvents); \
+ QCOMPARE(false, mTimedOut); \
+}
+
+#define waitForCallback() waitForCallbackGeneric(mEventLoop)
+#define waitForCallback2() waitForCallbackGeneric(mEventLoop2)
+
class JsonDbTestNotification
{
public:
diff --git a/tests/shared/qmltestutil.h b/tests/shared/qmltestutil.h
index 9d9d4d0f..0d1b78f0 100644
--- a/tests/shared/qmltestutil.h
+++ b/tests/shared/qmltestutil.h
@@ -50,23 +50,6 @@
#include <QQmlProperty>
#include <QDir>
-#define waitForCallbackGeneric(eventloop) \
-{ \
- QTimer timer; \
- QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout())); \
- QObject::connect(&timer, SIGNAL(timeout()), &eventloop, SLOT(quit())); \
- timer.start(mClientTimeout); \
- mElapsedTimer.start(); \
- mTimedOut = false;\
- callbackError = false; \
- eventloop.exec(QEventLoop::AllEvents); \
- QCOMPARE(false, mTimedOut); \
-}
-
-#define waitForCallback() waitForCallbackGeneric(mEventLoop)
-#define waitForCallback2() waitForCallbackGeneric(mEventLoop2)
-
-
inline QVariant createObject(const QString &functionName)
{
static QStringList greekAlphabets;
diff --git a/tests/shared/requestwrapper.h b/tests/shared/requestwrapper.h
new file mode 100644
index 00000000..df20de9b
--- /dev/null
+++ b/tests/shared/requestwrapper.h
@@ -0,0 +1,290 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef RequestWrapper_H
+#define RequestWrapper_H
+
+#include <QCoreApplication>
+#include <QList>
+#include <QTest>
+#include <QFile>
+#include <QProcess>
+#include <QEventLoop>
+#include <QDebug>
+#include <QLocalSocket>
+#include <QTimer>
+#include <QQmlEngine>
+#include <QQmlComponent>
+
+#include "qjsondbconnection.h"
+#include "qjsondbwriterequest.h"
+#include "qjsondbreadrequest.h"
+
+QT_USE_NAMESPACE_JSONDB
+
+#define waitForResponse(eventloop_, id_) \
+{ \
+ int givenid_ = (id_); \
+ lastRequestId = -1; \
+ lastResult.clear(); \
+ lastErrorCode = 0; \
+ lastErrorMessage.clear(); \
+ eventLoop = &eventloop_; \
+ \
+ QTimer timer; \
+ QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout())); \
+ QObject::connect(&timer, SIGNAL(timeout()), eventLoop, SLOT(quit())); \
+ timer.start(clientTimeout); \
+ elapsedTimer.start(); \
+ do { \
+ eventLoop->exec(QEventLoop::AllEvents); \
+ } while (lastRequestId < givenid_); \
+ eventLoop = 0; \
+ if (givenid_ != -1) QVERIFY2((lastRequestId!=-1), "Failed to receive an answer from the db server"); \
+ if (givenid_ != -1) QCOMPARE(lastRequestId, givenid_); \
+}
+
+#define waitForResponse1(id) waitForResponse(eventLoop1, id)
+
+#define waitForCallbackGeneric(eventloop) \
+{ \
+ QTimer timer; \
+ QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout())); \
+ QObject::connect(&timer, SIGNAL(timeout()), &eventloop, SLOT(quit())); \
+ timer.start(clientTimeout); \
+ elapsedTimer.start(); \
+ mTimedOut = false;\
+ callbackError = false; \
+ eventloop.exec(QEventLoop::AllEvents); \
+ QCOMPARE(false, mTimedOut); \
+}
+
+//#define waitForCallback() waitForCallbackGeneric(eventLoop)
+#define waitForCallback1() waitForCallbackGeneric(eventLoop1)
+
+class RequestWrapper: public QObject
+{
+ Q_OBJECT
+public:
+ RequestWrapper()
+ :clientTimeout(20000)
+ {
+ if (qgetenv("JSONDB_CLIENT_TIMEOUT").size())
+ clientTimeout = QString::fromLatin1(qgetenv("JSONDB_CLIENT_TIMEOUT")).toLong();
+
+ connect(this, SIGNAL(response(int,QVariantList)),
+ this, SLOT(onResponse(int,QVariantList)));
+ connect(this, SIGNAL(error(int,int,QString)),
+ this, SLOT(onError(int,int,QString)));
+ }
+
+ ~RequestWrapper()
+ {
+ if (connection)
+ delete connection;
+ }
+
+ int create(const QVariantMap &item, const QString &partitionName = QString())
+ {
+ QVariantList list;
+ list.append(item);
+ return create(list, partitionName);
+ }
+
+ int create(const QVariantList &list, const QString &partitionName = QString())
+ {
+ QList<QJsonObject> objects;
+ for (int i = 0; i<list.count(); i++) {
+ objects.append(QJsonObject::fromVariantMap(list[i].toMap()));
+ }
+ QtJsonDb::QJsonDbWriteRequest *request = new QtJsonDb::QJsonDbCreateRequest(objects);
+ request->setPartition(partitionName);
+ connect(request, SIGNAL(finished()), this, SLOT(onWriteFinished()));
+ connect(request, SIGNAL(finished()), request, SLOT(deleteLater()));
+ connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ this, SLOT(onWriteError(QtJsonDb::QJsonDbRequest::ErrorCode,QString)));
+ connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ request, SLOT(deleteLater()));
+ connection->send(request);
+ return request->property("requestId").toInt();
+ }
+
+ int update(const QVariantMap &item, const QString &partitionName = QString())
+ {
+ QVariantList list;
+ list.append(item);
+ return update(list, partitionName);
+ }
+
+ int update(const QVariantList &list, const QString &partitionName = QString())
+ {
+ QList<QJsonObject> objects;
+ for (int i = 0; i<list.count(); i++) {
+ objects.append(QJsonObject::fromVariantMap(list[i].toMap()));
+ }
+ QtJsonDb::QJsonDbWriteRequest *request = new QtJsonDb::QJsonDbUpdateRequest(objects);
+ request->setPartition(partitionName);
+ connect(request, SIGNAL(finished()), this, SLOT(onWriteFinished()));
+ connect(request, SIGNAL(finished()), request, SLOT(deleteLater()));
+ connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ this, SLOT(onWriteError(QtJsonDb::QJsonDbRequest::ErrorCode,QString)));
+ connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ request, SLOT(deleteLater()));
+ connection->send(request);
+ return request->property("requestId").toInt();
+ }
+
+ int remove(const QVariantMap &item, const QString &partitionName = QString())
+ {
+ QVariantList list;
+ list.append(item);
+ return remove(list, partitionName);
+ }
+
+ int remove(const QVariantList &list, const QString &partitionName = QString())
+ {
+ QList<QJsonObject> objects;
+ for (int i = 0; i<list.count(); i++) {
+ objects.append(QJsonObject::fromVariantMap(list[i].toMap()));
+ }
+ QtJsonDb::QJsonDbWriteRequest *request = new QtJsonDb::QJsonDbRemoveRequest(objects);
+ request->setPartition(partitionName);
+ connect(request, SIGNAL(finished()), this, SLOT(onWriteFinished()));
+ connect(request, SIGNAL(finished()), request, SLOT(deleteLater()));
+ connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ this, SLOT(onWriteError(QtJsonDb::QJsonDbRequest::ErrorCode,QString)));
+ connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ request, SLOT(deleteLater()));
+ connection->send(request);
+ return request->property("requestId").toInt();
+ }
+
+ int query(const QString &queryString, const QString &partitionName = QString())
+ {
+ QJsonDbReadRequest *request = new QJsonDbReadRequest;
+ request->setQuery(queryString);
+ request->setPartition(partitionName);
+ connect(request, SIGNAL(finished()), this, SLOT(onQueryFinished()));
+ connect(request, SIGNAL(finished()), request, SLOT(deleteLater()));
+ connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ this, SLOT(onWriteError(QtJsonDb::QJsonDbRequest::ErrorCode,QString)));
+ connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ request, SLOT(deleteLater()));
+ connection->send(request);
+ return request->property("requestId").toInt();
+ }
+
+public Q_SLOTS:
+ void onWriteFinished()
+ {
+ QtJsonDb::QJsonDbWriteRequest *request = qobject_cast<QtJsonDb::QJsonDbWriteRequest*>(sender());
+ if (request) {
+ QList<QJsonObject> objects = request->takeResults();
+ QVariantList list;
+ for (int i = 0; i<objects.count(); i++) {
+ list.append(objects[i].toVariantMap());
+ }
+ emit response(request->property("requestId").toInt(), list);
+ }
+ }
+ void onQueryFinished()
+ {
+ QtJsonDb::QJsonDbReadRequest *request = qobject_cast<QtJsonDb::QJsonDbReadRequest*>(sender());
+ if (request) {
+ QList<QJsonObject> objects = request->takeResults();
+ QVariantList list;
+ for (int i = 0; i<objects.count(); i++) {
+ list.append(objects[i].toVariantMap());
+ }
+ emit response(request->property("requestId").toInt(), list);
+ }
+ }
+ void onWriteError(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString &message)
+ {
+ QtJsonDb::QJsonDbWriteRequest *request = qobject_cast<QtJsonDb::QJsonDbWriteRequest*>(sender());
+ if (request) {
+ emit error(request->property("requestId").toInt(), int(code), message);
+ }
+ }
+ void onResponse(int id, const QVariantList& list)
+ {
+ //qDebug() << "onResponse" << id;
+ lastRequestId = id;
+ lastResult = list;
+ if (eventLoop)
+ eventLoop->quit();
+ }
+ void onError(int id, int code, const QString &message)
+ {
+ qDebug() << "onError" << id << code << message;
+ lastRequestId = id;
+ lastErrorCode = code;
+ lastErrorMessage = message;
+ if (eventLoop)
+ eventLoop->quit();
+ }
+ virtual void timeout()
+ {
+ qDebug() << "RequestWrapper::timeout() " << elapsedTimer.elapsed();
+ }
+Q_SIGNALS:
+ void response(int, const QVariantList&);
+ void error(int, int, const QString&);
+protected:
+ QPointer<QtJsonDb::QJsonDbConnection> connection;
+ QPointer<QEventLoop> eventLoop;
+ int lastRequestId;
+ QVariantList lastResult;
+ int lastErrorCode;
+ QString lastErrorMessage;
+ QEventLoop eventLoop1;
+ QElapsedTimer elapsedTimer;
+ int clientTimeout;
+
+ //Liang is trying
+ bool callbackError;
+ int callbackErrorCode;
+ QString callbackErrorMessage;
+ QVariant callbackMeta;
+ QVariant callbackResponse;
+ bool mCallbackReceived;
+};
+
+#endif
diff --git a/tests/shared/shared.pri b/tests/shared/shared.pri
index 4f47a0bc..b69a0b8c 100644
--- a/tests/shared/shared.pri
+++ b/tests/shared/shared.pri
@@ -1,12 +1,20 @@
+QT += jsondb jsondb-private
+
INCLUDEPATH += $$PWD
-HEADERS += $$PWD/util.h $$PWD/qmltestutil.h
+HEADERS += \
+ $$PWD/util.h \
+ $$PWD/qmltestutil.h
contains(QT, jsondbcompat|jsondbcompat-private) {
HEADERS += $$PWD/clientwrapper.h
SOURCES += $$PWD/clientwrapper.cpp
+} else {
+ HEADERS += $$PWD/testhelper.h
+ SOURCES += $$PWD/testhelper.cpp
}
RESOURCES += \
../../json.qrc
+DEFINES += JSONDB_DAEMON_BASE=\\\"$$QT.jsondb.bins\\\"
diff --git a/tests/shared/testhelper.cpp b/tests/shared/testhelper.cpp
new file mode 100644
index 00000000..961a533e
--- /dev/null
+++ b/tests/shared/testhelper.cpp
@@ -0,0 +1,419 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "testhelper.h"
+
+#include <QJsonDbWatcher>
+
+#include <QCoreApplication>
+#include <QDir>
+#include <QLocalSocket>
+#include <QProcess>
+#include <QTest>
+#include <QTimer>
+#include <QJsonArray>
+
+QT_USE_NAMESPACE_JSONDB
+
+TestHelper::TestHelper(QObject *parent) :
+ QObject(parent)
+ , mProcess(0)
+ , mConnection(0)
+ , mNotificationsReceived(0)
+ , mNotificationsExpected(0)
+ , mLastStateChangedExpected(0)
+ , mLastStateChangedReceived(0)
+ , mRequestsPending(0)
+{
+}
+
+QJsonDocument TestHelper::readJsonFile(const QString &filename, QJsonParseError *error)
+{
+ QString filepath = filename;
+ QFile jsonFile(filepath);
+ if (!jsonFile.exists()) {
+ if (error) {
+ error->error = QJsonParseError::MissingObject;
+ error->offset = 0;
+ }
+ return QJsonDocument();
+ }
+ jsonFile.open(QIODevice::ReadOnly);
+ QByteArray json = jsonFile.readAll();
+ QJsonDocument doc(QJsonDocument::fromJson(json, error));
+ return doc;
+}
+
+void TestHelper::launchJsonDbDaemon(const QString &basename, const QStringList &args, const char *sourceFile)
+{
+ qputenv("JSONDB_CONFIG_SEARCH_PATH", QFileInfo(QString::fromUtf8(sourceFile)).dir().absolutePath().toUtf8());
+
+ if (dontLaunch())
+ return;
+
+ QString jsondb_app = QDir(QString::fromLocal8Bit(JSONDB_DAEMON_BASE)).absoluteFilePath(QLatin1String("jsondb"));
+ if (!QFile::exists(jsondb_app))
+ jsondb_app = QLatin1String("jsondb"); // rely on the PATH
+
+ mProcess = new QProcess;
+ mProcess->setProcessChannelMode(QProcess::ForwardedChannels);
+ connect(mProcess, SIGNAL(finished(int,QProcess::ExitStatus)),
+ this, SLOT(processFinished(int,QProcess::ExitStatus)));
+
+ QString socketName = QString("testjsondb_%1").arg(getpid());
+
+ QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
+ env.insert("JSONDB_SOCKET", socketName);
+ mProcess->setProcessEnvironment(env);
+ ::setenv("JSONDB_SOCKET", qPrintable(socketName), 1);
+
+ QStringList argList = args;
+ argList << QLatin1String("-base-name") << basename;
+
+ qDebug() << "Starting process" << jsondb_app << argList << "with socket" << socketName;
+
+ if (useValgrind()) {
+ QStringList args1 = argList;
+ args1.prepend(jsondb_app);
+ mProcess->start("valgrind", args1);
+ } else {
+ mProcess->start(jsondb_app, argList);
+ }
+
+ if (!mProcess->waitForStarted())
+ qFatal("Unable to start jsondb database process");
+
+ /* Wait until the jsondb is accepting connections */
+ int tries = 0;
+ bool connected = false;
+ while (!connected && tries++ < 100) {
+ QLocalSocket socket;
+ socket.connectToServer(socketName);
+ if (socket.waitForConnected()) {
+ connected = true;
+ socket.close();
+ }
+ QTest::qWait(250);
+ }
+
+ if (!connected)
+ qFatal("Unable to connect to jsondb process");
+}
+
+inline qint64 TestHelper::launchJsonDbDaemonDetached(const QString &basename, const QStringList &args, const char *sourceFile)
+{
+ qputenv("JSONDB_CONFIG_SEARCH_PATH", QFileInfo(QString::fromUtf8(sourceFile)).dir().absolutePath().toUtf8());
+
+ if (dontLaunch())
+ return 0;
+
+ QString jsondb_app = QDir(QString::fromLocal8Bit(JSONDB_DAEMON_BASE)).absoluteFilePath(QLatin1String("jsondb"));
+ if (!QFile::exists(jsondb_app))
+ jsondb_app = QLatin1String("jsondb"); // rely on the PATH
+
+ QString socketName = QString("testjsondb_%1").arg(getpid());
+ ::setenv("JSONDB_SOCKET", qPrintable(socketName), 1);
+
+ QStringList argList = args;
+ argList << QLatin1String("-base-name") << basename;
+
+ qDebug() << "Starting process" << jsondb_app << argList << "with socket" << socketName;
+ qint64 pid;
+ if (useValgrind()) {
+ QStringList args1 = argList;
+ args1.prepend(jsondb_app);
+ QProcess::startDetached(jsondb_app, args1, QDir::currentPath(), &pid );
+ } else {
+ QProcess::startDetached(jsondb_app, argList, QDir::currentPath(), &pid);
+ }
+
+ /* Wait until the jsondb is accepting connections */
+ int tries = 0;
+ bool connected = false;
+ while (!connected && tries++ < 100) {
+ QLocalSocket socket;
+ socket.connectToServer(socketName);
+ if (socket.waitForConnected()) {
+ connected = true;
+ socket.close();
+ }
+ QTest::qWait(250);
+ }
+ if (!connected)
+ qFatal("Unable to connect to jsondb process");
+
+ return pid;
+}
+
+void TestHelper::stopDaemon()
+{
+ if (dontLaunch())
+ return;
+
+ if (mProcess) {
+ mProcess->close();
+ delete mProcess;
+ mProcess = 0;
+ }
+}
+
+void TestHelper::connectToServer()
+{
+ mConnection = new QJsonDbConnection(this);
+ connect(mConnection, SIGNAL(error(QtJsonDb::QJsonDbConnection::ErrorCode,QString)),
+ this, SLOT(connectionError(QtJsonDb::QJsonDbConnection::ErrorCode,QString)));
+
+ mConnection->connectToServer();
+}
+
+void TestHelper::disconnectFromServer()
+{
+ connect(mConnection, SIGNAL(disconnected()), &mEventLoop, SLOT(quit()), Qt::QueuedConnection);
+ mConnection->disconnectFromServer();
+ blockWithTimeout();
+
+ if (mConnection) {
+ delete mConnection;
+ mConnection = 0;
+ }
+
+ mRequestErrors.clear();
+}
+
+void TestHelper::removeDbFiles(const QStringList &additionalFiles)
+{
+ if (dontLaunch())
+ return;
+
+ QStringList files = QDir().entryList(QStringList() << QLatin1String("*.db"));
+ files << additionalFiles;
+ foreach (const QString &fileName, files)
+ QFile::remove(fileName);
+}
+
+void TestHelper::waitForResponse(QJsonDbRequest *request)
+{
+ mRequestsPending = 1;
+ mNotificationsExpected = 0;
+ mLastStateChangedExpected = 0;
+
+ connect(request, SIGNAL(finished()), this, SLOT(requestFinished()));
+ connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ this, SLOT(requestError(QtJsonDb::QJsonDbRequest::ErrorCode,QString)));
+
+ blockWithTimeout();
+
+ disconnect(request, SIGNAL(finished()), this, SLOT(requestFinished()));
+ disconnect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ this, SLOT(requestError(QtJsonDb::QJsonDbRequest::ErrorCode,QString)));
+ QVERIFY(!mRequestsPending);
+}
+
+void TestHelper::waitForResponse(QList<QJsonDbRequest *> requests)
+{
+ mRequestsPending = requests.count();
+ mNotificationsExpected = 0;
+ mLastStateChangedExpected = 0;
+
+ foreach (QJsonDbRequest *request, requests) {
+ connect(request, SIGNAL(finished()), this, SLOT(requestFinished()));
+ connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ this, SLOT(requestError(QtJsonDb::QJsonDbRequest::ErrorCode,QString)));
+ }
+
+ blockWithTimeout();
+
+ foreach (QJsonDbRequest *request, requests) {
+ disconnect(request, SIGNAL(finished()), this, SLOT(requestFinished()));
+ disconnect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ this, SLOT(requestError(QtJsonDb::QJsonDbRequest::ErrorCode,QString)));
+ }
+ QVERIFY(!mRequestsPending);
+}
+
+void TestHelper::waitForResponseAndNotifications(QJsonDbRequest *request,
+ QJsonDbWatcher *watcher,
+ int notificationsExpected,
+ int lastStateChangedExpected)
+{
+ mNotificationsExpected = notificationsExpected;
+ mNotificationsReceived = 0;
+ mLastStateChangedExpected = lastStateChangedExpected;
+ mLastStateChangedReceived = 0;
+
+ if (request) {
+ mRequestsPending = 1;
+
+ connect(request, SIGNAL(finished()), this, SLOT(requestFinished()));
+ connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ this, SLOT(requestError(QtJsonDb::QJsonDbRequest::ErrorCode,QString)));
+ }
+
+ connect(watcher, SIGNAL(notificationsAvailable(int)),
+ this, SLOT(watcherNotificationsAvailable(int)));
+ connect(watcher, SIGNAL(error(QtJsonDb::QJsonDbWatcher::ErrorCode,QString)),
+ this, SLOT(watcherError(QtJsonDb::QJsonDbWatcher::ErrorCode,QString)));
+ connect(watcher, SIGNAL(lastStateNumberChanged(int)),
+ this, SLOT(watcherLastStateNumberChanged(int)));
+
+ blockWithTimeout();
+
+ if (request) {
+ disconnect(request, SIGNAL(finished()), this, SLOT(requestFinished()));
+ disconnect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)),
+ this, SLOT(requestError(QtJsonDb::QJsonDbRequest::ErrorCode,QString)));
+ }
+
+ disconnect(watcher, SIGNAL(notificationsAvailable(int)),
+ this, SLOT(watcherNotificationsAvailable(int)));
+ disconnect(watcher, SIGNAL(error(QtJsonDb::QJsonDbWatcher::ErrorCode,QString)),
+ this, SLOT(watcherError(QtJsonDb::QJsonDbWatcher::ErrorCode,QString)));
+ disconnect(watcher, SIGNAL(lastStateNumberChanged(int)),
+ this, SLOT(watcherLastStateNumberChanged(int)));
+
+ QVERIFY(!mRequestsPending && mNotificationsReceived >= mNotificationsExpected
+ && mLastStateChangedReceived >= mLastStateChangedExpected);
+
+ mNotificationsExpected = 0;
+}
+
+void TestHelper::waitForStatus(QJsonDbWatcher *watcher, QJsonDbWatcher::Status status)
+{
+ mExpectedStatus = status;
+ connect(watcher, SIGNAL(statusChanged(QtJsonDb::QJsonDbWatcher::Status)),
+ this, SLOT(watcherStatusChanged(QtJsonDb::QJsonDbWatcher::Status)));
+ blockWithTimeout();
+ disconnect(watcher, SIGNAL(statusChanged(QtJsonDb::QJsonDbWatcher::Status)),
+ this, SLOT(watcherStatusChanged(QtJsonDb::QJsonDbWatcher::Status)));
+ QVERIFY(mExpectedStatus == status);
+}
+
+bool TestHelper::dontLaunch()
+{
+ static const bool dontlaunch = qgetenv("AUTOTEST_DONT_LAUNCH_JSONDB").toInt() == 1;
+ return dontlaunch;
+}
+
+bool TestHelper::useValgrind()
+{
+ static const bool usevalgrind = qgetenv("AUTOTEST_VALGRIND_JSONDB").toInt() == 1;
+ return usevalgrind;
+}
+
+void TestHelper::blockWithTimeout()
+{
+ QTimer t;
+ connect(&t, SIGNAL(timeout()), &mEventLoop, SLOT(quit()));
+ connect(&t, SIGNAL(timeout()), this, SLOT(timeout()));
+
+ t.start(10000);
+ mEventLoop.exec(QEventLoop::AllEvents);
+ t.stop();
+}
+
+void TestHelper::connectionError(QtJsonDb::QJsonDbConnection::ErrorCode code, QString msg)
+{
+ qCritical() << "Error from connection" << code << msg;
+}
+
+void TestHelper::processFinished(int code, QProcess::ExitStatus status)
+{
+ qDebug() << "jsondb process finished" << code << status;
+}
+
+void TestHelper::requestFinished()
+{
+ --mRequestsPending;
+ if (!mRequestsPending && mNotificationsReceived >= mNotificationsExpected
+ && mLastStateChangedReceived >= mLastStateChangedExpected)
+ mEventLoop.quit();
+}
+
+void TestHelper::requestError(QtJsonDb::QJsonDbRequest::ErrorCode code, QString msg)
+{
+ qWarning() << "Request error:" << code << msg;
+ QJsonDbRequest *request = qobject_cast<QJsonDbRequest*>(sender());
+ if (request)
+ mRequestErrors[request] = code;
+
+ requestFinished();
+}
+
+void TestHelper::requestStatusChanged(QtJsonDb::QJsonDbRequest::Status status)
+{
+ Q_UNUSED(status);
+}
+
+void TestHelper::watcherNotificationsAvailable(int count)
+{
+ mNotificationsReceived = count;
+
+ if (!mRequestsPending && mNotificationsReceived >= mNotificationsExpected
+ && mLastStateChangedReceived >= mLastStateChangedExpected)
+ mEventLoop.quit();
+}
+
+void TestHelper::watcherStatusChanged(QtJsonDb::QJsonDbWatcher::Status status)
+{
+ if (status == mExpectedStatus)
+ mEventLoop.quit();
+}
+
+void TestHelper::watcherLastStateNumberChanged(int stateNumber)
+{
+ Q_UNUSED(stateNumber);
+ mLastStateChangedReceived++;
+ if (!mRequestsPending && mNotificationsReceived >= mNotificationsExpected
+ && mLastStateChangedReceived >= mLastStateChangedExpected)
+ mEventLoop.quit();
+}
+
+void TestHelper::watcherError(QtJsonDb::QJsonDbWatcher::ErrorCode code, QString msg)
+{
+ qWarning() << "Watcher error:" << code << msg;
+}
+
+void TestHelper::timeout()
+{
+ qCritical() << "A timeout occurred";
+}
+
+
diff --git a/tests/shared/testhelper.h b/tests/shared/testhelper.h
new file mode 100644
index 00000000..1a148254
--- /dev/null
+++ b/tests/shared/testhelper.h
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef JSONDB_TESTHELPER_H
+#define JSONDB_TESTHELPER_H
+
+#include <QJsonDbConnection>
+#include <QJsonDbRequest>
+#include <QJsonDbWatcher>
+
+#include <QEventLoop>
+#include <QHash>
+#include <QJsonDocument>
+#include <QJsonValue>
+#include <QObject>
+#include <QProcess>
+#include <QStringList>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+class QProcess;
+QT_END_NAMESPACE
+
+class TestHelper : public QObject
+{
+ Q_OBJECT
+public:
+ explicit TestHelper(QObject *parent = 0);
+
+ QJsonDocument readJsonFile(const QString &filename, QJsonParseError *error = 0);
+
+ void launchJsonDbDaemon(const QString &basename, const QStringList &args, const char *sourceFile);
+ qint64 launchJsonDbDaemonDetached(const QString &basename, const QStringList &args, const char *sourceFile);
+ void stopDaemon();
+
+ void connectToServer();
+ void disconnectFromServer();
+
+ void removeDbFiles(const QStringList &additionalFiles = QStringList());
+
+ void waitForResponse(QtJsonDb::QJsonDbRequest *request);
+ void waitForResponse(QList<QtJsonDb::QJsonDbRequest*> requests);
+ void waitForResponseAndNotifications(QtJsonDb::QJsonDbRequest *request,
+ QtJsonDb::QJsonDbWatcher *watcher,
+ int notificationsExpected,
+ int lastStateChangedExpected = 0);
+ void waitForStatus(QtJsonDb::QJsonDbWatcher *watcher,
+ QtJsonDb::QJsonDbWatcher::Status status);
+
+protected:
+ QProcess *mProcess;
+ QtJsonDb::QJsonDbConnection *mConnection;
+ QEventLoop mEventLoop;
+ int mNotificationsReceived;
+ int mNotificationsExpected;
+ int mLastStateChangedExpected;
+ int mLastStateChangedReceived;
+ QHash<QtJsonDb::QJsonDbRequest *, QtJsonDb::QJsonDbRequest::ErrorCode> mRequestErrors;
+
+protected Q_SLOTS:
+ void connectionError(QtJsonDb::QJsonDbConnection::ErrorCode code, QString msg);
+
+ void processFinished(int,QProcess::ExitStatus);
+
+ void requestFinished();
+ void requestError(QtJsonDb::QJsonDbRequest::ErrorCode code, QString msg);
+ void requestStatusChanged(QtJsonDb::QJsonDbRequest::Status status);
+
+ void watcherNotificationsAvailable(int count);
+ void watcherStatusChanged(QtJsonDb::QJsonDbWatcher::Status status);
+ void watcherError(QtJsonDb::QJsonDbWatcher::ErrorCode code, QString msg);
+ void watcherLastStateNumberChanged(int stateNumber);
+ void timeout();
+
+private:
+ static bool dontLaunch();
+ static bool useValgrind();
+ void blockWithTimeout();
+
+ int mRequestsPending;
+ QtJsonDb::QJsonDbWatcher::Status mExpectedStatus;
+};
+
+#endif // JSONDB_TESTHELPER_H
diff --git a/tests/shared/util.h b/tests/shared/util.h
index 90e65355..93b43537 100644
--- a/tests/shared/util.h
+++ b/tests/shared/util.h
@@ -39,8 +39,8 @@
**
****************************************************************************/
-#ifndef UTIL_H
-#define UTIL_H
+#ifndef JSONDB_UTIL_H
+#define JSONDB_UTIL_H
#include <QFile>
#include <QDir>
@@ -49,6 +49,8 @@
#include <QLocalSocket>
#include <qtestsystem.h>
#include <qjsondocument.h>
+#include <qjsonarray.h>
+#include <qjsonobject.h>
inline QString findFile(const QString &filename)
{
@@ -73,7 +75,7 @@ inline QString findFile(const char *filename)
return findFile(QString::fromLocal8Bit(filename));
}
-QJsonDocument readJsonFile(const QString &filename, QJsonParseError *error = 0)
+inline QJsonValue readJsonFile(const QString &filename, QJsonParseError *error = 0)
{
QString filepath = filename;
QFile jsonFile(filepath);
@@ -82,16 +84,18 @@ QJsonDocument readJsonFile(const QString &filename, QJsonParseError *error = 0)
error->error = QJsonParseError::MissingObject;
error->offset = 0;
}
- return QJsonDocument();
+ return QJsonValue();
}
jsonFile.open(QIODevice::ReadOnly);
QByteArray json = jsonFile.readAll();
QJsonDocument doc(QJsonDocument::fromJson(json, error));
- return doc;
+ return doc.isArray() ? QJsonValue(doc.array()) : QJsonValue(doc.object());
}
-inline QProcess *launchJsonDbDaemon(const char *prefix, const QString &socketName, const QStringList &args)
+inline QProcess *launchJsonDbDaemon(const char *prefix, const QString &socketName, const QStringList &args, const char *sourceFile)
{
+ qputenv("JSONDB_CONFIG_SEARCH_PATH", QFileInfo(QString::fromUtf8(sourceFile)).dir().absolutePath().toUtf8());
+
static bool dontlaunch = qgetenv("AUTOTEST_DONT_LAUNCH_JSONDB").toInt() == 1;
static bool useValgrind = qgetenv("AUTOTEST_VALGRIND_JSONDB").toInt() == 1;
if (dontlaunch)
@@ -133,8 +137,10 @@ inline QProcess *launchJsonDbDaemon(const char *prefix, const QString &socketNam
return process;
}
-inline qint64 launchJsonDbDaemonDetached(const char *prefix, const QString &socketName, const QStringList &args)
+inline qint64 launchJsonDbDaemonDetached(const char *prefix, const QString &socketName, const QStringList &args, const char *sourceFile)
{
+ qputenv("JSONDB_CONFIG_SEARCH_PATH", QFileInfo(QString::fromUtf8(sourceFile)).dir().absolutePath().toUtf8());
+
static bool dontlaunch = qgetenv("AUTOTEST_DONT_LAUNCH_JSONDB").toInt() == 1;
static bool useValgrind = qgetenv("AUTOTEST_VALGRIND_JSONDB").toInt() == 1;
if (dontlaunch)
@@ -169,4 +175,4 @@ inline qint64 launchJsonDbDaemonDetached(const char *prefix, const QString &sock
return pid;
}
-#endif // UTIL_H
+#endif // JSONDB_UTIL_H
diff --git a/tools/jsondb-client/client.cpp b/tools/jsondb-client/client.cpp
index aba2bcbb..8e615be2 100644
--- a/tools/jsondb-client/client.cpp
+++ b/tools/jsondb-client/client.cpp
@@ -268,8 +268,6 @@ void Client::onNotificationsAvailable(int)
actionString = QStringLiteral("update"); break;
case QtJsonDb::QJsonDbWatcher::Removed:
actionString = QStringLiteral("remove"); break;
- case QtJsonDb::QJsonDbWatcher::StateChanged:
- actionString = QStringLiteral("stateChange"); break;
case QtJsonDb::QJsonDbWatcher::All: break;
}
@@ -390,6 +388,7 @@ void Client::aboutToRemove(void)
void Client::onRequestError(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString &message)
{
+ Q_UNUSED(code);
InputThread::print(message);
}