kiran-db
Version:
This is how javascript managa json data as the database
152 lines (110 loc) • 3.71 kB
text/typescript
import fs from 'fs'
import path from 'path'
interface Error {
exists: boolean
message: string
}
export default class DB {
private name: string
private data: any[] = []
private error: Error = { exists: false, message: '' }
private selected: any[] = []
private selection: boolean = false
protected constructor (name: string) {
this.name = name + '.json'
this.makesure()
}
protected makesure () {
const filename = path.join(path.resolve(), 'dbs', this.name)
if ( !fs.existsSync(filename) ) fs.writeFileSync(filename, '[]')
}
protected rewrite (affectedIDs: number[] | number) {
const filename = path.join(path.resolve(), 'dbs', this.name)
const datastring = JSON.stringify(this.data)
try {
fs.writeFileSync(filename, datastring)
console.log('Database re-written')
} catch {
this.error = { exists: true, message: 'Failed to re-write database!' }
}
this.end()
return this.error.exists ? this.error : { ok: true, affectedIDs }
}
protected getselected (field: string) {
return this.selected.map((selected: any) => selected[field])
}
protected getincrementid () {
const lastdata = this.data[this.data.length -1]
return lastdata ? lastdata.id + 1 : 1
}
protected loopcreate (newdata: any[], status: any[]) {
newdata.forEach((data: any) => {
const created = this.create(data)
status.push(created)
})
return status
}
protected end () {
this.selected = []
this.selection = false
}
public create (newdata: any) {
if ( Array.isArray(newdata) ) return this.loopcreate(newdata, [])
this.data = this.read()
const id = this.getincrementid()
this.data.push({ id, ...newdata })
return this.rewrite(id)
}
public read () {
if ( this.selection ) return this.selected
const filename: string = path.join(path.resolve(), 'dbs', this.name)
const datastring: string = fs.readFileSync(filename, 'utf8')
return JSON.parse(datastring)
}
public update (newdata: any) {
const selectedids = this.getselected('id')
if ( !selectedids.length ) return { ok: false, message: 'No item selected!' }
this.data = this.data.map((data: any) => {
if ( selectedids.includes(data.id) )
for ( let [key, val] of Object.entries(newdata) )
data[key] = val
return data
})
return this.rewrite(selectedids)
}
public delete () {
const selectedids = this.getselected('id')
if ( !selectedids.length ) return { ok: false, message: 'No item selected' }
this.data = this.data.filter((data: any) => {
if ( !selectedids.includes(data.id) ) return data
})
return this.rewrite(selectedids)
}
public where (callback: any) {
this.selection = false
this.data = this.read()
this.selected = this.data.filter(callback)
this.selection = true
return this
}
public join (other: string, field: string) {
const selectedids = this.getselected('id')
if ( !selectedids.length ) {
console.log('No selected items')
return []
} else console.log('Joining into ' + other)
const selecteddata = this.selected.map(selected => {
const joinmodel = new Join(other)
const joindata = joinmodel.where((data: any) => selectedids.includes(data[field])).read()
selected[other] = joindata
return selected
})
this.end()
return selecteddata
}
}
class Join extends DB {
public constructor (name: string) {
super(name)
}
}