Can't update index dynamically with dexie sample code - dexie

I have been trying updating the db index dynamically and keeps failed, stuck for a few days.
I'm using angular7 & type script and latest dexie version. When I try to use the same code, it give me error:
Is there anything I should do to get it working? Thx!
ERROR Error: Uncaught (in promise): UpgradeError: Dexie specification of currently installed DB version is missing
UpgradeError: Dexie specification of currently installed DB version is missing
I literally just copy pasted the sample code here:
changeSchema(db, schemaChanges) {
db.close();
const newDb = new Dexie(db.name);
newDb.version(db.verno + 1).stores(schemaChanges);
return newDb.open();
}
// Open database dynamically:
async playAround() {
let db = new Dexie('FriendsDatabase');
if (!(await Dexie.exists(db.name))) {
db.version(1).stores({});
}
await db.open();
// Add a table with some indexes:
db = await this.changeSchema(db, { friends: 'id, name' });
// Add another index in the friends table
db = await this.changeSchema(db, { friends: 'id, name, age' });
// Remove the age index again:
db = await this.changeSchema(db, { friends: 'id, name' });
// Remove the friends table
db = await this.changeSchema(db, { friends: null });
}

This sample was faulty. I've updated the docs with a working sample:
async function changeSchema(db, schemaChanges) {
db.close();
const newDb = new Dexie(db.name);
newDb.on('blocked', ()=>false); // Silence console warning of blocked event.
// Workaround: If DB is empty from tables, it needs to be recreated
if (db.tables.length === 0) {
await db.delete();
newDb.version(1).stores(schemaChanges);
return await newDb.open();
}
// Extract current schema in dexie format:
const currentSchema = db.tables.reduce((result,{name, schema}) => {
result[name] = [
schema.primKey.src,
...schema.indexes.map(idx => idx.src)
].join(',');
return result;
}, {});
console.log("Version: " + db.verno);
console.log("Current Schema: ", currentSchema);
// Tell Dexie about current schema:
newDb.version(db.verno).stores(currentSchema);
// Tell Dexie about next schema:
newDb.version(db.verno + 1).stores(schemaChanges);
// Upgrade it:
return await newDb.open();
}
// Open database dynamically:
async function playAround() {
let db = new Dexie ('FriendsDatabase2');
if (!(await Dexie.exists(db.name))) {
console.log("Db does not exist");
db.version(1).stores({});
}
await db.open();
console.log("Could open DB")
// Add a table with some indexes:
db = await changeSchema(db, {friends: 'id, name'});
console.log("Could enforce friends table with id and name")
// Add another index in the friends table
db = await changeSchema(db, {friends: 'id, name, age'});
console.log("Could add the age index")
// Remove the age index again:
db = await changeSchema(db, {friends: 'id, name'})
console.log("Could remove age index")
// Remove the friends table
db = await changeSchema(db, {friends: null});
console.log("Could delete friends table")
}
playAround().catch(err => console.error(err));
Fiddle:
https://jsfiddle.net/dfahlander/jzf2mc7n/

Related

Can't add more than one field user_meta_data supabase

I am doing a user registration through nodejs, this was already done in react but only with one field. The problem is that I try to send more than one field in the metadata of the record but it only adds username to the profiles table and not the others. However I get user information on the front end and there is the additional metadata that was added.
I'm using supabase v2.0
const createStripeAccount = async(req, res) => {
const { username, email, password } = req.body;
try {
const account = await stripe.accounts.create({
type: 'express',
country: 'US',
email: email,
capabilities: {
card_payments: {requested: true},
transfers: {requested: true},
}
});
const { id:stripeAccountId } = account;
let newData = null;
if(stripeAccountId) {
console.log(typeof stripeAccountId)
newData = await supabase.auth.signUp(
{
email: email,
password: password,
options: {
data: {
username: username,
stripe_account_user_id: 'stripeAccountId', <---additional
is_founder: true, <---additional
website: 'www.sdsoso.cl' <---additional
}
}
}
)
}
const { data: {user} } = newData;
console.log(newData)
return res.json({
user
});
} catch(error) {
console.log('error', error);
}
}
The response from the server is the full metadata sended. But in the table only add username and not the others.
I found the solution and it was that I had forgotten that when I add new metadata I must update the function that is fired in the supabase trigger after registering.
So every time you want to pass more data to the profiles table after registration, update the function that is triggered. In my case:
BEGIN
INSERT INTO public.profiles(id, username, new_col_name)
VALUES (
NEW.id,
NEW.raw_user_meta_data -> 'username',
NEW.raw_user_meta_data -> 'new_col_name'
);
RETURN NEW;
END;

Node Express - Database is created too late causing error

My problem is with creating a database. It is created too late and causes problems with further queries. I tried to use async and await but it seems it doesn't solve the problem.
async function storeDailyDealToDB(dailyDeal) {
const db = new sqlite3.Database('database.db');
await new Promise((resolve) => {
const QUERY_CREATE_TABLE =
"CREATE TABLE IF NOT EXISTS daily_deal ( id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT,)";
db.run(QUERY_CREATE_TABLE);
resolve("done")
});
await new Promise((resolve) => {
const insert =
"INSERT INTO daily_deal (title) VALUES (?)";
const stmt = db.prepare(insert);
stmt.run([dailyDeal['title']]);
stmt.finalize();
resolve("done")
});
let lastRow = await new Promise((resolve) => {
db.each("SELECT * FROM daily_deal ORDER BY id DESC LIMIT 1", function (err, row) {
resolve(err == null ? {} : row)
});
});
db.close();
return lastRow
}
Here is the error I get:
[Error: SQLITE_ERROR: no such table: daily_deal
Emitted 'error' event on Statement instance at:
] {
errno: 1,
code: 'SQLITE_ERROR'
}
Node.js v17.9.0
I did a lot of research and I am stuck. I read to use Promise but it works partially. I am not sure how to tackle this problem.
After looking at the reference docs, of Database#run, you should pass a callback to the run method. Inside this callback, you want to either resolve or reject the promise depending on the outcome.
await Promise((res, rej) => {
db.run(..., (err, result) => {
if (err) rej(err) else res(result)
});
});
I think this is correct (untested however).

using return statement in an async to sync javascript function/class

I'm querying a mariadb using a class i wrote, my code works when i use console.log but not when i use a return statement:
class DBinteractor{
//constructor of my class
constructor(){
this.mariadb = require('mariadb');
this.pool = this.mariadb.createPool({
socketPath: '/run/mysql/mysql.sock',
user: 'me_user',
password: 'me_password',
database: 'me_database',
connectionLimit: 5
});
}
//asyncronous method
async asyncQuery(){
var quest = "SELECT DISTINCT `Modalite1` FROM `synth_globale` WHERE 1;";
try {
this.conn = await this.pool.getConnection();
const rows = await this.conn.query(quest);
this.conn.end();
return rows;
}
catch (err) {
throw err;
}
finally {
}
}
// I need at some point a method able to return the result of my query
// to put it in a variable and use it outside:
syncQuery(){
// as is, a non-async function/method can not include async calls
// I must use an iife to be able to do it
(async () => {
let ResultOfQueryWithinMethod = (await this.asyncQuery());
console.log(ResultOfQueryWithinMethod);
//OK, my result query is rightfully printed on the console
return(ResultOfQueryWithinMethod);
})()
}
}
queryator = new DBinteractor();
let ResultOfQueryOutsideMethod = queryator.syncQuery();
console.log(ResultOfQueryOutsideMethod);
//NOT OK, ResultOfQueryOutsideMethod is undefined
It's just like the return statement in syncQuery doesn't make the link between ResultOfQueryWithinMethod and ResultOfQueryOutsideMethod
What am i missing ?
thanks for your help

don't know why my cursorForObjectInConnection returns null?

I am having this error on response:
Cannot return null for non-nullable field TodoEdge.cursor.
This is my mutation code:
mutateAndGetPayload: async ({text}, context) => {
let newTodo = new TodoModel({ text, _creatorUserId: context.user._id });
await newTodo.save();
return {newTodo};
},
outputFields: {
todoEdge: {
type: GraphQLTodoEdge,
resolve: async ({newTodo}, args,context) => {
const todos = await getTodosByUserContext(context.user._id, 'any');
console.log("cursorForObjectInConnection = ",cursorForObjectInConnection(todos, newTodo)) // this logs null?
return {
cursor: cursorForObjectInConnection(todos, newTodo),
node: newTodo,
};
},
},
todos and newTodo is retreived from mongoose database. I think I am following this relevant todo-modern sample properly. Help?
Let's try following:
1) Get todos from your DB like
const todos = await Todo.find({});
You can get todos for a specific user as per your Todo Schema. Todo.find({ userid: context.user._id});
2) once you get your todos then get cursor:
const cursor = offsetToCursor(todos.length);
This worked for me. Give it a try.

Primary sort key DynamoDB attribute expression

I am new to DynamoDB and want only to create a new object if the Primary sort key(name) does not exist twice. I tried it like this:
params.id = randomId();
var item = {
TableName: tableName,
Item: params,
ConditionExpression: "#na <> :n",
ExpressionAttributeNames:{"#na":"name"},
ExpressionAttributeValues:{
":n":params.name
}
};
docClient.put(item, function(err, data) {
console.log("Data:", data);
console.log("Err:", err);
});
But the item is still created :/ Is ist even possible to create a condition expression on the primary sort key ?
Actually just ran into this issue myself, as explained here it looks like you can't, you'll have to use a Global Secondary Index for the 'sort' key.
You will have to do a seperate get request on the GSI first to see if "name" exists for eg.
function checkNameDoesNotExist(name, fn){
query.IndexName = 'nameInUsers';
query.KeyConditionExpression = 'name = :n';
query.ExpressionAttributeValues = {
':n': name
};
dynamodb.query(query, function(err, data){
if (err) {
return fn(err);
} else {
fn(null, data);
}
});
}
Disclaimer: wrote the code off the top of my head, don't know if it works but should give you a good starting point
You can use the exist condition. It will return an error saying that the object already exists
var item = {
TableName: tableName,
Item: params,
Expected: {
name: {
Exists: false
}
};
docClient.put(item, function(err, data) {
console.log("Data:", data);
console.log("Err:", err);
});

Resources