Get Schema From db instance

Hey! There's a way to get a table instance just from the db object? Currently I have this: await db.insert(users)... And I want to provide a general function that performs an insert in a database:
function doSomething(db) {
// insert a record in users table by default, but allow a different table name
}
function doSomething(db) {
// insert a record in users table by default, but allow a different table name
}
However, I'd like to make the table dyamic (it's a plugin) so we can't depend on the users object to be available and I'd like to avoid asking users to provide it as a parameter. There's a way to make it work? The table needs to follow a given schema (specified in our docs), so I wonder if it's possible to get the schema similar to this (just pseudo-code 😅):
db.nonexistingproperty.users // default
db.nonexistingproperty[userProvidedTableName] // override
db.nonexistingproperty.users // default
db.nonexistingproperty[userProvidedTableName] // override
Thanks in advance for your help!
5 Replies
dandadan
dandadan•8mo ago
following this
GetPsyched
GetPsyched•8mo ago
Your question is ambiguous. What does it mean for a table to be "dynamic" Or do you mean that which table is being inserted to (i.e. the table name) is dynamic?
dandadan
dandadan•8mo ago
async function findMany<DB extends PostgresJsDatabase, TableName>(db: DB, table: TableName) {
let schema = null; // get schema from db instance
return await db.select().from(schema).limit(1);
}

findMany(db, "users");
async function findMany<DB extends PostgresJsDatabase, TableName>(db: DB, table: TableName) {
let schema = null; // get schema from db instance
return await db.select().from(schema).limit(1);
}

findMany(db, "users");
i think the goal is to achieve something like this ive messed around with many things, such as
async function testing<
TSchema extends Record<string, unknown>,
DB extends PostgresJsDatabase<TSchema>,
>(x: DB, table: keyof DB["_"]["schema"]) {
let schema = x._.schema;
if (schema === undefined) {
throw new Error("Schema is undefined");
}
return await x.select().from(schema[table]).limit(1);
}
async function testing<
TSchema extends Record<string, unknown>,
DB extends PostgresJsDatabase<TSchema>,
>(x: DB, table: keyof DB["_"]["schema"]) {
let schema = x._.schema;
if (schema === undefined) {
throw new Error("Schema is undefined");
}
return await x.select().from(schema[table]).limit(1);
}
unfortunately i havent been able to write an interface for that function that actually types out correctly or, an even simpler example, achieving something like this
let tb = db._.schema?.users
if (tb) {
db.select().from(tb);
}
let tb = db._.schema?.users
if (tb) {
db.select().from(tb);
}
unfortunately, what _.schema has is not the same thing as the actual schema youre supposed to use inside .from()
dandadan
dandadan•8mo ago
quick update, the select interface holds no type information regarding the schema given at db initialization
No description
dandadan
dandadan•8mo ago
this basically means you can pass whatever you want to it as long as its an actual table, it doesnt restrict possible tables based on the schema i guess whats left is to figure out if the previous desired behavior is at least achievable using the query api
async function findMany<
TSchema extends Record<string, unknown>,
DB extends PostgresJsDatabase<TSchema>,
TableName extends keyof NonNullable<DB["_"]["schema"]>,
>(db: DB, table: TableName) {
return await db.query[table].findMany();
}
findMany(db, "users");
async function findMany<
TSchema extends Record<string, unknown>,
DB extends PostgresJsDatabase<TSchema>,
TableName extends keyof NonNullable<DB["_"]["schema"]>,
>(db: DB, table: TableName) {
return await db.query[table].findMany();
}
findMany(db, "users");
this was probably my best attempt, unfortunately findMany errors with This expression is not callable
Want results from more Discord servers?
Add your server