-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathSimpleDB.ts
153 lines (143 loc) · 4.63 KB
/
SimpleDB.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
import pkg from "duckdb"
const { Database } = pkg
import runQueryNode from "../helpers/runQueryNode.js"
import SimpleWebDB from "./SimpleWebDB.js"
import SimpleTable from "./SimpleTable.js"
import cleanCache from "../helpers/cleanCache.js"
import { prettyDuration } from "journalism"
/**
* SimpleDB is a class that provides a simplified interface for working with DuckDB, a high-performance, in-memory analytical database. This class is meant to be used with NodeJS and similar runtimes. For web browsers, use SimpleWebDB.
*
* With very expensive computations, it might create a .tmp folder, so make sure to add .tmp to your gitignore.
*
* Here's how to instantiate a SimpleDB instance and then a SimpleTable.
*
* @example Basic usage
* ```ts
* // Instantiating the database.
* const sdb = new SimpleDB()
*
* // Creating a new table.
* const employees = sdb.newTable("employees")
*
* // You can now invoke methods on the table.
* await employees.loadData("./employees.csv")
* await employees.logTable()
*
* // To free up memory.
* await sdb.done()
* ```
*
* @example Instanciating with options
* ```ts
* // Creating a database with options. Debug information will be logged each time a method is invoked. The first 20 rows of tables will be logged (default is 10).
* const sdb = new SimpleWebDB({ debug: true, nbRowsToLog: 20 })
* ```
*
*/
export default class SimpleDB extends SimpleWebDB {
/** A flag to log messages relative to the cache. Defaults to false. */
cacheVerbose: boolean
constructor(
options: {
logDuration?: boolean
nbRowsToLog?: number
nbCharactersToLog?: number
cacheVerbose?: boolean
debug?: boolean
bigIntToInt?: boolean
} = {}
) {
super(options)
this.bigIntToInt = options.bigIntToInt ?? true
this.cacheVerbose = options.cacheVerbose ?? false
this.runQuery = runQueryNode
}
/**
* Initializes DuckDB and establishes a connection to the database. For internal use only.
*
* @category Internal
*/
async start() {
if (this.db === undefined || this.connection === undefined) {
this.debug && console.log("\nstart()")
this.db = new Database(":memory:")
this.connection = this.db.connect()
}
return this
}
/** Creates a table in the DB.
*
* @example Basic usage
* ```ts
* // This returns a new SimpleTable
* const employees = sdb.newTable()
* ```
*
* @example With a specific name
* ```ts
* // By default, tables will be named table1, table2, etc.
* // But you can also give them specific names.
* const employees = sdb.newTable("employees")
* ```
*
* @param name - The name of the new table.
* @param projections - The projections of the geospatial data, if any.
*
* @category DB methods
*/
newTable(
name?: string,
projections?: { [key: string]: string }
): SimpleTable {
this.debug && console.log("\nnewTable()")
const proj = projections ?? {}
let table
if (typeof name === "string") {
table = new SimpleTable(name, proj, this, {
debug: this.debug,
nbRowsToLog: this.nbRowsToLog,
nbCharactersToLog: this.nbCharactersToLog,
})
table.defaultTableName = false
} else {
table = new SimpleTable(`table${this.tableIncrement}`, proj, this, {
debug: this.debug,
nbRowsToLog: this.nbRowsToLog,
bigIntToInt: this.bigIntToInt,
nbCharactersToLog: this.nbCharactersToLog,
})
table.defaultTableName = true
this.tableIncrement += 1
}
this.debug &&
console.log(
`${table.name} has been created ${table.defaultTableName ? "(name automatically attributed)" : ""}`
)
return table
}
/**
* Frees up memory by closing down the database and cleans up cache so it doesn't grow in size indefinitely.
*
* @example Basic usage
* ```typescript
* await sdb.done();
* ```
*
* @category DB methods
*/
async done() {
this.debug && console.log("\ndone()")
if (this.db instanceof Database) {
this.db.close()
}
cleanCache(this)
if (typeof this.durationStart === "number") {
prettyDuration(this.durationStart, {
log: true,
prefix: "\nSimpleDB - Done in ",
suffix: "\n",
})
}
}
}