How to reset auto increment id in SQLite table in Dart - flutter

I need to reset the automatic incremental ID to 0. When I delete every record from the table, the data will be deleted, then adding new data onto the table, the numbering continues from where it was before. I tried
db.delete('table_name'); // works fine. but numbering continues.
....
db.execute('TRUNCATE TABLE table_name'); // shows exception
The exception I get is:
DatabaseException(near "TRUNCATE": syntax error (code 1 SQLITE_ERROR):
How to fix this ?

This will reset the sequence index for the table you specify
await db!.delete('table_name');
await db!.update('sqlite_sequence', {'seq':1}, where: 'name = ?', whereArgs: ['table_name']);
To query all tables in sqlite schema you can use:
Future<List<Object>> showTables() async {
List<Object> tableNames = [];
List<Map<String, Object?>> tables = await db!.rawQuery("SELECT * FROM sqlite_master WHERE type=?", ['table']);
for (Map<String, Object?> table in tables) {
tableNames.add(table['name']!);
}
return tableNames;
}

Related

How to bulk update SQLite table entries in Flutter

My Flutter app makes use of an SQLite database with multiple tables and Firebase authentication. Some time after publishing the app, I added a User ID column to each table, so that I could ensure that results could be filtered by users and they would only see their own data, should another user log into the app on the same device.
When I created the new column in each table though, for the entries that already existed, I allowed the data in the new column to be null to prevent an error with the database. The problem with that is that users who made the initial calculations where the User ID is null will now 'lose' that data, as it won't show up when I implement filtering with User ID.
What I want to do is bulk-update the null values in that column of each SQLite database table, if a null value exists in that table. The null values should be replaced by the current logged in User ID. I'm not sure of the best way to do this but my idea is something like this, with a database update function after it has been initialised:
Future _update(Database db, int oldVersion, int newVersion) async {
if (oldVersion < newVersion) {
Future<int> updateDB(String value) async {
final db = await instance.database;
return db.update(
values,
value.toJson(),
where: '${ValueFields.id} = ?',
whereArgs: [value.id],
);
}
}
}
Thing is, this doesn't seem to actually work and of course doesn't bulk update all rows in that particular column. Can someone advise on how I can build the bulk update function, to take all null User ID values in a particular table and change them to the current logged in user?
Thank you!
What you are doing is never updating anything if id is null. That is even if null were passed as the id via the whereargs, it would never update any rows as null is considered unique/distinct so will never be the same as another null. Instead you can use IS NULL. If the id is not null then it would not update rows where the id is null.
You can update all in one go if you use, (in SQL)
UPDATE the_table SET the_column = the_value WHERE the_column IS NULL
which I believe would be along the lines of:-
return db.update(
values,
value.toJson(),
where: '${ValueFields.id} IS NULL', /*<<<<< CHANGED WHERE CLAUSE */
whereArgs: [], /*<<<<< CHANGED NO WHERE ARGS*/
);

I want to create multiple table in sqflite by calling same function

I want to create multiple tables in sqflite by calling the same function, cause I want to create multiple playlists, playlist name will be the table name, which came from user input,
for this reason, users call the databaseCreate function in multiple time. But its show some error :
Unhandled Exception: DatabaseException(no such table: sports (code 1
SQLITE_ERROR): , while compiling: INSERT INTO sports (title, link, logo,
playlistName) VALUES (?, ?, NULL, ?)) sql 'INSERT INTO sports (title, link, logo,
playlistName)
Database Create Code :
Future open( String name) async {
Directory documentsDirectory = await getApplicationDocumentsDirectory();
final path = join(documentsDirectory.path, 'playlist1.db');
_database = await openDatabase(path, version: 2,
onCreate: (Database db, int version) async {
await db.execute('''
create table $name (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,playlistName TEXT, link TEXT, title TEXT,
logo TEXT)
''');
});
}
Hare's name comes from the user. At a very fast time, it will be okay but for creating a second playlist it will be crashed
You should prefer use parameterized queries:
await db.execute("
create table ? (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,playlistName TEXT, link TEXT, title TEXT,
logo TEXT)
", [name]);
UPDATE
If you need to update the database schema, you need to update the version of the database, like this:
return await openDatabase(
path,
version: 2, // <=== Update (increase) this number
onOpen: (db) {},
onCreate: createDatabase,
onUpgrade: upgradeDatabase,
);
Doing this, you ask SQFLite to update the schema. Use onUpgrade to tell the new schema.
You can also uninstall the app when you are in development stage. In this case, new schema should be in onCreate.
If i resume, onCreate is called once when database is created. And onUpgrade is called each time version is increased.
UPDATE 2
For unknown reasons (haven't search more), execute method does not replace the ? by parameter. Perharps for security reasons. In fact using dynamic table name is not a very good design.
So for achive this, you shoult not use parameterized query like i said previously. You should use a concatened string, like this:
await db.rawQuery(
"create table " +
name +
" ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,playlistName TEXT, link TEXT, title TEXT, logo TEXT)",[]);

update single record among multiple records by UserId in Back4App flutter

I am trying to update records in my Back4App database. The problem is that ..objectId = currentUser.objectId takes only the userid and there can be multiple records for the same id. Thus, I am unable to update a single record of that userid. I am trying to filter by te unique id of records "concatid" but nothing gets updated.
Future<void> updateTodo(String description, String dogName) async {
ParseUser? currentUser = await ParseUser.currentUser() as ParseUser?;
var concatid = currentUser!.objectId! + dogName;
await Future.delayed(Duration(seconds: 1), () {});
final todo = ParseObject('Todo')
..objectId = currentUser.objectId
..set('concatId', concatid)
..set('DogDescription', description);
await todo.save();
}
Here's the documentation about update methods, but it only takes into account a general approach where you can only set new data matching by objectId and assuming this is unique (which is not my case).

This row does not contain values for that table

I'm using Drift(moor).
When trying to get a sample of data using leftOuterJoin, the following situation happens:
The table that I join via leftOuterJoin returns null as a value.
I.e. leftOuterJoin itself works correctly but values from joined table are not read and return null.
As a result, I get a row where 1 or 2 columns have null values (depending on what table I join)
No one with such a situation is not faced?
final rows = await (select(favoritePlaces).join(
[
leftOuterJoin(
cachedPlaces, cachedPlaces.id.equalsExp(favoritePlaces.placeId)),
],
)).get();
parsedExpressions
Remove ".get()" from the last line.
Add below lines after your code:
final result = await rows.get();
return result.map((resultRow) {
return FavoritePlacesWithcachedPlaces(
resultRow.readTable(favoritePlaces),
resultRow.readTableOrNull(cachedPlaces),
);
}).toList();
where FavoritePlacesWithcachedPlaces object is something like:
class FavoritePlacesWithcachedPlaces {
final FavoritePlaces favoritePlaces;
final CachedPlaces? cachedPlaces;
FavoritePlacesWithcachedPlaces (this.favoritePlaces,
this.cachedPlaces);}
The key point is using "readTableOrNull".

Query a specific cell of sqflite data table in Flutter

There are already some questions and answers like "query a specific row". But I want a specific cell that means I need a specific row with a specific column from the sqflite data table in Flutter. My table has three columns which are id, fname, fid. But I need only fid. Here is my row selection code:
queryfid() async {
Database db = await DatabaseHelper.instance.database;
List<String> columnsToSelect = [
DatabaseHelper.columnId,
DatabaseHelper.columnfname,
DatabaseHelper.columnfid,
];
String whereString = '${DatabaseHelper.columnId} = ?';
int rowId = 1;
List<dynamic> whereArguments = [rowId];
List<Map> result = await db.query(DatabaseHelper.tableid,
columns: columnsToSelect,
where: whereString,
whereArgs: whereArguments);
result.forEach((row) => print(row));
}