## Feathers Knex Raw Sql Examples 2022-11-10
(cross-referenced in https://github.com/edwardsmarkf/comptonTransAnlys-conversion/blob/main/raw-feathers-example)0) Install feathers if not already done
npm install @feathersjs/feathers --save ;
1) Initialize new feathers environment
npm init --yes ; npm install knex feathers-knex ;
2) create a username/password:
DROP USER IF EXISTS ‘knexUser’@‘localhost’ ; CREATE USER ‘knexUser’@‘localhost’ IDENTIFIED BY ‘knexPassword’; GRANT ALL ON `comptonTransAnlys`.* TO ‘knexUser’@‘localhost’ IDENTIFIED BY ‘knexPassword’ WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0 ; GRANT ALL PRIVILEGES ON `comptonTransAnlys`.* TO ‘knexUser’@‘localhost’ ; # to test: # mariadb —host=localhost —user=knexUser —password=knexPassword comptonTransAnlys ;
3) Create feather application
feathers generate app ; ## probably select "n" for security, which can be created later
4) Create default Knex service
****** !!Only required if this is a NEW app, otherwise skip this entire step!! ******
feathers generate service ; ### create type "knex" named "knex-raw-init" and MariaDb"
4a) edit knex-raw-init.model.js
should look like this:module.exports = function (app) { return app.get('knexClient'); };its possible AFTER generating other calls that this file can (should?) be deleted
4b) move (or delete) directory
mv ./src/services/initialize-knex/ ./src/services/knex-raw-init-UNUSED/ ; ## -- or -- tar -zcvf knex-raw-init.gz ./src/services/knex-raw-init/ ; ## -- or/and -- rm -Rf ./src/services/knex-raw-init/ ;
4c) change index.js file
vi ./src/services/index.js ; COMMENT OUT:// const initializeKnex = require('./initialize-knex/initialize-knex.service.js'); // app.configure(knexInitialize);
4e) modify ./config/default.json to reflect the database access
(or answer this in the “generate service” prompt)'connection': 'mysql://knexUser:knexPassword@localhost:3306/comptonTransAnlys' -- or -- "mysql": { "client": "mysql2", "connection": { "host" : "localhost" , "port" : 3306 , "user" : "knexUser" , "password" : "knexPassword" , "database" : "comptonTransAnlys" } }
5) Create our custom service!
feathers generate service ; ## create custom service named "my-custom-service"
5a) change my-custom-service.class.js file
./src/services/my-custom-service/my-custom-service.class.js :/* eslint-disable no-unused-vars */ const { QueryTypes } = require(‘feathers-knex’); // new line!! exports.MyCustomService = class MyCustomService { constructor (options, app) { // formerly just constructor(options) this.options = options || {}; this.app = app; // new line! } async find (key) { /* note the default is “params” you may need to change this */ /* Postman GET: http://123.123.123.123:3030/my-custom-service/?one=twooo notice /?one=twoooo – last slash between service name and question mark is OPTIONAL! */ console.info(JSON.stringify(key.query) + ‘ in my find routine!!’); const knexClient = this.app.get(‘knexClient’); // const rows = await knexClient.raw(‘SELECT VERSION;’); // https://knexjs.org/guide/raw.html#raw-parameter-binding :: // Positional bindings ? are interpreted as values and ?? are interpreted as identifiers. const sqlStatement = ‘SELECT variable_value FROM information_schema.global_variables WHERE ?? = ?;’ ; const rows = await knexClient.raw( sqlStatement, [‘VARIABLE_NAME’, ‘VERSION’]);// should execute this: SELECT variable_value FROM information_schema.global_variables where variable_name = ‘VERSION’ ;
console.table (rows); return `${JSON.stringify(key.query) + JSON.stringify(rows)} find routine!!`; } async get (key) { /* Postman GET: http://123.123.123.123:3030/my-custom-service/123456789 notice /123456789 – only ONE parameter as a suffix */ console.info(JSON.stringify(key) + ‘ in get routine!!’); const knexClient = this.app.get(‘knexClient’); const mariaDbDate = await knexClient.raw(‘SELECT CURDATE ;’ ); console.table(mariaDbDate); return `${JSON.stringify(key) + JSON.stringify(mariaDbDate)} get routine!`; } };
6) stop firewall if necessary
systemctl stop firewalld ;
7) Start the app
run DEBUG=* npm start ; run DEBUG=knex:query npm start ;
8) either postman or browser do:
http://123.123.123.123:3030/my-custom-service/1234 # get http://123.123.123.123:3030/my-custom-service/?one=twoooooo # find
Optionally include parameters
/* named variables, please notice DOUBLE-COLON does backticks while SINGLE-COLON does quote characters! */ const sqlStatement = 'SELECT variable_value FROM information_schema.global_variables WHERE :var_name: = :val ;' ; const sqlQuery = { var_name: 'VARIABLE_NAME' , val: 'VERSION' } ; const rows = await knexClient.raw( sqlStatement, sqlQuery);
#########################################################################
easier to just generate…. to many steps to get this working.
4X) Create initial raw init model file (????)
mkdir --parent ./src/models/ ; // just in case this does not exist yet. cat <<END > ./src/models/INIT-KNEX-RAW.model.js; module.exports = function (app) { return app.get('knexClient'); }; END
###############################################################################
## S E Q U E L I Z E:
0) npm install sequelize
1) create sequelize CUSTOM SERVICE named: “my-custom-service”
2) edit ./src/sequelize.js change logging false to logging true
3) change: src/services/my-custom-service/my-custom-service.class.js :
/* eslint-disable no-unused-vars */
const { QueryTypes } = require(‘sequelize’);
exports.MyCustomService = class MyCustomService { constructor (options, app) { this.options = options || {}; this.app = app; }
async find (key) {
const sequelize = this.app.get(‘sequelizeClient’);
const stimwordPositionSelectFind =
‘SELECT * FROM stimwordPosition WHERE 1 AND stimwordPositionWord = $stimwordPositionWord;’ ;
const stimwordPositionSelectParms =
{ ‘stimwordPositionWord’ : JSON.parse(key.query).stimwordPositionWord } ;
const rows = await sequelize.query
( stimwordPositionSelectFind
, { ‘bind’ : stimwordPositionSelectParms }
);
return rows;
}
};
################################ browser-console:
in browser console (common initial setup for all examples)
[you may need to visit the “about:blank” webpage — 2022-22-21 ]
first visit http://123.123.123.123:3030/ to “initialize” chrome
[ ‘//cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.4/socket.io.js’
, ‘//unpkg.com/@feathersjs/client@^3.0.0/dist/feathers.js’
].forEach( (src) => {
let script = document.createElement(‘script’); script.src = src; script.async = false;
document.head.appendChild(script);
});
const app = feathers(); const socket = io(); app.configure(feathers.socketio(socket));
// optional if trying to run on another http[s] webpage rather than at http://123.123.123.123:3030:
const socket = io.connect ( ’35.192.14.166:3030’ , { ‘path’ : ‘/socket.io/’ , ‘port’ : ‘3030’ , ‘hostname’ : ’35.192.14.166’ , ‘secure’ : false } );
// socket.io.engine.transport
async function stimwordPositionFind(param) {
console.log( ‘param: ‘ + param);
let getResult = await app.service(‘my-custom-service’).find(param);
console.log(‘stimwordPosition function: ‘ + JSON.stringify(getResult) );
return getResult;
};
let stimwordPositionResult = null;
let key = { ‘query’ : { ‘stimwordWord’ : ‘horse’, ‘parm2’ : ‘answer2’ } } ;
stimwordPositionFind(key).then( value => { /* get(GET) */
stimwordPositionResult = value;
console.log(‘stimwordPosition(’ + key + ‘) : ‘ + JSON.stringify(stimwordPositionResult) );
});
async function stimwordPosition(id) { /* get(GET) (just one by index) */
console.log( ‘id: ‘ + id);
let getResult = await app.service(‘my-custom-service’).find(id);
console.log(‘stimwordPosition function: ‘ + JSON.stringify(getResult) );
return getResult;
};
############ GET GET GET GET GET GET
async get (id) { const sequelize = this.app.get(‘sequelizeClient’); const stimwordPositionSelectGet = `SELECT * FROM stimwordPosition WHERE 1 AND stimwordPositionAutoIncr = ${id};`; const rows = await sequelize.query(stimwordPositionSelectGet); return rows; }async function stimwordPosition(id) { /* get(GET) (just one by index) */
console.log( ‘id: ‘ + id);
let getResult = await app.service(‘my-custom-service’).get(id);
console.log(‘stimwordPosition function: ‘ + JSON.stringify(getResult) );
return getResult;
};
let stimwordPositionResult = null; let key = 1; // assuming your row ID is one
stimwordPosition(key).then( value => { /* get(GET) */
stimwordPositionResult = value;
console.log(‘stimwordPosition(’ + key + ‘) : ‘ + JSON.stringify(stimwordPositionResult) );
});
#####################################################
let stimwordPositionResult = null; let key = 1; // assuming your row ID is one
stimwordPosition(key).then( value => { /* get(GET) */
stimwordPositionResult = value;
console.log(‘stimwordPosition(’ + key + ‘) : ‘ + JSON.stringify(stimwordPositionResult) );
});