{"id":18069149,"url":"https://github.com/arcticfox1919/unqlite_flutter","last_synced_at":"2025-07-17T03:07:53.985Z","repository":{"id":44907578,"uuid":"375077347","full_name":"arcticfox1919/unqlite_flutter","owner":"arcticfox1919","description":"UnQLite database plugin wrapped for flutter.","archived":false,"fork":false,"pushed_at":"2022-08-03T16:29:07.000Z","size":3366,"stargazers_count":17,"open_issues_count":2,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-23T05:02:21.360Z","etag":null,"topics":["dart","flutter","nosql"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/arcticfox1919.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-06-08T16:33:52.000Z","updated_at":"2024-10-29T10:51:04.000Z","dependencies_parsed_at":"2022-08-12T11:40:28.005Z","dependency_job_id":null,"html_url":"https://github.com/arcticfox1919/unqlite_flutter","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/arcticfox1919/unqlite_flutter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arcticfox1919%2Funqlite_flutter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arcticfox1919%2Funqlite_flutter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arcticfox1919%2Funqlite_flutter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arcticfox1919%2Funqlite_flutter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/arcticfox1919","download_url":"https://codeload.github.com/arcticfox1919/unqlite_flutter/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arcticfox1919%2Funqlite_flutter/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265562233,"owners_count":23788491,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dart","flutter","nosql"],"created_at":"2024-10-31T08:09:27.017Z","updated_at":"2025-07-17T03:07:53.959Z","avatar_url":"https://github.com/arcticfox1919.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# unqlite_flutter\n\nUnQLite database plugin wrapped for flutter.UnQLite is an embedded NoSql database, see [here](https://github.com/symisc/unqlite) for details.\n\nTodo:\n\n- [x]  key-value store\n- [x]  JSON document store\n\n## Usage\n\n###  key-value store\n\nAdd dependencies：\n\n```yaml\n  unqlite: latest \n  unqlite_flutter: latest \n```\n\nSimple key-value store:\n\n```dart\n// create or open a database\nUnQLite db = UnQLite.open(\"${appDocDir.path}/test.db\");\n\n// save key-value pairs\ndb.store(\"name\", \"Alex\");\ndb.store(\"age\", 18);\ndb.store(19, \"haha\");\n\n// get value by key\n// but you have to specify the generic type of the value\ndebugPrint(db.fetch\u003cString\u003e(\"name\"));\ndebugPrint('${db.fetch\u003cint\u003e(\"age\")}');\ndebugPrint(db.fetch\u003cString\u003e(19));\n\n// another way to get a value\ndb.fetchCallback\u003cint\u003e(\"age\", (val) {\n    debugPrint('age=$val');\n});\n```\n\nOf course, there is another way to get the data, it might be faster than `fetch`：\n\n```dart\nvar cursor = db.cursor();\ncursor.seek('name');\ndebugPrint('=\u003e ${cursor.key} =\u003e ${cursor.value}');\n```\n\nAlso you can use transactions which is a great feature:\n\n```dart\n    var trans = db.transaction().begin();\n    try {\n      for (var i = 0; i \u003c 100000; i++) {\n        if (i == 10) {\n          // Here, we generate an exception\n          throw Exception('test');\n        }\n        db.store(\"transaction_$i\", \"here is a transaction_$i\");\n      }\n      trans.commit();\n    } catch (e) {\n      // the transaction is rolled back here\n      trans.rollback();\n    }\n```\n\nYou can also use iterators to iterate over all data:\n\n```dart\nfor (var entry in db.cursor()) {\n  var content = '${entry.key} =\u003e ${entry.value}';\n  debugPrint(content);\n}\n```\n\n### JSON\n\n```dart\n    UnQLite db = UnQLite.open(\"${appDocDir.path}/test2.db\");\n    var users = db.collection(\"users\");\n\t// Create a collection\n    users.create();\n\n\t// Save JSON\n    users.store(jsonDecode('''\n{\n        \"title\": \"test json string\",\n        \"author\": [\n                \"arcticfox1919\"\n        ],\n        \"year\": 2022,\n        \"like\": \"flutter\"\n}\n    '''));\n\n    users.store({'name': 'Mickey', 'age': 17});\n    users.store([\n      {'name': 'Alice', 'age': 18},\n      {'name': 'Bruce', 'age': 19},\n      {'name': 'Charlie', 'age': 20},\n    ]);\n\n\t// Get all\n    print(users.all());\n    // print(users.fetch(0));\n    // print(users.fetch(1));\n    // print(users.fetch(2));\n    // print(users.errorLog());\n\n    print(users.creationDate());\n    print(users.len());\n    print(users.fetchCurrent());\n\n    // Delete all\n    users.drop();\n    db.close();\n```\n\n\n## Why use it\n\n- Faster than Hive and takes up less memory\n- Can support JSON documents \n\nWhat are the drawbacks?  Because dart ffi is used, it cannot be used on the web.\n\nBelow is some performance test data, the percentage of memory is not listed here, but I'm sure unqlite only uses much less memory:\n\nUnQLite:\n\n```\nUnQLite init:1 ms\nwrite 100,000 entries :611 ms\nfetch 100,000 entries :370 ms\nseek  100,000 entries :215 ms\niterate 100,000 entries :225 ms\ntransaction rollback :39 ms\n```\n\nHive:\n\n```\nHive init:48 ms\nput 100,000 entries :807 ms\nget 100,000 entries :290 ms\n```\n\n\n\nHere is the code for testing, both running in profile mode on the same phone:\n\n```dart\ntestUnQLite() async {\n    var appDocDir = await getApplicationDocumentsDirectory();\n    final start = DateTime.now().millisecondsSinceEpoch;\n    UnQLite db = UnQLite.open(\"${appDocDir.path}/test.db\");\n    final t1 = DateTime.now().millisecondsSinceEpoch;\n\n    for (var i = 0; i \u003c 100000; i++) {\n      db.store(\"my_key_$i\", \"Here is a value for testing—$i\");\n    }\n\n    final t2 = DateTime.now().millisecondsSinceEpoch;\n    for (var i = 0; i \u003c 100000; i++) {\n      var r = db.fetch\u003cString\u003e(\"my_key_$i\");\n      // debugPrint(\"fetch :$r\");\n    }\n    final t3 = DateTime.now().millisecondsSinceEpoch;\n    \n    var cursor = db.cursor();\n    for (var i = 0; i \u003c 100000; i++) {\n      cursor.seek('my_key_$i');\n      // debugPrint('=\u003e ${cursor.key} =\u003e ${cursor.value}');\n    }\n    final t4 = DateTime.now().millisecondsSinceEpoch;\n\n    var count = 0;\n    for (var entry in db.cursor()) {\n      count++;\n      var content = '${entry.key} =\u003e ${entry.value}';\n      // debugPrint(content);\n    }\n    print('count =\u003e $count');\n    final t5 = DateTime.now().millisecondsSinceEpoch;\n\n    var trans = db.transaction().begin();\n    try {\n      for (var i = 0; i \u003c 100000; i++) {\n        if (i == 10) {\n          throw Exception('test');\n        }\n        db.store(\"transaction_$i\", \"here is a transaction_$i\");\n      }\n      trans.commit();\n    } catch (e) {\n      trans.rollback();\n    }\n    final t6 = DateTime.now().millisecondsSinceEpoch;\n\n    debugPrint(\"UnQLite init:${t1-start} ms\");\n    debugPrint(\"write 100,000 entries :${t2-t1} ms\");\n    debugPrint(\"fetch 100,000 entries :${t3-t2} ms\");\n    debugPrint(\"seek  100,000 entries :${t4-t3} ms\");\n    debugPrint(\"iterate 100,000 entries :${t5-t4} ms\");\n    debugPrint(\"transaction rollback :${t6-t5} ms\");\n    db.close();\n  }\n\n  testHive() async {\n    var appDocDir = await getApplicationDocumentsDirectory();\n    var path = appDocDir.path;\n    final start = DateTime.now().millisecondsSinceEpoch;\n    Hive.init(path);\n    var box = await Hive.openBox('testBox');\n\n    final t1 = DateTime.now().millisecondsSinceEpoch;\n\n    for (var i = 0; i \u003c 100000; i++) {\n      box.put(\"my_key_$i\", \"here is a transaction_$i\");\n    }\n\n    final t2 = DateTime.now().millisecondsSinceEpoch;\n\n    for (var i = 0; i \u003c 100000; i++) {\n      var name = box.get('my_key_$i');\n    }\n\n    final t3 = DateTime.now().millisecondsSinceEpoch;\n\n    box.close();\n    debugPrint(\"Hive init:${t1-start} ms\");\n    debugPrint(\"put 100,000 entries :${t2-t1} ms\");\n    debugPrint(\"get 100,000 entries :${t3-t2} ms\");\n  }\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farcticfox1919%2Funqlite_flutter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farcticfox1919%2Funqlite_flutter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farcticfox1919%2Funqlite_flutter/lists"}