猫史档案馆


NomenSQLite 1.2.0 - 支持二进制,注入防护,高效转换的轻量级SQL多表格管理助手

用户:NomenNomen查看:1 回复:2 评论:1 创建时间:2023-05-16T12:34:40


这里是没有开场白的Nomen;

这一次的NomenSQLite更新将会更新在Box3-Tools仓库中,同时,我也正在编写Nomen大家族工具包Gitbook(

这一次更新的内容如下:

增强注入防护,增加了对大部分数据结构的支持,修复一些历史遗留问题

该版本为开发版,较不稳定,建议仅有SQL基础的开发者使用

API变更:

1. _exec可以在第一个函数中为防注入或非字符串数据结构的环节替换为字符"?"(nodejs人狂喜),请注意,_exec不会处理双引号内的问号,第二个参数传入一个数组,则是这一些问号的替换值

2. operate不再强制要求初始化,你可以跳过初始化(仅限如果你对于性能十分执着并且认为你的代码流程化非常好,不需要初始化)

3. update第一参数为一个字符串表达式,表达式右侧的值会受到处理

4. launch第三参数回调函数的第二参数返回的报错信息静默默认值更改为空字符串

class NomenSQLite {
    constructor() {
        if (NomenSQLite.instance) return NomenSQLite.instance;
        NomenSQLite.instance = this;
    }
    static launched = false;
    static async launch(config, action, callback) {
        if (!config) throw new Error('请传入配置参数后重试');
        if (!this.instance) this.instance = new NomenSQLite();
        else return this.instance;
        this.tables = config || {};
        this._data = {};
        if (!Object.keys(this.tables).length) this._data = null;
        Object.keys(this.tables).forEach(v => {
            if (Array.isArray(this.tables[v]) && this.tables[v].length) {
                this._data[v] = [];
                this.tables[v].forEach(r => {
                    if (typeof r.name == "string" && Object.values(this.DataType).includes(r.type)) {
                        this._data[v].push({ name: r.name, type: r.type, notnull: r.notnull || false });
                    }
                })
            }
        })
        console.log(JSON.stringify(this._data));
        if (!Object.keys(this._data).length) return this.instance;
        let errMessage = '';
        if (typeof action == "string" && action.includes('create')) {
            for (let i = 0; i < Object.keys(this._data).length; i++) {
                let eString = `CREATE TABLE IF NOT EXISTS "${Object.keys(this._data)[i]}" 
                (${this._data[Object.keys(this._data)[i]].reduce((p, c) => {
                    let str = `"${c.name}" ${c.type} ${c.notnull ? 'NOT NULL' : ''}`;
                    return p ? p.concat(',', str) : str;
                }, false)})`;
                try { await this.instance._exec(eString); } catch (err) {
                    errMessage.concat(err);
                }
            }
        }
        this.launched = true;
        if (typeof callback == "function") callback(null, errMessage);
        return this.instance;
    }
    _exec(cmd, p) {
        return (typeof cmd == 'string') ? db.sql.apply(null, [cmd.split(/(?<!\\)[\?](?=(?:[^"]*"[^"]*")*[^"]*$)/g), ...(p ? p : [])]) : new Promise(resolve => resolve(new TypeError('传入参数有误,预期应该为string')))
    }
    getAllTables() {
        return Object.keys(NomenSQLite._data);
    }
    async getAllTablesInDatabase() {
        return (await this._exec(`SELECT * FROM sqlite_master`)).map(v => v.name)
    }
    operate(name) {
        let t = this;
        if (typeof name == "string") return {
            select(column, value) {
                let p = [];
                return t._exec(`SELECT * FROM "${name}" ${column == "*" ? `` : (`WHERE "${column}" = ` + (p.push(value), "?"))}`, p)
            },
            remove(column, value) {
                let p=[];
                return t._exec(`DELETE FROM "${name}" ${column == "*" ? `` : (`WHERE "${column}" = ` + (p.push(value),'?'))}`,p)
            },
            insert(value) {
                if (Object.prototype.toString.call(value) == '[object Object]' && Object.keys(value).length) {
                    let p = [];
                    let eString = `(${Object.keys(value).map(v => `"${v}"`).join(',')}) VALUES(${Object.values(value).map(v => { p.push(v); return `?`; }).join(',')})`;
                    return t._exec(`INSERT INTO "${name}" ${eString}`, p);
                } else return null;
            },
            update(column, value) {
                if (Object.prototype.toString.call(value) == '[object Object]' && Object.keys(value).length && typeof column == "string" && column.includes('=')) {
                    let eArr = [], p = [];
                    Object.entries(value).forEach(([k, v]) => eArr.push(`"${k}" = ${(p.push(v),'?')}`));
                    let aString = `${column == "*" ? "" : 'WHERE "' + column.split('=')[0] + '"=' + (p.push(column.split('=')[1]),'?')}`;
                    console.log(`UPDATE "${name}" SET ${eArr} ${aString}`)
                    return t._exec(`UPDATE "${name}" SET ${eArr} ${aString}`,p);
                } else return null;
            }
        }
        return {};
    }
    static instance = null;
    static LaunchAction = {
        CREATE_OR_LAUNCH: 'createlaunch',
        LAUNCH: 'launch'
    }
    static DataType = {
        NUMBER: 'INTEGER',
        FLOAT: 'REAL',
        TEXT: 'TEXT',
        NULL: 'NULL',
        BLOB: 'BLOB'
    }
}

--

奇怪的预告:NomenFileSystem即将上限,这是一个基于SQL的文件管理系统,拥有着目录,文件夹,文件等操作(fs人狂喜(?)


回复

上一页1 页 / 共 1下一页
NomenNomen

照例沙发

点赞1


评论


SCS_user_LoeheodVOQSCS_user_LoeheodVOQ

fs还能更改创建文件?

点赞0


评论