i want to read all data from table "add_news".the code is given below
var db = Mysql();
void _getnews() async{
await db.getConnection().then((conn) async{
// the select query
String sql = "select * from add_news;";
await conn.query(sql).then((results) {
for(var row in results){
print(row);
}
});
conn.close();
});
}
can some please tell me how can i do this??
If you want to show inside your flutter app, then try this.
Display it using future builder. And also make a Model of your database
Repo Link
Future<List<Profiles>> getSQLData() async {
final List<Profiles> profileList = [];
final Mysql db = Mysql();
await db.getConnection().then((conn) async {
String sqlQuery = 'select email, password from users';
await conn.query(sqlQuery).then((results) {
for (var res in results) {
final profileModel =
Profiles(email: res["email"], password: res["password"]);
profileList.add(profileModel);
}
}).onError((error, stackTrace) {
print(error);
return null;
});
conn.close();
});
return profileList;
}
Related
I've created a salt and a hash function to hash my password.
I'm trying to login with the original password and it won't let me, but if I try to log in with the hashed password from the database it will give me to log in.
const salt = "HashedPasswordCheck";
hash function:
function has(plainText: string):string{
if(!plainText) return null;
const hashedText = crypto.createHmac("sha512", salt).update(plainText).digest("hex");
return hashedText;
}
auth-logic.ts:
async function login(credentials:CredentialsModel):Promise<string>{
const error = credentials.validate();
if(error) throw new ValidationErrorModel(error);
const sql = `SELECT * FROM users WHERE username = ? AND password = ?`;
const users = await dal.execute(sql, [credentials.username, credentials.password]);
credentials.password = cyber.hash(credentials.password);
if (users.length === 0) throw new UnauthorizedErrorModel("Incorrect username or
password");
const user = users[0];
const token = cyber.getNewToken(user);
return token;
}
I tried to more the has before sending the query and still not working.
I checked this before and it was the same and worked but on this new project i'm working on it's not working properly.
credentials-model:
class CredentialsModel {
public username: string;
public password: string;
public constructor(credentials: CredentialsModel) {
this.username = credentials.username;
this.password = credentials.password;
}
public static validationSchema = Joi.object({
username: Joi.string().required().min(4).max(20),
password: Joi.string().required().min(4).max(50)
});
public validate(): string {
const result = CredentialsModel.validationSchema.validate(this);
return result.error?.message;
}
}
export default CredentialsModel;
auth-controller.ts:
// http://localhost:3001/api/auth/login
router.post("/auth/login", async (request: Request, response: Response, next:
NextFunction) => {
try {
const credentials = new CredentialsModel(request.body);
const token = await authLogic.login(credentials);
response.json(token);
}
catch(err:any){
next(err);
}
});
I didn't add a React code because it's a back end problem..
Thank you for any one that can help!
Found the issue.
I had 24 chars in my mySQL db, so it saved only part of the string and that's why I had an issue.
Solved by increasing the varchar amount on mySQL.
I'm new to Node, and I'm trying to follow a pattern from a Udemy API course. The API is structured to utilize route, controller and service modules for flow. Database queries are to be run as services and they are supposed to be called from controllers.
I need to run a series of DB queries to generate a list (I'm showing only 2 of 6 queries in this example). I am running these using async/await in my function. The queries are working fine. My problem occurs when I try to return the 'batch result' (the result of all the queries) to the controller at the end of the process. I get Promise { <pending> }. I have tried many things, but I cannot end the promise to access the final result from my controller module--I can only access it from my service module.
Here is my code from my controller module (groups.controller.js) where I call my function:
const groupsService = require('../services/groups.service');
exports.propertyList = (req, res, next) => {
const uid = req.body.uid;
const batchResponse = groupsService.batchQuery(uid, res);
console.log(batchResponse);
}
And here is my code from my service module (groups.services.js) where I run the queries:
const mysql = require('mysql2');
const dbAsync = require("../config/db.config");
async function batchQuery(uid, res) {
var Q1;
var Q2;
var uid = uid * -1;
const pool = mysql.createPool(dbAsync.dbAsync);
const promisePool = pool.promise();
try {
Q1 = await promisePool.query('SELECT PropertyID FROM GroupMembership WHERE GroupID = ?', [uid]);
Q2 = await promisePool.query('SELECT SubGroupID FROM GroupMembership WHERE GroupID = ? AND PropertyID = ?', [uid, 0]);
}
catch(error) {
console.log(error);
res.status(401).send('Server error');
return error;
}
finally {
const batchResponse = {
Q1: Q1[0],
Q2: Q2[0]
}
console.log('Q1: '+ Q1[0][0].PropertyID + ', Q2: ' + Q2[0][0].SubGroupID);
res.status(200).send(batchResponse);
return batchResponse;
}
}
module.exports = {batchQuery};
When I send a post via postman, I get the expected query result (below). However, I can only get this to work if I put my res in my service module.
{
"Q1": [
{
"PropertyID": 0
}
],
"Q2": [
{
"SubGroupID": 397
}
]
}
Is there a way to end the promise in this pattern and return the desired batch response? Thank you.
EDIT: Adding the code updates provided by #traynor.
New controller:
const groupsService = require('../services/groups.service');
exports.propertyList = async (req, res, next) => {
const uid = req.body.uid;
let batchResponse;
try {
batchResponse = await groupsService.batchQuery(uid);
console.log(batchResponse);
return res.status(200).send(batchResponse);
} catch(error) {
console.log('Error: ' + error);
return res.status(401).send('Server error');
}
}
New service:
const mysql = require('mysql2');
const dbAsync = require("../config/db.config");
function batchQuery(uid) {
return new Promise((resolve, reject) => {
var Q1;
var Q2;
var uid = uid * -1;
const pool = mysql.createPool(dbAsync.dbAsync);
const promisePool = pool.promise();
try {
Q1 = await promisePool.query('SELECT PropertyID FROM GroupMembership WHERE GroupID = ?', [uid]);
Q2 = await promisePool.query('SELECT SubGroupID FROM GroupMembership WHERE GroupID = ? AND PropertyID = ?', [uid, 0]);
} catch(error) {
console.log(error);
reject(error);
} finally {
const batchResponse = {
Q1: Q1[0],
Q2: Q2[0]
}
console.log('Q1: '+ Q1[0][0].PropertyID + ', Q2: ' + Q2[0][0].SubGroupID);
resolve(batchResponse);
}
})
}
module.exports = {batchQuery};
the service is now returning a promise, and it's also handling response instead of controller.
to return from service, you need to promisify service: return a promise which resolves when you get db data, or on error, and then you also need to await the service, which it's wrapped in try/catch for error handling.
once it's all done, handle response from the controller:
service:
function batchQuery(uid) {
return new Promise(async (resolve, reject) => {
var Q1;
var Q2;
//...
try {
//...
} catch (error) {
console.log(error);
reject(error);
} finally {
const batchResponse = {
Q1: Q1[0],
Q2: Q2[0]
}
console.log('Q1: ' + Q1[0][0].PropertyID + ', Q2: ' + Q2[0][0].SubGroupID);
resolve(batchResponse);
}
});
controller:
exports.propertyList = async (req, res, next) => {
const uid = req.body.uid;
let batchResponse;
try {
batchResponse = await groupsService.batchQuery(uid);
console.log(batchResponse);
res.status(200).send(batchResponse);
} catch(error) {
return res.status(401).send('Server error');
}
}
I have a lambda function that connects to mysql and runs a set of queries, but I actually have a sequence of mysql queries that need to run one after another. I.e., the value of one query is used in the next query, etc.
Currently, I have a bunch of callbacks to achieve this, but this is leading to "callback hell". How would I rewrite this to use async / await?
My code is actually split into 2 files. The first file does an initial query, and then the value is passed into a function of the second file. Please note that the mysql node_module is included but not shown here. The AWS API gateway calls index.js
// index.js
var mysql = require('mysql'); // from node_modules
var config = require('./config.json');
var dashboard = require('./dashboard.js');
var pool = mysql.createPool({
host : config.dbhost,
user : config.dbuser,
password : config.dbpassword,
database : config.dbname
});
exports.handler = (event, context, callback) => {
context.callbackWaitsForEmptyEventLoop = false;
pool.getConnection(function(err, connection) {
// check for mysql connection error first
if ( err ) {
throw err;
}
let qry = "select id from some_table where some_field = ?";
let someval = event.queryStringParameters.someval;
connection.query(qry, [someval], function(error, result) {
if ( error ) {
throw err;
}
else {
dashboard.processRequest(connection, callback, event, res[0].id);
}
});
});
}
// dashboard.js
module.exports = {
jsonResponse: function(results) {
return {
"statusCode": 200,
"body": JSON.stringify({ results }),
"isBase64Encoded": false,
"headers": {
"Access-Control-Allow-Origin": "*"
}
};
},
processRequest: function(connection, callback, event, val) {
let qry = "update first_table set some_field = ?";
connection.query(qry, [val], function(error, results) {
// return to client if error
if (error) {
callback(null, this.jsonResponse(error));
}
else {
// assume that this table must be update AFTER the previous statement
qry = "select id from second_table where some_field = ?";
connection.query(qry, [val], function(error1, results1) {
// return to client if error
if ( error1 ) {
callback(null, this.jsonResponse(error1));
}
qry = "update third_table set some_field = ? where id = ?";
connection.query(qry, [results1[0].id], function(error2, results2) {
// release connection when all queries are completed
connection.release();
if ( error2 ) {
callback(null, this.jsonResponse(error2));
}
else {
callback(null, this.jsonResponse(results2));
}
});
});
}
});
}
};
It was suggested to me that something like the below code might work. Unfortunately, it does not. I was curious to know why using try...catch blocks in the way shown below is not working, and is it the same thing as what you've shown, but just written differently?
// index.js
var mysql = require('mysql'); // from node_modules
var config = require('./config.json');
var dashboard = require('./dashboard.js');
var pool = mysql.createPool({
host : config.dbhost,
user : config.dbuser,
password : config.dbpassword,
database : config.dbname
});
exports.handler = (event, context, callback) => {
context.callbackWaitsForEmptyEventLoop = false;
pool.getConnection(function(err, connection) {
// check for mysql connection error first
if ( err ) {
throw err;
}
let qry = "select id from users where username = ? limit 1;";
let username = event.queryStringParameters.username;
try {
let res = await connection.query(qry, [event.queryStringParameters.username]);
dashboard.processRequest(connection, callback, event, res[0].id);
} catch (err) {
console.log(err);
}
});
}
// dashboard.js
module.exports = {
jsonResponse: function (results) {
return {
"statusCode": 200,
"body": JSON.stringify({results}),
"isBase64Encoded": false,
"headers": {
"Access-Control-Allow-Origin": "*"
}
};
},
processRequest: async function (connection, callback, event, val) {
let qry = "update first_table set some_field = ?";
try {
let results = await connection.query(qry, [val]);
qry = "select id from second_table where some_field = ?";
try {
let results1 = await connection.query(qry, [val]);
qry = "update third_table set some_field = ? where id = ?";
try {
let results2 = await connection.query(qry, [results1[0].id]);
connection.release();
callback(null, this.jsonResponse(results2));
} catch (error2) {
callback(null, this.jsonResponse(error2));
}
} catch (error1) {
callback(null, this.jsonResponse(error1));
}
} catch (error) {
callback(null, this.jsonResponse(error));
}
}
};
We need use promises.
Typically I follow this approach:
Create one async method mainProcess and have bunch of methods step by step called with in that method. one after the other with await or all at once.
Each async method getConnection and runQuery in this case, called within mainProcess must a Promise.
If any errors from these methods i.e promise rejects from individual methods, goes in catch block of mainProcess().
If no errors, all methods within mainProcess gets executed and goes to then block of mainProcess()
Your code can be refactored like this (just wrote in an editor untested)
var pool = mysql.createPool({
host: config.dbhost,
user: config.dbuser,
password: config.dbpassword,
database: config.dbname,
});
exports.handler = (event, context, callback) => {
context.callbackWaitsForEmptyEventLoop = false;
/**
* Main Lambda Process
*/
const mainProcess = async () => {
// Get Connection
let connection = await getConnection();
// Run Step 1
let qry1 = "select id from some_table1 where some_field = ?";
const response1 = await runQuery(connection, qry1, { someFiledValue: 1222})
// Run Step 2
let qry2 = "select id from some_table2 where some_field = ?";
const resonse2 = await runQuery(connection, qry2, { someFiledValue: 1222})
return 'All Good';
});
}
mainProcess()
.then(result => {
// All lambda success messages are returned from here
callback(null, result);
})
.catch(error => {
// All lambda errors thrown from here
callback(error);
});
};
function getConnection(qry, parms) {
return new Promise((resolve, reject) => {
pool.getConnection(function (error, connection) {
if (error) {
// return to client if error
reject(error);
} else {
// Return response
resolve(connection);
}
});
});
}
/**
* Runs a query, either resolves or rejects
*/
function runQuery(connection, qry, parms) {
return new Promise((resolve, reject) => {
connection.query(qry, [val], function (error, results) {
if (error) {
// return to client if error
reject(error);
} else {
// Return response
resolve(result);
}
});
});
}
When you're dealing with a lambda function which performs an async task you have two solutions:
you can use non async handlers, in which case you need to invoke "callback" on promises as you did in your example
you can use async handlers, which does not requires the "callback" input and that allows you to write async/await code, like the following example:
const mysql = require('mysql2/promise');
exports.handler = async(event, context) => {
//get path variable
const { pathVar } = event.pathParameters;
// get connection
const connection = await mysql.createConnection({
host : process.env.RDS_HOSTNAME,
user : process.env.RDS_USERNAME,
password : process.env.RDS_PASSWORD,
database : process.env.RDS_DB_NAME
});
// get text query
const textQuery = `SELECT field FROM entity WHERE attribute = ${pathVar}`;
// get res
const results = await connection.execute(textQuery);
return {
"statusCode": 200,
"body": results,
"isBase64Encoded": false
}
}
You can have a look at the AWS docs: https://docs.aws.amazon.com/lambda/latest/dg/nodejs-handler.html
I'm new to flutter and sqflite. For a project I was trying to use an existing database. I have kept my db file in a assest folder. When I run it on my emulator it shows nothing. Can someone tell me where did I do wrong? It's exactly not showing any error, but it's showing something like:
HostComposition ext ANDROID_EMU_CHECKSUM_HELPER_v1
ANDROID_EMU_native_sync_v2 ANDROID_EMU_native_sync_v3
ANDROID_EMU_native_sync_v4 ANDROID_EMU_dma_v1 ANDROID_EMU_direct_mem
ANDROID_EMU_host_composition_v1 ANDROID_EMU_host_composition_v2
ANDROID_EMU_YUV420_888_to_NV21 ANDROID_EMU_YUV_Cache
ANDROID_EMU_async_unmap_buffer GL_OES_EGL_image_external_essl3
GL_OES_vertex_array_object GL_KHR_texture_compression_astc_ldr
ANDROID_EMU_gles_max_version_3_0
W/OpenGLRenderer( 5874): Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without..
class DatabaseHelper {
static final _databaseName = "lastRandomdb.db";
static final _databaseVersion = 1;
static final table = "Randomdb";
static final columnEmail = "email";
static final columnName = "name";
DatabaseHelper._privateConstructor();
static final DatabaseHelper instance = DatabaseHelper._privateConstructor();
static Database _database;
Future<Database> get database async {
if (database != null) return database;
_database = await _initDatabase();
return _database;
}
_initDatabase() async {
var databasepath = await getDatabasesPath();
String path = join(databasepath, _databaseName);
//check existing
var exists = await databaseExists(path);
if (!exists) {
print("copy database start");
try {
await Directory(dirname(path)).create(recursive: true);
} catch (_) {
//copy
ByteData data = await rootBundle.load(join("assets", _databaseName));
List<int> bytes =
data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
//write
await File(path).writeAsBytes(bytes, flush: true);
}
} else {
print("opening exsisting database");
}
return await openDatabase(path, version: _databaseVersion);
}
//crud
Future<List<Contact>> getAllContacts() async {
Database db = await instance.database;
final List<Map<String, dynamic>> map = await db.query(table);
return List.generate(map.length, (index) {
return Contact.fromMap(map[index]);
});
}
Future<int> getCount() async {
Database db = await instance.database;
return Sqflite.firstIntValue(
await db.rawQuery("SELECT COUNT(EMAIL) FROM $table"));
}
}
this is my model file
final String COL_NAME = "name";
final String COL_EMAIL = "email";
class Contact {
String name, email;
Contact({this.name, this.email});
Contact.map(dynamic obj1) {
this.name = obj1['NAME'];
this.email = obj1['EMAIL'];
}
Map<String, dynamic> toMap() {
var map = <String, dynamic>{
//method
COL_NAME: name,
COL_EMAIL: email,
};
return map;
}
Contact.fromMap(Map<String, dynamic> map) {
//named constructor to return emoloyee model obj
name = map[COL_NAME];
email = map[COL_EMAIL];
}
#override
String toString() {
return 'Contact{name: $name, email: $email}';
}
}
Ok let's evaluate your _initDatabase line by line
first you create the path and check if it exists
var databasepath = await getDatabasesPath();
String path = join(databasepath,_databaseName);
//check existing
var exists = await databaseExists(path);
Seems good, then if it doesn't exist you want to copy it from the AssetFolder
try{
await Directory(dirname(path)).create(recursive: true);
}catch(_){
//copy
ByteData data = await rootBundle.load(join("assets",_databaseName));
List<int> bytes = data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
//write
await File(path).writeAsBytes(bytes, flush: true);
}
you try to create the Directory in the path (I don't know what method is dirname but I will believe it returns the path). If nothing fails then it will run
return await openDatabase(path,version: _databaseVersion);
It will enter the catch and copy the db from asset only if the creation of the Directory throws an error, is there a condition when it will fail that? If not then it will never try to copy the db. If you're sure that creating a Directory won't throw an error you should just run the code without the try catch
await Directory(dirname(path)).create(recursive: true);
ByteData data = await rootBundle.load(join("assets",_databaseName));
List<int> bytes = data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
await File(path).writeAsBytes(bytes, flush: true);
I'm trying to create an array of items from a MySQL query to return from an async function but the returns are empty.
Things I've tried:
Read up to the latest info about async/await
Stack overflow
Numerous test around changing code, replacing return calls, rewriting functions.
This is for a new webservice (nodejs) that needs to initialize values from a MySQL database and after that fast access to the values to compare them against values pulled from the internet. To limit the amount of database calls I'm planning to have the values in an array (in-memory) and whenever they change enough (based on calculations) write them to the DB.
All is Linux based using Node 11
require('dotenv').config()
var mysql = require('mysql')
var dbconnection = mysql.createConnection({
host: 'localhost',
user: process.env.MYSQL_USER,
password: process.env.MYSQL_PW,
database: process.env.MYSQL_DB
})
dbconnection.connect(function (err) {
if (err) {
console.error('error connecting: ' + err.stack)
}
})
async function ReadDB () {
var ArrBuyPrice = []
var query = 'SELECT * FROM pricing'
var items = await dbconnection.query(query, function (err, rows, result) {
if (err) throw err
for (var i in rows) {
ArrBuyPrice.push(rows[i].price_buy.toFixed(8))
}
return ArrBuyPrice
})
return items
}
async function InitialProcess () {
var DbResult = await ReadDB()
console.log(DbResult)
}
InitialProcess()
I would expect the console.log output to be [ '0.00000925', '0.00000012' ]
// https://stackoverflow.com/questions/44004418
var mysql = require('mysql')
var dbconnection = mysql.createConnection({
host: 'localhost',
user: process.env.MYSQL_USER,
password: process.env.MYSQL_PW,
database: process.env.MYSQL_DB
})
const util = require('util');
async function ReadDB() {
var ArrBuyPrice = []
const query = util.promisify(dbconnection.query).bind(dbconnection);
try {
const rows = await query('select * from pricing');
for (var i in rows) {
ArrBuyPrice.push(rows[i].price_buy.toFixed(8))
}
return ArrBuyPrice;
} catch (error) {
console.log(error)
return [];
} finally {
dbconnection.end();
}
}
async function InitialProcess() {
var DbResult = await ReadDB()
console.log(DbResult)
}
InitialProcess();
What is Problem:
async function ReadDB() {
var ArrBuyPrice = []
var query = 'SELECT * FROM pricing';
var items = await dbconnection.query(query, function (err, rows, result) {
if (err) throw err
for (var i in rows) {
ArrBuyPrice.push(rows[i].price_buy.toFixed(8))
}
return ArrBuyPrice
});
return items
}
At await dbconnection.query, await is not working, and it is unnecessary, because dbconnection.query() function is not Promise function.
So, the rows which query result will arrive after return items;
And return ArrBuyPrice function is not running.