猫史档案馆


NomenSQLite:神岛首个多表格便携式轻量级协同管理器

用户:NomenNomen查看:50 回复:22 评论:50 创建时间:2023-05-08T08:42:50


大好我Nomen,为了扩充我的Box3-Tools仓库,突然想到Nomen SQL有着如此多的缺陷:体积冗大,效率低下,难以理解,不利于开发和二次开发,(才不是懒得写),所以我在此基础上(实际上是重写)写了一个Nomen SQL二代,即NomenSQLite

NomenSQLite由class管理,有着容易理解的API和一定的可扩展范围,最重要的是

它有着创新的协同管理系统,在节省资源的同时实现了多表格同时管理,互相不受到污染,并且快速启动,只需要简单的写一个对象,即可快速管理表格的结构,非常利于二次开发

这意味着所有的操作都超级方便!萌新也能理解!!

 

本体只有约90行,十分轻量

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 = null;
        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) {
        return (typeof cmd == 'string') ? db.sql([cmd]) : 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" && NomenSQLite.launched) return {
            select(column, value) {
                return t._exec(`SELECT * FROM "${name}" ${column == "*" ? `` : (`WHERE "${column}" = ` + `"${value}"`)}`)
            },
            remove(column, value) {
                return t._exec(`DELETE FROM "${name}" ${column == "*" ? `` : (`WHERE "${column}" = ` + `"${value}"`)}`)
            },
            insert(value) {
                if (Object.prototype.toString.call(value) == '[object Object]' && Object.keys(value).length) {
                    let eString = `(${Object.keys(value).map(v => `"${v}"`).join(',')}) VALUES(${Object.values(value).map(v => `"${v}"`).join(',')})`;
                    return t._exec(`INSERT INTO "${name}" ${eString}`);
                } 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 = [];
                    Object.entries(value).forEach(([k, v]) => eArr.push(`"${k}" = "${v}"`));
                    let aString = `${column == "*" ? "" : 'WHERE "' + column.split('=')[0] + '"="' + column.split('=')[1] + '"'}`;
                    console.log(`UPDATE "${name}" SET ${eArr} ${aString}`)
                    return t._exec(`UPDATE "${name}" SET ${eArr} ${aString}`);
                } 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'
    }
}

附有一段示例代码

const tablesData = {
    'Nomenawa': [ // 表格名字-数据[]
        { name: 'coin', type: NomenSQLite.DataType.NUMBER, notnull: true }, // 一个数据,名字为coin,类型为NUMBER,不得为null
        { name: 'bag', type: NomenSQLite.DataType.TEXT, notnull: false }
    ],
    'Nomenawa2': [ // 可以是第二个表格
        { name: 'coin2', type: NomenSQLite.DataType.NUMBER, notnull: true },
        { name: 'bag2', type: NomenSQLite.DataType.TEXT, notnull: false }
    ], // 这意味着你可以无限创建更多的表格!并且有着超级高的自由度
};


(async () => {
    let Nomen = await NomenSQLite.launch(tablesData,  // 容易理解和修改的表格数据结构,传入一个对象
        NomenSQLite.LaunchAction.CREATE_OR_LAUNCH,  // 启动的方式,CREATE_OR_LAUNCH意思是启动的时候初始化表格,LAUNCH表示仅启动
        (value, error) => { console.log(error) }  // 一个callback,如果出现错误就会从第二个参数传出来
    );

    let NomenTable = Nomen.operate('Nomenawa');  // 初始化Nomenawa这个表格的管理器

    await NomenTable.insert({ coin: 18, bag: 'a bag!3' });  // 插入一个键-值对对象作为数据
    await NomenTable.update('coin=18', { bag: 'a bag!114' })  // 更新这个数据,第一个参数需要是一个字符串
    console.log(JSON.stringify(await NomenTable.select('coin',18)))  // 获取coin为18的数据
    console.log(JSON.stringify(await NomenTable.select('*')))  // 获取该表格中所有的数据
    await NomenTable.remove('coin', 18)  // 删除coin为18的所有数据

    console.log(Nomen.getAllTables())  // 获取所有受到管理的表格
    console.log(await Nomen.getAllTablesInDatabase())  // 获取数据库中所有的表格(即使它不受到NomenSQLite管理)



    let Nomenawa2 = Nomen.operate('Nomenawa2');  // 更多的表格,更多的操作,即刻开始你的数据便捷开发之旅!
})()

赶紧开始你的SQL开发之旅吧!

------------------

Box3-Tools正在征集有意义、有参考价值的代码与片段!加入Nomen小队,获得大佬的帮助或帮助他人!


回复

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

照例抢沙发

点赞0


评论


神岛吉吉喵神岛吉吉喵

emotion_编程猫_厉害了

点赞2


评论


NysidlaNysidla

《萌新也能理解》

点赞1


评论


145a145a

我看不懂,但是我大受震撼

点赞0


评论


时光紫烟时光紫烟

前排

点赞0


评论


𝙲ℴ𝗌𝔦𝒹ₑ𝑟𝙲ℴ𝗌𝔦𝒹ₑ𝑟

我一直好奇为什么要用class()明明不需要实例sql啊()一个object充当一个模块不好吗( )

点赞0


评论


全能代码师全能代码师

给个寻路代码吧(滑跪ing)

点赞0


评论


PlumStevenPlumSteven

我大受震撼

(另外想起我搁置n年的tool还没开发完)

点赞1


评论


烟魂烟魂

直接帮你做一个GUI好吧

点赞0


评论


烟魂烟魂

发到仓库...快点啊

点赞0


评论


烟魂烟魂

你先不要加太多啊awa我都奔溃了...

我都写了5761行代码嘤嘤嘤

点赞0


评论


烟魂烟魂

。。。你都没拉取。。。:)你快来github拉取我的代码。。。

点赞0


评论


烟魂烟魂

好了嘛庫???

点赞0


评论


一个破名七个字一个破名七个字

我只能说…………*

点赞0


评论


Function函数Function函数

许久未见,甚是想念。可爱的Nomen,近来可好?

点赞3


评论


NomenNomen

神奇的引路人:
【萌新向:妈妈再也不用担心我不会写SQL辣】https://shequ.codemao.cn/community/539624
【 NomenSQLitePro1.0:表格字段自动更新 - 为开发者提供的便捷调试工具】https://shequ.codemao.cn/community/539869
【 NomenPostgre-Base:神岛首个PG数据库动态多表格轻量级便携式管理器】https://shequ.codemao.cn/community/539700

点赞1


评论


一只小枫鸽一只小枫鸽

神岛写代码有两种人,一种是根据API写代码的,还有一种是创造API的()

点赞1


评论


AokenAoken

收藏

点赞0


评论


de丨丨bugde丨丨bug

大佬这个怎么解决:https://shequ.codemao.cn/community/548352

点赞0


评论


𝙲ℴ𝗌𝔦𝒹ₑ𝑟𝙲ℴ𝗌𝔦𝒹ₑ𝑟

把sql变成js属于是

点赞0


评论


星蘑本尊星蘑本尊

好了标记一下emotion_编程猫_点赞

点赞0


评论


Ir摆烂的钿璎高品质男女时装Ir摆烂的钿璎高品质男女时装

emotion_编程猫_加油不错

点赞0


评论