Browse Source

Introduce a CollectionsDB

Vishnu Mohandas 4 years ago
parent
commit
c66eb60d02
2 changed files with 129 additions and 11 deletions
  1. 108 0
      lib/db/collections_db.dart
  2. 21 11
      lib/models/collection.dart

+ 108 - 0
lib/db/collections_db.dart

@@ -0,0 +1,108 @@
+import 'dart:io';
+
+import 'package:path/path.dart';
+import 'package:path_provider/path_provider.dart';
+import 'package:photos/models/collection.dart';
+import 'package:sqflite/sqflite.dart';
+
+class CollectionsDB {
+  static final _databaseName = "ente.collections.db";
+  static final _databaseVersion = 1;
+
+  static final table = 'collections';
+
+  static final columnID = 'collection_id';
+  static final columnOwnerID = 'owner_id';
+  static final columnEncryptedKey = 'encrypted_key';
+  static final columnKeyDecryptionNonce = 'key_decryption_nonce';
+  static final columnName = 'name';
+  static final columnType = 'type';
+  static final columnEncryptedPath = 'path';
+  static final columnCreationTime = 'creation_time';
+
+  CollectionsDB._privateConstructor();
+  static final CollectionsDB instance = CollectionsDB._privateConstructor();
+
+  static Database _database;
+  Future<Database> get database async {
+    if (_database != null) return _database;
+    _database = await _initDatabase();
+    return _database;
+  }
+
+  _initDatabase() async {
+    Directory documentsDirectory = await getApplicationDocumentsDirectory();
+    String path = join(documentsDirectory.path, _databaseName);
+    return await openDatabase(
+      path,
+      version: _databaseVersion,
+      onCreate: _onCreate,
+    );
+  }
+
+  Future _onCreate(Database db, int version) async {
+    await db.execute('''
+                CREATE TABLE $table (
+                  $columnID INTEGER PRIMARY KEY NOT NULL,
+                  $columnOwnerID TEXT NOT NULL,
+                  $columnEncryptedKey TEXT NOT NULL,
+                  $columnKeyDecryptionNonce TEXT NOT NULL,
+                  $columnName TEXT NOT NULL,
+                  $columnType TEXT NOT NULL,
+                  $columnEncryptedPath TEXT,
+                  $columnCreationTime TEXT NOT NULL,
+                )
+                ''');
+  }
+
+  Future<List<dynamic>> insert(List<Collection> collections) async {
+    final db = await instance.database;
+    var batch = db.batch();
+    for (final collection in collections) {
+      batch.insert(table, _getRowForCollection(collection),
+          conflictAlgorithm: ConflictAlgorithm.replace);
+    }
+    return await batch.commit();
+  }
+
+  Future<int> getLastCollectionCreationTime() async {
+    final db = await instance.database;
+    final rows = await db.query(
+      table,
+      orderBy: '$columnCreationTime DESC',
+      limit: 1,
+    );
+    if (rows.isNotEmpty) {
+      return int.parse(rows[0][columnCreationTime]);
+    } else {
+      return null;
+    }
+  }
+
+  Map<String, dynamic> _getRowForCollection(Collection collection) {
+    var row = new Map<String, dynamic>();
+    row[columnID] = collection.id;
+    row[columnOwnerID] = collection.ownerID;
+    row[columnEncryptedKey] = collection.encryptedKey;
+    row[columnKeyDecryptionNonce] = collection.keyDecryptionNonce;
+    row[columnName] = collection.name;
+    row[columnType] = collection.type;
+    row[columnEncryptedPath] = collection.encryptedPath;
+    row[columnCreationTime] = collection.creationTime;
+    return row;
+  }
+
+  Collection _convertToCollection(Map<String, dynamic> row) {
+    return Collection(
+      row[columnID],
+      row[columnOwnerID],
+      row[columnEncryptedKey],
+      row[columnKeyDecryptionNonce],
+      row[columnName],
+      row[columnType],
+      row[columnEncryptedPath],
+      int.parse(row[columnCreationTime]),
+      null,
+    );
+  }
+}

+ 21 - 11
lib/models/collection.dart

@@ -9,7 +9,8 @@ class Collection {
   final String keyDecryptionNonce;
   final String keyDecryptionNonce;
   final String name;
   final String name;
   final CollectionType type;
   final CollectionType type;
-  final Map<String, dynamic> attributes;
+  final String encryptedPath;
+  final int creationTime;
   final List<String> sharees;
   final List<String> sharees;
 
 
   Collection(
   Collection(
@@ -19,12 +20,13 @@ class Collection {
     this.keyDecryptionNonce,
     this.keyDecryptionNonce,
     this.name,
     this.name,
     this.type,
     this.type,
-    this.attributes,
+    this.encryptedPath,
+    this.creationTime,
     this.sharees,
     this.sharees,
   );
   );
 
 
   static Collection emptyCollection() {
   static Collection emptyCollection() {
-    return Collection(null, null, null, null, null, null, null, List<String>());
+    return Collection(null, null, null, null, null, null, null, null, List<String>());
   }
   }
 
 
   Collection copyWith({
   Collection copyWith({
@@ -34,7 +36,8 @@ class Collection {
     String keyDecryptionNonce,
     String keyDecryptionNonce,
     String name,
     String name,
     CollectionType type,
     CollectionType type,
-    Map<String, dynamic> attributes,
+    String encryptedPath,
+    int creationTime,
     List<String> sharees,
     List<String> sharees,
   }) {
   }) {
     return Collection(
     return Collection(
@@ -44,7 +47,8 @@ class Collection {
       keyDecryptionNonce ?? this.keyDecryptionNonce,
       keyDecryptionNonce ?? this.keyDecryptionNonce,
       name ?? this.name,
       name ?? this.name,
       type ?? this.type,
       type ?? this.type,
-      attributes ?? this.attributes,
+      encryptedPath ?? this.encryptedPath,
+      creationTime ?? this.creationTime,
       sharees ?? this.sharees,
       sharees ?? this.sharees,
     );
     );
   }
   }
@@ -57,7 +61,8 @@ class Collection {
       'keyDecryptionNonce': keyDecryptionNonce,
       'keyDecryptionNonce': keyDecryptionNonce,
       'name': name,
       'name': name,
       'type': type.toString(),
       'type': type.toString(),
-      'attributes': attributes,
+      'creationTime': creationTime,
+      'encryptedPath': encryptedPath,
       'sharees': sharees,
       'sharees': sharees,
     };
     };
   }
   }
@@ -72,8 +77,9 @@ class Collection {
       map['keyDecryptionNonce'],
       map['keyDecryptionNonce'],
       map['name'],
       map['name'],
       fromString(map['type']),
       fromString(map['type']),
-      Map<String, dynamic>.from(map['attributes']),
-      List<String>.from(map['sharees']),
+      map['encryptedPath'],
+      map['creationTime'],
+      map['sharees'] == null ? null : List<String>.from(map['sharees']),
     );
     );
   }
   }
 
 
@@ -84,7 +90,7 @@ class Collection {
 
 
   @override
   @override
   String toString() {
   String toString() {
-    return 'Collection(id: $id, ownerID: $ownerID, encryptedKey: $encryptedKey, keyDecryptionNonce: $keyDecryptionNonce, name: $name, type: $type, attributes: $attributes, sharees: $sharees)';
+    return 'Collection(id: $id, ownerID: $ownerID, encryptedKey: $encryptedKey, keyDecryptionNonce: $keyDecryptionNonce, name: $name, type: $type, encryptedPath: $encryptedPath, creationTime: $creationTime, sharees: $sharees)';
   }
   }
 
 
   @override
   @override
@@ -98,7 +104,9 @@ class Collection {
         o.keyDecryptionNonce == keyDecryptionNonce &&
         o.keyDecryptionNonce == keyDecryptionNonce &&
         o.name == name &&
         o.name == name &&
         o.type == type &&
         o.type == type &&
-        mapEquals(o.attributes, attributes);
+        o.encryptedPath == encryptedPath &&
+        o.creationTime == creationTime &&
+        listEquals(o.sharees, sharees);
   }
   }
 
 
   @override
   @override
@@ -109,7 +117,9 @@ class Collection {
         keyDecryptionNonce.hashCode ^
         keyDecryptionNonce.hashCode ^
         name.hashCode ^
         name.hashCode ^
         type.hashCode ^
         type.hashCode ^
-        attributes.hashCode;
+        encryptedPath.hashCode ^
+        creationTime.hashCode ^
+        sharees.hashCode;
   }
   }
 }
 }