2
0
mirror of https://github.com/frappe/books.git synced 2024-11-09 23:30:56 +00:00

Merge pull request #27 from shridarpatil/mysql

Mysql Backend
This commit is contained in:
Rushabh Mehta 2018-02-12 18:12:57 +05:30 committed by GitHub
commit d0919ddf6c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 491 additions and 2 deletions

View File

@ -3,7 +3,13 @@ language: node_js
node_js:
- "8"
services:
- mysql
before_install:
- mysql -u root -e 'create database test_frappejs'
- echo "USE mysql;\nCREATE USER 'test_frappejs'@'localhost' IDENTIFIED BY 'test_frappejs';\nFLUSH PRIVILEGES;\n"
- echo "USE mysql;\nGRANT ALL PRIVILEGES ON \`test_frappejs\`.* TO 'test_frappejs'@'localhost';\n"
- "git clone https://github.com/frappe/frappejs && cd frappejs"
- "npm install -g yarn"
- "yarn"

208
backends/mysql.js Normal file
View File

@ -0,0 +1,208 @@
const frappe = require('frappejs');
const mysql = require('mysql');
const Database = require('./database');
const debug = false;
module.exports = class mysqlDatabse extends Database{
constructor({ db_name, username, password, host }) {
super();
this.db_name = db_name;
this.username = username;
this.password = password;
this.host = host;
this.init_type_map();
}
connect(db_name) {
if (db_name) {
this.db_name = db_name;
}
return new Promise(resolve => {
this.conn = new mysql.createConnection({
host : this.host,
user : this.username,
password : this.password,
database : this.db_name
});
() => {
if (debug) {
this.conn.on('trace', (trace) => console.log(trace));
}
};
resolve();
});
}
async tableExists(table) {
const name = await this.sql(`SELECT table_name
FROM information_schema.tables
WHERE table_schema = '${this.db_name}'
AND table_name = '${table}'`);
return (name && name.length) ? true : false;
}
async runCreateTableQuery(doctype, columns, values){
const query = `CREATE TABLE IF NOT EXISTS ${frappe.slug(doctype)} (
${columns.join(", ")})`;
return await this.run(query, values);
}
getColumnDefinition(df) {
return `${df.fieldname} ${this.type_map[df.fieldtype]} ${df.reqd && !df.default ? "not null" : ""} ${df.default ? `default '${df.default}'` : ""}`
}
async getTableColumns(doctype) {
return (await this.sql(`SHOW COLUMNS FROM ${doctype}`)).map(d => d.Field);
}
async runAlterTableQuery(doctype) {
await this.run(`ALTER TABLE ${frappe.slug(doctype)} ADD COLUMN ${this.get_column_definition(df)}`, values);
}
getOne(doctype, name, fields = '*') {
fields = this.prepareFields(fields);
return new Promise((resolve, reject) => {
this.conn.get(`select ${fields} from ${frappe.slug(doctype)}
where name = ?`, name,
(err, row) => {
resolve(row || {});
});
});
}
async insertOne(doctype, doc) {
let fields = this.get_keys(doctype);
let placeholders = fields.map(d => '?').join(', ');
if (!doc.name) {
doc.name = frappe.getRandomName();
}
return await this.run(`insert into ${frappe.slug(doctype)}
(${fields.map(field => field.fieldname).join(", ")})
values (${placeholders})`, this.getFormattedValues(fields, doc));
}
async updateOne(doctype, doc) {
let fields = this.getKeys(doctype);
let assigns = fields.map(field => `${field.fieldname} = ?`);
let values = this.getFormattedValues(fields, doc);
// additional name for where clause
values.push(doc.name);
return await this.run(`update ${frappe.slug(doctype)}
set ${assigns.join(", ")} where name=?`, values);
}
async runDeleteOtherChildren(field, added) {
await this.run(`delete from ${frappe.slug(field.childtype)}
where
parent = ? and
name not in (${added.slice(1).map(d => '?').join(', ')})`, added);
}
async deleteOne(doctype, name) {
return await this.run(`delete from ${frappe.slug(doctype)} where name=?`, name);
}
async deleteChildren(parenttype, parent) {
await this.run(`delete from ${parent} where parent=?`, parent);
}
getAll({ doctype, fields, filters, start, limit, order_by = 'modified', order = 'desc' } = {}) {
if (!fields) {
fields = frappe.getMeta(doctype).getKeywordFields();
}
return new Promise((resolve, reject) => {
let conditions = this.getFilterConditions(filters);
this.conn.all(`select ${fields.join(", ")}
from ${frappe.slug(doctype)}
${conditions.conditions ? "where" : ""} ${conditions.conditions}
${order_by ? ("order by " + order_by) : ""} ${order_by ? (order || "asc") : ""}
${limit ? ("limit " + limit) : ""} ${start ? ("offset " + start) : ""}`, conditions.values,
(err, rows) => {
if (err) {
reject(err);
} else {
resolve(rows);
}
});
});
}
run(query, params) {
// TODO promisify
return new Promise((resolve, reject) => {
this.conn.query(query, params, (err) => {
if (err) {
if (debug) {
console.error(err);
}
reject(err);
} else {
resolve();
}
});
});
}
sql(query, params) {
return new Promise((resolve) => {
this.conn.query(query, params, (err, rows) => {
resolve(rows);
});
});
}
async commit() {
try {
await this.run('commit');
} catch (e) {
if (e.errno !== 1) {
throw e;
}
}
}
init_type_map() {
this.type_map = {
'Currency': 'real'
, 'Int': 'INT'
, 'Float': 'decimal(18,6)'
, 'Percent': 'real'
, 'Check': 'INT(1)'
, 'Small Text': 'text'
, 'Long Text': 'text'
, 'Code': 'text'
, 'Text Editor': 'text'
, 'Date': 'DATE'
, 'Datetime': 'DATETIME'
, 'Time': 'TIME'
, 'Text': 'text'
, 'Data': 'VARCHAR(140)'
, 'Link': ' varchar(140)'
, 'Dynamic Link': 'text'
, 'Password': 'varchar(140)'
, 'Select': 'VARCHAR(140)'
, 'Read Only': 'varchar(140)'
, 'Attach': 'text'
, 'Attach Image': 'text'
, 'Signature': 'text'
, 'Color': 'text'
, 'Barcode': 'text'
, 'Geolocation': 'text'
}
}
}

264
package-lock.json generated Normal file
View File

@ -0,0 +1,264 @@
{
"name": "frappejs",
"version": "0.0.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"balanced-match": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
"dev": true
},
"bignumber.js": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-4.0.4.tgz",
"integrity": "sha512-LDXpJKVzEx2/OqNbG9mXBNvHuiRL4PzHCGfnANHMJ+fv68Ads3exDVJeGDJws+AoNEuca93bU3q+S0woeUaCdg=="
},
"brace-expansion": {
"version": "1.1.8",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
"integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
"dev": true,
"requires": {
"balanced-match": "1.0.0",
"concat-map": "0.0.1"
}
},
"browser-stdout": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz",
"integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=",
"dev": true
},
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
"dev": true
},
"core-util-is": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
},
"debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"dev": true,
"requires": {
"ms": "2.0.0"
}
},
"diff": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz",
"integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==",
"dev": true
},
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
"dev": true
},
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
"dev": true
},
"glob": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
"integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
"dev": true,
"requires": {
"fs.realpath": "1.0.0",
"inflight": "1.0.6",
"inherits": "2.0.3",
"minimatch": "3.0.4",
"once": "1.4.0",
"path-is-absolute": "1.0.1"
}
},
"growl": {
"version": "1.10.3",
"resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz",
"integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==",
"dev": true
},
"has-flag": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
"integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
"dev": true
},
"he": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
"integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=",
"dev": true
},
"inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
"dev": true,
"requires": {
"once": "1.4.0",
"wrappy": "1.0.2"
}
},
"inherits": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
},
"isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
},
"minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"dev": true,
"requires": {
"brace-expansion": "1.1.8"
}
},
"minimist": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
"dev": true
},
"mkdirp": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
"dev": true,
"requires": {
"minimist": "0.0.8"
}
},
"mocha": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz",
"integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==",
"dev": true,
"requires": {
"browser-stdout": "1.3.0",
"commander": "2.11.0",
"debug": "3.1.0",
"diff": "3.3.1",
"escape-string-regexp": "1.0.5",
"glob": "7.1.2",
"growl": "1.10.3",
"he": "1.1.1",
"mkdirp": "0.5.1",
"supports-color": "4.4.0"
},
"dependencies": {
"commander": {
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz",
"integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==",
"dev": true
}
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
"dev": true
},
"mysql": {
"version": "2.15.0",
"resolved": "https://registry.npmjs.org/mysql/-/mysql-2.15.0.tgz",
"integrity": "sha512-C7tjzWtbN5nzkLIV+E8Crnl9bFyc7d3XJcBAvHKEVkjrYjogz3llo22q6s/hw+UcsE4/844pDob9ac+3dVjQSA==",
"requires": {
"bignumber.js": "4.0.4",
"readable-stream": "2.3.3",
"safe-buffer": "5.1.1",
"sqlstring": "2.3.0"
}
},
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"dev": true,
"requires": {
"wrappy": "1.0.2"
}
},
"path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
"dev": true
},
"process-nextick-args": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
"integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M="
},
"readable-stream": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
"integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
"requires": {
"core-util-is": "1.0.2",
"inherits": "2.0.3",
"isarray": "1.0.0",
"process-nextick-args": "1.0.7",
"safe-buffer": "5.1.1",
"string_decoder": "1.0.3",
"util-deprecate": "1.0.2"
}
},
"safe-buffer": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
"integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
},
"sqlstring": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.0.tgz",
"integrity": "sha1-UluKT9Jtb3GqYegipsr5dtMa0qg="
},
"string_decoder": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
"integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
"requires": {
"safe-buffer": "5.1.1"
}
},
"supports-color": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
"integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
"dev": true,
"requires": {
"has-flag": "2.0.0"
}
},
"util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
},
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
"dev": true
}
}
}

View File

@ -15,6 +15,7 @@
"commander": "^2.13.0",
"express": "^4.16.2",
"jquery": "^3.3.1",
"mysql": "^2.15.0",
"node-fetch": "^1.7.3",
"popper.js": "^1.12.9",
"sqlite3": "^3.1.13",
@ -38,7 +39,7 @@
"devDependencies": {
"autoprefixer": "^7.2.4",
"eslint": "^4.9.0",
"mocha": "^4.0.1",
"mocha": "^4.1.0",
"node-sass": "^4.7.2",
"nodemon": "^1.14.7",
"precss": "^2.0.0",

View File

@ -1,5 +1,6 @@
const backends = {};
backends.sqlite = require('frappejs/backends/sqlite');
backends.mysql = require('frappejs/backends/mysql');
const express = require('express');
const app = express();
@ -52,4 +53,3 @@ module.exports = {
await frappe.db.migrate();
},
}

View File

@ -0,0 +1,10 @@
const server = require('frappejs/server');
server.start({
backend: 'mysql',
connection_params: {
host : "test_frappejs",
username : "test_frappejs",
password : "test_frappejs",
db_name : "test_frappejs"
}
});