How can i make once of this PostgreSQL querys in supabase?
I tried reading supabase doc but it doesn't work
select rooms.id as room_id, members.id as member_id, user_id from rooms
inner join members
on rooms.id = members.room_id
where rooms.id = members.room_id
and user_id = 1
Or
select room_id, user_id, members.id from members
inner join rooms
on rooms.id = members.room_id
where members.user_id = 1
No, there's not really any performance difference from calling an .rpc() vs. just calling the api directly. You should be fine. Just make sure to set up your database correctly (indexes, joins, etc.) for best performance.
Hello this might not be supabase specific solution, but in my case what I do use when I need to run custom queries like in your own case here is to use the pg package from npm https://www.npmjs.com/package/pg.
I would just create a client and parse my supabase db credentials to it.
export const pgClient = () => {
console.error(`using Postgres ${process.env.host}`)
const client = new Client({
user: process.env.user,
host: process.env.host,
database: process.env.database,
password: process.env.password,
port: parseInt(process.env.port!)
})
return client
}
export it to my router and simply connect
const client = pgClient()
await client.connect()
Run my custom query directly on the DB
await client.query("SELECT * from auth.users")
You can query a foreign table using the Supabase client, but only if there's a foreign key set up:
Supabase select(): Query foreign tables
As stated in the comments, you can create a view for this purpose:
Create View
Or you can create a PosgreSQL function and call that with Supabase .rpc():
Related
I'm quite new with the implementation of Oracle database with Node.js, currently I'm using oracledb library to connect my Node.js app to my Oracle database as follows
connection = await oracledb.getConnection({
user: "SYS",
password: password,
connectString: "localhost:1522/userdb",
privilege: oracledb.SYSDBA
});
I set everything up as a monolithic app(It's a simple user review app) to start, but I want to split the code in User and Review Controller, the same for the service, model for both objects.
The only problem I have now (That I know of), is that I am not able to make each model (User and Review) to take that connection and simply send a query depending on what the controller needs. I tried to create a separate db.js file and set the connection there and then use
class DBConnection {
constructor() {
this._connect();
}
async _connect() {
try {
connection = await oracledb.getConnection({
user: "SYS",
password: password,
connectString:process.env.DATABASE,
privilege: oracledb.SYSDBA
});
} catch (err) {
console.log(err.message);
}
}
}
module.exports = new DBConnection();
Then I would try to import it and use something like:
connection= DBConnection();
connection.execute(query);
But it has not worked, is there any way to do this?
I want to ask how to using nodemailer with dynamic email and pass from database
export const mailTransporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: email_user,
pass: email_pass,
},
});
email_user and email_pass from file env, I want to email_user and email_pass from the database, so I think to create a function for getting value email and pass from the database, then save into variable and use in mailTransport. Guys any suggestion or opinion for it?
Wrap your nodemailer.createTransport into a function before you export it, then from the function, you get the credential from DB before constructing the nodemailer.createTransport.
module.exports = createTransportWithCredential
function createTransportWithCredential(){
return new Promise((resolve,reject)=>{
//get credential from DB, you may need to use promise-then to handle async situation
//example:
getCredentialFromDB().then(credentials=>{
let transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: credential.user,
pass: credential.password,
},
});
resolve(transporter)
})
})
}
From the other js file you can do:
const mailer = require("./nodemailer")
mailer.createTransportWithCredential().then(transporter=>{
//use the transporter
})
Depends on what type of database you have. If you're using mysql you can use the mysql2 package to make queries. It looks like this.
I recommend creating a simple package outside of your main project but this is not completely necessary.
npm init
npm install dotenv mysql2
require('dotenv').config({ path: "/home/ubuntu/.env" });
const mysql = require("mysql2/promise");
const connection = mysql.createPool({
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: "main",
flags: "-FOUND_ROWS",
charset: "utf8mb4_0900_ai_ci",
multipleStatements: true,
connectionLimit: 10,
queueLimit: 0
});
module.exports = connection;
Edit the options as you like. This one creates a pool of 10 connections and connects to a database named main. It also allows for multiple statements within a single query. That might not be desirable so turn that off if you'd like. Finally, I'm requiring an environment file, but I am specifying a specific location rather than getting one automatically from within the project folder (since this is its own package that will be imported into the main project).
Next we import the database package into our main project.
Just follow this page to install a local package Installing a local module using npm?
It should be something like this while inside your main project directory.
npm install ../database
if your database package is located next to your main project folder. Just replace ../database with whatever the path is to the separate database package.
Now inside our main project, it would look something like this. (I'm assuming you labelled your new package database but if not, just replace with whatever name you used.
require('dotenv').config({ path: "/home/ubuntu/.env" });
const connection = require("database");
const userID = "81cae194-52bd-42d3-9554-66385030c35b";
connection.query(`
SELECT
EmailUsername,
EmailPassword
FROM
UserEmail
WHERE
UserID = ?
`, [userID])
.then(([results, fields]) => {
let transporter = nodemailer.createTransport({
host: process.env.EMAIL_HOST,
port: process.env.EMAIL_PORT,
secure: true,
auth: {
user: results[0].EmailUsername,
pass: results[0].EmailPassword
},
});
// Put transporter.sendMail() here
})
.catch(error => console.log(error));
This is just a sample of what you could do and how you could do it. You need to use your own critical thinking to fit it into your own project and style.
There is no one way to do it and some of the choices I've made are personal decisions. You should be able to merge this with Jerry's answer. He goes more into how to create the nodemailer module. I am only showing you how to connect database data with nodemailer.
Please read up on https://www.npmjs.com/package/mysql2 especially the promise wrapper section. This solution also uses dotenv https://www.npmjs.com/package/dotenv and https://nodemailer.com/about/
I have connected Sequelize to MySQL and the app successfully displays the data from my database in Postman and the browser. This is the initial data I inserted directly from the terminal into my database.
Now, I want to save new objects into my database through Sequelize but it only sends "null" values to the database as if it did not receive any values from my request.
However, when I post an object (User) from Postman, I do have a successful status and the body of my request has values of correct type.
Also added db.sequelize.sync() in my server.js file.
Any idea of what I could have missed?
Here is my code in the users.js controller file:
const db = require('../models');
const User = db.users;
User.sync();
exports.createUser = (req, res) => {
const userWithPic = new User({
...req.body,
picture: `${req.protocol}://${req.get('host')}/images/${req.file.filename}`,
});
User.create(userWithPic)
.then((data) => res.send(data))
.catch((err) => res.status(500).send(err);
});
};
Also noticed that the command npx sequelize-cli model:generate --name User --attributes firstName:string,lastName:string,email:string did create a model as it is supposed to however it did not create a migration in the migration folder. I doubt it is related however it should have.
Thanks !
I actually solved the issue. Just needed to remove the new User as Sequelize does not use this syntax with the create method.
i have searched lot to get a solution to my problem. but didn't got it.
if anyone have the experience in such situations please help me.
i have created a application server in node express with MySQL a database.
and successfully create REST API endpoints which works successfully.
but our projects scaled up. a new client approaches so we need to serve those clients too.
those client may have 1k users.but the database schema is same.
solution 1: create a separate server and database for each client with different port no.
but i don't think this is good solution because if we have 100 client we can't maintain the code base.
solution 2: create a separate database for each client and switch database connection at run time.
but i don't understand how to implement solution 2. any suggestion highly appreciated.
if more than one client requesting same server how to know which database need to connect using the endpoint URL. i there any alternate way to tackle this situation.
my solution: create a middle ware to find out the which database is required and return the connection string.is it good idea.
middleware. in below example i use JWT token which contain database name.
const dbHelper=new db();
class DbChooser {
constructor(){
this. db=
{
wesa:{
host: "xxx",
user: "xxxx",
password: "xxxxx",
database: "hdgh",
connectionLimit:10,
connectTimeout:30000,
multipleStatements:true,
charset:"utf8mb4"
},
svn:{
host: "x.x.x.x.",
user: "xxxx",
password: "xxx",
database: "xxx",
connectionLimit:10,
connectTimeout:30000,
multipleStatements:true,
charset:"utf8mb4"
}
};
}
async getConnectiontring(req,res,next){
//console.log(req.decoded);
let d=new DbChooser();
let con=d.db[req.decoded.userId];
console.log(mysql.createPool(con));
next();
}
}
module.exports=DbChooser;
You can create a config JSON. On every request, request header should have a client_id based on the client_id we can get the instance of the database connection.
your db config JSON
var dbconfig = {
'client1': {
databasename: '',
host: '',
password: '',
username: ''
},
'client2': {
databasename: '',
host: '',
password: '',
username: ''
}
}
You should declare a global object, to maintain the singleton db instances for every client.
global.dbinstances = {};
on every request, you are going to check whether the instance is already available in your global object or not. If it's available you can go continue to the next process, otherwise it creates a new instance.
app.use('*', function(req,res) {
let client_id = req.headers.client_id;
if(global.instance[client_id]) {
next();
} else {
const config = dbconfig[client_id];
connectoDb(config, client_id);
}
}
function connectoDb(config, client_id) {
//.. once it is connected
global.instance.push({client_id: con}); //con refers to the db connection instance.
}
i see that sequelize is compatible with sqlite's sqlcipher extension (docs | merged pr). the code suggests a way to authenticate on the db instance, but i can't find a way to set the cipher.
using sqlite3, can run something like this:
var sqlite = require('sqlite3);
var db = new sqlite.Database('test.db');
db.serialize(
// some sql commands
);
with the sequelize orm for sqlite i can get a db created, but can't get an encrypted instance:
var Sequelize = require('sequelize');
var db = new Sequelize('test.db', 'username', 'secretAsPragmaKey', {option1: true, option2: false});
db.query(
// some sql
);
i've tried running queries on this instance to explicitly set PRAGMA KEY to the password param, and PRAGMA CIPHER to sqlcipher's default [aes-256-cfb], but not while using sequelize.
does the encrypted db need to exist, and sequelize is just opening it? if so, how to ensure the keyed db exists without inserting tables?