ueberdb2 4.1.23 → 4.1.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cassandra_db.d.ts +1 -0
- package/dist/couch_db.d.ts +1 -0
- package/dist/databases/cassandra_db.cjs +1 -0
- package/dist/databases/couch_db.cjs +1 -0
- package/dist/databases/dirty_db.cjs +1 -0
- package/dist/databases/dirty_git_db.cjs +1 -0
- package/dist/databases/elasticsearch_db.cjs +1 -0
- package/dist/databases/memory_db.cjs +1 -0
- package/dist/databases/mock_db.cjs +1 -0
- package/dist/databases/mongodb_db.cjs +1 -0
- package/dist/databases/mssql_db.cjs +5 -0
- package/dist/databases/mysql_db.cjs +1 -0
- package/dist/databases/postgres_db.cjs +1 -0
- package/dist/databases/postgrespool_db.cjs +1 -0
- package/dist/databases/redis_db.cjs +1 -0
- package/dist/databases/rethink_db.cjs +1 -0
- package/dist/databases/sqlite_db.cjs +4 -0
- package/dist/dirty_db.d.ts +1 -0
- package/dist/dirty_git_db.d.ts +1 -0
- package/dist/elasticsearch_db.d.ts +1 -0
- package/dist/index.d.ts +85 -0
- package/dist/lib/AbstractDatabase.cjs +1 -0
- package/dist/lib/CacheAndBufferLayer.cjs +1 -0
- package/dist/lib/logging.cjs +1 -0
- package/dist/memory_db.d.ts +1 -0
- package/dist/mock_db.d.ts +1 -0
- package/dist/mongodb_db.d.ts +1 -0
- package/dist/mssql_db.d.ts +1 -0
- package/dist/mysql_db.d.ts +1 -0
- package/dist/postgres_db.d.ts +1 -0
- package/dist/postgrespool_db.d.ts +1 -0
- package/dist/redis_db.d.ts +1 -0
- package/dist/rethink_db.d.ts +1 -0
- package/dist/sqlite_db.d.ts +1 -0
- package/package.json +6 -5
- package/dist/databases/cassandra_db.js +0 -235
- package/dist/databases/couch_db.js +0 -173
- package/dist/databases/dirty_db.js +0 -75
- package/dist/databases/dirty_git_db.js +0 -59
- package/dist/databases/elasticsearch_db.js +0 -243
- package/dist/databases/memory_db.js +0 -37
- package/dist/databases/mock_db.js +0 -41
- package/dist/databases/mongodb_db.js +0 -134
- package/dist/databases/mssql_db.js +0 -185
- package/dist/databases/mysql_db.js +0 -167
- package/dist/databases/postgres_db.js +0 -190
- package/dist/databases/postgrespool_db.js +0 -12
- package/dist/databases/redis_db.js +0 -120
- package/dist/databases/rethink_db.js +0 -121
- package/dist/databases/sqlite_db.js +0 -138
- package/dist/index.js +0 -193
- package/dist/lib/AbstractDatabase.js +0 -40
- package/dist/lib/CacheAndBufferLayer.js +0 -658
- package/dist/lib/logging.js +0 -27
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './databases/cassandra_db'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './databases/couch_db'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var y=Object.defineProperty;var m=(o,r,e)=>r in o?y(o,r,{enumerable:!0,configurable:!0,writable:!0,value:e}):o[r]=e;var h=(o,r,e)=>(m(o,typeof r!="symbol"?r+"":r,e),e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const E=require("../lib/AbstractDatabase.cjs"),d=require("../node_modules/cassandra-driver/index.cjs"),f=class extends E{constructor(e){super();h(this,"client");h(this,"pool");if(!e.clientOptions)throw new Error("The Cassandra client options should be defined");if(!e.columnFamily)throw new Error("The Cassandra column family should be defined");this.settings={database:e.database},this.settings.clientOptions=e.clientOptions,this.settings.columnFamily=e.columnFamily,this.settings.logger=e.logger}init(e){this.client=new d.Client(this.settings.clientOptions),this.settings.logger&&this.client.on("log",this.settings.logger),this.client.execute("SELECT columnfamily_name FROM system.schema_columnfamilies WHERE keyspace_name = ?",[this.settings.clientOptions.keyspace],(i,t)=>{if(i)return e(i);let s=!1;const n=t.rows.length;for(let l=0;l<n;l++)if(t.rows[l].columnfamily_name===this.settings.columnFamily){s=!0;break}if(s)return e(null);{const l=`CREATE COLUMNFAMILY "${this.settings.columnFamily}" (key text PRIMARY KEY, data text)`;this.client&&this.client.execute(l,e)}})}get(e,i){const t=`SELECT data FROM "${this.settings.columnFamily}" WHERE key = ?`;this.client&&this.client.execute(t,[e],(s,n)=>s?i(s):!n.rows||n.rows.length===0?i(null,null):i(null,n.rows[0].data))}findKeys(e,i,t){let s=null;if(!i)s=`SELECT key FROM "${this.settings.columnFamily}"`,this.client&&this.client.execute(s,(n,l)=>{if(n)return t(n);const u=new RegExp(`^${e.replace(/\*/g,".*")}$`),a=[];return l.rows.forEach(c=>{u.test(c.key)&&a.push(c.key)}),t(null,a)});else if(i==="*:*:*"){const n=/^([^:]+):\*$/.exec(e);if(n)s=`SELECT * from "${this.settings.columnFamily}" WHERE key = ?`,this.client&&this.client.execute(s,[`ueberdb:keys:${n[1]}`],(l,u)=>{if(l)return t(l);if(!u.rows||u.rows.length===0)return t(null,[]);const a=u.rows.map(c=>c.data);return t(null,a)});else{const l="Cassandra db only supports key patterns like pad:* when notKey is set to *:*:*";return t(new Error(l),null)}}else return t(new Error("Cassandra db currently only supports *:*:* as notKey"),null)}set(e,i,t){this.doBulk([{type:"set",key:e,value:i}],t)}remove(e,i){this.doBulk([{type:"remove",key:e}],i)}doBulk(e,i){const t=[];e.forEach(s=>{const n=/^([^:]+):([^:]+)$/.exec(s.key);s.type==="set"?(t.push({query:`UPDATE "${this.settings.columnFamily}" SET data = ? WHERE key = ?`,params:[s.value,s.key]}),n&&t.push({query:`UPDATE "${this.settings.columnFamily}" SET data = ? WHERE key = ?`,params:["1",`ueberdb:keys:${n[1]}`]})):s.type==="remove"&&(t.push({query:`DELETE FROM "${this.settings.columnFamily}" WHERE key=?`,params:[s.key]}),n&&t.push({query:`DELETE FROM "${this.settings.columnFamily}" WHERE key = ?`,params:[`ueberdb:keys:${n[1]}`]}))}),this.client&&this.client.batch(t,{prepare:!0},i)}close(e){this.pool.shutdown(e)}};exports.Database=f;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var u=Object.defineProperty;var c=(o,n,t)=>n in o?u(o,n,{enumerable:!0,configurable:!0,writable:!0,value:t}):o[n]=t;var d=(o,n,t)=>(c(o,typeof n!="symbol"?n+"":n,t),t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const h=require("../lib/AbstractDatabase.cjs"),l=require("../_virtual/__vite-browser-external.cjs"),g=require("../node_modules/nano/lib/nano.cjs"),f=class extends h{constructor(t){super();d(this,"agent");d(this,"db");this.agent=null,this.db=null,this.settings=t,this.settings.cache=1e3,this.settings.writeInterval=100,this.settings.json=!1}get isAsync(){return!0}async init(){this.agent=new l.Agent({keepAlive:!0,maxSockets:this.settings.maxListeners||1});const t={url:`http://${this.settings.host}:${this.settings.port}`,requestDefaults:{agent:this.agent}};this.settings.user&&this.settings.password&&(t.requestDefaults.auth={username:this.settings.user,password:this.settings.password});const s=g(t);try{await s.db.get(this.settings.database)}catch(e){if(e.statusCode!==404)throw e;await s.db.create(this.settings.database)}this.db=s.use(this.settings.database)}async get(t){let s;try{this.db&&(s=await this.db.get(t))}catch(e){if(e.statusCode===404)return null;throw e}return s&&"value"in s?s.value:""}async findKeys(t,s){const e=t.indexOf("*");if(!this.db)return;const i=e<0?t:t.slice(0,e);return(await this.db.find({selector:{_id:e<0?i:{$gte:i,$lte:`${i}`,$regex:this.createFindRegex(t,s).source}},fields:["_id"]})).docs.map(r=>r._id)}async set(t,s){let e;if(this.db){try{e=await this.db.get(t)}catch(i){if(i.statusCode!==404)throw i}await this.db.insert({_id:t,value:s,...e==null?{}:{_rev:e._rev}})}}async remove(t){let s;if(!this.db)return;try{s=await this.db.head(t)}catch(i){if(i.statusCode===404)return;throw i}const e=JSON.parse(s.etag);await this.db.destroy(t,e)}async doBulk(t){if(!this.db)return;const s=t.map(a=>a.key),e={};for(const{key:a,value:r}of(await this.db.fetchRevs({keys:s})).rows)r!=null&&(e[a]=r.rev);const i=[];for(const a of t){const r={_id:a.key,_rev:void 0,_deleted:!1,value:""};e[a.key]!=null&&(r._rev=e[a.key]),a.type==="set"&&(r.value=a.value),a.type==="remove"&&(r._deleted=!0),i.push(r)}await this.db.bulk({docs:i})}async close(){this.db=null,this.agent&&this.agent.destroy(),this.agent=null}};exports.Database=f;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var h=Object.defineProperty;var d=(s,e,t)=>e in s?h(s,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):s[e]=t;var l=(s,e,t)=>(d(s,typeof e!="symbol"?e+"":e,t),t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("../lib/AbstractDatabase.cjs"),c=require("../node_modules/dirty/lib/dirty/index.cjs"),b=class extends o{constructor(e){super();l(this,"db");this.db=null,(!e||!e.filename)&&(e={filename:null}),this.settings=e,this.settings.cache=0,this.settings.writeInterval=0,this.settings.json=!1}init(e){this.db=new c.default(this.settings.filename),this.db.on("load",t=>{e()})}get(e,t){t(null,this.db.get(e))}findKeys(e,t,i){const n=[],r=this.createFindRegex(e,t);this.db.forEach((a,u)=>{a.search(r)!==-1&&n.push(a)}),i(null,n)}set(e,t,i){this.db.set(e,t,i)}remove(e,t){this.db.rm(e,t)}close(e){this.db.close(),this.db=null,e&&e()}};exports.Database=b;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var d=Object.defineProperty;var c=(s,t,e)=>t in s?d(s,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):s[t]=e;var a=(s,t,e)=>(c(s,typeof t!="symbol"?t+"":t,e),e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const h=require("../lib/AbstractDatabase.cjs"),l=require("../node_modules/dirty/lib/dirty/index.cjs"),u=class extends h{constructor(t){super();a(this,"db");this.db=null,(!t||!t.filename)&&(t={}),this.settings=t,this.settings.cache=0,this.settings.writeInterval=0,this.settings.json=!1}init(t){this.db=new l.dirty.Dirty(this.settings.filename),this.db.on("load",e=>{t()})}get(t,e){e(null,this.db.get(t))}findKeys(t,e,r){const i=[],o=this.createFindRegex(t,e);this.db.forEach((n,b)=>{n.search(o)!==-1&&i.push(n)}),r(null,i)}set(t,e,r){this.db.set(t,e,r);const i=require("path").dirname(this.settings.filename);require("simple-git")(i).silent(!0).add("./*.db").commit("Automated commit...").push(["-u","origin","master"],()=>console.debug("Stored git commit"))}remove(t,e){this.db.rm(t,e)}close(t){this.db.close(),t&&t()}};exports.Database=u;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var q=Object.defineProperty;var k=(i,e,t)=>e in i?q(i,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):i[e]=t;var l=(i,e,t)=>(k(i,typeof e!="symbol"?e+"":e,t),t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const v=require("../lib/AbstractDatabase.cjs"),w=require("assert");require("../node_modules/buffer/index.cjs");const C=require("crypto"),M=require("../node_modules/elasticsearch8/index.cjs"),S=require("../_virtual/index3.cjs"),j="2",c=i=>{const e=S.__exports.Buffer.from(i);return e.length>512?C.createHash("sha512").update(e).digest("hex"):i},y={properties:{key:{type:"wildcard"},value:{type:"object",enabled:!1}}},D=async(i,e,t,s)=>{let n=0,r=0;const f=new Map;s.info(`Attempting elasticsearch record migration from schema v1 at base index ${e} to schema v2 at index ${t}...`);const $=await i.indices.get({index:[e,`${e}-*-*`]}),u=new Map,d=[];try{for(const a of Object.keys($)){const o=await i.search({index:a,scroll:"10m"});u.set(a,o._scroll_id),d.push({index:a,res:o})}for(;d.length;){const{index:a,res:{hits:{hits:o,total:{value:b}}}}=d.shift();if(o.length===0)continue;f.set(a,b);const m=[];for(const{_id:h,_type:_,_source:{val:x}}of o){let g=`${_}:${h}`;if(e&&a!==e){const p=a.slice(e.length+1).split("-");if(p.length!==2)throw new Error(`unable to migrate records from index ${a} due to data ambiguity`);g=`${p[0]}:${decodeURIComponent(_)}:${p[1]}:${h}`}m.push({index:{_id:c(g)}},{key:g,value:JSON.parse(x)})}if(await i.bulk({index:t,body:m}),r+=o.length,Math.floor(r/100)>Math.floor(n/100)){const h=[...f.values()].reduce((_,x)=>_+x,0);s.info(`Migrated ${r} records out of ${h}`),n=r}d.push({index:a,res:await i.scroll({scroll:"5m",scroll_id:u.get(a)})})}s.info(`Finished migrating ${r} records`)}finally{await Promise.all([...u.values()].map(a=>i.clearScroll({scroll_id:a})))}},A=class extends v{constructor(e){super();l(this,"_client");l(this,"_index");l(this,"_indexClean");l(this,"_q");this._client=null,this.settings={host:"127.0.0.1",port:"9200",base_index:"ueberes",migrate_to_newer_schema:!1,api:"7.6",...e||{},json:!1},this._index=`${this.settings.base_index}_s${j}`,this._q={index:this._index},this._indexClean=!0}get isAsync(){return!0}async _refreshIndex(){this._indexClean||(this._indexClean=!0,await this._client.indices.refresh(this._q))}async init(){const e=new M.elasticsearch8.Client({node:`http://${this.settings.host}:${this.settings.port}`});if(await e.ping(),!await e.indices.exists({index:this._index})){let s;const n=await e.indices.exists({index:this.settings.base_index});if(n&&!this.settings.migrate_to_newer_schema)throw new Error(`Data exists under the legacy index (schema) named ${this.settings.base_index}. Set migrate_to_newer_schema to true to copy the existing data to a new index named ${this._index}.`);let r=0;for(;s=`${this._index}_${n?"migrate_attempt_":"i"}${r++}`,!!await e.indices.exists({index:s}););await e.indices.create({index:s,mappings:y}),n&&await D(e,this.settings.base_index,s,this.logger),await e.indices.putAlias({index:s,name:this._index})}const t=Object.values(await e.indices.get({index:this._index}));w.equal(t.length,1);try{w.deepEqual(t[0].mappings,y)}catch(s){this.logger.warn(`Index ${this._index} mappings does not match expected; attempting to use index anyway. Details: ${s}`)}this._client=e}async get(e){const t=await this._client.get({...this._q,id:c(e)},{ignore:[404]});return t.found?t._source.value:null}async findKeys(e,t){await this._refreshIndex();const s={...this._q,body:{query:{bool:{filter:{wildcard:{key:{value:e}}},...t==null?{}:{must_not:{wildcard:{key:{value:t}}}}}}}},{hits:n}=await this._client.search(s);return n.hits.map(r=>r._source.key)}async set(e,t){this._indexClean=!1,await this._client.index({...this._q,id:c(e),body:{key:e,value:t}})}async remove(e){this._indexClean=!1,await this._client.delete({...this._q,id:c(e)},{ignore:[404]})}async doBulk(e){const t=[];for(const{type:s,key:n,value:r}of e)switch(this._indexClean=!1,s){case"set":t.push({index:{_id:c(n)}}),t.push({key:n,value:r});break;case"remove":t.push({delete:{_id:c(n)}});break}await this._client.bulk({...this._q,body:t})}async close(){this._client!=null&&this._client.close(),this._client=null}};exports.Database=A;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var d=Object.defineProperty;var c=(a,e,t)=>e in a?d(a,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):a[e]=t;var r=(a,e,t)=>(c(a,typeof e!="symbol"?e+"":e,t),t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const l=require("../lib/AbstractDatabase.cjs"),o=class extends l{constructor(t){super();r(this,"_data");this.settings=t,t.json=!1,t.cache=0,t.writeInterval=0,this._data=null}get isAsync(){return!0}close(){this._data=null}findKeys(t,s){const i=this.createFindRegex(t,s);return[...this._data.keys()].filter(n=>i.test(n))}get(t){return this._data.get(t)}init(){this._data=this.settings.data||new Map}remove(t){this._data.delete(t)}set(t,s){this._data.set(t,s)}};exports.Database=o;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var n=Object.defineProperty;var r=(i,t,e)=>t in i?n(i,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):i[t]=e;var o=(i,t,e)=>(r(i,typeof t!="symbol"?t+"":t,e),e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("../node_modules/events/events.cjs"),c=class extends a.default.EventEmitter{constructor(t){super();o(this,"settings");o(this,"mock");this.settings={writeInterval:1,...t},t.mock=this,this.settings=t,console.log("Initialized")}close(t){this.emit("close",t)}doBulk(t,e){this.emit("doBulk",t,e)}findKeys(t,e,s){this.emit("findKeys",t,e,s)}get(t,e){this.emit("get",t,e)}async init(t){this.emit("init",t())}remove(t,e){this.emit("remove",t,e)}set(t,e,s){this.emit("set",t,e,s)}};exports.Database=c;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var c=Object.defineProperty;var h=(n,e,t)=>e in n?c(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t;var o=(n,e,t)=>(h(n,typeof e!="symbol"?e+"":e,t),t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("../lib/AbstractDatabase.cjs");require("../node_modules/mongodb/lib/index.cjs");const r=require("../_virtual/index2.cjs"),d=class extends a{constructor(e){super();o(this,"interval");o(this,"database");o(this,"client");o(this,"collection");if(this.settings=e,!this.settings.url)throw new Error("You must specify a mongodb url");this.settings.database==null&&(this.settings.database=this.settings.dbName),this.settings.collection||(this.settings.collection="ueberdb")}clearPing(){this.interval&&clearInterval(this.interval[Symbol.toPrimitive]())}schedulePing(){this.clearPing(),this.interval=setInterval(()=>{this.database.command({ping:1})},1e4)}init(e){r.__exports.MongoClient.connect(this.settings.url).then(t=>{this.client=t,this.database=t.db(this.settings.database),this.collection=this.database.collection(this.settings.collection),e(null)}).catch(t=>{e(t)}),this.schedulePing()}get(e,t){this.collection.findOne({_id:e}).then(i=>{t(null,i&&i.value)}).catch(i=>{console.log(i),t(i)}),this.schedulePing()}findKeys(e,t,i){const s={$and:[{_id:{$regex:`${e.replace(/\*/g,"")}`}}]};t&&s.$and.push({_id:{$not:{$regex:`${t.replace(/\*/g,"")}`}}}),this.collection.find(s).map(l=>l._id).toArray().then(l=>{i(null,l)}).catch(l=>i(l)),this.schedulePing()}set(e,t,i){e.length>100?i("Your Key can only be 100 chars"):this.collection.updateMany({_id:e},{$set:{value:t}},{upsert:!0}).then(()=>i(null)).catch(s=>i(s)),this.schedulePing()}remove(e,t){this.collection.deleteOne({_id:e}).then(i=>t(null,i)).catch(i=>t(i)),this.schedulePing()}doBulk(e,t){const i=this.collection.initializeOrderedBulkOp();for(const s in e)e[s].type==="set"?i.find({_id:e[s].key}).upsert().updateOne({$set:{value:e[s].value}}):e[s].type==="remove"&&i.find({_id:e[s].key}).deleteOne();i.execute().then(s=>{t(null,s)}).catch(s=>{t(s)}),this.schedulePing()}close(e){this.clearPing(),this.client.close().then(t=>e(t))}};exports.Database=d;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";var h=Object.defineProperty;var R=(T,N,e)=>N in T?h(T,N,{enumerable:!0,configurable:!0,writable:!0,value:e}):T[N]=e;var y=(T,N,e)=>(R(T,typeof N!="symbol"?N+"":N,e),e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const f=require("../lib/AbstractDatabase.cjs"),v=require("../node_modules/async/dist/async.cjs"),u=require("../node_modules/mssql/index.cjs"),A=class extends f{constructor(e){super();y(this,"db");e=e||{},e.json!=null&&(e.parseJSON=e.json),e.requestTimeout=3e5,e.server=e.host,this.settings=e,this.settings.cache=0,this.settings.writeInterval=0}init(e){const r="IF OBJECT_ID(N'dbo.store', N'U') IS NULL BEGIN CREATE TABLE [store] ( [key] NVARCHAR(100) PRIMARY KEY, [value] NTEXT NOT NULL ); END";new u.ConnectionPool(this.settings).connect().then(n=>{this.db=n,new u.Request(this.db).query(r,s=>{e(s)}),this.db.on("error",s=>{console.log(s)})})}get(e,r){const n=new u.Request(this.db);n.input("key",u.NVarChar(100),e),n.query("SELECT [value] FROM [store] WHERE [key] = @key",(o,s)=>{let E=null;!o&&s&&s.rowsAffected[0]===1&&(E=s.recordset[0].value),r(o,E)})}findKeys(e,r,n){const o=new u.Request(this.db);let s="SELECT [key] FROM [store] WHERE [key] LIKE @key";e=e.replace(/\*/g,"%"),o.input("key",u.NVarChar(100),e),r!=null&&(r=r.replace(/\*/g,"%"),o.input("notkey",u.NVarChar(100),r),s+=" AND [key] NOT LIKE @notkey"),o.query(s,(E,a)=>{const i=[];if(!E&&a&&a.rowsAffected[0]>0)for(let t=0;t<a.recordset.length;t++)i.push(a.recordset[t].key);n(E,i)})}set(e,r,n){const o=new u.Request(this.db);if(e.length>100)n("Your Key can only be 100 chars");else{const s="MERGE [store] t USING (SELECT @key [key], @value [value]) s ON t.[key] = s.[key] WHEN MATCHED AND s.[value] IS NOT NULL THEN UPDATE SET t.[value] = s.[value] WHEN NOT MATCHED THEN INSERT ([key], [value]) VALUES (s.[key], s.[value]);";o.input("key",u.NVarChar(100),e),o.input("value",u.NText,r),o.query(s,(E,a)=>{n(E?E.toString():"")})}}remove(e,r){const n=new u.Request(this.db);n.input("key",u.NVarChar(100),e),n.query("DELETE FROM [store] WHERE [key] = @key",r)}doBulk(e,r){const o=new u.Request(this.db);let s=!0,E=!0;const a=[];let i="DELETE FROM [store] WHERE [key] IN (";for(const t in e)e[t].type==="set"?(s?(a.push("BEGIN TRANSACTION;"),s=!1):Number(t)%100===0&&a.push(`
|
|
2
|
+
COMMIT TRANSACTION;
|
|
3
|
+
BEGIN TRANSACTION;
|
|
4
|
+
`),a.push(`MERGE [store] t USING (SELECT '${e[t].key}' [key], '${e[t].value}' [value]) s`,"ON t.[key] = s.[key]","WHEN MATCHED AND s.[value] IS NOT NULL THEN UPDATE SET t.[value] = s.[value]","WHEN NOT MATCHED THEN INSERT ([key], [value]) VALUES (s.[key], s.[value]);")):e[t].type==="remove"&&(E||(i+=","),E=!1,i+=`'${e[t].key}'`);i+=");",a.push("COMMIT TRANSACTION;"),v.default.parallel([t=>{s?t():o.batch(a.join(`
|
|
5
|
+
`),(l,c)=>{l&&t(l),t(l,c)})},t=>{E?t():o.query(i,t)}],(t,l)=>{t&&r(t),r(t,l)})}close(e){this.db&&this.db.close(e)}};exports.Database=A;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var c=Object.defineProperty;var h=(i,t,e)=>t in i?c(i,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):i[t]=e;var l=(i,t,e)=>(h(i,typeof t!="symbol"?t+"":t,e),e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=require("../lib/AbstractDatabase.cjs");require("crypto");require("../node_modules/events/events.cjs");require("../node_modules/buffer/index.cjs");const E=require("util");require("../node_modules/string_decoder/lib/string_decoder.cjs");const A=class extends u{constructor(t){super();l(this,"_mysqlSettings");l(this,"_pool");this.logger=console,this._mysqlSettings={charset:"utf8mb4",...t},this.settings={engine:"InnoDB",bulkLimit:100,json:!0,queryTimeout:6e4},this._pool=null}get isAsync(){return!0}async _query(t){try{return await new Promise((e,r)=>{t={timeout:this.settings.queryTimeout,...t},this._pool&&this._pool.query(t,(s,...n)=>s!=null?r(s):e(n))})}catch(e){throw this.logger.error(`${e.fatal?"Fatal ":""}MySQL error: ${e.stack||e}`),e}}async init(){this._pool=(void 0)(this._mysqlSettings);const{database:t,charset:e}=this._mysqlSettings,r=`CREATE TABLE IF NOT EXISTS \`store\` ( \`key\` VARCHAR( 100 ) NOT NULL COLLATE utf8mb4_bin, \`value\` LONGTEXT COLLATE utf8mb4_bin NOT NULL , PRIMARY KEY ( \`key\` ) ) ENGINE=${this.settings.engine} CHARSET=utf8mb4 COLLATE=utf8mb4_bin;`,s="ALTER TABLE store MODIFY `key` VARCHAR(100) COLLATE utf8mb4_bin;";await this._query({sql:r});const n=`SELECT DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = '${t}'`;let[a]=await this._query({sql:n});a=JSON.parse(JSON.stringify(a)),a[0].DEFAULT_CHARACTER_SET_NAME!==e&&(this.logger.error(`Database is not configured with charset ${e} -- This may lead to crashes when certain characters are pasted in pads`),this.logger.log(a[0],e)),a[0].DEFAULT_COLLATION_NAME.indexOf(e)===-1&&(this.logger.error(`Database is not configured with collation name that includes ${e} -- This may lead to crashes when certain characters are pasted in pads`),this.logger.log(a[0],e,a[0].DEFAULT_COLLATION_NAME));const o=`SELECT CCSA.character_set_name AS character_set_name FROM information_schema.\`TABLES\` T,information_schema.\`COLLATION_CHARACTER_SET_APPLICABILITY\` CCSA WHERE CCSA.collation_name = T.table_collation AND T.table_schema = '${t}' AND T.table_name = 'store'`;[a]=await this._query({sql:o}),a[0]||this.logger.warn("Data has no character_set_name value -- This may lead to crashes when certain characters are pasted in pads"),a[0]&&a[0].character_set_name!==e&&(this.logger.error(`table is not configured with charset ${e} -- This may lead to crashes when certain characters are pasted in pads`),this.logger.log(a[0],e)),await this.get("MYSQL_MIGRATION_LEVEL")!=="1"&&(await this._query({sql:s}),await this.set("MYSQL_MIGRATION_LEVEL","1"))}async get(t){const[e]=await this._query({sql:"SELECT `value` FROM `store` WHERE `key` = ? AND BINARY `key` = ?",values:[t,t]});return e.length===1?e[0].value:null}async findKeys(t,e){let r="SELECT `key` FROM `store` WHERE `key` LIKE ?";const s=[];t=t.replace(/\*/g,"%"),s.push(t),e!=null&&(e=e.replace(/\*/g,"%"),r+=" AND `key` NOT LIKE ?",s.push(e));const[n]=await this._query({sql:r,values:s});return n.map(a=>a.key)}async set(t,e){if(t.length>100)throw new Error("Your Key can only be 100 chars");await this._query({sql:"REPLACE INTO `store` VALUES (?,?)",values:[t,e]})}async remove(t){await this._query({sql:"DELETE FROM `store` WHERE `key` = ? AND BINARY `key` = ?",values:[t,t]})}async doBulk(t){const e=[],r=[];for(const s of t)switch(s.type){case"set":e.push([s.key,s.value]);break;case"remove":r.push(s.key);break;default:throw new Error(`unknown op type: ${s.type}`)}await Promise.all([e.length?this._query({sql:"REPLACE INTO `store` VALUES ?;",values:[e]}):null,r.length?this._query({sql:"DELETE FROM `store` WHERE `key` IN (?) AND BINARY `key` IN (?);",values:[r,r]}):null])}async close(){await E.promisify(this._pool.end.bind(this._pool))()}};exports.Database=A;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var c=Object.defineProperty;var T=(E,e,t)=>e in E?c(E,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):E[e]=t;var l=(E,e,t)=>(T(E,typeof e!="symbol"?e+"":e,t),t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const p=require("../lib/AbstractDatabase.cjs"),y=require("../node_modules/async/dist/async.cjs");require("../node_modules/pg/lib/client.cjs");require("../node_modules/pg/lib/defaults.cjs");require("../node_modules/pg/lib/connection.cjs");require("../node_modules/events/events.cjs");require("../node_modules/pg-protocol/dist/index.cjs");require("../node_modules/pg-types/index.cjs");require("../node_modules/pg/lib/type-overrides.cjs");require("util");require("../node_modules/pg/lib/connection-parameters.cjs");const d=class extends p{constructor(e){super();l(this,"db");l(this,"upsertStatement");typeof e=="string"&&(e={connectionString:e}),this.settings=e,this.settings.cache=e.cache||1e3,this.settings.writeInterval=100,this.settings.json=!0,this.settings.max=this.settings.max||20,this.settings.min=this.settings.min||4,this.settings.idleTimeoutMillis=this.settings.idleTimeoutMillis||1e3,this.db=new(void 0)(this.settings)}init(e){const t="SELECT 1 as exists FROM pg_tables WHERE tablename = 'store'",n='CREATE TABLE IF NOT EXISTS store ("key" character varying(100) NOT NULL, "value" text NOT NULL, CONSTRAINT store_pkey PRIMARY KEY (key))';this.upsertStatement=null;const r=s=>{const o="SELECT ueberdb_insert_or_update($1,$2)",u="INSERT INTO store(key, value) VALUES ($1, $2) ON CONFLICT (key) DO UPDATE SET value = excluded.value",a="CREATE OR REPLACE FUNCTION ueberdb_insert_or_update(character varying, text) RETURNS void AS $$ BEGIN IF EXISTS( SELECT * FROM store WHERE key = $1 ) THEN UPDATE store SET value = $2 WHERE key = $1; ELSE INSERT INTO store(key,value) VALUES( $1, $2 ); END IF; RETURN; END; $$ LANGUAGE plpgsql;",i=`EXPLAIN ${u}`;this.db.query(i,["test-key","test-value"],h=>{if(h){this.upsertStatement=o,this.db.query(a,[],s);return}this.upsertStatement=u,s()})};this.db.query(t,(s,o)=>{if(s!=null)return e(s);o.rows.length===0?this.db.query(n,u=>{if(u!=null)return e(u);r(e)}):r(e)})}get(e,t){this.db.query("SELECT value FROM store WHERE key=$1",[e],(n,r)=>{let s=null;!n&&r.rows.length===1&&(s=r.rows[0].value),t(n,s)})}findKeys(e,t,n){let r="SELECT key FROM store WHERE key LIKE $1";const s=[];e=e.replace(/\*/g,"%"),s.push(e),t!=null&&(t=t.replace(/\*/g,"%"),r+=" AND key NOT LIKE $2",s.push(t)),this.db.query(r,s,(o,u)=>{const a=[];!o&&u.rows.length>0&&u.rows.forEach(i=>{a.push(i.key)}),n(o,a)})}set(e,t,n){if(e.length>100){const r="";n(Error("Your Key can only be 100 chars"),r)}else this.upsertStatement!=null&&this.db.query(this.upsertStatement,[e,t],n)}remove(e,t){this.db.query("DELETE FROM store WHERE key=$1",[e],t)}doBulk(e,t){const n=[];let r="DELETE FROM store WHERE key IN (";const s=[];let o=0;for(const i in e)e[i].type==="set"?n.push([e[i].key,e[i].value]):e[i].type==="remove"&&(o!==0&&(r+=","),o+=1,r+=`$${o}`,s.push(e[i].key));if(r+=");",!this.upsertStatement)return;const u=n.map(i=>h=>this.db.query(this.upsertStatement,i,h)),a=i=>{s.length>1?i():this.db.query(r,s,i)};u.push(a),y.default.parallel(u,t)}close(e){this.db.end(e)}};exports.Database=d;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("./postgres_db"),t=class extends s.Database{constructor(e){console.warn("ueberdb: The postgrespool database driver is deprecated and will be removed in a future version. Use postgres instead."),super(e)}};exports.Database=t;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var h=Object.defineProperty;var o=(l,i,t)=>i in l?h(l,i,{enumerable:!0,configurable:!0,writable:!0,value:t}):l[i]=t;var u=(l,i,t)=>(o(l,typeof i!="symbol"?i+"":i,t),t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const _=require("../lib/AbstractDatabase.cjs");require("../node_modules/redis/dist/index.cjs");const a=require("../_virtual/index.cjs"),f=class extends _{constructor(t){super();u(this,"_client");this._client=null,this.settings=t||{}}get isAsync(){return!0}async init(){if(this.settings.url)this._client=a.__exports.createClient({url:this.settings.url});else if(this.settings.host){const t={socket:{host:this.settings.host,port:Number(this.settings.port)}};this.settings.password&&(t.password=this.settings.password),this.settings.user&&(t.username=this.settings.user),this._client=a.__exports.createClient(t)}this._client&&(await this._client.connect(),await this._client.ping())}async get(t){return this._client==null?null:await this._client.get(t)}async findKeys(t,e){if(this._client==null)return null;const[s]=/^([^:*]+):\*$/.exec(t)||[];if(s!=null&&["*:*:*",`${t}:*`].includes(e))return await this._client.sMembers(`ueberDB:keys:${s}`);let r=await this._client.keys(t.replace(/[?[\]\\]/g,"\\$&"));if(e!=null){const c=this.createFindRegex(t,e);r=r.filter(n=>c.test(n))}return r}async set(t,e){if(this._client==null)return null;const s=/^([^:]+):([^:]+)$/.exec(t);await Promise.all([s&&this._client.sAdd(`ueberDB:keys:${s[1]}`,s[0]),this._client.set(t,e)])}async remove(t){if(this._client==null)return null;const e=/^([^:]+):([^:]+)$/.exec(t);await Promise.all([e&&this._client.sRem(`ueberDB:keys:${e[1]}`,e[0]),this._client.del(t)])}async doBulk(t){if(this._client==null)return null;const e=this._client.multi();for(const{key:s,type:r,value:c}of t){const n=/^([^:]+):([^:]+)$/.exec(s);r==="set"?(n&&e.sAdd(`ueberDB:keys:${n[1]}`,n[0]),e.set(s,c)):r==="remove"&&(n&&e.sRem(`ueberDB:keys:${n[1]}`,n[0]),e.del(s))}await e.exec()}async close(){if(this._client==null)return null;await this._client.quit(),this._client=null}};exports.Database=f;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var l=Object.defineProperty;var h=(s,t,e)=>t in s?l(s,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):s[t]=e;var r=(s,t,e)=>(h(s,typeof t!="symbol"?t+"":t,e),e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const b=require("../lib/AbstractDatabase.cjs"),c=require("../node_modules/rethinkdb/rethinkdb.cjs"),u=require("../node_modules/async/dist/async.cjs"),d=class extends b{constructor(t){super();r(this,"host");r(this,"db");r(this,"port");r(this,"table");r(this,"connection");t||(t={}),t.host||(t.host="localhost"),t.port||(t.port=28015),t.db||(t.db="test"),t.table||(t.table="test"),this.host=t.host,this.db=t.db,this.port=t.port,this.table=t.table,this.connection=null}init(t){c.connect(this,(e,o)=>{if(e)throw e;this.connection=o,c.table(this.table).run(this.connection,(i,n)=>{i?c.tableCreate(this.table).run(this.connection,t):t&&t(null,n)})})}get(t,e){c.table(this.table).get(t).run(this.connection,(o,i)=>{e(o,i&&i.content)})}findKeys(t,e,o){const i=[],n=this.createFindRegex(t,e);c.filter(a=>{a.id.search(n)!==-1&&i.push(a.id)}).run(this.connection,o)}set(t,e,o){c.table(this.table).insert({id:t,content:e},{conflict:"replace"}).run(this.connection,o)}doBulk(t,e){const o=[],i=[];for(const n in t)t[n].type==="set"?o.push({id:t[n].key,content:t[n].value}):t[n].type==="remove"&&i.push(t[n].key);u.default.parallel([n=>{c.table(this.table).insert(o,{conflict:"replace"}).run(this.connection,n)},n=>{c.table(this.table).getAll(i).delete().run(this.connection,n)}],e)}remove(t,e){c.table(this.table).get(t).delete().run(this.connection,e)}close(t){this.connection&&this.connection.close(t)}};exports.Database=d;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
"use strict";var f=Object.defineProperty;var d=(n,a,e)=>a in n?f(n,a,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[a]=e;var h=(n,a,e)=>(d(n,typeof a!="symbol"?a+"":a,e),e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const T=require("../lib/AbstractDatabase.cjs"),b=require("util");let c;try{c=require("sqlite3").Database}catch{throw new Error(`sqlite3 not found. It was removed from ueberdb's dependencies because it requires compilation which fails on several systems. If you still want to use sqlite, run "npm install sqlite3" in your etherpad-lite ./src directory.`)}const l=n=>`'${n.replace(/'/g,"''")}'`,m=class extends T{constructor(e){super();h(this,"db");this.db=null,(!e||!e.filename)&&(e={filename:":memory:"}),this.settings=e,e.filename===":memory:"?(this.settings.cache=0,this.settings.writeInterval=0,this.settings.json=!0):(this.settings.cache=1e3,this.settings.writeInterval=100,this.settings.json=!0)}init(e){b.callbackify(async()=>{this.db=new c(this.settings.filename),await this._query("CREATE TABLE IF NOT EXISTS store (key TEXT PRIMARY KEY, value TEXT)")})(e)}async _query(e,s=[]){return await new Promise((i,t)=>{this.db&&this.db.all(e,s,(r,o)=>{if(r!=null)return t(r);i(o)})})}_queryCb(e,s,i){const t=this._query(e,s);i&&t.then(r=>i(null,r),r=>i(r||new Error(r)))}get(e,s){this._queryCb("SELECT value FROM store WHERE key = ?",[e],(i,t)=>s(i,i==null&&t&&t.length?t[0].value:null))}findKeys(e,s,i){let t="SELECT key FROM store WHERE key LIKE ?";const r=[];e=e.replace(/\*/g,"%"),r.push(e),s!=null&&(s=s.replace(/\*/g,"%"),t+=" AND key NOT LIKE ?",r.push(s)),this._queryCb(t,r,(o,u)=>{const E=[];!o&&Object.keys(u).length>0&&u.forEach(y=>{E.push(y.key)}),i(o,E)})}set(e,s,i){this._queryCb("REPLACE INTO store VALUES (?,?)",[e,s],i)}remove(e,s){this._queryCb("DELETE FROM store WHERE key = ?",[e],s)}doBulk(e,s){let i=`BEGIN TRANSACTION;
|
|
2
|
+
`;for(const t in e)e[t].type==="set"?i+=`REPLACE INTO store VALUES (${l(e[t].key)}, ${l(e[t].value)});
|
|
3
|
+
`:e[t].type==="remove"&&(i+=`DELETE FROM store WHERE key = ${l(e[t].key)};
|
|
4
|
+
`);i+="END TRANSACTION;",this.db&&this.db.exec(i,t=>{t&&(console.error("ERROR WITH SQL: "),console.error(i)),s(t)})}close(e){e(),this.db&&this.db.close(s=>e(s))}};exports.Database=m;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './databases/dirty_db'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './databases/dirty_git_db'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './databases/elasticsearch_db'
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { Settings } from './lib/AbstractDatabase';
|
|
2
|
+
export declare const Database: {
|
|
3
|
+
new (type: undefined | string, dbSettings: Settings | null | string, wrapperSettings?: null | {}, logger?: any): {
|
|
4
|
+
readonly type: any;
|
|
5
|
+
dbModule: any;
|
|
6
|
+
readonly dbSettings: any;
|
|
7
|
+
readonly wrapperSettings: any | {};
|
|
8
|
+
readonly logger: Function | null;
|
|
9
|
+
db: any;
|
|
10
|
+
metrics: any;
|
|
11
|
+
/**
|
|
12
|
+
* @param callback - Deprecated. Node-style callback. If null, a Promise is returned.
|
|
13
|
+
*/
|
|
14
|
+
init(callback?: null): Promise<any>;
|
|
15
|
+
/**
|
|
16
|
+
* Wrapper functions
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Deprecated synonym of flush().
|
|
20
|
+
*
|
|
21
|
+
* @param callback - Deprecated. Node-style callback. If null, a Promise is returned.
|
|
22
|
+
*/
|
|
23
|
+
doShutdown(callback?: null): any;
|
|
24
|
+
/**
|
|
25
|
+
* Writes any unsaved changes to the underlying database.
|
|
26
|
+
*
|
|
27
|
+
* @param callback - Deprecated. Node-style callback. If null, a Promise is returned.
|
|
28
|
+
*/
|
|
29
|
+
flush(callback?: null): any;
|
|
30
|
+
/**
|
|
31
|
+
* @param key
|
|
32
|
+
* @param callback - Deprecated. Node-style callback. If null, a Promise is returned.
|
|
33
|
+
*/
|
|
34
|
+
get(key: string, callback?: null): any;
|
|
35
|
+
/**
|
|
36
|
+
* @param key
|
|
37
|
+
* @param notKey
|
|
38
|
+
* @param callback - Deprecated. Node-style callback. If null, a Promise is returned.
|
|
39
|
+
*/
|
|
40
|
+
findKeys(key: string, notKey: string, callback?: null): any;
|
|
41
|
+
/**
|
|
42
|
+
* Removes an entry from the database if present.
|
|
43
|
+
*
|
|
44
|
+
* @param key
|
|
45
|
+
* @param cb Deprecated. Node-style callback. Called when the write has been committed to the
|
|
46
|
+
* underlying database driver. If null, a Promise is returned.
|
|
47
|
+
* @param deprecated Deprecated callback that is called just after cb. Ignored if cb is null.
|
|
48
|
+
*/
|
|
49
|
+
remove(key: string, cb?: null, deprecated?: null): any;
|
|
50
|
+
/**
|
|
51
|
+
* Adds or changes the value of an entry.
|
|
52
|
+
*
|
|
53
|
+
* @param key
|
|
54
|
+
* @param value
|
|
55
|
+
* @param cb Deprecated. Node-style callback. Called when the write has been committed to the
|
|
56
|
+
* underlying database driver. If null, a Promise is returned.
|
|
57
|
+
* @param deprecated Deprecated callback that is called just after cb. Ignored if cb is null.
|
|
58
|
+
*/
|
|
59
|
+
set(key: string, value: string, cb?: null, deprecated?: null): any;
|
|
60
|
+
/**
|
|
61
|
+
* @param key
|
|
62
|
+
* @param sub
|
|
63
|
+
* @param callback - Deprecated. Node-style callback. If null, a Promise is returned.
|
|
64
|
+
*/
|
|
65
|
+
getSub(key: string, sub: string, callback?: null): any;
|
|
66
|
+
/**
|
|
67
|
+
* Adds or changes a subvalue of an entry.
|
|
68
|
+
*
|
|
69
|
+
* @param key
|
|
70
|
+
* @param sub
|
|
71
|
+
* @param value
|
|
72
|
+
* @param cb Deprecated. Node-style callback. Called when the write has been committed to the
|
|
73
|
+
* underlying database driver. If null, a Promise is returned.
|
|
74
|
+
* @param deprecated Deprecated callback that is called just after cb. Ignored if cb is null.
|
|
75
|
+
*/
|
|
76
|
+
setSub(key: string, sub: string, value: string, cb?: null, deprecated?: null): any;
|
|
77
|
+
/**
|
|
78
|
+
* Flushes unwritten changes then closes the connection to the underlying database. After this
|
|
79
|
+
* returns, any future call to a method on this object may result in an error.
|
|
80
|
+
*
|
|
81
|
+
* @param callback - Deprecated. Node-style callback. If null, a Promise is returned.
|
|
82
|
+
*/
|
|
83
|
+
close(callback?: null): any;
|
|
84
|
+
};
|
|
85
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var i=Object.defineProperty;var l=(r,e,t)=>e in r?i(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t;var o=(r,e,t)=>(l(r,typeof e!="symbol"?e+"":e,t),t);const g=require("./logging.cjs"),a=g.normalizeLogger(null),s=r=>r.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*");class c{constructor(){o(this,"logger");o(this,"settings");if(new.target===module.exports)throw new TypeError("cannot instantiate Abstract Database directly");for(const e of["init","close","get","findKeys","remove","set"])if(typeof this[e]!="function")throw new TypeError(`method ${e} not defined`);this.logger=a}createFindRegex(e,t){let n=`^(?=${s(e)}$)`;return t!=null&&(n+=`(?!${s(t)}$)`),new RegExp(n)}doBulk(e,t){throw new Error("the doBulk method must be implemented if write caching is enabled")}get isAsync(){return!1}}module.exports=c;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const d=require("util");class f{constructor(t,s=(e,i)=>!0){this._capacity=t,this._evictable=s,this._cache=new Map}[Symbol.iterator](){return this._cache.entries()}get(t,s=!0){if(!this._cache.has(t))return;const e=this._cache.get(t);return s&&(this._cache.delete(t),this._cache.set(t,e)),e}set(t,s){this._cache.delete(t),this._cache.set(t,s),this.evictOld()}evictOld(){for(const[t,s]of this._cache.entries()){if(this._cache.size<=this._capacity)break;this._evictable(t,s)&&this._cache.delete(t)}}}class u extends Promise{constructor(t=null){let s;super((e,i)=>{s=(o,n)=>o!=null?i(o):e(n),t!=null&&t(e,i)}),this.done=s}}const g={bulkLimit:0,cache:1e4,writeInterval:100,json:!0,charset:"utf8mb4"},w=class{constructor(t,s,e){if(t.isAsync)this.wrappedDB=t;else{this.wrappedDB={};for(const i of["close","doBulk","findKeys","get","init","remove","set"]){const o=t[i];typeof o=="function"&&(this.wrappedDB[i]=d.promisify(o.bind(t)))}}this.logger=e,this.settings=Object.freeze({...g,...t.settings||{},...s||{}}),this.buffer=new f(this.settings.cache,(i,o)=>!o.dirty&&!o.writingInProgress),this._flushPaused=null,this._locks=new Map,this.metrics={lockAwaits:0,lockAcquires:0,lockReleases:0,reads:0,readsFailed:0,readsFinished:0,readsFromCache:0,readsFromDb:0,readsFromDbFailed:0,readsFromDbFinished:0,writes:0,writesFailed:0,writesFinished:0,writesObsoleted:0,writesToDb:0,writesToDbFailed:0,writesToDbFinished:0,writesToDbRetried:0},this.flushInterval=this.settings.writeInterval>0?setInterval(()=>this.flush(),this.settings.writeInterval):null}async _lock(t){for(;;){const s=this._locks.get(t);if(s==null)break;++this.metrics.lockAwaits,await s}++this.metrics.lockAcquires,this._locks.set(t,new u)}async _unlock(t){++this.metrics.lockReleases,this._locks.get(t).done(),this._locks.delete(t)}_pauseFlush(){this._flushPaused==null&&(this._flushPaused=new u,this._flushPaused.count=0),++this._flushPaused.count}_resumeFlush(){--this._flushPaused.count>0||(this._flushPaused.done(),this._flushPaused=null)}async init(){await this.wrappedDB.init()}async close(){clearInterval(this.flushInterval),await this.flush(),await this.wrappedDB.close(),this.wrappedDB=null}async get(t){let s;await this._lock(t);try{s=await this._getLocked(t)}finally{this._unlock(t)}return c(s)}async _getLocked(t){++this.metrics.reads;try{const s=this.buffer.get(t);if(s!=null)return++this.metrics.readsFromCache,this.logger.isDebugEnabled()&&this.logger.debug(`GET - ${t} - ${JSON.stringify(s.value)} - from ${s.dirty?"dirty buffer":"cache"}`),s.value;let e;++this.metrics.readsFromDb;try{e=await this.wrappedDB.get(t)}catch(i){throw++this.metrics.readsFromDbFailed,i}finally{++this.metrics.readsFromDbFinished}if(this.settings.json)try{e=JSON.parse(e)}catch(i){throw this.logger.error(`JSON-PROBLEM:${e}`),i}return this.settings.cache>0&&this.buffer.set(t,{value:e,dirty:null,writingInProgress:!1}),this.logger.isDebugEnabled()&&this.logger.debug(`GET - ${t} - ${JSON.stringify(e)} - from database `),e}catch(s){throw++this.metrics.readsFailed,s}finally{++this.metrics.readsFinished}}async findKeys(t,s){await this.flush();const e=await this.wrappedDB.findKeys(t,s);return this.logger.isDebugEnabled()&&this.logger.debug(`GET - ${t}-${s} - ${JSON.stringify(e)} - from database `),c(e)}async remove(t){this.logger.isDebugEnabled()&&this.logger.debug(`DELETE - ${t} - from database `),await this.set(t,null)}async set(t,s){s=c(s);let e;this._pauseFlush();try{await this._lock(t);try{e=this._setLocked(t,s)}finally{this._unlock(t)}}finally{this._resumeFlush()}await e}async _setLocked(t,s){++this.metrics.writes;try{let e=this.buffer.get(t);!e||e.writingInProgress?e={}:e.dirty&&++this.metrics.writesObsoleted,e.value=s,e.dirty||(e.dirty=new u),this.buffer.set(t,e);const i=this.settings.writeInterval>0;this.logger.isDebugEnabled()&&this.logger.debug(`SET - ${t} - ${JSON.stringify(s)} - to ${i?"buffer":"database"}`),i||this._write([[t,e]]),await e.dirty}catch(e){throw++this.metrics.writesFailed,e}finally{++this.metrics.writesFinished}}async setSub(t,s,e){e=c(e),this.logger.isDebugEnabled()&&this.logger.debug(`SETSUB - ${t}${JSON.stringify(s)} - ${JSON.stringify(e)}`);let i;this._pauseFlush();try{await this._lock(t);try{let o;try{const n=await this._getLocked(t);o={fullValue:n};const r={obj:o,prop:"fullValue"};for(let a=0;a<s.length;a++){if(s[a]==="__proto__")throw new Error("Modifying object prototype is not supported for security reasons");let h=r.obj[r.prop];if(h==null&&(r.obj[r.prop]=h={}),typeof h!="object")throw new TypeError(`Cannot set property ${JSON.stringify(s[a])} on non-object ${JSON.stringify(h)} (key: ${JSON.stringify(t)} value in db: ${JSON.stringify(n)} sub: ${JSON.stringify(s.slice(0,a+1))})`);r.obj=r.obj[r.prop],r.prop=s[a]}r.obj[r.prop]=e}catch(n){throw++this.metrics.writes,++this.metrics.writesFailed,++this.metrics.writesFinished,n}i=this._setLocked(t,o.fullValue)}finally{this._unlock(t)}}finally{this._resumeFlush()}await i}async getSub(t,s){await this._lock(t);try{let e=await this._getLocked(t);for(const i of s){if((typeof e!="object"||e!=null&&!Object.prototype.hasOwnProperty.call(e,i)||i==="__proto__")&&(e=null),e==null)break;e=e[i]}return this.logger.isDebugEnabled()&&this.logger.debug(`GETSUB - ${t}${JSON.stringify(s)} - ${JSON.stringify(e)}`),c(e)}finally{this._unlock(t)}}async flush(){this._flushDone==null&&(this._flushDone=(async()=>{for(;;){for(;this._flushPaused!=null;)await this._flushPaused;const t=[];for(const s of this.buffer)if(s[1].dirty&&!s[1].writingInProgress&&(t.push(s),this.settings.bulkLimit&&t.length>=this.settings.bulkLimit))break;if(t.length===0)return;await this._write(t)}})()),await this._flushDone,this._flushDone=null}async _write(t){const s=(n,r)=>{n.writingInProgress&&(n.writingInProgress=!1,r!=null&&++this.metrics.writesToDbFailed,++this.metrics.writesToDbFinished),n.dirty.done(r),n.dirty=null},e=[],i=[];for(const[n,r]of t){let a=r.value;try{a=this.settings.json&&a!=null?JSON.stringify(a):c(a)}catch(h){s(r,h);continue}r.writingInProgress=!0,e.push({type:a==null?"remove":"set",key:n,value:a}),i.push(r)}if(e.length===0)return;this.metrics.writesToDb+=e.length;const o=async(n,r)=>{let a=null;try{switch(n.type){case"remove":await this.wrappedDB.remove(n.key);break;case"set":await this.wrappedDB.set(n.key,n.value);break;default:throw new Error(`unsupported operation type: ${n.type}`)}}catch(h){a=h||new Error(h)}s(r,a)};if(e.length===1)await o(e[0],i[0]);else{let n=!1;try{await this.wrappedDB.doBulk(e),n=!0}catch(r){this.logger.error(`Bulk write of ${e.length} ops failed, retrying individually: ${r.stack||r}`),this.metrics.writesToDbRetried+=e.length,await Promise.all(e.map(async(a,h)=>await o(a,i[h])))}n&&i.forEach(r=>s(r,null))}this.buffer.evictOld()}},c=(l,t="")=>{if(l==null||typeof l!="object")return l;if(typeof l.toJSON=="function")return c(l.toJSON(t));if(l instanceof Date){const s=new Date;return s.setTime(l.getTime()),s}if(l instanceof Array){const s=[];for(let e=0,i=l.length;e<i;++e)s[e]=c(l[e],String(e));return s}if(l instanceof Object){const s={};for(const e in l)Object.prototype.hasOwnProperty.call(l,e)&&(s[e]=c(l[e],e));return s}throw new Error("Unable to copy obj! Its type isn't supported.")};exports.Database=w;exports.LRU=f;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require("console");require("process");const o=e=>{const r=["debug","info","warn","error"];e=Object.create(e||{});for(const t of r){const n=`is${t.charAt(0).toUpperCase()+t.slice(1)}Enabled`;typeof e[t]!="function"?(e[t]=()=>{},e[n]=()=>!1):typeof e[n]!="function"&&(e[n]=()=>!0)}return e};exports.normalizeLogger=o;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './databases/memory_db'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './databases/mock_db'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './databases/mongodb_db'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './databases/mssql_db'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './databases/mysql_db'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './databases/postgres_db'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './databases/postgrespool_db'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './databases/redis_db'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './databases/rethink_db'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './databases/sqlite_db'
|
package/package.json
CHANGED
|
@@ -41,6 +41,9 @@
|
|
|
41
41
|
"sqlite3": "^5.1.6"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
|
+
"vite": "^4.4.9",
|
|
45
|
+
"vite-plugin-dts": "^3.5.3",
|
|
46
|
+
"@rollup/plugin-commonjs": "^25.0.4",
|
|
44
47
|
"@types/async": "^3.2.20",
|
|
45
48
|
"@types/mssql": "^8.1.2",
|
|
46
49
|
"@types/mysql": "^2.15.21",
|
|
@@ -54,9 +57,6 @@
|
|
|
54
57
|
"vitest": "^0.34.3",
|
|
55
58
|
"typescript": "^4.9.5",
|
|
56
59
|
"wtfnode": "^0.9.1",
|
|
57
|
-
"rollup": "^3.28.1",
|
|
58
|
-
"rollup-plugin-typescript2": "^0.35.0",
|
|
59
|
-
"@rollup/plugin-node-resolve": "^15.2.1",
|
|
60
60
|
"glob": "^10.3.3"
|
|
61
61
|
},
|
|
62
62
|
"repository": {
|
|
@@ -64,20 +64,21 @@
|
|
|
64
64
|
"url": "https://github.com/ether/ueberDB.git"
|
|
65
65
|
},
|
|
66
66
|
"main": "./dist/index",
|
|
67
|
-
"version": "4.1.
|
|
67
|
+
"version": "4.1.25",
|
|
68
68
|
"bugs": {
|
|
69
69
|
"url": "https://github.com/ether/ueberDB/issues"
|
|
70
70
|
},
|
|
71
71
|
"files": [
|
|
72
72
|
"dist/databases",
|
|
73
73
|
"dist/index.js",
|
|
74
|
+
"dist/*.d.ts",
|
|
74
75
|
"dist/lib"
|
|
75
76
|
],
|
|
76
77
|
"homepage": "https://github.com/ether/ueberDB",
|
|
77
78
|
"scripts": {
|
|
78
79
|
"lint": "eslint .",
|
|
79
80
|
"lint:fix": "eslint --fix .",
|
|
80
|
-
"build": "
|
|
81
|
+
"build": "vite build",
|
|
81
82
|
"test": "vitest"
|
|
82
83
|
},
|
|
83
84
|
"_npmUser": {
|
|
@@ -1,235 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var AbstractDatabase = require('../lib/AbstractDatabase.js');
|
|
4
|
-
var cassandraDriver = require('cassandra-driver');
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
-
* you may not use this file except in compliance with the License.
|
|
9
|
-
* You may obtain a copy of the License at
|
|
10
|
-
*
|
|
11
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
-
*
|
|
13
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
14
|
-
* distributed under the License is distributed on an "AS-IS" BASIS,
|
|
15
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
-
* See the License for the specific language governing permissions and
|
|
17
|
-
* limitations under the License.
|
|
18
|
-
*/
|
|
19
|
-
const Database = class Cassandra_db extends AbstractDatabase {
|
|
20
|
-
client;
|
|
21
|
-
pool;
|
|
22
|
-
/**
|
|
23
|
-
* @param {Object} settings The required settings object to initiate the Cassandra database
|
|
24
|
-
* @param {String[]} settings.clientOptions See
|
|
25
|
-
* http://www.datastax.com/drivers/nodejs/2.0/global.html#ClientOptions for a full set of
|
|
26
|
-
* options that can be used
|
|
27
|
-
* @param {String} settings.columnFamily The column family that should be used to store data. The
|
|
28
|
-
* column family will be created if it doesn't exist
|
|
29
|
-
* @param {Function} [settings.logger] Function that will be used to pass on log events emitted by
|
|
30
|
-
* the Cassandra driver. See https://github.com/datastax/nodejs-driver#logging for more
|
|
31
|
-
* information
|
|
32
|
-
*/
|
|
33
|
-
constructor(settings) {
|
|
34
|
-
super();
|
|
35
|
-
if (!settings.clientOptions) {
|
|
36
|
-
throw new Error('The Cassandra client options should be defined');
|
|
37
|
-
}
|
|
38
|
-
if (!settings.columnFamily) {
|
|
39
|
-
throw new Error('The Cassandra column family should be defined');
|
|
40
|
-
}
|
|
41
|
-
this.settings = { database: settings.database };
|
|
42
|
-
this.settings.clientOptions = settings.clientOptions;
|
|
43
|
-
this.settings.columnFamily = settings.columnFamily;
|
|
44
|
-
this.settings.logger = settings.logger;
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Initializes the Cassandra client, connects to Cassandra and creates the CF if it didn't exist
|
|
48
|
-
* already
|
|
49
|
-
*
|
|
50
|
-
* @param {Function} callback Standard callback method.
|
|
51
|
-
* @param {Error} callback.err An error object (if any.)
|
|
52
|
-
*/
|
|
53
|
-
init(callback) {
|
|
54
|
-
// Create a client
|
|
55
|
-
this.client = new cassandraDriver.Client(this.settings.clientOptions);
|
|
56
|
-
// Pass on log messages if a logger has been configured
|
|
57
|
-
if (this.settings.logger) {
|
|
58
|
-
this.client.on('log', this.settings.logger);
|
|
59
|
-
}
|
|
60
|
-
// Check whether our column family already exists and create it if necessary
|
|
61
|
-
this.client.execute('SELECT columnfamily_name FROM system.schema_columnfamilies WHERE keyspace_name = ?', [this.settings.clientOptions.keyspace], (err, result) => {
|
|
62
|
-
if (err) {
|
|
63
|
-
return callback(err);
|
|
64
|
-
}
|
|
65
|
-
let isDefined = false;
|
|
66
|
-
const length = result.rows.length;
|
|
67
|
-
for (let i = 0; i < length; i++) {
|
|
68
|
-
if (result.rows[i].columnfamily_name === this.settings.columnFamily) {
|
|
69
|
-
isDefined = true;
|
|
70
|
-
break;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
if (isDefined) {
|
|
74
|
-
return callback(null);
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
const cql = `CREATE COLUMNFAMILY "${this.settings.columnFamily}" ` +
|
|
78
|
-
'(key text PRIMARY KEY, data text)';
|
|
79
|
-
this.client && this.client.execute(cql, callback);
|
|
80
|
-
}
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Gets a value from Cassandra
|
|
85
|
-
*
|
|
86
|
-
* @param {String} key The key for which the value should be retrieved
|
|
87
|
-
* @param {Function} callback Standard callback method
|
|
88
|
-
* @param {Error} callback.err An error object, if any
|
|
89
|
-
* @param {String} callback.value The value for the given key (if any)
|
|
90
|
-
*/
|
|
91
|
-
get(key, callback) {
|
|
92
|
-
const cql = `SELECT data FROM "${this.settings.columnFamily}" WHERE key = ?`;
|
|
93
|
-
this.client && this.client.execute(cql, [key], (err, result) => {
|
|
94
|
-
if (err) {
|
|
95
|
-
return callback(err);
|
|
96
|
-
}
|
|
97
|
-
if (!result.rows || result.rows.length === 0) {
|
|
98
|
-
return callback(null, null);
|
|
99
|
-
}
|
|
100
|
-
return callback(null, result.rows[0].data);
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* Cassandra has no native `findKeys` method. This function implements a naive filter by
|
|
105
|
-
* retrieving *all* the keys and filtering those. This should obviously be used with the utmost
|
|
106
|
-
* care and is probably not something you want to run in production.
|
|
107
|
-
*
|
|
108
|
-
* @param {String} key The filter for keys that should match
|
|
109
|
-
* @param {String} [notKey] The filter for keys that shouldn't match
|
|
110
|
-
* @param {Function} callback Standard callback method
|
|
111
|
-
* @param {Error} callback.err An error object, if any
|
|
112
|
-
* @param {String[]} callback.keys An array of keys that match the specified filters
|
|
113
|
-
*/
|
|
114
|
-
findKeys(key, notKey, callback) {
|
|
115
|
-
let cql = null;
|
|
116
|
-
if (!notKey) {
|
|
117
|
-
// Get all the keys
|
|
118
|
-
cql = `SELECT key FROM "${this.settings.columnFamily}"`;
|
|
119
|
-
this.client && this.client.execute(cql, (err, result) => {
|
|
120
|
-
if (err) {
|
|
121
|
-
return callback(err);
|
|
122
|
-
}
|
|
123
|
-
// Construct a regular expression based on the given key
|
|
124
|
-
const regex = new RegExp(`^${key.replace(/\*/g, '.*')}$`);
|
|
125
|
-
const keys = [];
|
|
126
|
-
result.rows.forEach((row) => {
|
|
127
|
-
if (regex.test(row.key)) {
|
|
128
|
-
keys.push(row.key);
|
|
129
|
-
}
|
|
130
|
-
});
|
|
131
|
-
return callback(null, keys);
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
else if (notKey === '*:*:*') {
|
|
135
|
-
// restrict key to format 'text:*'
|
|
136
|
-
const matches = /^([^:]+):\*$/.exec(key);
|
|
137
|
-
if (matches) {
|
|
138
|
-
// Get the 'text' bit out of the key and get all those keys from a special column.
|
|
139
|
-
// We can retrieve them from this column as we're duplicating them on .set/.remove
|
|
140
|
-
cql = `SELECT * from "${this.settings.columnFamily}" WHERE key = ?`;
|
|
141
|
-
this.client &&
|
|
142
|
-
this.client
|
|
143
|
-
.execute(cql, [`ueberdb:keys:${matches[1]}`], (err, result) => {
|
|
144
|
-
if (err) {
|
|
145
|
-
return callback(err);
|
|
146
|
-
}
|
|
147
|
-
if (!result.rows || result.rows.length === 0) {
|
|
148
|
-
return callback(null, []);
|
|
149
|
-
}
|
|
150
|
-
const keys = result.rows.map((row) => row.data);
|
|
151
|
-
return callback(null, keys);
|
|
152
|
-
});
|
|
153
|
-
}
|
|
154
|
-
else {
|
|
155
|
-
const msg = 'Cassandra db only supports key patterns like pad:* when notKey is set to *:*:*';
|
|
156
|
-
return callback(new Error(msg), null);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
else {
|
|
160
|
-
return callback(new Error('Cassandra db currently only supports *:*:* as notKey'), null);
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
/**
|
|
164
|
-
* Sets a value for a key
|
|
165
|
-
*
|
|
166
|
-
* @param {String} key The key to set
|
|
167
|
-
* @param {String} value The value associated to this key
|
|
168
|
-
* @param {Function} callback Standard callback method
|
|
169
|
-
* @param {Error} callback.err An error object, if any
|
|
170
|
-
*/
|
|
171
|
-
set(key, value, callback) {
|
|
172
|
-
this.doBulk([{ type: 'set', key, value }], callback);
|
|
173
|
-
}
|
|
174
|
-
/**
|
|
175
|
-
* Removes a key and it's value from the column family
|
|
176
|
-
*
|
|
177
|
-
* @param {String} key The key to remove
|
|
178
|
-
* @param {Function} callback Standard callback method
|
|
179
|
-
* @param {Error} callback.err An error object, if any
|
|
180
|
-
*/
|
|
181
|
-
remove(key, callback) {
|
|
182
|
-
this.doBulk([{ type: 'remove', key }], callback);
|
|
183
|
-
}
|
|
184
|
-
/**
|
|
185
|
-
* Performs multiple operations in one action
|
|
186
|
-
*
|
|
187
|
-
* @param {Object[]} bulk The set of operations that should be performed
|
|
188
|
-
* @param {Function} callback Standard callback method
|
|
189
|
-
* @param {Error} callback.err An error object, if any
|
|
190
|
-
*/
|
|
191
|
-
doBulk(bulk, callback) {
|
|
192
|
-
const queries = [];
|
|
193
|
-
bulk.forEach((operation) => {
|
|
194
|
-
// We support finding keys of the form `test:*`. If anything matches, we will try and save
|
|
195
|
-
// this
|
|
196
|
-
const matches = /^([^:]+):([^:]+)$/.exec(operation.key);
|
|
197
|
-
if (operation.type === 'set') {
|
|
198
|
-
queries.push({
|
|
199
|
-
query: `UPDATE "${this.settings.columnFamily}" SET data = ? WHERE key = ?`,
|
|
200
|
-
params: [operation.value, operation.key],
|
|
201
|
-
});
|
|
202
|
-
if (matches) {
|
|
203
|
-
queries.push({
|
|
204
|
-
query: `UPDATE "${this.settings.columnFamily}" SET data = ? WHERE key = ?`,
|
|
205
|
-
params: ['1', `ueberdb:keys:${matches[1]}`],
|
|
206
|
-
});
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
else if (operation.type === 'remove') {
|
|
210
|
-
queries.push({
|
|
211
|
-
query: `DELETE FROM "${this.settings.columnFamily}" WHERE key=?`,
|
|
212
|
-
params: [operation.key],
|
|
213
|
-
});
|
|
214
|
-
if (matches) {
|
|
215
|
-
queries.push({
|
|
216
|
-
query: `DELETE FROM "${this.settings.columnFamily}" WHERE key = ?`,
|
|
217
|
-
params: [`ueberdb:keys:${matches[1]}`],
|
|
218
|
-
});
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
});
|
|
222
|
-
this.client && this.client.batch(queries, { prepare: true }, callback);
|
|
223
|
-
}
|
|
224
|
-
/**
|
|
225
|
-
* Closes the Cassandra connection
|
|
226
|
-
*
|
|
227
|
-
* @param {Function} callback Standard callback method
|
|
228
|
-
* @param {Error} callback.err Error object in case something goes wrong
|
|
229
|
-
*/
|
|
230
|
-
close(callback) {
|
|
231
|
-
this.pool.shutdown(callback);
|
|
232
|
-
}
|
|
233
|
-
};
|
|
234
|
-
|
|
235
|
-
exports.Database = Database;
|