Import csv to sqlite in Flutter (insert issue) - sqlite

I've already read the related article and solution + mentioned method, but still I don't get it what should I add to my code for importing csv to sqlite table List<<Map<String, dynamic>. I need to replace existing table with a new one and insert each lines of converted csv. How can I solve it? Here's my code below.The problem is importVoca() of db.dart.
db.dart
class DBHelper {
var _db;
// create database
Future<Database> get database async {
if (_db != null) return _db;
_db = openDatabase(
join(await getDatabasesPath(), 'vocas.db'),
onCreate: (db, version) {
return db.execute(
"CREATE TABLE vocas(id TEXT PRIMARY KEY, word TEXT, meaning TEXT, createTime TEXT)",
);
},
version: 1,
);
return _db;
}
// insert voca
Future<void> insertVoca(Voca voca) async {
final db = await database;
await db.insert('vocas', voca.toMap(),
conflictAlgorithm: ConflictAlgorithm.replace);
}
// Voca list
Future<List<Voca>> vocas() async {
final db = await database;
final List<Map<String, dynamic>> maps = await db.query('vocas');
return List.generate(maps.length, (i) {
return Voca(
id: maps[i]['id'],
word: maps[i]['word'],
meaning: maps[i]['meaning'],
createTime: maps[i]['createTime']);
});
}
//update voca list
Future<void> updateVoca(Voca voca) async {
final db = await database;
await db.update(
'vocas',
voca.toMap(),
where: "id = ?",
whereArgs: [voca.id],
);
}
//delete voca
Future<void> deleteVoca(String id) async {
final db = await database;
await db.delete(
'vocas',
where: "id = ?",
whereArgs: [id],
);
}
//find voca to edit
Future<List<Voca>> findVoca(String id) async {
final db = await database;
final List<Map<String, dynamic>> maps =
await db.query('vocas', where: 'id = ?', whereArgs: [id]);
return List.generate(maps.length, (i) {
return Voca(
id: maps[i]['id'],
word: maps[i]['word'],
meaning: maps[i]['meaning'],
createTime: maps[i]['createTime'],
);
});
}
//export voca to csv
Future exportVoca() async {
var year = DateFormat('yy').format(DateTime.now());
var month = DateFormat('MM').format(DateTime.now());
var day = DateFormat('d').format(DateTime.now());
final db = await database;
var result = await db.query('vocas');
var csv = mapListToCsv(result);
final directory = await getApplicationDocumentsDirectory();
final pathOfFile = await directory.path;
File file = File("$pathOfFile/dontForget_$year$month$day.csv");
file.writeAsString(csv);
}
//import csv to sqlite
Future importVoca() async {
File file = await FilePicker.getFile(
type: FileType.custom, allowedExtensions: ['csv']);
final data = file.openRead();
final fields = await data
.transform(utf8.decoder)
.transform(new CsvToListConverter())
.toList();
Database _db = await openDatabase(
join(await getDatabasesPath(), 'vocas.db'),
version: 1, onCreate: (Database db, int version) async {
await db.execute("DROP TABLE IF EXISTS vocas");
await db.execute(
"CREATE TABLE vocas(id TEXT PRIMARY KEY, word TEXT, meaning TEXT, createTime TEXT)");
});
}
}

Related

Flutter SQLITE how to delete with limit

In my database I have several times the same value which returns, I want to delete the most recent value but when I want to perform a LIMIT I have an error.
My databaseHelper :
class DatabaseHelper{
static final _dbName = AppConfig.DATABASE_NAME;
static final _dbVersion = AppConfig.DATABASE_VERSION;
static final tableName = 'counter';
static final columnId = '_id';
static final columnType = 'type';
static final columnStatus = 'status';
DatabaseHelper._privateConstructor();
static final DatabaseHelper instance = DatabaseHelper._privateConstructor();
static Database _database;
Future<Database> get database async{
if(_database != null) return _database;
_database = await _initiateDatabase();
return _database;
}
_initiateDatabase() async{
return await openDatabase(join(await getDatabasesPath(), _dbName), version: _dbVersion, onCreate: _onCreate);
}
Future _onCreate(Database db, int version) async{
await db.execute('''
CREATE TABLE $tableName (
$columnId ID INTEGER PRIMARY KEY,
$columnType TEXT NOT NULL,
$columnStatus TEXT NOT NULL
)
'''
);
}
Future<int> insert(Map<String, dynamic> row) async
{
Database db = await instance.database;
return await db.insert(tableName, row);
}
Future<List<Map<String, dynamic>>> queryAll() async
{
Database _db = await instance.database;
return await _db.query(tableName);
}
Future<int> delete(int id) async
{
Database _db = await instance.database;
return await _db.delete(tableName, where: '$columnId = ?', whereArgs: [id]);
}
Future<void> deleteAll() async
{
Database _db = await instance.database;
return await _db.delete(tableName);
}
// Here is my problem
Future<int> deletePersonnel(String type) async
{
Database _db = await instance.database;
return await _db.rawDelete("DELETE FROM $tableName WHERE $columnType = $type LIMIT 1");
}
}
In my deletePersonnel function, The request works if I write this :
wait _db.rawDelete("DELETE FROM $tableName");
But I have an error if I write this :
wait _db.rawDelete("DELETE FROM $tableName WHERE $columnType = $type LIMIT 1");
Here is an exemple of the value in my database:
[
{type: Test, status: High},
{type: Test, status: High},
{type: Active, status: Low},
{type: Test, status: High}
]
As you can see I have several times the same values ​​which appear in my database, so I want to delete a value which corresponds to my type by deleting the last entry
The error that I have :
E/SQLiteLog(10576): (1) near "LIMIT": syntax error
BUT if I remove the LIMIT 1 in my request I have an error too :
no such column: Test

Fluttet sqfLite delete

I am trying to build a note app. I watch some tutorials on sqflite in order to save data after the app is terminated. I have managed to save the data but i cant delete data.
Here is the DBelper class i have created:
import 'package:sqflite/sqflite.dart' as sql;
import 'package:path/path.dart' as path;
import 'package:sqflite/sqlite_api.dart';
class DBHelper {
static Future<Database> databse() async {
final dbPath = await sql.getDatabasesPath();
return sql.openDatabase(path.join(dbPath, 'notes.db'),
onCreate: (db, version) {
return db.execute(
'CREATE TABLE user_notes(id TEXT PRIMARY KEY, title TEXT, text TEXT)');
}, version: 1);
}
static Future<void> insert(String table, Map<String, Object> data) async {
final db = await DBHelper.databse();
db.insert(
table,
data,
);
}
static Future<List<Map<String, dynamic>>> getData(String table) async {
final db = await DBHelper.databse();
return db.query(table);
}
}
And this is how i save the data :
onPressed: () {
Provider.of<Notes>(context, listen: false)
.addNote(newNoteTitle, newNoteText);
DBHelper.insert('user_notes',
{'title': newNoteTitle, 'text': newNoteText});
Navigator.pop(context);
},
I have been trying to create the DBHelper.deleteNote but even if i manage to write some code without errors nothing gets deleted. Thanks in advance for any help
If you simply want to delete a note then you can use its id, something like this:
deleteNote(String id) async {
final db = await DBHelper.databse();
db.delete('user_notes', where: 'id = ?', whereArgs: [id]);
}

Using SQLite in main.dart from seperate file?

I've followed this easy example from the flutter documentation. However, this is wrote in a separate file (db_test.db). I'm aiming to convert data into a ListView at some point. So, how would I use CRUD operations like retrieving data in my main.dart? I could add this to my main.dart file but I'd like to keep it clean and separate.
Official Flutter tutorial
My db.dart file
void main () async {
final database = openDatabase(
join(await getDatabasesPath(), 'to_do.db'),
onCreate: (db, version) {
return db.execute("CREATE TABLE tasks(id INTEGER PRIMARY KEY, title TEXT, created TEXT, INTEGER is_complete)");
},
version: 1,
);
Future<void> insertTask (Task task) async {
final Database db = await database;
await db.insert(
'tasks',
task.toMap(),
conflictAlgorithm: ConflictAlgorithm.replace
);
}
Future<List<Task>> tasks () async {
final Database db = await database;
final List<Map<String, dynamic>> maps = await db.query('tasks');
return List.generate(maps.length, (i) {
return Task(
id: maps[i]['id'],
title: maps[i]['title'],
created: maps[i]['created'],
isComplete: maps[i]['is_complete']
);
});
}
Future<void> updateTask(Task task) async {
// Get a reference to the database.
final db = await database;
// Update the given Dog.
await db.update(
'tasks',
task.toMap(),
// Ensure that the Dog has a matching id.
where: "id = ?",
// Pass the Dog's id as a whereArg to prevent SQL injection.
whereArgs: [task.id],
);
}
Future<void> deleteTask(int id) async {
// Get a reference to the database.
final db = await database;
// Remove the Dog from the database.
await db.delete(
'tasks',
// Use a `where` clause to delete a specific dog.
where: "id = ?",
// Pass the Dog's id as a whereArg to prevent SQL injection.
whereArgs: [id],
);
}
}
You can create a new file containing Class with static members to help. Static members ensure that only one instance of database is created in your whole app.
class DatabaseHelper {
static Database _database;
///Returns db instance if already opened
///else call the initDatabase
static Future<Database> getDBConnector() async {
if (_database != null) {
return _database;
}
return await _initDatabase();
}
///Open DB Connection, returns a Database instance.
///
static Future<Database> _initDatabase() async {
_database = await openDatabase(
join(await getDatabasesPath(), "my_path.db"),
onCreate: (db, version) async {
//on create
},
version: 1,
);
return _database;
}
//put your CRUD in static function
static Future<void> insertTask (Task task) async {
final Database db = await getDBConnector();
await db.insert(
'tasks',
task.toMap(),
conflictAlgorithm: ConflictAlgorithm.replace
);
}
//the same with edit, delete
}
Then in your other file (like main.dart) you can just call it like this:
import "./databaseHelper.dart";
void caller() async{
//create task
//insert
await DatabaseHelper.insertTask(task);
}
Make sure the caller is asynchronous.

How to fix slow issue storing cache?

Response time is 18 seconds but storing to cache time is 3 minutes. Why is that? I used sqflite plugin to store data.
This is my function calling server with an insert to cache
storeWoDescription(String url,String token) async {
final response = await http.get(
'${url}/v1.0/WoDescription',
headers: {'Authorization': 'Bearer ${token}'},);
final jsonResponse = json.decode(response.body);
WoDescription model = WoDescription.fromJson(jsonResponse);
int length = model.data.length;
for(int i=0; i<length; i++) {
var data = DataWoDescription(
i: model.data[i].i,
d: model.data[i].d,
e: model.data[i].e,
w: model.data[i].w,
a: model.data[i].a,
r: model.data[i].r,
t: model.data[i].t,
du: model.data[i].du,
s: model.data[i].s,
ra: model.data[i].ra,
cul: model.data[i].cul,
);
await HelperDefCatMaster().insertWoDescription(data);
}
}
after click button calling like this:
await storeWoDescription(_url,tokens);
HelperDefCatMaster
this is my database provider. I created multiple tables in one database. and before insert, I deleted the database and after that I inserted.
class HelperDefCatMaster {
static final HelperDefCatMaster _instance = HelperDefCatMaster.internal();
factory HelperDefCatMaster() => _instance;
static Database _db;
Future<Database> get db1 async {
if (_db != null) return _db;
_db = await initDb();
return _db;
}
HelperDefCatMaster.internal();
initDb() async {
io.Directory documentsDirectory = await getApplicationDocumentsDirectory();
String path = join(documentsDirectory.path, "HelperDefCatMasterDB.db");
var theDb = await openDatabase(path, version: 1, onCreate: _onCreate);
return theDb;
}
void _onCreate(Database db, int version) async {
await db.execute(
"""CREATE TABLE WoDescriptionTable(i INTEGER, d STRING, e INTEGER, w STRING, a INTEGER, r INTEGER, t INTEGER, du DOUBLE, s INTEGER, ra INTEGER, cul INTEGER)""");
}
Future<void> insertWoDescription(DataWoDescription assetregister) async {
var db = await db1;
await db.insert(
'WoDescriptionTable',
assetregister.toMap()
// conflictAlgorithm: ConflictAlgorithm.replace,
);
}
Future<void> deleteWoDescription() async {
var db = await db1;
await db.delete('WoDescriptionTable');
}
Future<List<DataWoDescription>> displayWoDescription() async {
var db = await db1;
final List<Map<String, dynamic>> maps = await db.query('WoDescriptionTable');
return List.generate(maps.length, (i) {
return DataWoDescription(
i: maps[i]['i'],
d: '${maps[i]['d']}',
e: maps[i]['e'],
w: '${maps[i]['w']}',
a: maps[i]['a'],
r: maps[i]['r'],
t: maps[i]['t'],
du: maps[i]['du'],
s: maps[i]['s'],
ra: maps[i]['ra'],
cul: maps[i]['cul'],
);
});
}
}

How to get element/value from a future of a list

I used SQLite for the cache. Everything is working well. But I don't know how to display value from this promise? (display() returns Future<List<Token>>)
What I want is properly something like var value = display().refreshToken
print statement printing List values
print(await display());
Database.dart
// Open the database and store the reference
import 'dart:async';
import 'package:path/path.dart';
import 'package:reborn_next_job02/models/Token.dart';
import 'package:sqflite/sqflite.dart';
databaseToken(
String tokenModel, String refreshTokenModel, String method) async {
final database = openDatabase(
join(await getDatabasesPath(), 'tokenDB.db'),
onCreate: (db, version) {
return db.execute(
"CREATE TABLE tokenTable(id INTEGER PRIMARY KEY, token TEXT, refreshToken TEXT)",
);
},
version: 1,
);
Future<void> insert(Token token) async {
final Database db = await database;
await db.insert(
'tokenTable',
token.toMap(),
//same use insert multiple times using ConfiictAlgorithm
conflictAlgorithm: ConflictAlgorithm.replace,
);
}
Future<List<Token>> display() async {
final Database db = await database;
final List<Map<String, dynamic>> maps = await db.query('tokenTable');
return List.generate(maps.length, (i) {
return Token(
id: maps[i]['id'],
token: maps[i]['token'],
refreshToken: maps[i]['refreshToken'],
);
});
}
Future<void> update(Token token) async {
final db = await database;
await db.update(
'tokenTable',
token.toMap(),
where: "id = ?",
whereArgs: [token.id],
);
}
Future<void> delete(int id) async {
final db = await database;
await db.delete(
'tokenTable',
where: "id = ?",
whereArgs: [id],
);
}
if (method == "insert") {
var token = Token(
id: 1,
token: tokenModel,
refreshToken: refreshTokenModel,
);
await insert(token);
print(await display());
} else if (method == "update") {
var token = Token(
id: 1,
token: tokenModel,
refreshToken: refreshTokenModel,
);
await update(token);
print(await display());
}
}
Model.dart
class Token {
int id;
String token;
String refreshToken;
Token({this.id,this.token, this.refreshToken});
factory Token.fromJson(Map<String, dynamic> json){
return Token(
id: json['id'],
token:json['token'],
refreshToken: json['refreshToken']
);
}
Map<String, dynamic> toMap() {
return {
'id': id,
'token': token,
'refreshToken': refreshToken,
};
}
#override
String toString() {
return 'Token{id: $id, token: $token, refreshToken: $refreshToken}';
}
}
You can get it with
print((await display())?.elementAt(0)?.refreshToken);
display() returns a future of list, so you have to wrap (await display()) before doing list manipulation, such as get an element from a list. list[0] is equivalent to list.elementAt(0), but list.elementAt(0)? is null-safe and out-of-bound-safe.

Resources