how to initialize SQLite Database variable in flutter - flutter

I'm a beginner in flutter, i want to use SQlite database using sqflite package in my Flutter App, when I declare the _database variable with this syntax static Database _database; i got a compilation error saying that i must initialize _database, and when i use this syntax static Database? _database;, i have a compilation error under return _database saying A value of type 'Database?' can't be returned from the function 'database' because it has a return type of 'Future<Database>'.
my code is
class AnnonceDataBase {
AnnonceDataBase._();
static final AnnonceDataBase instance = AnnonceDataBase._();
static Database _database;
Future<Database> get database async {
if (_database != null) return _database;
_database = await initDB();
return _database;
}
}

Just use like this.
/// late variable initialization
static late Database _database;
Here is more insight why late keyword is used.
https://blog.gskinner.com/archives/2021/03/flutter-lazy-instantiation-with-the-late-keyword.html
Have Fun!

class AppData {
static const _dbName = '<Database-Name>';
static const _dbVersion = 1;
static const _tableName = '<Table-Name>';
AppData._();
static final AppData instance = AppData._();
static Database? _database;
Future<Database?> get database async {
if (_database != null) {
return _database;
}
_database = await _initializeDatabase();
return _database;
}
Future<Database> _initializeDatabase() async {
Directory directory = await getApplicationDocumentsDirectory();
String path = join(directory.path, _dbName);
return await openDatabase(path, version: _dbVersion, onCreate: _onCreate);
}
Future _onCreate(Database db, int version) async {
try {
const createQuery = '''
CREATE TABLE $_tableName(
/// TODO : <Define table structure here using SQL Query>
);
''';
await db.execute(createQuery);
} catch (e) { }
}
}

Related

how to initialize SQLite Database variable in flutter app

I'm a beginner in flutter, i want to use SQlite database using sqflite package in my Flutter App, when I declare the_database variable with this syntax static Database _database; , I get a compilation error saying _database must be initialized except I don't know how to initialize it ?
class AnnonceDataBase {
AnnonceDataBase._();
static final AnnonceDataBase instance = AnnonceDataBase._();
static Database _database;
Future<Database> get database async {
if (_database != null) return _database;
_database = await initDB();
return _database;
}
initDB() async {
WidgetsFlutterBinding.ensureInitialized();
return await openDatabase(
join(await getDatabasesPath(), 'annonce_database.db'),
onCreate: (db, version) {
return db.execute(
"CREATE TABLE annonce (id INTEGER PRIMARY KEY, titre Text,prix INTEGER, description TEXT, idAnnonceur INTEGER, active INTEGER)");
},
version: 1,
);
}
}
I will answer here, because without the code this answer would seem out of context on your other question.
You should replace
static Database _database;
with
static Database? _database;
to mark the static variable as an optional (can be null).

how to initialize SQLite Database variable in my flutter app

I'm a beginner in flutter, i want to use SQlite database using sqflite package in my Flutter App, when I declare the _database variable with this syntax static Database _database; i got a compilation error saying that i must initialize _database, and when i use this syntax static Database? _database;, i have a compilation error under return _database saying A value of type 'Database?' can't be returned from the function 'database' because it has a return type of 'Future<Database>'. and when i put static late Database _database; i have an error in execution saying Error: LateInitializationError: Field '_database' has not been initialized.
my code is
class AnnonceDataBase {
AnnonceDataBase._();
static final AnnonceDataBase instance = AnnonceDataBase._();
static Database _database;
Future<Database> get database async {
if (_database != null) return _database;
_database = await initDB();
return _database;
}
}
I have modified it a bit but it works for you using a singleton to maintain the state of the database
class AnnonceDataBase {
AnnonceDataBase._();
static final AnnonceDataBase _instance = AnnonceDataBase._();
static Database? _database;
factory AnnonceDataBase() => _instance;
Future<Database> get database async {
if (_database != null) return _database!;
_database = await initDB();
return _database!;
}
Future<Database> initDB() async {
String table1 = "CREATE TABLE IF NOT EXISTS table1(id INTEGER PRIMARY KEY,key TEXT NOT NULL UNIQUE,name TEXT,phone NUMERIC)";
String table2 = "CREATE TABLE IF NOT EXISTS table2(id INTEGER PRIMARY KEY,key TEXT NOT NULL UNIQUE,name TEXT,phone NUMERIC)";
String path = await getDatabasesPath();
// Open the database and save the reference.
final Future<Database> database = openDatabase(
// Set the path to the database. Note: Using the `join` function of the
// plugin `path` is best practice to ensure the path is correct
// built for each platform.
p.join(path, 'admin.db'),
// When the database is first created, create a table to store data
onCreate: (db, version) {
db.execute(table1);
return db.execute(table2);
},
// Set the version. This runs the onCreate function and provides a
// path to perform updates and downgrades on the database.
version: 1,
);
return database;
}
}
You can use it like this
#override
void initState() {
AnnonceDataBase._instance.database; //Initialize when loading the application or in the singleton
super.initState();
}
Create a record
Future<void> addData() async {
Database database = AnnonceDataBase._database!;
database.transaction((txn) async {
await txn.rawInsert('INSERT INTO table1(id,key,name,phone) VALUES(?,?,?,?)', ["1", DateTime.now().toString(), "name", "+5555555"]);
});
}
Read all records
Future<void> readData() async {
Database database = AnnonceDataBase._database!;
List<Map> data = await database.rawQuery("SELECT * FROM table1");
debugPrint("data: $data");
}

A value of type 'Database?' can't be returned from the function 'db' because it has a return type of 'Future<Database>'

i am getting error
A value of type 'Database?' can't be returned from the function 'db' because it has a return type of 'Future'
for the code
class DatabaseHelper {
static final DatabaseHelper _instance = new DatabaseHelper.internal();
factory DatabaseHelper() => _instance;
static Database? _db;
Future<Database> get db async {
if (_db != null) {
return _db;
}
_db = await initDb();
return _db;
}
DatabaseHelper.internal();
initDb() async {
Directory documentDirectory = await getApplicationDocumentsDirectory();
String path = join(documentDirectory.path, "main.db");
var ourDb = await openDatabase(path, version: 1, onCreate: _onCreate);
return ourDb;
}
void _onCreate(Database db, int version) async {
await db.execute(
"CREATE TABLE User(id INTEGER PRIMARY KEY, username TEXT, password TEXT)");
print("Table is created");
}
The issue is db isnot nullable type where _db is nullable. You can include ! while you've already checked null state.
Future<Database> get db async {
if (_db != null) {
return _db!;
}
_db = await initDb();
return _db!;
}
I recommend to check null-safety

How to set up sqlite database in flutter with null safety?

I've been struggling for a while to set up a sqlite database with sqflite in flutter. Code is producing a new instance of the database every time I call the getter method for a database. Here is the code:
class DatabaseProvider {
DatabaseProvider._();
static final DatabaseProvider dbProvider = DatabaseProvider._();
static Database? _database;
Future<Database> get database async => _database ??= await _createDatabase();
}
...
You need to initialize the _database in your getter. So, change it to this:
Future<Database> get database async {
if (_database == null) {
// initialize database from _createDatabase result.
_database = await _createDatabase();
}
// because _database have beeen initialized above,
// then we can use ! to tell that the _database can't be null.
return _database!;
}

how to avoid safety null

in this class while declaring the constructor Repository i get this error 'Non-nullable instance field '_database' must be initialized.
Try adding an initializer expression, or add a field initializer in this constructor, or mark it 'late'' i added late but it doesn't work the same error while declaring the static Database _database .
this is the class Repository
import 'package:sqflite/sqflite.dart';
import 'package:todo/repositories/database_connection.dart';
class Repository {
DatabaseConnection _databaseConnection;
Repository() {
_databaseConnection = DatabaseConnection();
}
static Database _database;
Future<Database> get database async {
if (_database != null) return _database;
_database = await _databaseConnection.setDatabase();
return _database;
}
insertData(table, data) async {
var connection = await database;
return await connection.insert(table,data)
}
and this is the DatabaseConnection
class DatabaseConnection {
setDatabase() async {
var directory = await getApplicationDocumentsDirectory();
var path = join(directory.path, 'db_todo_sqflite');
var database =
await openDatabase(path, version: 1, onCreate: _onCreateDatabase);
return database;
}
_onCreateDatabase(Database database, int version) async {
await database.execute(
"CREATE TABLE categories(id INTEGER KEY , name TEXT , descrption TEXT");
}
}
Your database itself is nullable, so you add a ?
static Database? _database;
That makes the _database nullable, but in your getter you are returning a non nullable instance of Database.
The nullable instance would be Database?
Future<Database?> get database async {
...
}
If you are sure that the _database is initialized, and can't be null at that point you return the value, and tell dart that this value is never null.
static Database? _database;
Future<Database> get database async {
if (_database != null) return _database!;
_database = await _databaseConnection.setDatabase();
return _database!;
}
Note the "!" at the return _database!
See also https://dart.dev/null-safety/understanding-null-safety
And https://dart.dev/tools/diagnostic-messages#unchecked_use_of_nullable_value
You are getting an error because
static Database _database is no nullable
Change the code to
static Database? _database
thank all for the response
this how i correct the code
import 'package:sqflite/sqflite.dart';
import 'package:todo/repositories/database_connection.dart';
class Repository {
DatabaseConnection? _databaseConnection;
Repository() {
_databaseConnection = DatabaseConnection();
}
static Database? _database;
Future<Database?> get database async {
if (_database != null) return _database;
_database = await _databaseConnection!.setDatabase();
return _database! ;
}
insertData(table, data) async {
var connection = await database;
return await connection!.insert(table, data);
}
}
You also can use the late modifier:
late DatabaseConnection _databaseConnection;
Just make sure you set this variable before you try to use it.