db_helper.dart 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. import 'dart:io';
  2. import 'package:logger/logger.dart';
  3. import 'package:myapp/models/photo.dart';
  4. import 'package:path/path.dart';
  5. import 'package:sqflite/sqflite.dart';
  6. import 'package:path_provider/path_provider.dart';
  7. class DatabaseHelper {
  8. static final _databaseName = "orma.db";
  9. static final _databaseVersion = 1;
  10. static final table = 'photos';
  11. static final columnGeneratedId = '_id';
  12. static final columnUploadedFileId = 'uploaded_file_id';
  13. static final columnLocalId = 'local_id';
  14. static final columnLocalPath = 'local_path';
  15. static final columnThumbnailPath = 'thumbnail_path';
  16. static final columnPath = 'path';
  17. static final columnHash = 'hash';
  18. static final columnIsDeleted = 'is_deleted';
  19. static final columnCreateTimestamp = 'create_timestamp';
  20. static final columnSyncTimestamp = 'sync_timestamp';
  21. // make this a singleton class
  22. DatabaseHelper._privateConstructor();
  23. static final DatabaseHelper instance = DatabaseHelper._privateConstructor();
  24. // only have a single app-wide reference to the database
  25. static Database _database;
  26. Future<Database> get database async {
  27. if (_database != null) return _database;
  28. // lazily instantiate the db the first time it is accessed
  29. _database = await _initDatabase();
  30. return _database;
  31. }
  32. // this opens the database (and creates it if it doesn't exist)
  33. _initDatabase() async {
  34. Directory documentsDirectory = await getApplicationDocumentsDirectory();
  35. String path = join(documentsDirectory.path, _databaseName);
  36. return await openDatabase(path,
  37. version: _databaseVersion, onCreate: _onCreate);
  38. }
  39. // SQL code to create the database table
  40. Future _onCreate(Database db, int version) async {
  41. await db.execute('''
  42. CREATE TABLE $table (
  43. $columnGeneratedId INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
  44. $columnLocalId TEXT,
  45. $columnUploadedFileId INTEGER NOT NULL,
  46. $columnLocalPath TEXT NOT NULL,
  47. $columnThumbnailPath TEXT NOT NULL,
  48. $columnPath TEXT,
  49. $columnHash TEXT NOT NULL,
  50. $columnIsDeleted INTEGER DEFAULT 0,
  51. $columnCreateTimestamp TEXT NOT NULL,
  52. $columnSyncTimestamp TEXT
  53. )
  54. ''');
  55. }
  56. Future<int> insertPhoto(Photo photo) async {
  57. Database db = await instance.database;
  58. return await db.insert(table, _getRowForPhoto(photo));
  59. }
  60. Future<List<dynamic>> insertPhotos(List<Photo> photos) async {
  61. Database db = await instance.database;
  62. var batch = db.batch();
  63. int batchCounter = 0;
  64. for (Photo photo in photos) {
  65. if (batchCounter == 400) {
  66. await batch.commit();
  67. batch = db.batch();
  68. }
  69. batch.insert(table, _getRowForPhoto(photo));
  70. batchCounter++;
  71. }
  72. return await batch.commit();
  73. }
  74. Future<List<Photo>> getAllPhotos() async {
  75. Database db = await instance.database;
  76. var results = await db.query(table,
  77. where: '$columnIsDeleted = 0', orderBy: '$columnCreateTimestamp DESC');
  78. return _convertToPhotos(results);
  79. }
  80. Future<List<Photo>> getAllDeletedPhotos() async {
  81. Database db = await instance.database;
  82. var results = await db.query(table,
  83. where: '$columnIsDeleted = 1', orderBy: '$columnCreateTimestamp DESC');
  84. return _convertToPhotos(results);
  85. }
  86. Future<List<Photo>> getPhotosToBeUploaded() async {
  87. Database db = await instance.database;
  88. var results = await db.query(table, where: '$columnUploadedFileId = -1');
  89. return _convertToPhotos(results);
  90. }
  91. Future<int> updatePhoto(Photo photo) async {
  92. Database db = await instance.database;
  93. return await db.update(table, _getRowForPhoto(photo),
  94. where: '$columnGeneratedId = ?', whereArgs: [photo.generatedId]);
  95. }
  96. Future<Photo> getPhotoByPath(String path) async {
  97. Database db = await instance.database;
  98. var rows =
  99. await db.query(table, where: '$columnPath =?', whereArgs: [path]);
  100. if (rows.length > 0) {
  101. return _getPhotofromRow(rows[0]);
  102. } else {
  103. throw ("No cached photo");
  104. }
  105. }
  106. Future<int> markPhotoAsDeleted(Photo photo) async {
  107. Database db = await instance.database;
  108. var values = new Map<String, dynamic>();
  109. values[columnIsDeleted] = 1;
  110. return db.update(table, values,
  111. where: '$columnGeneratedId =?', whereArgs: [photo.generatedId]);
  112. }
  113. Future<int> deletePhoto(Photo photo) async {
  114. Database db = await instance.database;
  115. return db.delete(table,
  116. where: '$columnGeneratedId =?', whereArgs: [photo.generatedId]);
  117. }
  118. List<Photo> _convertToPhotos(List<Map<String, dynamic>> results) {
  119. var photos = List<Photo>();
  120. for (var result in results) {
  121. photos.add(_getPhotofromRow(result));
  122. }
  123. return photos;
  124. }
  125. Map<String, dynamic> _getRowForPhoto(Photo photo) {
  126. var row = new Map<String, dynamic>();
  127. row[columnLocalId] = photo.localId;
  128. row[columnUploadedFileId] =
  129. photo.uploadedFileId == null ? -1 : photo.uploadedFileId;
  130. row[columnLocalPath] = photo.localPath;
  131. row[columnThumbnailPath] = photo.thumbnailPath;
  132. row[columnPath] = photo.path;
  133. row[columnHash] = photo.hash;
  134. row[columnCreateTimestamp] = photo.createTimestamp;
  135. row[columnSyncTimestamp] = photo.syncTimestamp;
  136. return row;
  137. }
  138. Photo _getPhotofromRow(Map<String, dynamic> row) {
  139. Photo photo = Photo();
  140. photo.generatedId = row[columnGeneratedId];
  141. photo.localId = row[columnLocalId];
  142. photo.uploadedFileId = row[columnUploadedFileId];
  143. photo.localPath = row[columnLocalPath];
  144. photo.thumbnailPath = row[columnThumbnailPath];
  145. photo.path = row[columnPath];
  146. photo.hash = row[columnHash];
  147. photo.createTimestamp = int.parse(row[columnCreateTimestamp]);
  148. photo.syncTimestamp = row[columnSyncTimestamp] == null
  149. ? -1
  150. : int.parse(row[columnSyncTimestamp]);
  151. return photo;
  152. }
  153. }