Check which PKs in List of PKs is present within SQFLITE database - flutter

For a list of PKs of length k:
listPK = [1,2,3...k]
I'm currently running a for loop, and querying the database k times to check whether the item is present within the database or not.
List<bool> isPresent(List listPK)async{
final db = await database;
List<bool> output = List.filled(listPK.length, false)
for (var i = 0; i<listPk.length; i++){
List<Map> result = await db.query('elements', where: "id = ?", whereArgs: listPk[i]);
if (result[0] != null) {output[i] = true}
}
}
Was wondering if there was a more efficient way to do this. I only want to know if the id is present within the database or not.

Use a WHERE ... IN to check against all the IDs in one call.
String listQuery = listPK.join(', '); // "1, 2, 3, ..., k"
String query = 'SELECT * FROM table_name WHERE id IN ($listQuery);`;
List<Map> result = await db.rawQuery(query);

It would be more efficient to query the database once and get all the id's in the 'elements' table. Once you have all the id's in the 'elements' table you can iterate through and find which id's are present and which are not.

Related

I want to get documents for multiple fields from a collection in firestore

"titleList" is a list of names of collection documents.
For "questionMaps", the document name is the key and the "text" field of the document's array type is the value.
I would like to make this questionMaps have 30 elements, but I have tried using a for statement but it did not work.
I would like to know how to solve this problem. This is my code.
Map questionMaps = {};
for (int i = 0; i < 30; i++) {
FirebaseFirestore.instance
.collection("titles")
.doc(widget.titleList[i])
.get()
.then(
(ref) {
List questions = ref.get("text");
questionMaps[widget.titleList[i]] = questions;
},
);
}
consider trying to get the whole snapshot of the collection, then run your logic over it.
since you said that your documents ids are the names in your titleList list, consider this:
Map questionMaps = {};
final querySnapshot = await FirebaseFirestore.instance.collection("titles").get();
querySnapshot.docs.forEach((doc) {
List questions = (doc.data() as Map<String, dynamic>)["text"];
questionMaps[doc.id] = questions;
});
this will register your questions List for each doc.id, then you can get it based on titleList like this as example:
print(questionMaps[titleList[0]]); // will get you questions which have the name key.

How to combine 2 or more Sqflite queries with logical operators?

Im currently trying to combine the results of 2 queries in flutter. These are the queries:
Future<List> filterExercises({
List<String> equipmentFilter,
List<String> muscleFilter,
int custom, //0 = false, 1 = true
int recent, //0 = false, 1 = true
String orderBy,
}) async {
Database db = await initDatabase();
final muscleRes = await db.query(
'exercises',
where: "targetMuscle IN (${('?' * (muscleFilter.length)).split('').join(', ')})",
whereArgs: muscleFilter,
);
final equipmentRes = await db.query(
'exercises',
where: "equipment IN (${('?' * (equipmentFilter.length)).split('').join(', ')})",
whereArgs: equipmentFilter,
);
return finalResult; //need to combine the results with a logical AND somehow
}
I know there's the option the use a rawQuery with logical OR / AND, but that doesn't work for my case.
It should be possible for the user to select different attributes and thus filter the list. Im looking for a way to pass arguments to this function and query my table accordingly to the passed arguments but I already fail when merging the first two queries.
How to add a logical AND to these two queries?
And furthermore: How to add even more attributes with a logical AND and order the final result?
I managed to find a way to the first question:
List<String> muscleFilter = ['Chest', 'Biceps'];
List<String> equipmentFilter = ['Machine', 'Cable'];
return db.rawQuery('''
select * from exercises
where targetMuscle in (${('?' * (muscleFilter.length)).split('').join(', ')})
and equipment in (${('?' * (equipmentFilter.length)).split('').join(', ')})
''',
muscleFilter + equipmentFilter
);

Mongoose Custom update on many documents of a collection

I have a collection with the following schema:
const CategorySchema = Schema({
name: String,
order: Number,
});
I'm trying to update the order field of the categories. The why I'm planning to do it is to have a local array with the ids of the categories in the order I want. Then, I'd fetch all categories (they are not many), and I'd start looping over the local array of ids. For each id, I'll locate it in the fetched array, and update the order according to the index of that id in the local array. The issue now is how to save it. Below is what I'm trying to do:
// Get all categories.
const categories = await Category.find({}, 'order');
console.log(categories);
// Get the order from the request.
const orderedItemIds = req.body.itemIds || [];
orderedItemIds.forEach((id, idx) => {
categories.find(x => x._id === id).order = idx;
});
// Save.
try {
await categories.save();
res.sendStatus(200);
} catch (e) {
console.log(e);
res.sentStatus(423);
}
When you query your categories, mongoose by default returns an array of instances of the Mongoose Document class. That means you can call their save() method whenever you mutate them.
So you can save your docs immediately after you assign the idx variable:
const orderedItemIds = req.body.itemIds || [];
orderedItemIds.forEach((id, idx) => {
const cat = categories.find(x => x._id.toString() === id);
cat.order = idx;
cat.save();
});
Note a few things about this code.
I assume that req.body.itemIds is a array of strings representing ObjectIds (e.g. '602454847756575710020545'). So In order to find a category in categories, you will need to use the .toString() method of the x._id object, because otherwise you will be trying to compare an Object and a string, which will never be true.
You can save the category right after assigning idx to cat.order without having to await it, because the next update is not depending on the save status of the previous.

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));
}

Multiple arguments in sqllite in flutter

I would like to know how to pass multiple arguments to a raw query in sqllite.
My code is below
query() async {
// get a reference to the database
Database db = await DatabaseHelper.instance.database;
// raw query
List<Map> result = await db.rawQuery('SELECT * FROM my_table WHERE name=?', ['Peter']);
// print the results
result.forEach((row) => print(row));
}
In the above code i am passing one argument 'Peter' but what if I want to pass multiple arguments, for example:
List<Map> result = await db.rawQuery('SELECT * FROM my_table WHERE name=? and last_name=? and year=?', ['Peter'], ['Smith'],[2019]);
If I do the code above, I get error "Too many positional arguments: 2 expected, but 4 found." can someone show me how to pass multiple arguments to a query in sqllite flutter?
I'm assuming you're using sqflite.
You need to put all your arguments into one list and not multiple.
The code below should work like this:
List<Map> result = await db.rawQuery(
'SELECT * FROM my_table WHERE name=? and last_name=? and year=?',
['Peter', 'Smith', 2019]
);
For more examples how to use raw queries see their examples on their pub.dev page.
Or if you want to use the query function you can do it like this:
String strVal = 'str';
int intVal = 0;
String likeVal = 'str';
final List<Map<String, dynamic>> maps = await db.query('my_table',
where: "col1 LIKE ? and col2 = ? and col3 = ?",
whereArgs: ['$likeVal%', strVal, intVal],
orderBy: 'id',
limit: 10);