tekartik / sembast_sqflite

sembast on top of sqflite
BSD 2-Clause "Simplified" License
13 stars 1 forks source link

Is This Plugin Work for Flutter Mobile? #1

Closed Peng-Qian closed 4 years ago

Peng-Qian commented 4 years ago

Problem

I try to apply this plug for IOS and Android by example steps,

  var factory = getDatabaseFactorySqflite(databaseFactoryFfi);
  var db = await factory.openDatabase('example.db');

but there it fails to open database and throw the following exception:

sqfliteffiexception(sqlite_error14, , open_failed: sqliteexception(14): bad parameter or other api misuse, bad parameter or other api misuse (code 21)} databaseexception(open_failed: sqliteexception(14): bad parameter or other api misuse, bad parameter or other api misuse (code 21)) {}

Is this plugin support for flutter mobile?

alextekartik commented 4 years ago

Sorry for the lack of documentation. Per say it is not really a plugin, just a library that will use sqflite as its core persistency engine exposing a sembast database API.

I started some setup doc here: https://github.com/tekartik/sembast_sqflite/blob/master/sembast_sqflite/doc/setup.md

FFI based is only for Desktop and Unit test support. For iOS and Android you have to import and use sqflite

Sembast sqflite setup

Flutter iOS/Android/MacOS

Flutter context needed.

You have to import the sqflite dependency in a flutter context.

pubspec.yaml:

dependencies:
  sembast_sqflite:
  sqflite:

The default factory based on sqflite can be created this way:

import 'package:sembast_sqflite/sembast_sqflite.dart';
import 'package:sqflite/sqflite.dart' as sqflite;

export 'package:sembast/sembast.dart';

/// Sembast sqflite based database factory.
///
/// Supports iOS/Android/MacOS for now.
final databaseFactorySqflite =
    getDatabaseFactorySqflite(sqflite.databaseFactory);

A sembast database can be opened/created this way:

var factory = databaseFactorySqflite;
var db = await factory.openDatabase('my_file.db');

await db.close();

The file could be a relative path to the default platform database path or an absolute path, pointing to a sqlite database.

Peng-Qian commented 4 years ago

Hi @alextekartik,

Thx for your quick reply, it solved my problem.

The reason I wanna try the sembast_sqflite is that I found sembast actually add a whole store record no matter put or update data. I think it may involve performance issues to save chatting records (which may frequently write and read with large amounts of data).

So, am I right about the performance understanding, and does the sembast_sqflite be able to read/write specific data instead of the whole store data?

alextekartik commented 4 years ago

So, am I right about the performance understanding, and does the sembast_sqflite be able to read/write specific data instead of the whole store data?

That's correct. sembast_sqflite and sembast_web are more efficient in storage usage since only the last version of a record is saved which is not the case in regular sembast (only the lengthy compact operation get rid of old records).

I found sembast actually add a whole store record no matter put or update data.

That does not change though, a whole record is updated since records are immutable. The old record is deleted though (which is not the case in regular sembast)

Peng-Qian commented 4 years ago

Thx for your explanation!

I still curious about the actual process of read/write a single data from a table.

For following data:

    final info = <String, dynamic>{
      'basic': {
        'name': 'someName',
        'age': 999,
        'gender': 'male',
      },
      'contact': {
        'phone': 123456,
        'email': 'email@email.com',
      },
      'heath': {
        'weight': 111,
      }
    };

If I try to get 'name' from 'basic' of info store, does it load the whole database in memory, or load the Info store records in memory, or it only loads the 'name' in memory?

For write data, if I try to update 'name' from 'basic' of info store, does it create whole store records and replace the older one (delete the old one and add a new one) or it only replaces 'name' data? and how it stored in the SQL table since the records have different property and column numbers?

Sorry to bord you again, I am eager to understand how the sembast work since it determinate how to design a high-performance local database structure. These questions are concerned because I am currently struggling with the data depth of the one store records.

Just like the above data, should I save all different type info in one info store or should I create basicInfo store, contractInfo store and healthInfo store separately?

Should I consider data fragmentization with multiple stores for fast read and write, e.g. for chatting data, should I create a store for each conversation since it could be a large number of records for a single conversation?

alextekartik commented 4 years ago

All your questions are valid!

does it load the whole database in memory,

Yes sembast is for now a all in memory solution. It might surprise but many solutions uses this (hive, lovefield).

For write data, if I try to update 'name' from 'basic' of info store, does it create whole store records and replace the older one

Yes it creates a new record and replace the old one.

how it stored in the SQL table since the records have different property and column numbers?

SQLite is used as a journal database storing the whole record as json string (similar to sembast, format explained here

Just like the above data, should I save all different type info in one info store or should I create basicInfo store, contractInfo store and healthInfo store separately?

There is no strong recommendation. Personally I would create a store for each entity and store a reference for relationship. Loading record by id is almost immediate as sembast is a fast a key value storage. Then for convenience/performance you might consider nesting data when needed. Designing as you would do for firestore should work.

for chatting data, should I create a store for each conversation

Since there is no indexing yet on secondary field (I don't know yet how to handle that in a correct way), having one store by conversation could work. Another store could enumerate the list of conversation (i.e. store name) available. Or you can have one store filtered by a conversation participant id.

Peng-Qian commented 4 years ago

Thx so much, you really helped me to understand the mechanism!

Personally I would create a store for each entity and store a reference for relationship

Sounds like you love sqflite more. lol.