2
0
mirror of https://github.com/frappe/books.git synced 2024-12-25 20:11:15 +00:00
books/backends/mysql.js

211 lines
6.3 KiB
JavaScript
Raw Normal View History

2018-02-07 06:27:37 +00:00
const frappe = require('frappejs');
const mysql = require('mysql');
const Database = require('./database');
2018-02-07 06:27:37 +00:00
const debug = false;
2018-02-13 07:26:25 +00:00
module.exports = class mysqlDatabase extends Database{
2018-02-07 06:27:37 +00:00
constructor({ db_name, username, password, host }) {
super();
2018-02-07 06:27:37 +00:00
this.db_name = db_name;
this.username = username;
this.password = password;
this.host = host;
this.init_typeMap();
2018-02-07 06:27:37 +00:00
}
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) {
2018-02-07 06:27:37 +00:00
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;
2018-02-07 06:27:37 +00:00
}
async runCreateTableQuery(doctype, columns, values){
const query = `CREATE TABLE IF NOT EXISTS ${doctype} (
2018-02-07 06:27:37 +00:00
${columns.join(", ")})`;
return await this.run(query, values);
}
2018-02-20 09:53:38 +00:00
updateColumnDefinition(df, columns, indexes) {
2018-03-26 12:18:07 +00:00
columns.push(`${df.fieldname} ${this.typeMap[df.fieldtype]} ${df.required && !df.default ? "not null" : ""} ${df.default ? `default '${df.default}'` : ""}`);
2018-02-07 06:27:37 +00:00
}
async getTableColumns(doctype) {
return (await this.sql(`SHOW COLUMNS FROM ${doctype}`)).map(d => d.Field);
2018-02-07 06:27:37 +00:00
}
2018-02-20 14:11:44 +00:00
async runAddColumnQuery(doctype, fields) {
await this.run(`ALTER TABLE ${doctype} ADD COLUMN ${this.get_column_definition(doctype)}`);
2018-02-07 06:27:37 +00:00
}
getOne(doctype, name, fields = '*') {
fields = this.prepareFields(fields);
2018-02-07 06:27:37 +00:00
return new Promise((resolve, reject) => {
this.conn.get(`select ${fields} from ${doctype}
2018-02-07 06:27:37 +00:00
where name = ?`, name,
(err, row) => {
resolve(row || {});
});
});
}
async insertOne(doctype, doc) {
2018-02-07 06:27:37 +00:00
let fields = this.get_keys(doctype);
let placeholders = fields.map(d => '?').join(', ');
if (!doc.name) {
2018-03-05 16:45:21 +00:00
doc.name = frappe.getRandomString();
2018-02-07 06:27:37 +00:00
}
return await this.run(`insert into ${doctype}
2018-02-07 06:27:37 +00:00
(${fields.map(field => field.fieldname).join(", ")})
values (${placeholders})`, this.getFormattedValues(fields, doc));
2018-02-07 06:27:37 +00:00
}
async updateOne(doctype, doc) {
let fields = this.getKeys(doctype);
2018-02-07 06:27:37 +00:00
let assigns = fields.map(field => `${field.fieldname} = ?`);
let values = this.getFormattedValues(fields, doc);
2018-02-07 06:27:37 +00:00
// additional name for where clause
values.push(doc.name);
return await this.run(`update ${doctype}
2018-02-07 06:27:37 +00:00
set ${assigns.join(", ")} where name=?`, values);
}
async runDeleteOtherChildren(field, added) {
await this.run(`delete from ${field.childtype}
where
parent = ? and
name not in (${added.slice(1).map(d => '?').join(', ')})`, added);
2018-02-07 06:27:37 +00:00
}
async deleteOne(doctype, name) {
return await this.run(`delete from ${doctype} where name=?`, name);
2018-02-07 06:27:37 +00:00
}
async deleteChildren(parenttype, parent) {
await this.run(`delete from ${parent} where parent=?`, parent);
2018-02-07 06:27:37 +00:00
}
getAll({ doctype, fields, filters, start, limit, order_by = 'modified', order = 'desc' } = {}) {
2018-02-07 06:27:37 +00:00
if (!fields) {
fields = frappe.getMeta(doctype).getKeywordFields();
2018-02-07 06:27:37 +00:00
}
return new Promise((resolve, reject) => {
let conditions = this.getFilterConditions(filters);
2018-02-07 06:27:37 +00:00
this.conn.all(`select ${fields.join(", ")}
from ${doctype}
2018-02-07 06:27:37 +00:00
${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_typeMap() {
this.typeMap = {
2019-10-26 14:46:34 +00:00
'AutoComplete': 'VARCHAR(140)'
2018-03-30 16:56:30 +00:00
, 'Currency': 'real'
2018-02-07 06:43:18 +00:00
, 'Int': 'INT'
, 'Float': 'decimal(18,6)'
2018-02-07 06:27:37 +00:00
, 'Percent': 'real'
2018-02-08 10:06:30 +00:00
, 'Check': 'INT(1)'
2018-02-07 06:27:37 +00:00
, '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)'
2018-03-27 04:20:42 +00:00
, 'DynamicLink': 'text'
2018-02-07 06:27:37 +00:00
, 'Password': 'varchar(140)'
, 'Select': 'VARCHAR(140)'
, 'Read Only': 'varchar(140)'
2018-03-29 18:51:24 +00:00
, 'File': 'text'
2018-02-07 06:27:37 +00:00
, 'Attach': 'text'
, 'Attach Image': 'text'
, 'Signature': 'text'
, 'Color': 'text'
, 'Barcode': 'text'
, 'Geolocation': 'text'
}
}
}