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

239 lines
5.6 KiB
JavaScript
Raw Normal View History

const frappe = require('frappe');
2018-02-07 06:27:37 +00:00
const mysql = require('mysql');
const Database = require('./database');
2018-02-07 06:27:37 +00:00
const debug = false;
module.exports = class mysqlDatabase 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_typeMap();
}
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));
2018-02-07 06:27:37 +00:00
}
};
resolve();
});
}
2018-02-07 06:27:37 +00:00
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 ${doctype} (
${columns.join(', ')})`;
return await this.run(query, values);
}
updateColumnDefinition(df, columns, indexes) {
columns.push(
`${df.fieldname} ${this.typeMap[df.fieldtype]} ${
df.required && !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 runAddColumnQuery(doctype, fields) {
await this.run(
`ALTER TABLE ${doctype} ADD COLUMN ${this.get_column_definition(doctype)}`
);
}
getOne(doctype, name, fields = '*') {
fields = this.prepareFields(fields);
return new Promise((resolve, reject) => {
this.conn.get(
`select ${fields} from ${doctype}
where name = ?`,
name,
(err, row) => {
resolve(row || {});
2018-02-07 06:27:37 +00:00
}
);
});
}
async insertOne(doctype, doc) {
let fields = this.get_keys(doctype);
let placeholders = fields.map((d) => '?').join(', ');
if (!doc.name) {
doc.name = frappe.getRandomString();
}
return await this.run(
`insert into ${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 ${doctype}
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
);
}
async deleteOne(doctype, name) {
return await this.run(`delete from ${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 ${doctype}
${conditions.conditions ? 'where' : ''} ${conditions.conditions}
${order_by ? 'order by ' + order_by : ''} ${
order_by ? order || 'asc' : ''
2018-02-07 06:27:37 +00:00
}
${limit ? 'limit ' + limit : ''} ${
start ? 'offset ' + start : ''
}`,
conditions.values,
(err, rows) => {
if (err) {
reject(err);
} else {
resolve(rows);
}
2018-02-07 06:27:37 +00:00
}
);
});
}
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 = {
AutoComplete: 'VARCHAR(140)',
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)',
DynamicLink: 'text',
Password: 'varchar(140)',
Select: 'VARCHAR(140)',
'Read Only': 'varchar(140)',
File: 'text',
Attach: 'text',
'Attach Image': 'text',
Signature: 'text',
Color: 'text',
Barcode: 'text',
Geolocation: 'text',
};
}
};