How version ConnectionPool for mssql is better and why? I try understand,
both work. I want a correct connection, I don't want create redundant connections.
All the examples I found use .then and version A, maybe is another better option?
Should I close connection?
version A
// db.js
import sql from "mssql"
const config = {...}
export const mssqlPool = new sql.ConnectionPool(config).connect()
// n endpoint.js
import { mssqlPool } from "../lib/mssql/db"
try {
const pool = await mssqlPool
const result = await pool.request().query(`SELECT * FROM table`)
console.log(result)
} catch (err) {
console.log('error')
}
version B
// db.js
import sql from "mssql"
const config = {...}
export const mssqlPool = new sql.ConnectionPool(config)
// n endpoint.js
import { mssqlPool } from "../lib/mssql/db"
try {
const pool = await mssqlPool.connect();
const result = await pool.request().query(`SELECT * FROM table`)
console.log(result)
} catch (err) {
console.log('error')
}
Related
I am trying to copy a folder and all of it's content using node.js cp feature as follows
fs.cp('D:\\Developer\\insomniac-beta\\template', dir_path, {recursive: true});
however its throwing me this error
node:internal/validators:232
throw new ERR_INVALID_ARG_TYPE(name, 'Function', value);
^
TypeError [ERR_INVALID_ARG_TYPE]: The "cb" argument must be of type function. Received undefined
at makeCallback (node:fs:191:3)
at Object.cp (node:fs:2848:14)
at D:\Developer\igbot\generate_config.js:30:13
at FSReqCallback.oncomplete (node:fs:193:23) {
code: 'ERR_INVALID_ARG_TYPE'
}
how is this possible ? i do not have any calls to cb ?
If you dont want to use asynchronous copy with callback you can use synchronous version.
fs.cpSync(sourceDir, destDir, {recursive: true});
You are missing one argument. As mentioned in the documentation, fs.cp is an asynchronous function that takes in a callback function
the final arguement needs to be a callback function
fs.cp('D:\\Developer\\insomniac-beta\\template', dir_path, (err)=>{
// handle error
})
It seems like you're using the promises API, but you didn't show how you import the module. Here's an example with the current Node LTS (v16.x):
Ref: fsPromises.cp(src, dest[, options])
import {promises as fs} from 'fs';
// ...
await fs.cp(sourceDir, destDir, {recursive: true});
Here's a full, self-contained example which creates a sample dir structure, copies it, verifies the copy, and cleans up the sample data:
example.mjs:
import * as path from 'path';
import {constants as fsConstants, promises as fs} from 'fs';
import {fileURLToPath} from 'url';
import {ok as assert} from 'assert/strict';
// Create sample folder structure, return relative file paths
async function createSampleFiles (rootDir) {
const writeFileOpts = {encoding: 'utf8'};
const filePaths = [];
await fs.mkdir(rootDir, {recursive: true});
let fPath = 'hello.txt';
filePaths.push(fPath);
fPath = path.join(rootDir, fPath);
let text = 'hello world\n';
await fs.writeFile(fPath, text, writeFileOpts);
let dir = 'more';
await fs.mkdir(path.join(rootDir, dir), {recursive: true});
fPath = path.join(dir, 'wow.txt');
filePaths.push(fPath);
fPath = path.join(rootDir, fPath);
text = 'wow\n';
await fs.writeFile(fPath, text, writeFileOpts);
return filePaths;
}
async function fsEntryExists (filePath) {
try {
await fs.access(filePath, fsConstants.F_OK);
return true;
}
catch (ex) {
if (ex instanceof Error && ex.code === 'ENOENT') return false;
throw ex;
}
}
async function assertFSEntryExists (filePath) {
assert(await fsEntryExists(filePath), `FS entry not found for "${filePath}"`);
}
async function main () {
const moduleDir = path.dirname(fileURLToPath(import.meta.url));
const sourceDir = path.join(moduleDir, 'data');
const destDir = path.join(moduleDir, 'data-copy');
const relativePaths = await createSampleFiles(sourceDir);
await fs.cp(sourceDir, destDir, {recursive: true});
let exitCode = 0;
try {
const filePaths = relativePaths.map(fPath => path.join(destDir, fPath));
for (const fPath of filePaths) await assertFSEntryExists(fPath);
console.log('Copy successful');
}
catch {
console.error('Copy failed');
exitCode = 1;
}
finally {
// Cleanup
for (const dir of [sourceDir, destDir]) {
if (await fsEntryExists(dir)) await fs.rm(dir, {recursive: true});
}
process.exit(exitCode);
}
}
main();
$ node --version
v16.15.0
$ node example.mjs
Copy successful
I am trying to run this 'getting started' example from the docs. However I think there's been a change and programs.metadata.Metadata (shown there) no longer works.
https://docs.metaplex.com/sdk/js/getting-started
They suggest this:
import { Connection, programs } from '#metaplex/js';
const connection = new Connection('devnet');
const tokenPublicKey = 'Gz3vYbpsB2agTsAwedtvtTkQ1CG9vsioqLW3r9ecNpvZ';
const run = async () => {
try {
const ownedMetadata = await programs.metadata.Metadata.load(connection, tokenPublicKey);
console.log(ownedMetadata);
} catch {
console.log('Failed to fetch metadata');
}
};
run();
I have this in my React app:
import { Connection, programs } from '#metaplex/js';
const connection = new Connection('devnet');
const tokenPublicKey = 'Gz3vYbpsB2agTsAwedtvtTkQ1CG9vsioqLW3r9ecNpvZ';
const run = async () => {
try {
const ownedMetadata = await programs.metadata.Metadata.load(connection, tokenPublicKey);
console.log(ownedMetadata);
} catch(error) {
console.log('Failed to fetch metadata');
console.log(error);
}
};
function App() {
return (
<div className="App">
<p onClick={run}>would be cool if it worked</p>
</div>
);
}
export default App;
I get an error as though programs.metadata.Metadata doesn't exist - "Cannot read properties of undefined (reading 'Metadata')". I even took this out of React and did a plain node script to just run the example code, which fails in the same way.
Any idea on how I could fix this?
For users that find this question via search:
There is now a better solution than using #metaplex-foundation/mpl-token-metadata directly. Have a look at #metaplex/js-next findByMint
Those lines should be all you need. imageUrl would be the image path.
import { Metaplex } from "#metaplex-foundation/js-next";
import { Connection, clusterApiUrl } from "#solana/web3.js";
const connection = new Connection(clusterApiUrl("mainnet-beta"));
const metaplex = new Metaplex(connection);
const mint = new PublicKey("ATe3DymKZadrUoqAMn7HSpraxE4gB88uo1L9zLGmzJeL");
const nft = await metaplex.nfts().findByMint(mint);
const imageUrl = nft.metadata.image;
(1/9/2023) Update : SvelteKit now supports server only load functions and Form actions to send requests to the server.
I want to call my database, but I don't want it be able to get accessed by end users by them going to the API endpoint that I set up. I was wondering how I would be able to just call my database from a file in the lib folder and just returning the data there. When I try it I get the error global not defined:
lib/db.js:
import dotenv from "dotenv";
dotenv.config();
import { MongoClient } from "mongodb";
const uri = process.env["MONGODB_URI"];
const options = {
useUnifiedTopology: true,
useNewUrlParser: true,
};
let client;
let clientPromise;
if (!uri) {
throw new Error("Please add your Mongo URI to .env.local");
}
if (process.env["NODE_ENV"] === "development") {
if (!global._mongoClientPromise) {
client = new MongoClient(uri, options);
global._mongoClientPromise = client.connect();
}
clientPromise = global._mongoClientPromise;
} else {
client = new MongoClient(uri, options);
clientPromise = client.connect();
}
export default clientPromise;
routes/items/index.js:
import clientPromise from "$lib/db";
export async function get() {
const client = await clientPromise;
const db = client.db();
const data = await db.collection("items").find({}).toArray();
const items = data.map(({ name }) => ({ name }));
if (items) {
return {
body: {
items,
},
};
}
}
My attempt:
lib/stores/items.js
import clientPromise from "$lib/db";
import { writable } from "svelte/store";
export const items= writable([]);
const fetchItems = async () => {
const client = await clientPromise;
const db = client.db();
const data = await db.collection("items").find({}).toArray();
const items = data.map(({ name }) => ({ name }));
substances.set(items);
};
fetchItems();
Trying the above code in various places always yields a global not defined error in the client.
I found one question from someone with the same problem, but I couldn't figure out how to create a helper file.
Protecting API is done on back-end side. Usually it either server (like NodeJS) or tools Nginx/Apache (proxy, etc.). You're basically looking for Content-Security-Policy topic, which is vaporous but not related to SvelteKit.
Btw, calling DB directly from the Front-end wouldn't be secure and is not possible.
To get data from any database, you should create enpoint
For user authentication, you can create handle hook:
export async function handle({ request, resolve }) {
let user = await authenticate(request)
request.locals.user = user
request.locals.isAuthenticated = !!user
if (request.path.startsWith('/api')) {
if (!user) {
return {
status: 401,
body: JSON.stringify({
error: {
message: 'Unauthorized'
}
})
}
}
const response = await resolve(request)
return response
}
I am using the code below to upload data to Firestore but am getting the error message below:
SyntaxError: Cannot use import statement outside a module
on this line of code:
"import promises from 'fs';"
import { promises } from 'fs';
const { readFile } = promises;
import { promisify } from 'util';
const parse = promisify(import('csv-parse'));
import { Firestore } from '#google-cloud/firestore';
if (process.argv.length < 3) {
console.error('Please include a path to a csv file');
process.exit(1);
}
const db = new Firestore();
function writeToFirestore(records) {
const batchCommits = [];
let batch = db.batch();
records.forEach((record, i) => {
var docRef = db.collection('firebasetest').doc(record.acctid);
batch.set(docRef, record);
if ((i + 1) % 500 === 0) {
console.log(`Writing record ${i + 1}`);
batchCommits.push(batch.commit());
batch = db.batch();
}
});
batchCommits.push(batch.commit());
return Promise.all(batchCommits);
}
async function importCsv(csvFileName) {
const fileContents = await readFile(csvFileName, 'utf8');
const records = await parse(fileContents, { columns: true });
try {
await writeToFirestore(records);
}
catch (e) {
console.error(e);
process.exit(1);
}
console.log(`Wrote ${records.length} records`);
}
importCsv(process.argv[2]).catch(e => console.error(e));
Download and install Firefoo.
sign in with Google. Right-click your project in the left sidebar and choose Import Collections.
Click on the Data File field and select your JSON or CSV file.
That’s it! Click the Import button.
Your CSV rows are imported into Firestore and a progress popup opens.
I would like to create a local Javascript module I can "require" in other files to handle all MongoDB CRUD operations.
I wrote something as:
-- dbConn.js file --
require('dotenv').config()
const MongoClient = require('mongodb').MongoClient
const ObjectID = require('mongodb').ObjectID
let _connection
const connectDB = async () => {
try {
const client = await MongoClient.connect(process.env.MONGO_DB_URI, {
useNewUrlParser: true,
useUnifiedTopology: true
})
console.log('Connected to MongoDB')
return client
} catch (err) {
console.log(error)
}
}
exports.findOne = async () => {
let client = await connectDB()
if (!client) {
return;
}
try {
const db = client.db("Test_DB");
const collection = db.collection('IoT_data_Coll');
const query = {}
let res = await collection.findOne(query);
return res;
} catch (err) {
console.log(err);
} finally {
client.close();
}
}
exports.findAll = async () => {
let client = await connectDB()
if (!client) {
return;
}
try {
const db = client.db("Test_DB");
const collection = db.collection('IoT_data_Coll');
const query = {}
let res = await collection.find(query).toArray();
return res;
} catch (err) {
console.log(err);
} finally {
client.close();
}
}
Then in another file (not necessary inside Express app), say
-- app.js ---
const findAll = require('./dbConn').findAll
const findOne = require('./dbConn').findOne
findAll().then(res => JSON.stringify(console.log(res)))
findOne().then(res => JSON.stringify(console.log(res)))
I wonder if it is correct?
I have to close the connection after each method/CRUD operation?
I was trying to use IIF instead of ".then", as:
(async () => {
console.log(await findOne())
})()
But I receive a weird error saying that findAll is not a function.
What's wrong with it?
Thanks.
It really depends on your use case which isn’t clear If you are using Express or just stand alone and how frequent are you planning to run app.js
Either way your code is expensive, each time you reference dbCon.js you are opening a new connection to the database.
So you can fix app.js by only requiring dbCon.js once and use it..
The best practice is to ofcourse use connection pooling https://www.compose.com/articles/connection-pooling-with-mongodb/