@onurege3467/zerohelper 8.0.0 → 9.0.0
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/README.md +292 -612
- package/dist/database/IDatabase.d.ts +77 -0
- package/dist/database/IDatabase.js +10 -0
- package/dist/database/cacheWrapper.d.ts +31 -0
- package/dist/database/cacheWrapper.js +228 -0
- package/dist/database/index.d.ts +11 -0
- package/dist/database/index.js +94 -0
- package/dist/database/json.d.ts +32 -0
- package/dist/database/json.js +210 -0
- package/dist/database/migration.d.ts +21 -0
- package/dist/database/migration.js +97 -0
- package/dist/database/mongodb.d.ts +24 -0
- package/dist/database/mongodb.js +153 -0
- package/dist/database/mysql.d.ts +31 -0
- package/dist/database/mysql.js +385 -0
- package/dist/database/pg.d.ts +30 -0
- package/dist/database/pg.js +300 -0
- package/dist/database/redis.d.ts +23 -0
- package/dist/database/redis.js +157 -0
- package/dist/database/sqlite.d.ts +25 -0
- package/dist/database/sqlite.js +273 -0
- package/dist/database/types.d.ts +76 -0
- package/dist/database/types.js +2 -0
- package/dist/database/zpack.d.ts +59 -0
- package/dist/database/zpack.js +462 -0
- package/dist/functions/index.d.ts +183 -0
- package/dist/functions/index.js +636 -0
- package/dist/functions/temp_isphone.d.ts +1 -0
- package/dist/functions/temp_isphone.js +7 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +45 -0
- package/dist/test.d.ts +1 -0
- package/dist/test.js +55 -0
- package/dist/test_zpack.d.ts +1 -0
- package/dist/test_zpack.js +64 -0
- package/package.json +23 -6
- package/database/IDatabase.js +0 -92
- package/database/cacheWrapper.js +0 -585
- package/database/index.js +0 -72
- package/database/json.js +0 -281
- package/database/migration.js +0 -227
- package/database/mongodb.js +0 -203
- package/database/mysql.js +0 -526
- package/database/pg.js +0 -527
- package/database/redis.js +0 -342
- package/database/sqlite.js +0 -551
- package/functions/index.js +0 -705
- package/index.js +0 -7
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.SQLiteDatabase = void 0;
|
|
7
|
+
const IDatabase_1 = require("./IDatabase");
|
|
8
|
+
const sqlite3_1 = __importDefault(require("sqlite3"));
|
|
9
|
+
const fs_1 = __importDefault(require("fs"));
|
|
10
|
+
const path_1 = __importDefault(require("path"));
|
|
11
|
+
class SQLiteDatabase extends IDatabase_1.IDatabase {
|
|
12
|
+
constructor(config) {
|
|
13
|
+
super();
|
|
14
|
+
if (!config || !config.filename) {
|
|
15
|
+
throw new Error('SQLite yapılandırması için "filename" gereklidir.');
|
|
16
|
+
}
|
|
17
|
+
const dir = path_1.default.dirname(config.filename);
|
|
18
|
+
if (!fs_1.default.existsSync(dir)) {
|
|
19
|
+
fs_1.default.mkdirSync(dir, { recursive: true });
|
|
20
|
+
}
|
|
21
|
+
this.db = new sqlite3_1.default.Database(config.filename, (err) => {
|
|
22
|
+
if (err) {
|
|
23
|
+
console.error("SQLite connection error:", err.message);
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
_detectColumnType(value) {
|
|
28
|
+
if (value === null || value === undefined)
|
|
29
|
+
return 'TEXT';
|
|
30
|
+
if (typeof value === 'boolean')
|
|
31
|
+
return 'BOOLEAN';
|
|
32
|
+
if (typeof value === 'number')
|
|
33
|
+
return Number.isInteger(value) ? 'INTEGER' : 'REAL';
|
|
34
|
+
if (value instanceof Date)
|
|
35
|
+
return 'DATETIME';
|
|
36
|
+
if (typeof value === 'string') {
|
|
37
|
+
if (value.trim() === '')
|
|
38
|
+
return 'TEXT';
|
|
39
|
+
if (/^-?\d+$/.test(value.trim()))
|
|
40
|
+
return 'INTEGER';
|
|
41
|
+
if (/^-?\d+\.\d+$/.test(value.trim()))
|
|
42
|
+
return 'REAL';
|
|
43
|
+
const lowerValue = value.toLowerCase().trim();
|
|
44
|
+
if (lowerValue === 'true' || lowerValue === 'false')
|
|
45
|
+
return 'BOOLEAN';
|
|
46
|
+
if (value.match(/^\d{4}-\d{2}-\d{2}/))
|
|
47
|
+
return 'DATETIME';
|
|
48
|
+
}
|
|
49
|
+
return 'TEXT';
|
|
50
|
+
}
|
|
51
|
+
_determineBestColumnType(values) {
|
|
52
|
+
const types = values.map(v => this._detectColumnType(v));
|
|
53
|
+
const typePriority = { 'INTEGER': 1, 'REAL': 2, 'BOOLEAN': 3, 'DATETIME': 4, 'TEXT': 5 };
|
|
54
|
+
const maxPriority = Math.max(...types.map(t => typePriority[t] || 5));
|
|
55
|
+
return Object.keys(typePriority).find(t => typePriority[t] === maxPriority) || 'TEXT';
|
|
56
|
+
}
|
|
57
|
+
async _ensureMissingColumns(table, data) {
|
|
58
|
+
const columnsInfo = await this.query(`PRAGMA table_info(\`${table}\`)
|
|
59
|
+
`);
|
|
60
|
+
const existingNames = columnsInfo.map(col => col.name);
|
|
61
|
+
for (const key of Object.keys(data)) {
|
|
62
|
+
if (!existingNames.includes(key)) {
|
|
63
|
+
const columnType = this._detectColumnType(data[key]);
|
|
64
|
+
await this.query(`ALTER TABLE
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
query(sql, params = []) {
|
|
69
|
+
return new Promise((resolve, reject) => {
|
|
70
|
+
const upperSql = sql.trim().toUpperCase();
|
|
71
|
+
if (upperSql.startsWith('SELECT') || upperSql.startsWith('PRAGMA')) {
|
|
72
|
+
this.db.all(sql, params, (err, rows) => {
|
|
73
|
+
if (err)
|
|
74
|
+
reject(err);
|
|
75
|
+
else
|
|
76
|
+
resolve(rows);
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
this.db.run(sql, params, function (err) {
|
|
81
|
+
if (err)
|
|
82
|
+
reject(err);
|
|
83
|
+
else
|
|
84
|
+
resolve({ changes: this.changes, lastInsertRowid: this.lastID });
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
async ensureTable(table, data = {}) {
|
|
90
|
+
try {
|
|
91
|
+
await this.query(`SELECT 1 FROM
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
if (error.message.includes('no such table')) {
|
|
95
|
+
const columnDefinitions = Object.keys(data).map(col => {
|
|
96
|
+
const columnType = this._detectColumnType(data[col]);
|
|
97
|
+
return `reverse{col}
|
|
98
|
+
});
|
|
99
|
+
const columnsPart = columnDefinitions.length > 0 ? ', ' + columnDefinitions.join(", ") : '';
|
|
100
|
+
const createTableSQL = `CREATE TABLE
|
|
101
|
+
await this.query(createTableSQL);
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
throw error;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
_serializeValue(value) {
|
|
109
|
+
if (value instanceof Date)
|
|
110
|
+
return value.toISOString();
|
|
111
|
+
if (Array.isArray(value) || (typeof value === 'object' && value !== null))
|
|
112
|
+
return JSON.stringify(value);
|
|
113
|
+
return value;
|
|
114
|
+
}
|
|
115
|
+
_deserializeValue(value) {
|
|
116
|
+
if (typeof value === 'string' && (value.startsWith('[') || value.startsWith('{'))) {
|
|
117
|
+
try {
|
|
118
|
+
const parsed = JSON.parse(value);
|
|
119
|
+
if (typeof parsed === 'object' && parsed !== null)
|
|
120
|
+
return parsed;
|
|
121
|
+
}
|
|
122
|
+
catch (e) { }
|
|
123
|
+
}
|
|
124
|
+
return value;
|
|
125
|
+
}
|
|
126
|
+
async insert(table, data) {
|
|
127
|
+
const copy = { ...data };
|
|
128
|
+
await this.ensureTable(table, copy);
|
|
129
|
+
await this._ensureMissingColumns(table, copy);
|
|
130
|
+
const keys = Object.keys(copy);
|
|
131
|
+
const placeholders = keys.map(() => '?').join(',');
|
|
132
|
+
const values = Object.values(copy).map(v => this._serializeValue(v));
|
|
133
|
+
const sql = `INSERT INTO
|
|
134
|
+
const result = await this.query(sql, values);
|
|
135
|
+
return result.lastInsertRowid;
|
|
136
|
+
}
|
|
137
|
+
async update(table, data, where) {
|
|
138
|
+
await this.ensureTable(table, { ...data, ...where });
|
|
139
|
+
await this._ensureMissingColumns(table, { ...data, ...where });
|
|
140
|
+
const setString = Object.keys(data).map(k => `reverse{k}
|
|
141
|
+
const whereString = Object.keys(where).map(k => `reverse{k}
|
|
142
|
+
const sql = `UPDATE
|
|
143
|
+
const result = await this.query(sql, [...Object.values(data).map(v => this._serializeValue(v)), ...Object.values(where).map(v => this._serializeValue(v))]);
|
|
144
|
+
return result.changes;
|
|
145
|
+
}
|
|
146
|
+
async delete(table, where) {
|
|
147
|
+
if (!where || Object.keys(where).length === 0)
|
|
148
|
+
return 0;
|
|
149
|
+
await this.ensureTable(table, { ...where });
|
|
150
|
+
await this._ensureMissingColumns(table, where);
|
|
151
|
+
const whereString = Object.keys(where).map(k => `reverse{k}
|
|
152
|
+
const sql = `DELETE FROM
|
|
153
|
+
const result = await this.query(sql, Object.values(where).map(v => this._serializeValue(v)));
|
|
154
|
+
return result.changes;
|
|
155
|
+
}
|
|
156
|
+
async select(table, where = null) {
|
|
157
|
+
await this.ensureTable(table, where || {});
|
|
158
|
+
if (where && Object.keys(where).length > 0) {
|
|
159
|
+
await this._ensureMissingColumns(table, where);
|
|
160
|
+
}
|
|
161
|
+
let sql = `SELECT * FROM
|
|
162
|
+
let params = [];
|
|
163
|
+
if (where && Object.keys(where).length > 0) {
|
|
164
|
+
const whereString = Object.keys(where).map(k => `reverse{k}
|
|
165
|
+
sql += ` WHERE ${whereString}`;
|
|
166
|
+
params = Object.values(where).map(v => this._serializeValue(v));
|
|
167
|
+
}
|
|
168
|
+
const rows = await this.query(sql, params);
|
|
169
|
+
return rows.map((row) => {
|
|
170
|
+
const newRow = {};
|
|
171
|
+
for (const key in row) {
|
|
172
|
+
newRow[key] = this._deserializeValue(row[key]);
|
|
173
|
+
}
|
|
174
|
+
return newRow;
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
async set(table, data, where) {
|
|
178
|
+
const existing = await this.select(table, where);
|
|
179
|
+
if (existing.length === 0) {
|
|
180
|
+
return await this.insert(table, { ...where, ...data });
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
return await this.update(table, data, where);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
async selectOne(table, where = null) {
|
|
187
|
+
const results = await this.select(table, where);
|
|
188
|
+
return results[0] || null;
|
|
189
|
+
}
|
|
190
|
+
async bulkInsert(table, dataArray) {
|
|
191
|
+
if (!Array.isArray(dataArray) || dataArray.length === 0)
|
|
192
|
+
return 0;
|
|
193
|
+
await this.ensureTable(table, dataArray[0]);
|
|
194
|
+
const allKeys = new Set();
|
|
195
|
+
dataArray.forEach(obj => Object.keys(obj).forEach(key => allKeys.add(key)));
|
|
196
|
+
for (const key of allKeys) {
|
|
197
|
+
const columnsInfo = await this.query(`PRAGMA table_info(
|
|
198
|
+
if (!columnsInfo.map(col => col.name).includes(key)) {
|
|
199
|
+
const columnValues = dataArray.map(obj => obj[key]).filter(val => val !== undefined && val !== null);
|
|
200
|
+
const columnType = columnValues.length > 0 ? this._determineBestColumnType(columnValues) : 'TEXT';
|
|
201
|
+
await this.query(`ALTER TABLE
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
const keys = Array.from(allKeys);
|
|
205
|
+
const sql = `INSERT INTO
|
|
206
|
+
return new Promise((resolve, reject) => {
|
|
207
|
+
this.db.serialize(() => {
|
|
208
|
+
this.db.run("BEGIN TRANSACTION;");
|
|
209
|
+
let completed = 0;
|
|
210
|
+
let hasError = false;
|
|
211
|
+
const stmt = this.db.prepare(sql);
|
|
212
|
+
for (const item of dataArray) {
|
|
213
|
+
if (hasError)
|
|
214
|
+
break;
|
|
215
|
+
stmt.run(keys.map(k => this._serializeValue(item[k])), (err) => {
|
|
216
|
+
if (err && !hasError) {
|
|
217
|
+
hasError = true;
|
|
218
|
+
this.db.run("ROLLBACK;");
|
|
219
|
+
reject(err);
|
|
220
|
+
}
|
|
221
|
+
completed++;
|
|
222
|
+
if (completed === dataArray.length && !hasError) {
|
|
223
|
+
this.db.run("COMMIT;", (err) => {
|
|
224
|
+
if (err)
|
|
225
|
+
reject(err);
|
|
226
|
+
else {
|
|
227
|
+
stmt.finalize();
|
|
228
|
+
resolve(dataArray.length);
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
async increment(table, increments, where = {}) {
|
|
238
|
+
const incrementClauses = Object.keys(increments).map(field => `reverse{field}
|
|
239
|
+
const incrementValues = Object.values(increments);
|
|
240
|
+
const { whereClause, values: whereValues } = this._buildWhereClause(where);
|
|
241
|
+
const sql = `UPDATE
|
|
242
|
+
const result = await this.query(sql, [...incrementValues, ...whereValues]);
|
|
243
|
+
return result.changes;
|
|
244
|
+
}
|
|
245
|
+
async decrement(table, decrements, where = {}) {
|
|
246
|
+
const decrementClauses = Object.keys(decrements).map(field => `reverse{field}
|
|
247
|
+
const decrementValues = Object.values(decrements);
|
|
248
|
+
const { whereClause, values: whereValues } = this._buildWhereClause(where);
|
|
249
|
+
const sql = `UPDATE
|
|
250
|
+
const result = await this.query(sql, [...decrementValues, ...whereValues]);
|
|
251
|
+
return result.changes;
|
|
252
|
+
}
|
|
253
|
+
_buildWhereClause(where = {}) {
|
|
254
|
+
const conditions = Object.keys(where);
|
|
255
|
+
if (conditions.length === 0)
|
|
256
|
+
return { whereClause: '', values: [] };
|
|
257
|
+
const whereClause = ' WHERE ' + conditions.map(key => `reverse{key}
|
|
258
|
+
const values = Object.values(where).map(v => this._serializeValue(v));
|
|
259
|
+
return { whereClause, values };
|
|
260
|
+
}
|
|
261
|
+
async close() {
|
|
262
|
+
return new Promise((resolve, reject) => {
|
|
263
|
+
this.db.close((err) => {
|
|
264
|
+
if (err)
|
|
265
|
+
reject(err);
|
|
266
|
+
else
|
|
267
|
+
resolve();
|
|
268
|
+
});
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
exports.SQLiteDatabase = SQLiteDatabase;
|
|
273
|
+
exports.default = SQLiteDatabase;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
export interface MySQLConfig {
|
|
2
|
+
host: string;
|
|
3
|
+
user: string;
|
|
4
|
+
password?: string;
|
|
5
|
+
database: string;
|
|
6
|
+
port?: number;
|
|
7
|
+
connectionLimit?: number;
|
|
8
|
+
cache?: CacheConfig;
|
|
9
|
+
}
|
|
10
|
+
export interface SQLiteConfig {
|
|
11
|
+
filename: string;
|
|
12
|
+
cache?: CacheConfig;
|
|
13
|
+
}
|
|
14
|
+
export interface MongoDBConfig {
|
|
15
|
+
uri: string;
|
|
16
|
+
dbName: string;
|
|
17
|
+
cache?: CacheConfig;
|
|
18
|
+
}
|
|
19
|
+
export interface PostgreSQLConfig {
|
|
20
|
+
host: string;
|
|
21
|
+
user: string;
|
|
22
|
+
password?: string;
|
|
23
|
+
database: string;
|
|
24
|
+
port?: number;
|
|
25
|
+
connectionLimit?: number;
|
|
26
|
+
cache?: CacheConfig;
|
|
27
|
+
}
|
|
28
|
+
export interface RedisConfig {
|
|
29
|
+
host?: string;
|
|
30
|
+
port?: number;
|
|
31
|
+
password?: string;
|
|
32
|
+
db?: number;
|
|
33
|
+
keyPrefix?: string;
|
|
34
|
+
cache?: CacheConfig;
|
|
35
|
+
}
|
|
36
|
+
export interface JsonConfig {
|
|
37
|
+
filePath: string;
|
|
38
|
+
saveInterval?: number;
|
|
39
|
+
cache?: CacheConfig;
|
|
40
|
+
}
|
|
41
|
+
export interface ZPackConfig {
|
|
42
|
+
filePath: string;
|
|
43
|
+
autoFlush?: boolean;
|
|
44
|
+
cache?: CacheConfig;
|
|
45
|
+
}
|
|
46
|
+
export interface CacheConfig {
|
|
47
|
+
type: 'memory' | 'redis';
|
|
48
|
+
ttl?: number;
|
|
49
|
+
max?: number;
|
|
50
|
+
host?: string;
|
|
51
|
+
port?: number;
|
|
52
|
+
password?: string;
|
|
53
|
+
}
|
|
54
|
+
export type DatabaseOptions = {
|
|
55
|
+
adapter: 'mysql';
|
|
56
|
+
config: MySQLConfig;
|
|
57
|
+
} | {
|
|
58
|
+
adapter: 'sqlite';
|
|
59
|
+
config: SQLiteConfig;
|
|
60
|
+
} | {
|
|
61
|
+
adapter: 'mongodb';
|
|
62
|
+
config: MongoDBConfig;
|
|
63
|
+
} | {
|
|
64
|
+
adapter: 'postgres';
|
|
65
|
+
config: PostgreSQLConfig;
|
|
66
|
+
} | {
|
|
67
|
+
adapter: 'json';
|
|
68
|
+
config: JsonConfig;
|
|
69
|
+
} | {
|
|
70
|
+
adapter: 'redis';
|
|
71
|
+
config: RedisConfig;
|
|
72
|
+
} | {
|
|
73
|
+
adapter: 'zpack';
|
|
74
|
+
config: ZPackConfig;
|
|
75
|
+
};
|
|
76
|
+
export type AdapterType = DatabaseOptions['adapter'];
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { IDatabase } from './IDatabase';
|
|
2
|
+
import { ZPackConfig } from './types';
|
|
3
|
+
export declare class ZPackDatabase {
|
|
4
|
+
filePath: string;
|
|
5
|
+
private fd;
|
|
6
|
+
private fileSize;
|
|
7
|
+
private index;
|
|
8
|
+
private deleted;
|
|
9
|
+
private version;
|
|
10
|
+
private _nextId;
|
|
11
|
+
private _writeQueue;
|
|
12
|
+
private _closed;
|
|
13
|
+
private _autoFlush;
|
|
14
|
+
private _contentEnd;
|
|
15
|
+
constructor(filePath: string, options?: {
|
|
16
|
+
autoFlush?: boolean;
|
|
17
|
+
});
|
|
18
|
+
open(): Promise<void>;
|
|
19
|
+
close(): Promise<void>;
|
|
20
|
+
insert(document: Record<string, any>, docId?: number): Promise<number>;
|
|
21
|
+
insertBatch(documents: Record<string, any>[]): Promise<number[]>;
|
|
22
|
+
delete(docId: number): Promise<void>;
|
|
23
|
+
get(docId: number): Promise<Record<string, any> | null>;
|
|
24
|
+
keys(): number[];
|
|
25
|
+
private _ensureOpen;
|
|
26
|
+
private _enqueue;
|
|
27
|
+
private _internalWriteFooter;
|
|
28
|
+
private _writeFooter;
|
|
29
|
+
private _encodeDocument;
|
|
30
|
+
private _encodeTombstone;
|
|
31
|
+
private _peekDocMeta;
|
|
32
|
+
private _decodeDocument;
|
|
33
|
+
private _tryLoadIndexFromFooter;
|
|
34
|
+
private _scanAndRebuildIndex;
|
|
35
|
+
}
|
|
36
|
+
export declare class ZPackAdapter extends IDatabase {
|
|
37
|
+
private db;
|
|
38
|
+
private initPromise;
|
|
39
|
+
private tableMaxId;
|
|
40
|
+
private keyIndex;
|
|
41
|
+
private rowCache;
|
|
42
|
+
private secondary;
|
|
43
|
+
constructor(config: ZPackConfig);
|
|
44
|
+
private _init;
|
|
45
|
+
ensureTable(table: string): Promise<void>;
|
|
46
|
+
private _coerce;
|
|
47
|
+
private _matches;
|
|
48
|
+
select<T = any>(table: string, where?: Record<string, any> | null): Promise<T[]>;
|
|
49
|
+
selectOne<T = any>(table: string, where?: Record<string, any> | null): Promise<T | null>;
|
|
50
|
+
insert(table: string, data: Record<string, any>): Promise<number>;
|
|
51
|
+
update(table: string, data: Record<string, any>, where: Record<string, any>): Promise<number>;
|
|
52
|
+
set(table: string, data: Record<string, any>, where: Record<string, any>): Promise<any>;
|
|
53
|
+
delete(table: string, where: Record<string, any>): Promise<number>;
|
|
54
|
+
bulkInsert(table: string, dataArray: Record<string, any>[]): Promise<number>;
|
|
55
|
+
increment(table: string, increments: Record<string, number>, where?: Record<string, any>): Promise<number>;
|
|
56
|
+
decrement(table: string, decrements: Record<string, number>, where?: Record<string, any>): Promise<number>;
|
|
57
|
+
close(): Promise<void>;
|
|
58
|
+
}
|
|
59
|
+
export default ZPackAdapter;
|