Reputation: 131
I am trying to read data from a database which is already made outside and placed in assets folder in my project. I have quiet checked some tutorials to build code. Here am simply copying database in my assets folder to application documents directory and trying to get (debugprint to console) the count of data in the column "father" using the rawQuery method, my table name is "items". I am getting an error saying, No such table. So am guessing I have a broken code on my database helper class.
static DatabaseHelper _databaseHelper; // Singleton DatabaseHelper
static Database _database; // Singleton Database
static String _path;
DatabaseHelper._createInstance(); // Named constructor to create instance of DatabaseHelper
factory DatabaseHelper() {
if (_databaseHelper == null) {
_databaseHelper = DatabaseHelper
._createInstance(); // This is executed only once, singleton object
}
return _databaseHelper;
}
Future<Database> get database async {
if (_database == null) {
_database = await initializeDatabase();
}
return _database;
}
Future<Database> initializeDatabase() async {
// Get the directory path for both Android and iOS to store database.
Directory directory = await getApplicationDocumentsDirectory();
_path = directory.path + 'bomdb.sqlite';
// Open/create the database at a given path
var bomDatabase = await openDatabase(
_path, version: 1, onCreate: _createDb);
return bomDatabase;
}
void _createDb(Database db, int newVersion) async {
ByteData data = await rootBundle.load('assets/bomdb.sqlite');
List<int> bytes =
data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
debugPrint('Database is in path: ' + _path);
await new File(_path).writeAsBytes(bytes);
}
Future<int> sampleData() async {
Database db = await this.database;
List<Map<String, dynamic>> x = await db.rawQuery(
'SELECT COUNT(father) FROM items');
var res = await db.rawQuery('SELECT COUNT(father) FROM items');
int result = Sqflite.firstIntValue(x);
debugPrint(result.toString());
return result;
}
}
Upvotes: 1
Views: 2884
Reputation: 131
I refer the sqflite doc provided by Mr. Tommie C, I changed my initializeDatabase
to the following and removed _createDb
function that is not require in here:
Future<Database> initializeDatabase() async {
var databasesPath = await getDatabasesPath();
var path = join(databasesPath, "bomdb.sqlite");
// Check if the database exists
var exists = await databaseExists(path);
if (!exists) {
// Should happen only the first time you launch your application
print("Creating new copy from asset");
// Make sure the parent directory exists
try {
await Directory(dirname(path)).create(recursive: true);
} catch (_) {}
// Copy from asset
ByteData data = await rootBundle.load(join("assets", "bomdb.sqlite"));
List<int> bytes =
data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
// Write and flush the bytes written
await File(path).writeAsBytes(bytes, flush: true);
} else {
print("Opening existing database");
}
// open the database
var bomDataTable = await openDatabase(path, readOnly: true);
return bomDataTable;
}
I still not figured why it is not worked with oncreate
statement with opendatabase
, but no issues with this as it is described in the document: https://github.com/tekartik/sqflite/blob/master/sqflite/doc/opening_asset_db.md
Upvotes: 4