marcus-j-davies / node-red-contrib-json2mysql

JSON to MYSQL

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

JSON 2 MySQL for NodeRed

Takes JSON payloads which then creates and executes MySQL queries, that are sql injection safe, with automatic quoting for input params, andtable.column back-ticking.

Although json might seem a bit more bloated than straight sql strings, I believe having the payloads like this allows for better readability and flexibility. Eg: generating the conditions on the fly.

Dependencies

NodeJS MySQL:

$ npm install mysql

https://www.npmjs.com/package/mysql

MySQL server:

Here's an example tutorial on installing for Raspberry Pi, but you do you....

https://linuxhint.com/setup-mysql-raspberry-pi/

Some prior knowledge of SQL syntax:

Although I've changed certain keywords to simplify the json, some prior knowledge is beneficial.

Config node

Create a config node to connect to your database server

host domain|IP|localhost

database Name of database to connect

user Username to database

password Password to database

Query node

This is the node you'll use in your flows to pass in JSON and receive string|array|object from the output.

name [optional] Node label

server Config node used for database connection.

template [optional] JSON string to create static payloads. Input payload can override/appended via input payload.

Example template:

{
	"select": {
		"table": {"users": "user"},
		"columns": [
			"user.*"
		]
	}
	"where": [
		["user.first_name", "=", "?:first_name"]
	]
}

Example input payload to append to the template:

{
	"params": {
		"first_name": "John"
	}
}

Example input payload to override (where clause) of the template, the rest of the template will remain unchanged:

{
	"where": [
		["user.first_name", "is not", null]
	]
}

Supported query types

Currently supports the following query types:

  • SELECT
  • INSERT
  • DELETE
  • UPDATE

Use lowercase keywords within your json. Eg: select, not SELECT. Optional keywords to use with the above query types: joins,where,having,order,group,limit,params,return

Currently only supports one query at a time. A full example is at the bottom of this page.

Payload keywords:

select keyword must have the following:

table Either string table_name, or {"table_name":"alias"} object.

columns array of strings. Best practice to use alias.column identifiers.

"select": {
	"table": {"users": "user"}
	"columns: [
		"user.first_name",
		"YEAR(user.date_added) AS year_added",
		"salery.amount",
	]
},

insert keyword must have the following:

table string table name

columns object of "column":"value"pairs. See params for injection safe values.

duplicates [Optional] array of strings. Adds ON DUPLICATE KEY UPDATE ... statement.

"insert": {
	"table": "users",
	"columns": {
		"id": 10,
		"date_added": "NOW()",
		"first_name": "?"
	},
	"duplicates": [
		"id = id + 1"
	]
},

delete keyword must have the following:

table Either string table_name, or {"table_name":"alias"} object.

"delete": {
	"table": {"users": "user"}
},

update keyword must have the following:

table Either string table_name, or {"table_name":"alias"} object.

columns object of "table.column":"value"pairs. See params for injection safe values.

"update": {
	"table": {"users": "user"},
	"columns": {
		"user.first_name": "?",
		"user.date_modified": "NOW()"
	}
},

joins keyword must have the following:

An array of objects, each with:

type string inner|left|right|cross

table Either string table_name, or {"table_name":"alias"} object.

conditions An array of arrays, each being [column, operator, value] See where for all operators.

"joins": [
	{
		"type": "inner",
		"table": {"salaries":"salary"},
		"conditions": [
			["salary.user_id", "=", "user.id"]
		]
	},
	{
		"type": "left",
		"table": {"attendances":"attendance"},
		"conditions": [
			["attendance.user_id", "=", "user.id"]
		]
	}
],

where keyword:

array of arrays, each being [column, operator, value]. See params for implementing injection safe values. See Operators for possible conditions. value can be null|bool|number|string

"where": [
	["user.active", "=", true],
	["YEAR(user.date_added)", ">", "?"],
	["user.first_name", "is", null],
	["user.date_modified", "BETWEEN", ["?", "?"]],
	["user.age", "in", [20,21,22,23]],
	["user.last_name", "contains", "?"],
	["user.last_name", "begins", "?"],
	["user.last_name", "ends", "?"],
],

Operators:

= Equals.

<=Less than or equals.

>= More than or equals.

< Less than.

> More than.

!= Not equal.

<> Not equal.

is Typically used with value of null.

is not Typically used with value of null.

between Value must be an array of ["start", "end"] values.

in Value must be an array ["x","y","z"].

not in Value must be an array["x","y","z"].

contains Performs a LIKE condition in which column value contains given value value.

begins Performs a LIKE condition in which the column value starts with given value.

ends Performs a LIKE conditions in which the column value ends with given value.

having keyword:

array of arrays, each being [column, operator, value]. See where for more information.

"having": [
	["total", ">", 100]
],

params keyword:

Either array of strings, or {"name":"value"} object.

These will replace the ? placeholders, matching the order of each occurrence.

"where": [
	["user.first_name", '=', "?"],
	["user.last_name", '=', "?"],
	["user.gender", '=', "?"],
],
"params": [
	"John",
	"Smith",
	"Male"
],

These will replace the named placeholders, eg: ?:first_name. Useful for multiple occurrences of that input. Ordering is ignored.

"where": [
	["user.first_name", '=', "?:first_name"],
	["user.last_name", '=', "?:last_name"],
	["user.gender", '=', "?:gender"],
],
"params": {
	"first_name": "John",
	"last_name": "Smith",
	"gender": "Male"
},

order keyword:

Either array of strings, or {"column":"asc|desc"} object(s).

"order": [
	"user.first_name",
	{"user.first_name": "desc"},
],

group keyword:

Array of strings.

"group": [
	"user.age",
	"user.gender",
]

limit keyword:

Either integer or array of [offset, limit]

"limit": 50,
"limit": [100,50],

returnkeyword:

string with default value of string if omitted.

string Returns a string of the generated query. Useful for debugging.

array Returns array of rows, where each row is{column: value, ...} objects.

array-num Returns array of rows, where each row is a numeric array

row Returns object of a single row {column: value, ...}

row-num Returns a single row, as a numeric array [0: value, 1: value, ...]

map Returns array of {column: value} object where the identifier is the first column in the result set, and the value is the second.

map-array Returns object of {identifier: {column: value, ...}}, where the identifier is the first column in the result set, and the value an object of {name:value} pairs.

val Returns a single value, of the first column of the first row.

col Returns an array from the first column of each row [0: value, 1: value, ...].

count Number of rows returned/affected.

Complete payload example

Example of a typical payload.

{
	"select": {
		"table": {"users": "user"},
		"columns": [
			"user.id",
			"user.name",
			"YEAR(user.date_added) AS year_added"
		]
	},
	"joins": [
		{
			"type": "inner",
			"table": {"salaries": "salary"},
			"conditions": [
				["salary.user_id", "=", "user.id"]
			]
		}
	],
	"where": [
		["salary.amount", ">", 100],
		["user.first_name", "!=", "?"]
	],
	"group": [
		"user.id"
	],
	"order": [
		{"salary.amount": "DESC"},
		"user.name"
	],
	"limit": 10,
	"params": [
		"Sam"
	],
	"return": "string"
}

Which will return the following:

SELECT `user`.`id`, `user`.`name`, YEAR(`user`.`date_added`) AS `year_added`
FROM `users` AS `user`
INNER JOIN `salaries` AS `salary` ON `salary`.`user_id` = `user`.`id`
WHERE `salary`.`amount` > 100
AND `user`.`first_name` != 'Sam'
GROUP BY `user`.`id`
ORDER BY `salary`.`amount` DESC, `user`.`name`
LIMIT 10

About

JSON to MYSQL

License:MIT License


Languages

Language:JavaScript 91.6%Language:HTML 8.4%