@dlovely/mysql
Version:
对mysql的简易连接,能创建数据库、数据表管理,并使用sql编辑器
17 lines (16 loc) • 8.19 kB
JavaScript
/*!
* @dlovely/mysql v1.1.0
* (c) 2023 MZ-Dlovely
* @license MIT
*/
"use strict";var e=require("node:path"),t=require("node:fs"),s=require("node:module"),a=require("mysql2/promise"),n=require("@dlovely/sql-editor"),i=require("@dlovely/utils"),o=require("node:fs/promises");
/* istanbul ignore file -- @preserve */
const r=process.cwd(),c=s.createRequire(r),h=e.join(r,".mysql");t.existsSync(h)&&t.rmSync(h,{recursive:!0,force:!0});const l=e.join(h,"types");t.mkdirSync(l,{recursive:!0});const _=e.join(h,"global.d.ts"),u=[[".json",function(e){return c(e)}],[".js",p],[".ts",p],[".cjs",p],[".mjs",p],[".cts",p],[".mts",p]],d={host:process.env.MYSQL_HOST||"localhost",port:Number(process.env.MYSQL_PORT||"3306"),user:process.env.MYSQL_USER||"localhost",password:process.env.MYSQL_AUTH};function p(e){const t=c(e);if(t.default){if("config"in t.default)return t.default;t.config=t.default,delete t.default}return t}
/* istanbul ignore file -- @preserve */const f=new class{changed=new Set;change(e){this.changed.has(e)&&this.changed.delete(e),this.changed.add(e),this._start()}_timer=null;_start(){this._timer||(this._timer=setTimeout((()=>{this._timer=null,this.save()}),0))}_stop(){this._timer&&(clearTimeout(this._timer),this._timer=null)}async _save(s){const a=e.dirname(s.path);t.existsSync(a)||await o.mkdir(a,{recursive:!0}),await o.writeFile(s.path,s.content,{flag:"w",encoding:"utf-8"})}save(){const e=[...this.changed];return this.changed.clear(),this._stop(),Promise.all(e.map((e=>this._save(e))))}};const y=new class{_global=new Set;get content(){return[...this._global].join("\n")}push(e){this._global.has(e)||(this._global.add(e),f.change(this))}remove(e){this._global.has(e)&&(this._global.delete(e),f.change(this))}path=_};new class{constructor(){const t="database.d.ts";this.path=e.join(l,t),this.reference=`/// <reference path="./types/${t}" />`}_database=new Map;_content_cache=new Map;get content(){const e=["declare namespace MySql {"," interface DataBase {"];for(const[t,s]of this._database){if(this._content_cache.has(t)){e.push(this._content_cache.get(t));continue}const a=[` ${t}: {`];for(const e of s)a.push(` ${e}: Table['${t}.${e}']`);a.push(" }");const n=a.join("\n");e.push(n),this._content_cache.set(t,n)}return e.push(" }","}"),e.join("\n")}load(e,t=[]){this._database.set(e,new Set(t)),f.change(this),y.push(this.reference)}drop(e){this._database.delete(e),this._content_cache.delete(e),f.change(this)}create(e,t){this._database.has(e)||this.load(e);const s=this._database.get(e);s.has(t)||(s.add(t),this._content_cache.delete(e),f.change(this))}delete(e,t){if(!this._database.has(e))return;const s=this._database.get(e);s.has(t)&&(s.delete(t),0===s.size?this.drop(e):(this._content_cache.delete(e),f.change(this)))}path;reference};class b{type;connection;constructor(e,t){this.type=e,this.connection=t}_active=!1;get active(){return this._active}async begin(){this._active||(await this.connection.beginTransaction(),this._active=!0)}
/* istanbul ignore next -- @preserve */async execute(e){if(!this._active)throw new Error("Transaction not begin");try{const{sql:t,params:s}=n.formatSql(e),a=await this.connection.execute(t,s);return i.isArray(a)?a[0]:a}catch(e){this._handleError(e),this._rollback(),await this.release()}}async commit(){if(!this._active)throw new Error("Transaction not begin");try{await this.connection.commit(),this._active=!1}catch(e){await this._handleError(e),await this._rollback()}finally{await this.release()}}_handleError=async function(e){console.error(e)};setHandleError(e){this._handleError=e.bind(this)}async release(){if(this._active)throw new Error("Transaction is active");"pool"===this.type?this.connection.release():await this.connection.end()}async _rollback(){this._active=!1,await this.connection.rollback()}async rollback(){if(!this._active)throw new Error("Transaction not begin");this._rollback(),await this.release()}}class m{type;config;options;json_key;constructor(){const{type:s,config:a,database:n,json_key:i}=(()=>{let s=null;for(const[a,n]of u){const i=e.join(r,`mysql.config${a}`);if(t.existsSync(i)){s=n(i);break}}return s?{...s,type:s.type||"pool",config:{...d,...s.config}}:{type:"pool",config:d}})();this.type=s,this.config=a,this.options=n,this._active_database=a.database,this.json_key=i}_active_database;get active_database(){return this._active_database}use(e){"connection"===this.type&&(this._active_database=e,this.config.database=e)}_pool;
/* istanbul ignore next -- @preserve */
async getConnection(){const{active_database:e}=this;if("pool"===this.type){this._pool||(this._pool=a.createPool(this.config));const t=await this._pool.getConnection(),s=()=>t.release();return{active_database:e,connection:t,release:s}}{const t=await a.createConnection(this.config),s=()=>t.end();return{active_database:e,connection:t,release:s}}}
/* istanbul ignore next -- @preserve */async execute(e,t){const{sql:s,params:a}=n.formatSql(e),{active_database:i,connection:o,release:r}=await this.getConnection();t&&t!==i&&await o.changeUser({database:t});const[c]=await o.execute(s,a);return r(),c}
/* istanbul ignore next -- @preserve */async transaction(){const{connection:e}=await this.getConnection();return new b(this.type,e)}}let g=null;const w=()=>(g||(g=new m),g);class T{left_table;left_key;right_table;right_key;join_type;constructor(e,t,s,a,n){if(this.left_table=e,this.left_key=t,this.right_table=s,this.right_key=a,this.join_type=n,e instanceof T&&e._used||s instanceof T&&s._used)throw new Error("JoinTable has been used");e instanceof T&&(e._used=!0),s instanceof T&&(s._used=!0)}_used=!1;get used(){return this._used}get name(){let{name:e}=this.left_table,{name:t}=this.right_table,s=this.left_key,a=this.right_key;return this.left_table instanceof T?e=`(${e})`:s=`${e}.${s}`,this.right_table instanceof T?t=`(${t})`:a=`${t}.${a}`,`${e} ${this.join_type} JOIN ${t} ON ${s}=${a}`}join(e,t,s,a=exports.JoinType.INNER){return new T(this,s,e,t,a)}leftJoin(e,t,s){return this.join(e,t,s,exports.JoinType.LEFT)}rightJoin(e,t,s){return this.join(e,t,s,exports.JoinType.RIGHT)}fullJoin(e,t,s){return this.join(e,t,s,exports.JoinType.FULL)}async select(e,t,s={}){const a=w(),i=n.formatJoinSelect({...s,table:this.name,columns:e,where:t});return await a.execute(i)}get __showTCR(){return null}}var v;exports.JoinType=void 0,(v=exports.JoinType||(exports.JoinType={})).INNER="INNER",v.LEFT="LEFT",v.RIGHT="RIGHT",v.FULL="FULL";exports.DataBase=class{name;constructor(e){this.name=e}
/* istanbul ignore next -- @preserve */
async setConfig({charset:e="utf8mb4",collate:t="utf8mb4_general_ci"}){const s=w();return await s.execute({sql:"ALTER DATABASE ? CHARACTER SET ? COLLATE ?",params:[this.name,e,t]})}async create(e={}){const t=w(),s=n.formatCreateDatabase({name:this.name,...e});return await t.execute(s)}async drop(){const e=w();return await e.execute({sql:"DROP DATABASE IF EXISTS ?",params:[this.name]})}},exports.JoinTable=T,exports.Table=class{database;name;constructor(e,t){this.database=e,this.name=t,this._json_keys=new Map}_json_keys;async insert(...e){const t=w(),s=n.formatInsert({table:this.name,datas:e,json_key:this._json_keys});return await t.execute(s,this.database)}delete(e){const t=w(),s=n.formatDelete({table:this.name,where:e});return t.execute(s,this.database)}update(e,t){const s=w(),a=n.formatUpdate({table:this.name,data:e,where:t,json_key:this._json_keys});return s.execute(a,this.database)}select(e,t,s={}){const a=w(),i=n.formatSelect({...s,table:this.name,columns:e,where:t});return a.execute(i,this.database)}join(e,t,s,a=exports.JoinType.INNER){return new T(this,s,e,t,a)}leftJoin(e,t,s){return this.join(e,t,s,exports.JoinType.LEFT)}rightJoin(e,t,s){return this.join(e,t,s,exports.JoinType.RIGHT)}fullJoin(e,t,s){return this.join(e,t,s,exports.JoinType.FULL)}async create(e,t={}){const s=w(),a=n.formatCreateTable({...t,database:this.database,name:this.name,columns:e});return await s.execute(a,this.database)}async truncate(){const e=w(),t=`TRUNCATE TABLE ${this.name}`;return await e.execute(t,this.database)}async drop(){const e=w(),t=`DROP TABLE ${this.name}`;return await e.execute(t,this.database)}},exports.defineMysqlConfig=e=>e,exports.useServer=w;