diff --git a/lib/src/cache/cache.dart b/lib/src/cache/cache.dart index a63cadc46..f209598cc 100644 --- a/lib/src/cache/cache.dart +++ b/lib/src/cache/cache.dart @@ -1,5 +1,6 @@ abstract class Cache { dynamic read(String key) {} + Future remove(String key, bool cascade) async {} void write( String key, dynamic value, diff --git a/lib/src/cache/in_memory.dart b/lib/src/cache/in_memory.dart index 6b4126364..4be115de7 100644 --- a/lib/src/cache/in_memory.dart +++ b/lib/src/cache/in_memory.dart @@ -102,4 +102,10 @@ class InMemoryCache implements Cache { return HashMap(); } } + + @override + Future remove(String key, bool cascade) { + // TODO: implement remove + return null; + } } diff --git a/lib/src/cache/normalized/record_field_json_adapter.dart b/lib/src/cache/normalized/record_field_json_adapter.dart new file mode 100644 index 000000000..797a26db6 --- /dev/null +++ b/lib/src/cache/normalized/record_field_json_adapter.dart @@ -0,0 +1,77 @@ +import 'dart:core'; + +class RecordFieldJsonAdapter { + + static RecordFieldJsonAdapter create() { + return new RecordFieldJsonAdapter(); + } + + RecordFieldJsonAdapter() { + } + + /* String toJson(Map fields) { + checkNotNull(fields, "fields == null"); + Buffer buffer = new Buffer(); + JsonWriter jsonWriter = JsonWriter.of(buffer); + jsonWriter.setSerializeNulls(true); + + try { + jsonWriter.beginObject(); + for (Map.Entry fieldEntry : fields.entrySet()) { + String key = fieldEntry.getKey(); + Object value = fieldEntry.getValue(); + jsonWriter.name(key); + writeJsonValue(value, jsonWriter); + } + jsonWriter.endObject(); + jsonWriter.close(); + return buffer.readUtf8(); + } catch (IOException e) { + // should never happen as we are working with mem buffer + throw new RuntimeException(e); + } + } + + private Map fromBufferSource(BufferedSource bufferedFieldSource) throws IOException { + final CacheJsonStreamReader cacheJsonStreamReader = + cacheJsonStreamReader(bufferedSourceJsonReader(bufferedFieldSource)); + return cacheJsonStreamReader.toMap(); + } + + public Map from(String jsonFieldSource) throws IOException { + final BufferedSource bufferSource + = Okio.buffer(Okio.source(new ByteArrayInputStream(jsonFieldSource.getBytes(Charset.defaultCharset())))); + return fromBufferSource(bufferSource); + } + + private static void writeJsonValue(Object value, JsonWriter jsonWriter) throws IOException { + if (value == null) { + jsonWriter.nullValue(); + } else if (value instanceof String) { + jsonWriter.value((String) value); + } else if (value instanceof Boolean) { + jsonWriter.value((boolean) value); + } else if (value instanceof Number) { + jsonWriter.value((Number) value); + } else if (value instanceof CacheReference) { + jsonWriter.value(((CacheReference) value).serialize()); + } else if (value instanceof List) { + jsonWriter.beginArray(); + for (Object item : (List) value) { + writeJsonValue(item, jsonWriter); + } + jsonWriter.endArray(); + } else if (value instanceof Map) { + //noinspection unchecked + Map fields = (Map) value; + jsonWriter.beginObject(); + for (Map.Entry fieldEntry : fields.entrySet()) { + jsonWriter.name(fieldEntry.getKey()); + writeJsonValue(fieldEntry.getValue(), jsonWriter); + } + jsonWriter.endObject(); + } else { + throw new RuntimeException("Unsupported record value type: " + value.getClass()); + } + } */ +} \ No newline at end of file diff --git a/lib/src/cache/normalized/sql/sql-normalized-cache.dart b/lib/src/cache/normalized/sql/sql-normalized-cache.dart new file mode 100644 index 000000000..f58dd155c --- /dev/null +++ b/lib/src/cache/normalized/sql/sql-normalized-cache.dart @@ -0,0 +1,61 @@ +import 'package:flutter_graphql/src/cache/cache.dart'; +import 'package:flutter_graphql/src/cache/normalized/sql/sql_helper.dart'; +import 'package:sqflite/sqflite.dart'; + +class SqlNormalizedCache implements Cache { + + static const String INSERT_STATEMENT = '''INSERT INTO ${SqlHelper.TABLE_RECORDS} (${SqlHelper.COLUMN_KEY},${SqlHelper.COLUMN_RECORD}) VALUES (?,?)'''; + static const String UPDATE_STATEMENT = '''UPDATE ${SqlHelper.TABLE_RECORDS} SET ${SqlHelper.COLUMN_KEY}=?, ${SqlHelper.COLUMN_RECORD}=? WHERE ${SqlHelper.COLUMN_KEY}=?'''; + + static const String DELETE_STATEMENT = '''DELETE FROM ${SqlHelper.TABLE_RECORDS} WHERE ${SqlHelper.COLUMN_KEY}=?'''; + static const String DELETE_ALL_RECORD_STATEMENT = '''DELETE FROM ${SqlHelper.TABLE_RECORDS}'''; + + Database database; + final SqlHelper dbHelper; + final allColumns = [ + SqlHelper.COLUMN_ID, + SqlHelper.COLUMN_KEY, + SqlHelper.COLUMN_RECORD]; + + SqlNormalizedCache(this.dbHelper); + + /* + private final SQLiteStatement insertStatement; + private final SQLiteStatement updateStatement; + private final SQLiteStatement deleteStatement; + private final SQLiteStatement deleteAllRecordsStatement; + private final RecordFieldJsonAdapter recordFieldAdapter;*/ + + @override + Object read(String key) { + // TODO: implement read + return null; + } + + @override + void reset() { + // TODO: implement reset + } + + @override + void restore() { + // TODO: implement restore + } + + @override + void save() { + // TODO: implement save + } + + @override + void write(String key, value) { + // TODO: implement write + } + + @override + Future remove(String key, bool cascade) { + // TODO: implement remove + return null; + } + +} \ No newline at end of file diff --git a/lib/src/cache/normalized/sql/sql_helper.dart b/lib/src/cache/normalized/sql/sql_helper.dart new file mode 100644 index 000000000..86820f87a --- /dev/null +++ b/lib/src/cache/normalized/sql/sql_helper.dart @@ -0,0 +1,33 @@ +import 'package:path/path.dart'; +import 'package:sqflite/sqflite.dart'; + +class SqlHelper { + + static const String TABLE_RECORDS = 'records'; + static const String COLUMN_ID = '_id'; + static const String COLUMN_RECORD = 'record'; + static const String COLUMN_KEY = 'key'; + + static const String DATABASE_NAME = 'graphql-flutter.db'; + static const int DATABASE_VERSION = 1; + + static const String DATABASE_CREATE = '''CREATE TABLE $TABLE_RECORDS ($COLUMN_ID INTEGER PRIMARY KEY AUTOINCREMENT, $COLUMN_KEY TEXT NOT NULL, $COLUMN_RECORD TEXT NOT NULL'''; + static const String IDX_RECORDS_KEY = 'idx_records_key'; + static const String CREATE_KEY_INDEX = '''CREATE INDEX $IDX_RECORDS_KEY ON $TABLE_RECORDS ($COLUMN_KEY)'''; + + Database db; + + Future open() async { + final databasesPath = await getDatabasesPath(); + String path = join(databasesPath, DATABASE_NAME); + db = await openDatabase(path, version: DATABASE_VERSION, onCreate: (Database db, int version) async { + await db.execute(DATABASE_CREATE); + await db.execute(CREATE_KEY_INDEX); + }); + } + + Future close() async { + await db.close(); + } + +} \ No newline at end of file diff --git a/pubspec.yaml b/pubspec.yaml index 19e70f5ab..2650831bc 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -16,6 +16,7 @@ dependencies: path_provider: ^0.4.1 uuid: ^1.0.3 graphql_parser: ^1.1.1 + sqflite: ^1.1.0 dev_dependencies: flutter_test: