Mostly working on search and create and changing location of Database file.
New key bindings! Added ability to search by tag and by date. Though there is still a bug in by date. Lots of DB code updates. Adding electron if casses. Some of these features are electrong spesific so it is checking that it is electron. Changing how tagging control works so I could have multiple on the same page. Added some error tracking code so I would get notified of internal errors if online. New preload script (special feature in electron)
This commit is contained in:
parent
a76c3491d2
commit
4d57642db4
18
main.js
18
main.js
@ -1,8 +1,18 @@
|
|||||||
const { app, BrowserWindow } = require('electron')
|
const { app, BrowserWindow } = require('electron')
|
||||||
require('./src/data/sqlite-electron-ipc');
|
const path = require('path')
|
||||||
|
|
||||||
|
const here = app.getAppPath()
|
||||||
|
console.log('here', here)
|
||||||
|
|
||||||
let mainWin;
|
require('./src/data/sqlite-electron-ipc')
|
||||||
|
|
||||||
|
// Preload
|
||||||
|
const Sentry = require('@sentry/browser')
|
||||||
|
Sentry.init({
|
||||||
|
dsn: 'http://a12d5c5f800b406f8d1c0c5d2ed63a78@216.128.138.128:8000/1'
|
||||||
|
})
|
||||||
|
|
||||||
|
let mainWin
|
||||||
|
|
||||||
function createWindow () {
|
function createWindow () {
|
||||||
mainWin = new BrowserWindow({
|
mainWin = new BrowserWindow({
|
||||||
@ -13,11 +23,12 @@ function createWindow () {
|
|||||||
webPreferences: {
|
webPreferences: {
|
||||||
nodeIntegration: true,
|
nodeIntegration: true,
|
||||||
contextIsolation: false,
|
contextIsolation: false,
|
||||||
|
preload: path.join(here, 'preload.js')
|
||||||
},
|
},
|
||||||
nodeIntegration: true
|
nodeIntegration: true
|
||||||
})
|
})
|
||||||
|
|
||||||
//win.autoHideMenuBar = true;
|
// win.autoHideMenuBar = true;
|
||||||
|
|
||||||
mainWin.loadFile('index.html')
|
mainWin.loadFile('index.html')
|
||||||
}
|
}
|
||||||
@ -25,4 +36,3 @@ function createWindow () {
|
|||||||
app.whenReady().then(() => {
|
app.whenReady().then(() => {
|
||||||
createWindow()
|
createWindow()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
3384
package-lock.json
generated
3384
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -34,7 +34,8 @@
|
|||||||
"electron-rebuild": "^3.2.7",
|
"electron-rebuild": "^3.2.7",
|
||||||
"jest": "^27.4.7",
|
"jest": "^27.4.7",
|
||||||
"less": "^4.1.2",
|
"less": "^4.1.2",
|
||||||
"parcel": "^2"
|
"parcel": "^2",
|
||||||
|
"standard": "^16.0.4"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sentry/browser": "^6.17.6",
|
"@sentry/browser": "^6.17.6",
|
||||||
@ -43,6 +44,7 @@
|
|||||||
"better-sqlite3": "^7.5.0",
|
"better-sqlite3": "^7.5.0",
|
||||||
"conf": "^10.1.1",
|
"conf": "^10.1.1",
|
||||||
"dayjs": "^1.10.7",
|
"dayjs": "^1.10.7",
|
||||||
|
"electron-config": "^2.0.0",
|
||||||
"empty-lite": "^1.2.0",
|
"empty-lite": "^1.2.0",
|
||||||
"es6-interface": "^3.2.1",
|
"es6-interface": "^3.2.1",
|
||||||
"hash.js": "^1.1.7",
|
"hash.js": "^1.1.7",
|
||||||
|
|||||||
22
preload.js
Normal file
22
preload.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// Preload
|
||||||
|
const Sentry = require('@sentry/browser')
|
||||||
|
// const { BrowserTracing } require( '@sentry/tracing' )
|
||||||
|
|
||||||
|
Sentry.init({
|
||||||
|
dsn: 'http://a12d5c5f800b406f8d1c0c5d2ed63a78@216.128.138.128:8000/1',
|
||||||
|
|
||||||
|
// Alternatively, use `process.env.npm_package_version` for a dynamic release version
|
||||||
|
// if your build tool supports it.
|
||||||
|
release: 'timechain@1.0.0'
|
||||||
|
// integrations: [new BrowserTracing()],
|
||||||
|
|
||||||
|
// Set tracesSampleRate to 1.0 to capture 100%
|
||||||
|
// of transactions for performance monitoring.
|
||||||
|
// We recommend adjusting this value in production
|
||||||
|
// tracesSampleRate: 1.0
|
||||||
|
})
|
||||||
|
|
||||||
|
window.Sentry = Sentry
|
||||||
|
window.Timechain_isElectron = true
|
||||||
|
window.Timechain_dbModule = 'sqlite-client'
|
||||||
|
window.Timechain_canChooseDbLocation = true
|
||||||
@ -1,146 +1,192 @@
|
|||||||
const { ipcMain } = require('electron');
|
const { ipcMain } = require('electron')
|
||||||
|
const { app } = require('electron')
|
||||||
|
const path = require('path')
|
||||||
|
const fs = require('fs')
|
||||||
|
// const config = app.getPath('userData');
|
||||||
|
|
||||||
const {app} = require('electron');
|
const Config = require('electron-config')
|
||||||
//const config = app.getPath('userData');
|
const config = new Config()
|
||||||
|
|
||||||
const {TimeChainDataSqliteRecord,ConnectToDatabase, TimeChainDataSqliteFile, TimeChainDataSqliteTag, TimeChainDataSqliteTagLink} = require('./sqlite');
|
let DBPath = config.get('database.path')
|
||||||
|
if (!DBPath) {
|
||||||
|
DBPathDir = app.getPath('userData')
|
||||||
|
DBPath = path.join(DBPathDir, '/timechain.db')
|
||||||
|
config.set('database.path', DBPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
const { TimeChainDataSqliteRecord, ConnectToDatabase, TimeChainDataSqliteFile, TimeChainDataSqliteTag, TimeChainDataSqliteTagLink } = require('./sqlite')
|
||||||
|
|
||||||
const appPath = app.getPath('userData');
|
console.log(DBPath)
|
||||||
|
|
||||||
const DBPath = appPath+"/timechain.db";
|
const DB = ConnectToDatabase(DBPath)
|
||||||
console.log(DBPath);
|
|
||||||
|
|
||||||
const DB = ConnectToDatabase(DBPath);
|
const DbRecord = new TimeChainDataSqliteRecord()
|
||||||
|
const DbFile = new TimeChainDataSqliteFile()
|
||||||
|
const DbTag = new TimeChainDataSqliteTag()
|
||||||
|
const DbTagLink = new TimeChainDataSqliteTagLink()
|
||||||
|
|
||||||
const DbRecord = new TimeChainDataSqliteRecord();
|
// ** Extra IPC Functions
|
||||||
const DbFile = new TimeChainDataSqliteFile();
|
|
||||||
const DbTag = new TimeChainDataSqliteTag();
|
|
||||||
const DbTagLink = new TimeChainDataSqliteTagLink();
|
|
||||||
//const configDir = app.getPath('userData');
|
|
||||||
//const appPath = app.getPath('exe');
|
|
||||||
|
|
||||||
|
ipcMain.handle('select-sqlite-file', (event, arg) => {
|
||||||
|
const { dialog } = require('electron')
|
||||||
|
const files = dialog.showOpenDialog({
|
||||||
|
filters: [{
|
||||||
|
name: 'Sqlite File',
|
||||||
|
extensions: ['db', 'db3']
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!files) return false
|
||||||
|
return files
|
||||||
|
})
|
||||||
|
|
||||||
|
ipcMain.handle('create-sqlite-file', (event, arg) => {
|
||||||
|
const { dialog } = require('electron')
|
||||||
|
const files = dialog.showSaveDialogSync({
|
||||||
|
filters: [{
|
||||||
|
name: 'Sqlite File',
|
||||||
|
extensions: ['db', 'db3']
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
|
||||||
// ** Extra Data
|
if (!files) return false
|
||||||
ipcMain.handle('timechain-config-dir', (event,arg) => {
|
return files
|
||||||
return false;
|
})
|
||||||
});
|
|
||||||
|
/**
|
||||||
|
* Allows the UI to select another database file
|
||||||
|
*/
|
||||||
|
ipcMain.handle('timechain-database-open', (event, arg) => {
|
||||||
|
if (!arg.filename) return false
|
||||||
|
if (!fs.existsSync(arg.filename)) return false
|
||||||
|
config.set('database.path', arg.filename)
|
||||||
|
app.relaunch()
|
||||||
|
app.quit()
|
||||||
|
// DB = ConnectToDatabase(arg.filename)
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows the UI to create a new database instance
|
||||||
|
*/
|
||||||
|
ipcMain.handle('timechain-database-create', (event, arg) => {
|
||||||
|
if (!arg.filename) return false
|
||||||
|
console.log('database.path', arg.filename)
|
||||||
|
config.set('database.path', arg.filename)
|
||||||
|
app.relaunch()
|
||||||
|
app.quit()
|
||||||
|
// DB = ConnectToDatabase(arg.filename)
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
// ** RECORD **
|
// ** RECORD **
|
||||||
console.log("Register timechain-record");
|
console.log('Register timechain-record')
|
||||||
ipcMain.handle('timechain-record', async (event,arg) => {
|
ipcMain.handle('timechain-record', async (event, arg) => {
|
||||||
|
let res = null
|
||||||
|
|
||||||
let res = null;
|
switch (arg.func) {
|
||||||
|
|
||||||
switch(arg.func){
|
|
||||||
case 'add':
|
case 'add':
|
||||||
res = await DbRecord.add(arg.uuid, arg.timestamp, arg.content, arg.mime, arg.hash);
|
res = await DbRecord.add(arg.uuid, arg.timestamp, arg.content, arg.mime, arg.hash)
|
||||||
break;
|
break
|
||||||
case 'delete':
|
case 'delete':
|
||||||
res = await DbRecord.delete(arg.uuid);
|
res = await DbRecord.delete(arg.uuid)
|
||||||
break;
|
break
|
||||||
case 'update':
|
case 'update':
|
||||||
res = await DbRecord.update(arg.uuid,arg.content,arg.mime,arg.hash);
|
res = await DbRecord.update(arg.uuid, arg.content, arg.mime, arg.hash)
|
||||||
break;
|
break
|
||||||
case 'find':
|
case 'find':
|
||||||
res = await DbRecord.find(arg.search,arg.sort,arg.limit,arg.offset);
|
res = await DbRecord.find(arg.search, arg.sort, arg.limit, arg.offset)
|
||||||
break;
|
break
|
||||||
case 'get':
|
case 'get':
|
||||||
res = await DbRecord.get(arg.uuid);
|
res = await DbRecord.get(arg.uuid)
|
||||||
break;
|
break
|
||||||
default:
|
default:
|
||||||
res = new Error('unknown command');
|
res = new Error('unknown command')
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// ** FILE **
|
// ** FILE **
|
||||||
|
|
||||||
ipcMain.handle('timechain-file', async (event, arg) => {
|
ipcMain.handle('timechain-file', async (event, arg) => {
|
||||||
let res = null;
|
let res = null
|
||||||
|
|
||||||
switch(arg.func){
|
switch (arg.func) {
|
||||||
case 'add':
|
case 'add':
|
||||||
res = await DbFile.add(arg.uuid_record,arg.uuid,arg.timestamp,arg.content,arg.mime,arg.hash);
|
res = await DbFile.add(arg.uuid_record, arg.uuid, arg.timestamp, arg.content, arg.mime, arg.hash)
|
||||||
break;
|
break
|
||||||
case 'update':
|
case 'update':
|
||||||
res = await DbFile.update(arg.uuid,arg.timestamp,arg.content,arg.mime,arg.hash);
|
res = await DbFile.update(arg.uuid, arg.timestamp, arg.content, arg.mime, arg.hash)
|
||||||
break;
|
break
|
||||||
case 'get-record':
|
case 'get-record':
|
||||||
res = await DbFile.getByRecord(arg.uuid_record);
|
res = await DbFile.getByRecord(arg.uuid_record)
|
||||||
break;
|
break
|
||||||
case 'delete-record':
|
case 'delete-record':
|
||||||
res = await DbFile.deleteRecord(arg.uuid_record);
|
res = await DbFile.deleteRecord(arg.uuid_record)
|
||||||
break;
|
break
|
||||||
case 'get':
|
case 'get':
|
||||||
res = await DbFile.get(arg.uuid);
|
res = await DbFile.get(arg.uuid)
|
||||||
break;
|
break
|
||||||
case 'delete':
|
case 'delete':
|
||||||
res = await DbFile.delete(arg.uuid);
|
res = await DbFile.delete(arg.uuid)
|
||||||
break;
|
break
|
||||||
default:
|
default:
|
||||||
res = new Error('Unknow a command');
|
res = new Error('Unknow a command')
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res
|
||||||
});
|
})
|
||||||
|
|
||||||
// ** TAG **
|
// ** TAG **
|
||||||
|
|
||||||
ipcMain.handle('timechain-tag', async (event, arg) => {
|
ipcMain.handle('timechain-tag', async (event, arg) => {
|
||||||
|
let res = null
|
||||||
|
|
||||||
let res = null;
|
switch (arg.func) {
|
||||||
|
|
||||||
switch(arg.func){
|
|
||||||
case 'add':
|
case 'add':
|
||||||
res = await DbTag.add(arg.tag);
|
res = await DbTag.add(arg.tag)
|
||||||
break;
|
break
|
||||||
case 'delete':
|
case 'delete':
|
||||||
res = await DbTag.delete(arg.tag);
|
res = await DbTag.delete(arg.tag)
|
||||||
break;
|
break
|
||||||
case 'has':
|
case 'has':
|
||||||
res = await DbTag.delete(arg.tag);
|
res = await DbTag.delete(arg.tag)
|
||||||
break;
|
break
|
||||||
default:
|
default:
|
||||||
res = new Error('Command Unknown');
|
res = new Error('Command Unknown')
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res
|
||||||
|
})
|
||||||
});
|
|
||||||
|
|
||||||
// TAG LINK
|
// TAG LINK
|
||||||
|
|
||||||
ipcMain.handle('timechain-taglink', async (event, arg) => {
|
ipcMain.handle('timechain-taglink', async (event, arg) => {
|
||||||
|
let res = null
|
||||||
|
|
||||||
let res = null;
|
switch (arg.func) {
|
||||||
|
|
||||||
switch(arg.func){
|
|
||||||
case 'add':
|
case 'add':
|
||||||
res = await DbTagLink.add(arg.uuid,arg.tag)
|
res = await DbTagLink.add(arg.uuid, arg.tag)
|
||||||
break;
|
break
|
||||||
case 'delete':
|
case 'delete':
|
||||||
res = await DbTagLink.delete(arg.uuid,arg.tag);
|
res = await DbTagLink.delete(arg.uuid, arg.tag)
|
||||||
break;
|
break
|
||||||
case 'delete-tag':
|
case 'delete-tag':
|
||||||
res = await DbTagLink.deleteTag(arg.tag);
|
res = await DbTagLink.deleteTag(arg.tag)
|
||||||
break;
|
break
|
||||||
case 'delete-record':
|
case 'delete-record':
|
||||||
res = await DbTagLink.deleteRecord(arg.uuid);
|
res = await DbTagLink.deleteRecord(arg.uuid)
|
||||||
break;
|
break
|
||||||
case 'get-records':
|
case 'get-records':
|
||||||
res = await DbTagLink.getRecords(atg.tag);
|
res = await DbTagLink.getRecords(atg.tag)
|
||||||
break;
|
break
|
||||||
case 'get-tags':
|
case 'get-tags':
|
||||||
res = await DbTagLink.getTags(atg.uuid);
|
res = await DbTagLink.getTags(atg.uuid)
|
||||||
break;
|
break
|
||||||
default:
|
default:
|
||||||
res = Error("Commande not known");
|
res = Error('Commande not known')
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res
|
||||||
});
|
})
|
||||||
|
|||||||
@ -1,111 +1,112 @@
|
|||||||
const Interface = require("es6-interface");
|
const Interface = require('es6-interface')
|
||||||
const {InterfaceRecord,InterfaceFile,InterfaceTag,InterfaceTagLink} = require("./interfaces");
|
const { InterfaceRecord, InterfaceFile, InterfaceTag, InterfaceTagLink } = require('./interfaces')
|
||||||
|
const Database = require('better-sqlite3')
|
||||||
|
|
||||||
let db = null;
|
let db = null
|
||||||
|
|
||||||
const ConnectToDatabase = (path)=>{
|
const ConnectToDatabase = (path) => {
|
||||||
db = require('better-sqlite3')(path, {});
|
if (db) {
|
||||||
return db;
|
db.close()
|
||||||
|
db = null
|
||||||
|
}
|
||||||
|
db = new Database(path, {})
|
||||||
|
return db
|
||||||
}
|
}
|
||||||
|
|
||||||
class TimeChainDataSqliteTag extends Interface(InterfaceTag) {
|
class TimeChainDataSqliteTag extends Interface(InterfaceTag) {
|
||||||
|
constructor () {
|
||||||
constructor(){
|
super()
|
||||||
super();
|
|
||||||
const table = `CREATE TABLE IF NOT EXISTS "tags" (
|
const table = `CREATE TABLE IF NOT EXISTS "tags" (
|
||||||
"tag" TEXT UNIQUE,
|
"tag" TEXT UNIQUE,
|
||||||
"created_at" INTEGER NOT NULL,
|
"created_at" INTEGER NOT NULL,
|
||||||
"updated_at" INTEGER NOT NULL,
|
"updated_at" INTEGER NOT NULL,
|
||||||
PRIMARY KEY("tag")
|
PRIMARY KEY("tag")
|
||||||
);`;
|
);`
|
||||||
|
|
||||||
const table_idx = ``;
|
const table_idx = ''
|
||||||
|
|
||||||
if(!db){
|
if (!db) {
|
||||||
throw new Error("Database is not connected");
|
throw new Error('Database is not connected')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
db.exec(table + '\n' + table_idx)
|
||||||
db.exec(table + "\n" + table_idx);
|
this.db = db
|
||||||
this.db = db;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get table_add(){
|
get table_add () {
|
||||||
if(!this._table_add){
|
if (!this._table_add) {
|
||||||
this._table_add = db.prepare("INSERT INTO tags (tag,created_at,updated_at) VALUES (?,?,?)");
|
this._table_add = db.prepare('INSERT INTO tags (tag,created_at,updated_at) VALUES (?,?,?)')
|
||||||
}
|
}
|
||||||
return this._table_add;
|
return this._table_add
|
||||||
}
|
}
|
||||||
|
|
||||||
get table_delete(){
|
get table_delete () {
|
||||||
if(!this._table_delete){
|
if (!this._table_delete) {
|
||||||
this._table_delete = db.prepare("DELETE FROM tags WHERE tag = ?");
|
this._table_delete = db.prepare('DELETE FROM tags WHERE tag = ?')
|
||||||
}
|
}
|
||||||
return this._table_delete;
|
return this._table_delete
|
||||||
}
|
}
|
||||||
|
|
||||||
get table_get(){
|
get table_get () {
|
||||||
if(!this._table_get){
|
if (!this._table_get) {
|
||||||
this._table_get = db.prepare("SELECT * FROM tags WHERE tag = ?");
|
this._table_get = db.prepare('SELECT * FROM tags WHERE tag = ?')
|
||||||
}
|
}
|
||||||
return this._table_get;
|
return this._table_get
|
||||||
}
|
}
|
||||||
|
|
||||||
get table_count(){
|
get table_count () {
|
||||||
if(!this._table_count){
|
if (!this._table_count) {
|
||||||
this._table_count = db.prepare("SELECT count(tag) as cnt FROM tags WHERE tag = ?");
|
this._table_count = db.prepare('SELECT count(tag) as cnt FROM tags WHERE tag = ?')
|
||||||
}
|
}
|
||||||
return this._table_count;
|
return this._table_count
|
||||||
}
|
}
|
||||||
|
|
||||||
add(tag){
|
add (tag) {
|
||||||
return new Promise(resolve=>{
|
return new Promise(resolve => {
|
||||||
this.has(tag).then(cnt=>{
|
this.has(tag).then(cnt => {
|
||||||
if(cnt){
|
if (cnt) {
|
||||||
return resolve(1);
|
return resolve(1)
|
||||||
}else{
|
} else {
|
||||||
const dt = Math.floor(Date.now());
|
const dt = Math.floor(Date.now())
|
||||||
const res = this.table_add.run(tag,dt,dt);
|
const res = this.table_add.run(tag, dt, dt)
|
||||||
return resolve(res?.changes);
|
return resolve(res?.changes)
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(tag){
|
delete (tag) {
|
||||||
return new Promise(resolve=>{
|
return new Promise(resolve => {
|
||||||
const dt = Math.floor(Date.now());
|
const dt = Math.floor(Date.now())
|
||||||
const res = this.table_delete.run(tag);
|
const res = this.table_delete.run(tag)
|
||||||
return resolve(res?.changes);
|
return resolve(res?.changes)
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
get(tag){
|
get (tag) {
|
||||||
return new Promise(resolve=>{
|
return new Promise(resolve => {
|
||||||
const res = this.table_get.get(tag);
|
const res = this.table_get.get(tag)
|
||||||
return resolve(res);
|
return resolve(res)
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
has(tag){
|
has (tag) {
|
||||||
return new Promise(resolve=>{
|
return new Promise(resolve => {
|
||||||
const res = this.table_count.get(tag);
|
const res = this.table_count.get(tag)
|
||||||
return resolve(res && res.cnt>0);
|
return resolve(res && res.cnt > 0)
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class TimeChainDataSqliteTagLink extends Interface(InterfaceTagLink) {
|
class TimeChainDataSqliteTagLink extends Interface(InterfaceTagLink) {
|
||||||
|
constructor () {
|
||||||
constructor(){
|
super()
|
||||||
super();
|
|
||||||
|
|
||||||
this.table = `CREATE TABLE IF NOT EXISTS "taglink" (
|
this.table = `CREATE TABLE IF NOT EXISTS "taglink" (
|
||||||
"uuid" TEXT NOT NULL,
|
"uuid" TEXT NOT NULL,
|
||||||
"tag" TEXT NOT NULL,
|
"tag" TEXT NOT NULL,
|
||||||
"created_at" INTEGER NOT NULL
|
"created_at" INTEGER NOT NULL
|
||||||
);`;
|
);`
|
||||||
this.table_idx = `
|
this.table_idx = `
|
||||||
CREATE INDEX IF NOT EXISTS "uuid_idx" ON "taglink" (
|
CREATE INDEX IF NOT EXISTS "uuid_idx" ON "taglink" (
|
||||||
"uuid"
|
"uuid"
|
||||||
@ -113,108 +114,107 @@ class TimeChainDataSqliteTagLink extends Interface(InterfaceTagLink) {
|
|||||||
CREATE INDEX IF NOT EXISTS "tag_idx" ON "taglink" (
|
CREATE INDEX IF NOT EXISTS "tag_idx" ON "taglink" (
|
||||||
"tag"
|
"tag"
|
||||||
);
|
);
|
||||||
`;
|
`
|
||||||
|
|
||||||
db.exec(this.table + "\n" + this.table_idx);
|
db.exec(this.table + '\n' + this.table_idx)
|
||||||
this.db = db;
|
this.db = db
|
||||||
}
|
}
|
||||||
|
|
||||||
get table_add(){
|
get table_add () {
|
||||||
if(!this._table_add){
|
if (!this._table_add) {
|
||||||
this._table_add = db.prepare('INSERT INTO taglink (uuid,tag,created_at) VALUES (?,?,?)');
|
this._table_add = db.prepare('INSERT INTO taglink (uuid,tag,created_at) VALUES (?,?,?)')
|
||||||
}
|
}
|
||||||
return this._table_add;
|
return this._table_add
|
||||||
}
|
}
|
||||||
|
|
||||||
get table_delete(){
|
get table_delete () {
|
||||||
if(!this._table_delete){
|
if (!this._table_delete) {
|
||||||
this._table_delete = db.prepare('DELETE FROM taglink WHERE uuid=? AND tag=?');
|
this._table_delete = db.prepare('DELETE FROM taglink WHERE uuid=? AND tag=?')
|
||||||
}
|
}
|
||||||
return this._table_delete;
|
return this._table_delete
|
||||||
}
|
}
|
||||||
|
|
||||||
get table_delete_tag(){
|
get table_delete_tag () {
|
||||||
if(!this._table_delete_tag){
|
if (!this._table_delete_tag) {
|
||||||
this._table_delete_tag = db.prepare('DELETE FROM taglink WHERE tag=?');
|
this._table_delete_tag = db.prepare('DELETE FROM taglink WHERE tag=?')
|
||||||
}
|
}
|
||||||
return this._table_delete_tag;
|
return this._table_delete_tag
|
||||||
}
|
}
|
||||||
|
|
||||||
get table_delete_record(){
|
get table_delete_record () {
|
||||||
if(!this._table_delete_record){
|
if (!this._table_delete_record) {
|
||||||
this._table_delete_record = db.prepare('DELETE FROM taglink WHERE uuid=?');
|
this._table_delete_record = db.prepare('DELETE FROM taglink WHERE uuid=?')
|
||||||
}
|
}
|
||||||
return this._table_delete_record;
|
return this._table_delete_record
|
||||||
}
|
}
|
||||||
|
|
||||||
get table_get_records(){
|
get table_get_records () {
|
||||||
if(!this._table_get_records){
|
if (!this._table_get_records) {
|
||||||
this._table_get_records = db.prepare("SELECT * FROM taglink WHERE tag=?");
|
this._table_get_records = db.prepare('SELECT * FROM taglink WHERE tag=?')
|
||||||
}
|
}
|
||||||
return this._table_get_records;
|
return this._table_get_records
|
||||||
}
|
}
|
||||||
|
|
||||||
get table_get_tags(){
|
get table_get_tags () {
|
||||||
if(!this._table_get_tags){
|
if (!this._table_get_tags) {
|
||||||
this._table_get_tags = db.prepare("SELECT * FROM taglink WHERE uuid=?");
|
this._table_get_tags = db.prepare('SELECT * FROM taglink WHERE uuid=?')
|
||||||
}
|
}
|
||||||
return this._table_get_tags;
|
return this._table_get_tags
|
||||||
}
|
}
|
||||||
|
|
||||||
add(uuid,tag){
|
add (uuid, tag) {
|
||||||
return new Promise(resolve=>{
|
return new Promise(resolve => {
|
||||||
const prepare = this.table_add;
|
const prepare = this.table_add
|
||||||
const dt = Math.floor(Date.now());
|
const dt = Math.floor(Date.now())
|
||||||
const res = prepare.run(uuid,tag,dt);
|
const res = prepare.run(uuid, tag, dt)
|
||||||
return resolve(res?.changes);
|
return resolve(res?.changes)
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
delete(uuid,tag){
|
|
||||||
return new Promise(resolve=>{
|
|
||||||
const prepare = this.table_delete;
|
|
||||||
const res = prepare.run(uuid,tag);
|
|
||||||
return resolve(res?.changes);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
deleteTag(tag){
|
|
||||||
return new Promise(resolve=>{
|
|
||||||
const prepare = this.table_delete_tag;
|
|
||||||
const res = prepare.run(tag);
|
|
||||||
return resolve(res?.changes);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
deleteRecord(uuid){
|
|
||||||
return new Promise(resolve=>{
|
|
||||||
const prepare = this.table_delete_record;
|
|
||||||
const res = prepare.run(uuid);
|
|
||||||
return resolve(res?.changes);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
getRecords(tag){
|
|
||||||
return new Promise(resolve=>{
|
|
||||||
const prepare = this.table_get_records;
|
|
||||||
const res = prepare.all(tag);
|
|
||||||
return resolve(res);
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
getTags(uuid){
|
delete (uuid, tag) {
|
||||||
return new Promise(resolve=>{
|
return new Promise(resolve => {
|
||||||
const prepare = this.table_get_tags;
|
const prepare = this.table_delete
|
||||||
const res = prepare.all(uuid);
|
const res = prepare.run(uuid, tag)
|
||||||
return resolve(res);
|
return resolve(res?.changes)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteTag (tag) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
const prepare = this.table_delete_tag
|
||||||
|
const res = prepare.run(tag)
|
||||||
|
return resolve(res?.changes)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteRecord (uuid) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
const prepare = this.table_delete_record
|
||||||
|
const res = prepare.run(uuid)
|
||||||
|
return resolve(res?.changes)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
getRecords (tag) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
const prepare = this.table_get_records
|
||||||
|
const res = prepare.all(tag)
|
||||||
|
return resolve(res)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
getTags (uuid) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
const prepare = this.table_get_tags
|
||||||
|
const res = prepare.all(uuid)
|
||||||
|
return resolve(res)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TimeChainDataSqliteFile extends Interface(InterfaceFile) {
|
class TimeChainDataSqliteFile extends Interface(InterfaceFile) {
|
||||||
|
constructor () {
|
||||||
constructor(){
|
super()
|
||||||
super();
|
|
||||||
const table = `CREATE TABLE IF NOT EXISTS "files" (
|
const table = `CREATE TABLE IF NOT EXISTS "files" (
|
||||||
"uuid" TEXT UNIQUE,
|
"uuid" TEXT UNIQUE,
|
||||||
"uuid_record" TEXT NOT NULL,
|
"uuid_record" TEXT NOT NULL,
|
||||||
@ -225,117 +225,115 @@ class TimeChainDataSqliteFile extends Interface(InterfaceFile) {
|
|||||||
"created_at" INTEGER NOT NULL,
|
"created_at" INTEGER NOT NULL,
|
||||||
"updated_at" INTEGER NOT NULL,
|
"updated_at" INTEGER NOT NULL,
|
||||||
PRIMARY KEY("uuid")
|
PRIMARY KEY("uuid")
|
||||||
);`;
|
);`
|
||||||
const table_idx = `
|
const table_idx = `
|
||||||
CREATE INDEX IF NOT EXISTS "files_idx_record" ON "files" (
|
CREATE INDEX IF NOT EXISTS "files_idx_record" ON "files" (
|
||||||
"uuid_record"
|
"uuid_record"
|
||||||
);
|
);
|
||||||
CREATE INDEX IF NOT EXISTS "files_idx_time" ON "files" (
|
CREATE INDEX IF NOT EXISTS "files_idx_time" ON "files" (
|
||||||
"timestamp" DESC
|
"timestamp" DESC
|
||||||
);`;
|
);`
|
||||||
|
|
||||||
if(!db){
|
if (!db) {
|
||||||
throw new Error("Database is not connected");
|
throw new Error('Database is not connected')
|
||||||
}
|
}
|
||||||
|
|
||||||
db.exec(table + "\n" + table_idx);
|
db.exec(table + '\n' + table_idx)
|
||||||
this.db = db;
|
this.db = db
|
||||||
}
|
}
|
||||||
|
|
||||||
get table_insert() {
|
get table_insert () {
|
||||||
if(!this._table_insert){
|
if (!this._table_insert) {
|
||||||
this._table_insert = db.prepare(`INSERT INTO files (uuid,uuid_record,timestamp,content,mime,hash,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?)`);
|
this._table_insert = db.prepare('INSERT INTO files (uuid,uuid_record,timestamp,content,mime,hash,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?)')
|
||||||
}
|
}
|
||||||
return this._table_insert;
|
return this._table_insert
|
||||||
}
|
}
|
||||||
|
|
||||||
get table_update() {
|
get table_update () {
|
||||||
if(!this._table_update){
|
if (!this._table_update) {
|
||||||
this._table_update = db.prepare(`UPDATE files SET timestamp = ?, content = ?, mime = ? hash = ?, updated_at = ? WHERE uuid = ?`);
|
this._table_update = db.prepare('UPDATE files SET timestamp = ?, content = ?, mime = ? hash = ?, updated_at = ? WHERE uuid = ?')
|
||||||
}
|
}
|
||||||
return this._table_update;
|
return this._table_update
|
||||||
}
|
}
|
||||||
|
|
||||||
get table_delete() {
|
get table_delete () {
|
||||||
if(!this._table_delete){
|
if (!this._table_delete) {
|
||||||
this._table_delete = db.prepare(`DELETE FROM files WHERE uuid = ?`);
|
this._table_delete = db.prepare('DELETE FROM files WHERE uuid = ?')
|
||||||
}
|
}
|
||||||
return this._table_delete;
|
return this._table_delete
|
||||||
}
|
}
|
||||||
|
|
||||||
get table_delete_record() {
|
get table_delete_record () {
|
||||||
|
if (!this._table_delete_record) {
|
||||||
if(!this._table_delete_record){
|
this._table_delete_record = db.prepare('DELETE FROM files WHERE uuid_record = ?')
|
||||||
this._table_delete_record = db.prepare(`DELETE FROM files WHERE uuid_record = ?`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return this._table_delete_record;
|
return this._table_delete_record
|
||||||
}
|
}
|
||||||
|
|
||||||
get table_find_one() {
|
get table_find_one () {
|
||||||
if(!this._table_find_one){
|
if (!this._table_find_one) {
|
||||||
this._table_find_one = db.prepare(`SELECT * FROM files WHERE uuid = ?`);
|
this._table_find_one = db.prepare('SELECT * FROM files WHERE uuid = ?')
|
||||||
}
|
}
|
||||||
return this._table_find_one;
|
return this._table_find_one
|
||||||
}
|
}
|
||||||
|
|
||||||
get table_find_record(){
|
get table_find_record () {
|
||||||
if(!this._table_find_record){
|
if (!this._table_find_record) {
|
||||||
this._table_find_record = db.prepare(`SELECT * FROM files WHERE uuid_record = ?`);
|
this._table_find_record = db.prepare('SELECT * FROM files WHERE uuid_record = ?')
|
||||||
}
|
}
|
||||||
return this._table_find_record;
|
return this._table_find_record
|
||||||
}
|
}
|
||||||
|
|
||||||
add(uuid_record,uuid,timestamp,content,mime,hash){
|
add (uuid_record, uuid, timestamp, content, mime, hash) {
|
||||||
return new Promise(resolve=>{
|
|
||||||
const dt = Math.floor(Date.now());
|
|
||||||
const res = this.table_insert.run(uuid,uuid_record,timestamp,content,mime,hash,dt,dt);
|
|
||||||
return resolve(res?.changes);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
getByRecord(uuid_record){
|
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
const res = this.table_find_record.get(uuid_record);
|
const dt = Math.floor(Date.now())
|
||||||
return resolve(res);
|
const res = this.table_insert.run(uuid, uuid_record, timestamp, content, mime, hash, dt, dt)
|
||||||
});
|
return resolve(res?.changes)
|
||||||
}
|
|
||||||
|
|
||||||
get(uuid){
|
|
||||||
return new Promise(resolve => {
|
|
||||||
const res = this.table_find_one.get(uuid);
|
|
||||||
return resolve(res);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
delete(uuid){
|
|
||||||
return new Promise(resolve=>{
|
|
||||||
const prepare = this.table_delete;
|
|
||||||
const res = prepare.run(uuid);
|
|
||||||
return resolve(res?.changes);
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteRecord(uuid_record){
|
getByRecord (uuid_record) {
|
||||||
return new Promise(resolve=>{
|
return new Promise(resolve => {
|
||||||
const res = this.table_delete_record.run(uuid_record);
|
const res = this.table_find_record.get(uuid_record)
|
||||||
return resolve(res?.changes);
|
return resolve(res)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
update(uuid,timestamp,content,mime,hash){
|
get (uuid) {
|
||||||
return new Promise(resolve=>{
|
return new Promise(resolve => {
|
||||||
const res = this.table_update.run(timestamp,content,mime,hash,uuid);
|
const res = this.table_find_one.get(uuid)
|
||||||
return resolve(res?.changes);
|
return resolve(res)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
delete (uuid) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
const prepare = this.table_delete
|
||||||
|
const res = prepare.run(uuid)
|
||||||
|
return resolve(res?.changes)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteRecord (uuid_record) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
const res = this.table_delete_record.run(uuid_record)
|
||||||
|
return resolve(res?.changes)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
update (uuid, timestamp, content, mime, hash) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
const res = this.table_update.run(timestamp, content, mime, hash, uuid)
|
||||||
|
return resolve(res?.changes)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TimeChainDataSqliteRecord extends Interface(InterfaceRecord) {
|
class TimeChainDataSqliteRecord extends Interface(InterfaceRecord) {
|
||||||
|
constructor () {
|
||||||
constructor(){
|
super()
|
||||||
super();
|
// TODO: Create Tables Here if not exist
|
||||||
//TODO: Create Tables Here if not exist
|
|
||||||
const table = `CREATE TABLE IF NOT EXISTS "records" (
|
const table = `CREATE TABLE IF NOT EXISTS "records" (
|
||||||
"uuid" TEXT NOT NULL UNIQUE,
|
"uuid" TEXT NOT NULL UNIQUE,
|
||||||
"timestamp" INTEGER NOT NULL,
|
"timestamp" INTEGER NOT NULL,
|
||||||
@ -345,113 +343,182 @@ class TimeChainDataSqliteRecord extends Interface(InterfaceRecord) {
|
|||||||
"created_at" INTEGER NOT NULL,
|
"created_at" INTEGER NOT NULL,
|
||||||
"updated_at" INTEGER NOT NULL,
|
"updated_at" INTEGER NOT NULL,
|
||||||
PRIMARY KEY("uuid")
|
PRIMARY KEY("uuid")
|
||||||
);`;
|
);`
|
||||||
const table_idx = `CREATE INDEX IF NOT EXISTS "records_idx_timestamp" ON "records" (
|
const table_idx = `CREATE INDEX IF NOT EXISTS "records_idx_timestamp" ON "records" (
|
||||||
"timestamp" DESC
|
"timestamp" DESC
|
||||||
);`
|
);`
|
||||||
|
|
||||||
if(!db){
|
if (!db) {
|
||||||
throw new Error("Database is not connected");
|
throw new Error('Database is not connected')
|
||||||
}
|
}
|
||||||
|
|
||||||
db.exec(table + "\n" + table_idx);
|
db.exec(table + '\n' + table_idx)
|
||||||
this.db = db;
|
this.db = db
|
||||||
}
|
}
|
||||||
|
|
||||||
get table_insert() {
|
get table_insert () {
|
||||||
if(!this._table_insert){
|
if (!this._table_insert) {
|
||||||
this._table_insert = db.prepare(`INSERT INTO records (uuid,timestamp,content,mime,hash,created_at,updated_at) VALUES (?,?,?,?,?,?,?)`);
|
this._table_insert = db.prepare('INSERT INTO records (uuid,timestamp,content,mime,hash,created_at,updated_at) VALUES (?,?,?,?,?,?,?)')
|
||||||
}
|
}
|
||||||
return this._table_insert;
|
return this._table_insert
|
||||||
}
|
}
|
||||||
|
|
||||||
get table_update(){
|
get table_update () {
|
||||||
if(!this._table_update){
|
if (!this._table_update) {
|
||||||
this._table_update = db.prepare(`UPDATE records SET timestamp = ?, content = ?, mime = ?, hash = ? updated_at = ? WHERE uuid = ?`);
|
this._table_update = db.prepare('UPDATE records SET timestamp = ?, content = ?, mime = ?, hash = ? updated_at = ? WHERE uuid = ?')
|
||||||
}
|
}
|
||||||
return this._table_update;
|
return this._table_update
|
||||||
}
|
}
|
||||||
|
|
||||||
get table_delete(){
|
get table_delete () {
|
||||||
if(!this._table_delete){
|
if (!this._table_delete) {
|
||||||
this._table_delete = db.prepare(`DELETE FROM records WHERE uuid = ?`);
|
this._table_delete = db.prepare('DELETE FROM records WHERE uuid = ?')
|
||||||
}
|
}
|
||||||
return this._table_delete;
|
return this._table_delete
|
||||||
}
|
}
|
||||||
|
|
||||||
get table_fine_one(){
|
get table_fine_one () {
|
||||||
if(!this._table_fine_one){
|
if (!this._table_fine_one) {
|
||||||
this._table_fine_one = db.prepare(`SELECT * FROM records WHERE uuid = ?`);
|
this._table_fine_one = db.prepare('SELECT * FROM records WHERE uuid = ?')
|
||||||
}
|
}
|
||||||
return this._table_fine_one;
|
return this._table_fine_one
|
||||||
}
|
}
|
||||||
|
|
||||||
get table_find(){
|
get table_find () {
|
||||||
if(!this._table_find){
|
if (!this._table_find) {
|
||||||
this._table_find = db.prepare(`
|
this._table_find = db.prepare(`
|
||||||
select records.*, GROUP_CONCAT(taglink.tag,',') AS tags
|
select records.*,
|
||||||
|
(SELECT GROUP_CONCAT(tag,',') FROM taglink WHERE taglink.uuid = records.uuid) as tags
|
||||||
|
from records
|
||||||
|
order by records.timestamp DESC
|
||||||
|
limit ? offset ?
|
||||||
|
`)
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._table_find
|
||||||
|
}
|
||||||
|
|
||||||
|
generator_find_sql (tags) {
|
||||||
|
let query = `
|
||||||
|
select records.*,
|
||||||
|
(SELECT GROUP_CONCAT(tag,',') FROM taglink WHERE taglink.uuid = records.uuid) as tags
|
||||||
from records
|
from records
|
||||||
left join taglink on (taglink.uuid = records.uuid)
|
left join taglink on (taglink.uuid = records.uuid)
|
||||||
|
{where}
|
||||||
group by records.uuid
|
group by records.uuid
|
||||||
order by records.timestamp DESC
|
order by records.timestamp DESC
|
||||||
limit ? offset ?
|
limit ? offset ?
|
||||||
`);
|
`;
|
||||||
|
|
||||||
|
const where = [];
|
||||||
|
|
||||||
|
tags.forEach(tag => {
|
||||||
|
|
||||||
|
if( tag.indexOf(':') != -1 ){
|
||||||
|
//Skip Filter
|
||||||
|
const parts = tag.split(':');
|
||||||
|
const cmd = parts[0];
|
||||||
|
|
||||||
|
const dayjs = require('dayjs');
|
||||||
|
|
||||||
|
switch (cmd){
|
||||||
|
case 'before':
|
||||||
|
const time_before = Math.floor(dayjs(parts[1]).toDate().getTime());
|
||||||
|
where.push(`record.timestamp < ${time_before}`);
|
||||||
|
break;
|
||||||
|
case 'after':
|
||||||
|
const time_after = Math.floor(dayjs(parts[1]).toDate().getTime());
|
||||||
|
where.push(`record.timestamp > ${time_after}`);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this._table_find;
|
}else{
|
||||||
|
let cleantag = tag.replace(/\'/g,"''");
|
||||||
|
where.push(`taglink.tag = '${cleantag}'`);
|
||||||
}
|
}
|
||||||
|
|
||||||
add(uuid,timestamp,content,mime,hash){
|
|
||||||
return new Promise(resolve=>{
|
|
||||||
const dt = Math.floor(Date.now());
|
|
||||||
const res = this.table_insert.run(uuid,timestamp,content,mime,hash,dt,dt);
|
|
||||||
return resolve(res?.changes);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let where_string = "WHERE " + where.join(" AND ");
|
||||||
|
|
||||||
|
query = query.replace('{where}', where_string);
|
||||||
|
|
||||||
|
console.log(query);
|
||||||
|
|
||||||
|
return db.prepare(query);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get(uuid){
|
add (uuid, timestamp, content, mime, hash) {
|
||||||
return new Promise(resolve=>{
|
return new Promise(resolve => {
|
||||||
const rec = this.table_fine_one.get(uuid);
|
const dt = Math.floor(Date.now())
|
||||||
return resolve(rec);
|
const res = this.table_insert.run(uuid, timestamp, content, mime, hash, dt, dt)
|
||||||
});
|
return resolve(res?.changes)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
find(search,sort=null,limit=undefined,offset=0){
|
get (uuid) {
|
||||||
//TODO: add logic for seach and sort (Currently does nothing)
|
return new Promise(resolve => {
|
||||||
return new Promise(resolve=>{
|
const rec = this.table_fine_one.get(uuid)
|
||||||
const prepare = this.table_find;
|
return resolve(rec)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const res = prepare.all(100,0);
|
find (search, sort = null, limit = undefined, offset = 0) {
|
||||||
|
// TODO: add logic for seach and sort (Currently does nothing)
|
||||||
|
return new Promise(resolve => {
|
||||||
|
|
||||||
//TODO: add count here
|
if(!search || !search.tags || Object.keys(search.tags).length === 0){
|
||||||
const rescount = {cnt:100};
|
const prepare = this.table_find
|
||||||
|
|
||||||
|
const res = prepare.all(100, 0)
|
||||||
|
|
||||||
|
// TODO: add count here
|
||||||
|
const rescount = { cnt: 100 }
|
||||||
|
|
||||||
return resolve({
|
return resolve({
|
||||||
data: res,
|
data: res,
|
||||||
count: rescount?.cnt,
|
count: rescount?.cnt,
|
||||||
limit: limit,
|
limit: limit,
|
||||||
offset: offset
|
offset: offset
|
||||||
});
|
})
|
||||||
|
|
||||||
|
}else{
|
||||||
|
|
||||||
|
console.log(search);
|
||||||
|
|
||||||
|
const prepare = this.generator_find_sql(search.tags);
|
||||||
|
const res = prepare.all(100, 0)
|
||||||
|
const rescount = { cnt: 100 }
|
||||||
|
return resolve({
|
||||||
|
data: res,
|
||||||
|
count: rescount?.cnt,
|
||||||
|
limit: limit,
|
||||||
|
offset: offset
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(uuid){
|
|
||||||
return new Promise(resolve=>{
|
|
||||||
const prepare = this.table_delete;
|
|
||||||
const res = prepare.run(uuid);
|
|
||||||
return resolve(res?.changes);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
update(uuid,content,mime,hash){
|
|
||||||
return new Promise(resolve=>{
|
|
||||||
const dt = Math.floor(Date.now());
|
|
||||||
const res = this.table_update.run(content,mime,hash,dt,uuid);
|
|
||||||
return resolve(res?.changes);
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete (uuid) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
const prepare = this.table_delete
|
||||||
|
const res = prepare.run(uuid)
|
||||||
|
return resolve(res?.changes)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
update (uuid, content, mime, hash) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
const dt = Math.floor(Date.now())
|
||||||
|
const res = this.table_update.run(content, mime, hash, dt, uuid)
|
||||||
|
return resolve(res?.changes)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TimeChainDataSqlite {
|
class TimeChainDataSqlite {
|
||||||
@ -466,6 +533,3 @@ module.exports = {
|
|||||||
TimeChainDataSqliteTagLink,
|
TimeChainDataSqliteTagLink,
|
||||||
TimeChainDataSqliteTag
|
TimeChainDataSqliteTag
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
102
src/ui/app.riot
102
src/ui/app.riot
@ -13,6 +13,12 @@
|
|||||||
import TimechainInput from './timechain-input.riot'
|
import TimechainInput from './timechain-input.riot'
|
||||||
import TimechainList from './timechain-list.riot'
|
import TimechainList from './timechain-list.riot'
|
||||||
import AppDivider from './app-divider.riot'
|
import AppDivider from './app-divider.riot'
|
||||||
|
import keymage from 'keymage';
|
||||||
|
import pubsub from 'pubsub-js';
|
||||||
|
|
||||||
|
if(window.Timechain_isElectron){
|
||||||
|
const { ipcRenderer } = window.require('electron')
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@ -20,7 +26,103 @@
|
|||||||
TimechainInput,
|
TimechainInput,
|
||||||
TimechainList,
|
TimechainList,
|
||||||
AppDivider
|
AppDivider
|
||||||
|
},
|
||||||
|
onBeforeMount(){
|
||||||
|
console.log('Init');
|
||||||
|
},
|
||||||
|
onMounted(){
|
||||||
|
|
||||||
|
console.log("Application Mounted");
|
||||||
|
|
||||||
|
if(window.Timechain_isElectron){
|
||||||
|
console.log("Is Electron");
|
||||||
|
this.setupElectronKeyEvents();
|
||||||
|
}else{
|
||||||
|
console.log("Is Browser");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
setupElectronKeyEvents(){
|
||||||
|
const kevents = [];
|
||||||
|
kevents.push( keymage('ctrl-o', this.onElectronOpenDatabase.bind(this)) );
|
||||||
|
kevents.push( keymage('ctrl-n', this.onElectronCreateDatabase.bind(this)) );
|
||||||
|
|
||||||
|
this._keyEvents = kevents;
|
||||||
|
},
|
||||||
|
async onElectronOpenDatabase(){
|
||||||
|
const file = await ipcRenderer.invoke('select-sqlite-file',{});
|
||||||
|
console.log(file)
|
||||||
|
|
||||||
|
const filepath = (file && file.filePaths) ? file.filePaths[0] : false;
|
||||||
|
console.log(filepath);
|
||||||
|
|
||||||
|
if(!filepath){
|
||||||
|
return alert("Could not load file. Filename not provided.")
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("Loading new database");
|
||||||
|
const loaded = await ipcRenderer.invoke('timechain-database-open',{filename:filepath});
|
||||||
|
|
||||||
|
if(!loaded){
|
||||||
|
return alert("Database loading failed");
|
||||||
|
}else{
|
||||||
|
console.log("%c Database Reloaded","background-color:red;color:white;");
|
||||||
|
pubsub.publish('database-reloaded',true);
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
async onElectronCreateDatabase(){
|
||||||
|
|
||||||
|
console.log("Create Datbase Event");
|
||||||
|
|
||||||
|
const file = await ipcRenderer.invoke('create-sqlite-file',{});
|
||||||
|
console.log("Returned")
|
||||||
|
console.log(file);
|
||||||
|
|
||||||
|
//const filepath = (file && file.filePaths) ? file.filePaths[0] : false;
|
||||||
|
//console.log(filepath);
|
||||||
|
|
||||||
|
const filepath = file;
|
||||||
|
|
||||||
|
if(!filepath){
|
||||||
|
console.warn("No file name");
|
||||||
|
return alert("Could not create file. Filename not provided.",filepath);
|
||||||
|
}else{
|
||||||
|
console.log("We have a file name.. Time to make db");
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("Creating new database")
|
||||||
|
|
||||||
|
const loaded = await ipcRenderer.invoke('timechain-database-create',{filename:filepath});
|
||||||
|
|
||||||
|
if(!loaded){
|
||||||
|
return alert("Database not created");
|
||||||
|
}else{
|
||||||
|
console.log("%c Database Created","background-color:red;color:white;");
|
||||||
|
pubsub.publish('database-reloaded', true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*onElectronCreateDatabaseOld(){
|
||||||
|
return ipcRenderer.invoke('select-sqlite-file',{}).then(file=>{
|
||||||
|
console.log(file)
|
||||||
|
const filepath = (file && file.filePaths) ? file.filePaths[0] : false;
|
||||||
|
console.log(filepath);
|
||||||
|
if(!filepath){
|
||||||
|
return alert("Could not load file. Filename not provided.")
|
||||||
|
|
||||||
|
return ipcRenderer.invoke('timechain-database-open',{}).then(success=>{
|
||||||
|
console.log("DB RETURNED");
|
||||||
|
if(success){
|
||||||
|
console.log("%c Database Reloaded","background-color:red;color:white;");
|
||||||
|
pubsub.publish('database-reloaded',true);
|
||||||
|
}else{
|
||||||
|
console.log("Database loading failed");
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -54,6 +54,10 @@
|
|||||||
onMounted(){
|
onMounted(){
|
||||||
document.addEventListener('paste', this.pasteEvent.bind(this));
|
document.addEventListener('paste', this.pasteEvent.bind(this));
|
||||||
|
|
||||||
|
this.event_dbreloaded = pubsub.subscribe('database-reloaded', (event,res)=>{
|
||||||
|
pubsub.publish('timechain-list-update', true);
|
||||||
|
})
|
||||||
|
|
||||||
this.setupKeyEvents();
|
this.setupKeyEvents();
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
@ -86,6 +90,7 @@
|
|||||||
this._keyevents.forEach(f=>{
|
this._keyevents.forEach(f=>{
|
||||||
f();
|
f();
|
||||||
});
|
});
|
||||||
|
pubsub.unsubscribe(this.event_dbreloaded);
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Window paste event has been fire.
|
* Window paste event has been fire.
|
||||||
|
|||||||
@ -1,5 +1,11 @@
|
|||||||
<timechain-list>
|
<timechain-list>
|
||||||
|
|
||||||
|
<div class="search-row">
|
||||||
|
<div class="search-tag">
|
||||||
|
<timechain-tag ontag="{onTags}" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="top-gradient"></div>
|
<div class="top-gradient"></div>
|
||||||
<div class="timechain-list">
|
<div class="timechain-list">
|
||||||
|
|
||||||
@ -41,6 +47,9 @@
|
|||||||
import TimechainTagList from './timechain-tag-list.riot'
|
import TimechainTagList from './timechain-tag-list.riot'
|
||||||
import pubsub from 'pubsub-js'
|
import pubsub from 'pubsub-js'
|
||||||
|
|
||||||
|
import TimechainTag from './timechain-tag.riot'
|
||||||
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
TimeChainDataSqliteRecord
|
TimeChainDataSqliteRecord
|
||||||
} = require('../data/sqlite-client');
|
} = require('../data/sqlite-client');
|
||||||
@ -54,7 +63,8 @@
|
|||||||
components: {
|
components: {
|
||||||
Raw,
|
Raw,
|
||||||
TimestampStatic,
|
TimestampStatic,
|
||||||
TimechainTagList
|
TimechainTagList,
|
||||||
|
TimechainTag
|
||||||
},
|
},
|
||||||
onMounted(){
|
onMounted(){
|
||||||
console.log("List mounted");
|
console.log("List mounted");
|
||||||
@ -67,11 +77,19 @@
|
|||||||
pubsub.unsubscribe(this.event_load);
|
pubsub.unsubscribe(this.event_load);
|
||||||
},
|
},
|
||||||
|
|
||||||
loadRecords(){
|
loadRecords(search){
|
||||||
this.update({loading:true});
|
this.update({loading:true});
|
||||||
const TR = new TimeChainDataSqliteRecord();
|
const TR = new TimeChainDataSqliteRecord();
|
||||||
|
|
||||||
TR.find({},null,100,0).then(records=>{
|
if(!search) {
|
||||||
|
if(this.last_search){
|
||||||
|
search = this.last_search
|
||||||
|
}else{
|
||||||
|
search = {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TR.find(search,null,100,0).then(records=>{
|
||||||
console.log("Records", records);
|
console.log("Records", records);
|
||||||
this.update({records:records.data,loading:false});
|
this.update({records:records.data,loading:false});
|
||||||
}).then(()=>{
|
}).then(()=>{
|
||||||
@ -88,6 +106,25 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.update();
|
this.update();
|
||||||
|
},
|
||||||
|
|
||||||
|
onTags(tags){
|
||||||
|
|
||||||
|
if(tags==''){
|
||||||
|
return this.loadRecords({});
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(tags);
|
||||||
|
tags = JSON.parse(tags);
|
||||||
|
const search = [];
|
||||||
|
tags.map(t=>{
|
||||||
|
//console.log(t.value);
|
||||||
|
search.push(t.value);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.loadRecords({
|
||||||
|
tags:search
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<timechain-tag>
|
<timechain-tag>
|
||||||
<div class="timechain-tagging">
|
<div class="timechain-tagging">
|
||||||
<input id="tagging" placeholder="tag your paste">
|
<input id="{state.id}" placeholder="tag your paste">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@ -8,8 +8,14 @@
|
|||||||
const pubsub = require('pubsub-js');
|
const pubsub = require('pubsub-js');
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
state:{
|
||||||
|
id:'tagging'
|
||||||
|
},
|
||||||
|
onBeforeMount(){
|
||||||
|
this.state.id = "tagging"+this.makeid(5);
|
||||||
|
},
|
||||||
onMounted(){
|
onMounted(){
|
||||||
const inputElm = this.$('#tagging');
|
const inputElm = this.$('#'+this.state.id);
|
||||||
this.tagify = new Tagify(inputElm);
|
this.tagify = new Tagify(inputElm);
|
||||||
inputElm.addEventListener('change', this.onChange.bind(this));
|
inputElm.addEventListener('change', this.onChange.bind(this));
|
||||||
this.event_clean = pubsub.subscribe('tag.clean', this.onClean.bind(this));
|
this.event_clean = pubsub.subscribe('tag.clean', this.onClean.bind(this));
|
||||||
@ -22,6 +28,15 @@
|
|||||||
},
|
},
|
||||||
onClean(){
|
onClean(){
|
||||||
this.tagify.removeAllTags();
|
this.tagify.removeAllTags();
|
||||||
|
},
|
||||||
|
makeid(length) {
|
||||||
|
var result = '';
|
||||||
|
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||||
|
var charactersLength = characters.length;
|
||||||
|
for ( var i = 0; i < length; i++ ) {
|
||||||
|
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
36
start.js
36
start.js
@ -1,34 +1,14 @@
|
|||||||
import './src/less/main.less';
|
import './src/less/main.less'
|
||||||
import './src/css/tagify.scss';
|
import './src/css/tagify.scss'
|
||||||
|
|
||||||
import * as Sentry from "@sentry/browser";
|
|
||||||
import { BrowserTracing } from "@sentry/tracing";
|
|
||||||
|
|
||||||
Sentry.init({
|
|
||||||
dsn: "http://a12d5c5f800b406f8d1c0c5d2ed63a78@216.128.138.128:8000/1",
|
|
||||||
|
|
||||||
// Alternatively, use `process.env.npm_package_version` for a dynamic release version
|
|
||||||
// if your build tool supports it.
|
|
||||||
release: "timechain@1.0.0",
|
|
||||||
integrations: [new BrowserTracing()],
|
|
||||||
|
|
||||||
// Set tracesSampleRate to 1.0 to capture 100%
|
|
||||||
// of transactions for performance monitoring.
|
|
||||||
// We recommend adjusting this value in production
|
|
||||||
tracesSampleRate: 1.0,
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
import App from './src/ui/app.riot'
|
import App from './src/ui/app.riot'
|
||||||
|
|
||||||
import { component } from 'riot'
|
import { component } from 'riot'
|
||||||
|
|
||||||
window.debugging = true;
|
window.debugging = true
|
||||||
|
|
||||||
setTimeout(()=>{
|
|
||||||
document.getElementById('main-loading')?.remove();
|
|
||||||
component(App)(document.getElementById('timechain'));
|
|
||||||
Sentry.captureMessage('Application Started');
|
|
||||||
},0)
|
|
||||||
|
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
document.getElementById('main-loading')?.remove()
|
||||||
|
component(App)(document.getElementById('timechain'))
|
||||||
|
Sentry.captureMessage('Application Started')
|
||||||
|
}, 0)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user