mirror of
https://github.com/aljazceru/turso.git
synced 2025-12-20 09:54:19 +01:00
properly guard access to the private fields
This commit is contained in:
@@ -11,29 +11,29 @@ async function init(): Promise<Worker> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Database extends DatabasePromise {
|
class Database extends DatabasePromise {
|
||||||
worker: Worker | null;
|
#worker: Worker | null;
|
||||||
constructor(path: string, opts: DatabaseOpts = {}) {
|
constructor(path: string, opts: DatabaseOpts = {}) {
|
||||||
super(new NativeDatabase(path, opts) as unknown as any)
|
super(new NativeDatabase(path, opts) as unknown as any)
|
||||||
}
|
}
|
||||||
override async connect() {
|
override async connect() {
|
||||||
if (!this.db.memory) {
|
if (!this.memory) {
|
||||||
const worker = await init();
|
const worker = await init();
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
registerFileAtWorker(worker, this.name),
|
registerFileAtWorker(worker, this.name),
|
||||||
registerFileAtWorker(worker, `${this.name}-wal`)
|
registerFileAtWorker(worker, `${this.name}-wal`)
|
||||||
]);
|
]);
|
||||||
this.worker = worker;
|
this.#worker = worker;
|
||||||
}
|
}
|
||||||
await super.connect();
|
await super.connect();
|
||||||
}
|
}
|
||||||
async close() {
|
async close() {
|
||||||
if (this.name != null && this.worker != null) {
|
if (this.name != null && this.#worker != null) {
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
unregisterFileAtWorker(this.worker, this.name),
|
unregisterFileAtWorker(this.#worker, this.name),
|
||||||
unregisterFileAtWorker(this.worker, `${this.name}-wal`)
|
unregisterFileAtWorker(this.#worker, `${this.name}-wal`)
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
this.db.close();
|
await super.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,29 +11,29 @@ async function init(): Promise<Worker> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Database extends DatabasePromise {
|
class Database extends DatabasePromise {
|
||||||
worker: Worker | null;
|
#worker: Worker | null;
|
||||||
constructor(path: string, opts: DatabaseOpts = {}) {
|
constructor(path: string, opts: DatabaseOpts = {}) {
|
||||||
super(new NativeDatabase(path, opts) as unknown as any)
|
super(new NativeDatabase(path, opts) as unknown as any)
|
||||||
}
|
}
|
||||||
override async connect() {
|
override async connect() {
|
||||||
if (!this.db.memory) {
|
if (!this.memory) {
|
||||||
const worker = await init();
|
const worker = await init();
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
registerFileAtWorker(worker, this.name),
|
registerFileAtWorker(worker, this.name),
|
||||||
registerFileAtWorker(worker, `${this.name}-wal`)
|
registerFileAtWorker(worker, `${this.name}-wal`)
|
||||||
]);
|
]);
|
||||||
this.worker = worker;
|
this.#worker = worker;
|
||||||
}
|
}
|
||||||
await super.connect();
|
await super.connect();
|
||||||
}
|
}
|
||||||
async close() {
|
async close() {
|
||||||
if (this.name != null && this.worker != null) {
|
if (this.name != null && this.#worker != null) {
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
unregisterFileAtWorker(this.worker, this.name),
|
unregisterFileAtWorker(this.#worker, this.name),
|
||||||
unregisterFileAtWorker(this.worker, `${this.name}-wal`)
|
unregisterFileAtWorker(this.#worker, `${this.name}-wal`)
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
this.db.close();
|
await super.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,29 +11,29 @@ async function init(): Promise<Worker> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Database extends DatabasePromise {
|
class Database extends DatabasePromise {
|
||||||
worker: Worker | null;
|
#worker: Worker | null;
|
||||||
constructor(path: string, opts: DatabaseOpts = {}) {
|
constructor(path: string, opts: DatabaseOpts = {}) {
|
||||||
super(new NativeDatabase(path, opts) as unknown as any)
|
super(new NativeDatabase(path, opts) as unknown as any)
|
||||||
}
|
}
|
||||||
override async connect() {
|
override async connect() {
|
||||||
if (!this.db.memory) {
|
if (!this.memory) {
|
||||||
const worker = await init();
|
const worker = await init();
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
registerFileAtWorker(worker, this.name),
|
registerFileAtWorker(worker, this.name),
|
||||||
registerFileAtWorker(worker, `${this.name}-wal`)
|
registerFileAtWorker(worker, `${this.name}-wal`)
|
||||||
]);
|
]);
|
||||||
this.worker = worker;
|
this.#worker = worker;
|
||||||
}
|
}
|
||||||
await super.connect();
|
await super.connect();
|
||||||
}
|
}
|
||||||
async close() {
|
async close() {
|
||||||
if (this.name != null && this.worker != null) {
|
if (this.name != null && this.#worker != null) {
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
unregisterFileAtWorker(this.worker, this.name),
|
unregisterFileAtWorker(this.#worker, this.name),
|
||||||
unregisterFileAtWorker(this.worker, `${this.name}-wal`)
|
unregisterFileAtWorker(this.#worker, `${this.name}-wal`)
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
this.db.close();
|
await super.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,29 +11,29 @@ async function init(): Promise<Worker> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Database extends DatabasePromise {
|
class Database extends DatabasePromise {
|
||||||
worker: Worker | null;
|
#worker: Worker | null;
|
||||||
constructor(path: string, opts: DatabaseOpts = {}) {
|
constructor(path: string, opts: DatabaseOpts = {}) {
|
||||||
super(new NativeDatabase(path, opts) as unknown as any)
|
super(new NativeDatabase(path, opts) as unknown as any)
|
||||||
}
|
}
|
||||||
override async connect() {
|
override async connect() {
|
||||||
if (!this.db.memory) {
|
if (!this.memory) {
|
||||||
const worker = await init();
|
const worker = await init();
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
registerFileAtWorker(worker, this.name),
|
registerFileAtWorker(worker, this.name),
|
||||||
registerFileAtWorker(worker, `${this.name}-wal`)
|
registerFileAtWorker(worker, `${this.name}-wal`)
|
||||||
]);
|
]);
|
||||||
this.worker = worker;
|
this.#worker = worker;
|
||||||
}
|
}
|
||||||
await super.connect();
|
await super.connect();
|
||||||
}
|
}
|
||||||
async close() {
|
async close() {
|
||||||
if (this.name != null && this.worker != null) {
|
if (this.name != null && this.#worker != null) {
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
unregisterFileAtWorker(this.worker, this.name),
|
unregisterFileAtWorker(this.#worker, this.name),
|
||||||
unregisterFileAtWorker(this.worker, `${this.name}-wal`)
|
unregisterFileAtWorker(this.#worker, `${this.name}-wal`)
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
this.db.close();
|
await super.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,13 @@ function createErrorByName(name, message) {
|
|||||||
* Database represents a connection that can prepare and execute SQL statements.
|
* Database represents a connection that can prepare and execute SQL statements.
|
||||||
*/
|
*/
|
||||||
class Database {
|
class Database {
|
||||||
db: NativeDatabase;
|
name: string;
|
||||||
|
readonly: boolean;
|
||||||
|
open: boolean;
|
||||||
|
memory: boolean;
|
||||||
|
inTransaction: boolean;
|
||||||
|
|
||||||
|
private db: NativeDatabase;
|
||||||
private _inTransaction: boolean = false;
|
private _inTransaction: boolean = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -47,10 +53,11 @@ class Database {
|
|||||||
this.db.connectSync();
|
this.db.connectSync();
|
||||||
|
|
||||||
Object.defineProperties(this, {
|
Object.defineProperties(this, {
|
||||||
inTransaction: { get: () => this._inTransaction },
|
|
||||||
name: { get: () => this.db.path },
|
name: { get: () => this.db.path },
|
||||||
readonly: { get: () => this.db.readonly },
|
readonly: { get: () => this.db.readonly },
|
||||||
open: { get: () => this.db.open },
|
open: { get: () => this.db.open },
|
||||||
|
memory: { get: () => this.db.memory },
|
||||||
|
inTransaction: { get: () => this._inTransaction },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,7 +72,7 @@ class Database {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return new Statement(this.db.prepare(sql), this);
|
return new Statement(this.db.prepare(sql), this.db);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw convertError(err);
|
throw convertError(err);
|
||||||
}
|
}
|
||||||
@@ -202,11 +209,11 @@ class Database {
|
|||||||
*/
|
*/
|
||||||
class Statement {
|
class Statement {
|
||||||
stmt: NativeStatement;
|
stmt: NativeStatement;
|
||||||
db: Database;
|
db: NativeDatabase;
|
||||||
|
|
||||||
constructor(stmt: NativeStatement, database: Database) {
|
constructor(stmt: NativeStatement, db: NativeDatabase) {
|
||||||
this.stmt = stmt;
|
this.stmt = stmt;
|
||||||
this.db = database;
|
this.db = db;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -264,14 +271,14 @@ class Statement {
|
|||||||
* Executes the SQL statement and returns an info object.
|
* Executes the SQL statement and returns an info object.
|
||||||
*/
|
*/
|
||||||
run(...bindParameters) {
|
run(...bindParameters) {
|
||||||
const totalChangesBefore = this.db.db.totalChanges();
|
const totalChangesBefore = this.db.totalChanges();
|
||||||
|
|
||||||
this.stmt.reset();
|
this.stmt.reset();
|
||||||
bindParams(this.stmt, bindParameters);
|
bindParams(this.stmt, bindParameters);
|
||||||
for (; ;) {
|
for (; ;) {
|
||||||
const stepResult = this.stmt.stepSync();
|
const stepResult = this.stmt.stepSync();
|
||||||
if (stepResult === STEP_IO) {
|
if (stepResult === STEP_IO) {
|
||||||
this.db.db.ioLoopSync();
|
this.db.ioLoopSync();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (stepResult === STEP_DONE) {
|
if (stepResult === STEP_DONE) {
|
||||||
@@ -283,8 +290,8 @@ class Statement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const lastInsertRowid = this.db.db.lastInsertRowid();
|
const lastInsertRowid = this.db.lastInsertRowid();
|
||||||
const changes = this.db.db.totalChanges() === totalChangesBefore ? 0 : this.db.db.changes();
|
const changes = this.db.totalChanges() === totalChangesBefore ? 0 : this.db.changes();
|
||||||
|
|
||||||
return { changes, lastInsertRowid };
|
return { changes, lastInsertRowid };
|
||||||
}
|
}
|
||||||
@@ -300,7 +307,7 @@ class Statement {
|
|||||||
for (; ;) {
|
for (; ;) {
|
||||||
const stepResult = this.stmt.stepSync();
|
const stepResult = this.stmt.stepSync();
|
||||||
if (stepResult === STEP_IO) {
|
if (stepResult === STEP_IO) {
|
||||||
this.db.db.ioLoopSync();
|
this.db.ioLoopSync();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (stepResult === STEP_DONE) {
|
if (stepResult === STEP_DONE) {
|
||||||
@@ -324,7 +331,7 @@ class Statement {
|
|||||||
while (true) {
|
while (true) {
|
||||||
const stepResult = this.stmt.stepSync();
|
const stepResult = this.stmt.stepSync();
|
||||||
if (stepResult === STEP_IO) {
|
if (stepResult === STEP_IO) {
|
||||||
this.db.db.ioLoopSync();
|
this.db.ioLoopSync();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (stepResult === STEP_DONE) {
|
if (stepResult === STEP_DONE) {
|
||||||
@@ -348,7 +355,7 @@ class Statement {
|
|||||||
for (; ;) {
|
for (; ;) {
|
||||||
const stepResult = this.stmt.stepSync();
|
const stepResult = this.stmt.stepSync();
|
||||||
if (stepResult === STEP_IO) {
|
if (stepResult === STEP_IO) {
|
||||||
this.db.db.ioLoopSync();
|
this.db.ioLoopSync();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (stepResult === STEP_DONE) {
|
if (stepResult === STEP_DONE) {
|
||||||
|
|||||||
@@ -30,18 +30,25 @@ function createErrorByName(name, message) {
|
|||||||
* Database represents a connection that can prepare and execute SQL statements.
|
* Database represents a connection that can prepare and execute SQL statements.
|
||||||
*/
|
*/
|
||||||
class Database {
|
class Database {
|
||||||
db: NativeDatabase;
|
|
||||||
execLock: AsyncLock;
|
|
||||||
name: string;
|
name: string;
|
||||||
|
readonly: boolean;
|
||||||
|
open: boolean;
|
||||||
|
memory: boolean;
|
||||||
|
inTransaction: boolean;
|
||||||
|
|
||||||
|
private db: NativeDatabase;
|
||||||
|
private execLock: AsyncLock;
|
||||||
private _inTransaction: boolean = false;
|
private _inTransaction: boolean = false;
|
||||||
|
|
||||||
constructor(db: NativeDatabase) {
|
constructor(db: NativeDatabase) {
|
||||||
this.db = db;
|
this.db = db;
|
||||||
this.execLock = new AsyncLock();
|
this.execLock = new AsyncLock();
|
||||||
Object.defineProperties(this, {
|
Object.defineProperties(this, {
|
||||||
inTransaction: { get: () => this._inTransaction },
|
|
||||||
name: { get: () => this.db.path },
|
name: { get: () => this.db.path },
|
||||||
readonly: { get: () => this.db.readonly },
|
readonly: { get: () => this.db.readonly },
|
||||||
open: { get: () => this.db.open },
|
open: { get: () => this.db.open },
|
||||||
|
memory: { get: () => this.db.memory },
|
||||||
|
inTransaction: { get: () => this._inTransaction },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,7 +67,7 @@ class Database {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return new Statement(this.db.prepare(sql), this);
|
return new Statement(this.db.prepare(sql), this.db, this.execLock);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw convertError(err);
|
throw convertError(err);
|
||||||
}
|
}
|
||||||
@@ -196,11 +203,14 @@ class Database {
|
|||||||
* Statement represents a prepared SQL statement that can be executed.
|
* Statement represents a prepared SQL statement that can be executed.
|
||||||
*/
|
*/
|
||||||
class Statement {
|
class Statement {
|
||||||
stmt: NativeStatement;
|
private stmt: NativeStatement;
|
||||||
db: Database;
|
private db: NativeDatabase;
|
||||||
constructor(stmt, database) {
|
private execLock: AsyncLock;
|
||||||
|
|
||||||
|
constructor(stmt: NativeStatement, db: NativeDatabase, execLock: AsyncLock) {
|
||||||
this.stmt = stmt;
|
this.stmt = stmt;
|
||||||
this.db = database;
|
this.db = db;
|
||||||
|
this.execLock = execLock;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -258,17 +268,17 @@ class Statement {
|
|||||||
* Executes the SQL statement and returns an info object.
|
* Executes the SQL statement and returns an info object.
|
||||||
*/
|
*/
|
||||||
async run(...bindParameters) {
|
async run(...bindParameters) {
|
||||||
const totalChangesBefore = this.db.db.totalChanges();
|
const totalChangesBefore = this.db.totalChanges();
|
||||||
|
|
||||||
this.stmt.reset();
|
this.stmt.reset();
|
||||||
bindParams(this.stmt, bindParameters);
|
bindParams(this.stmt, bindParameters);
|
||||||
|
|
||||||
await this.db.execLock.acquire();
|
await this.execLock.acquire();
|
||||||
try {
|
try {
|
||||||
while (true) {
|
while (true) {
|
||||||
const stepResult = await this.stmt.stepSync();
|
const stepResult = await this.stmt.stepSync();
|
||||||
if (stepResult === STEP_IO) {
|
if (stepResult === STEP_IO) {
|
||||||
await this.db.db.ioLoopAsync();
|
await this.db.ioLoopAsync();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (stepResult === STEP_DONE) {
|
if (stepResult === STEP_DONE) {
|
||||||
@@ -280,12 +290,12 @@ class Statement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const lastInsertRowid = this.db.db.lastInsertRowid();
|
const lastInsertRowid = this.db.lastInsertRowid();
|
||||||
const changes = this.db.db.totalChanges() === totalChangesBefore ? 0 : this.db.db.changes();
|
const changes = this.db.totalChanges() === totalChangesBefore ? 0 : this.db.changes();
|
||||||
|
|
||||||
return { changes, lastInsertRowid };
|
return { changes, lastInsertRowid };
|
||||||
} finally {
|
} finally {
|
||||||
this.db.execLock.release();
|
this.execLock.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -298,12 +308,12 @@ class Statement {
|
|||||||
this.stmt.reset();
|
this.stmt.reset();
|
||||||
bindParams(this.stmt, bindParameters);
|
bindParams(this.stmt, bindParameters);
|
||||||
|
|
||||||
await this.db.execLock.acquire();
|
await this.execLock.acquire();
|
||||||
try {
|
try {
|
||||||
while (true) {
|
while (true) {
|
||||||
const stepResult = await this.stmt.stepSync();
|
const stepResult = await this.stmt.stepSync();
|
||||||
if (stepResult === STEP_IO) {
|
if (stepResult === STEP_IO) {
|
||||||
await this.db.db.ioLoopAsync();
|
await this.db.ioLoopAsync();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (stepResult === STEP_DONE) {
|
if (stepResult === STEP_DONE) {
|
||||||
@@ -314,7 +324,7 @@ class Statement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
this.db.execLock.release();
|
this.execLock.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -327,12 +337,12 @@ class Statement {
|
|||||||
this.stmt.reset();
|
this.stmt.reset();
|
||||||
bindParams(this.stmt, bindParameters);
|
bindParams(this.stmt, bindParameters);
|
||||||
|
|
||||||
await this.db.execLock.acquire();
|
await this.execLock.acquire();
|
||||||
try {
|
try {
|
||||||
while (true) {
|
while (true) {
|
||||||
const stepResult = await this.stmt.stepSync();
|
const stepResult = await this.stmt.stepSync();
|
||||||
if (stepResult === STEP_IO) {
|
if (stepResult === STEP_IO) {
|
||||||
await this.db.db.ioLoopAsync();
|
await this.db.ioLoopAsync();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (stepResult === STEP_DONE) {
|
if (stepResult === STEP_DONE) {
|
||||||
@@ -343,7 +353,7 @@ class Statement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
this.db.execLock.release();
|
this.execLock.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -357,12 +367,12 @@ class Statement {
|
|||||||
bindParams(this.stmt, bindParameters);
|
bindParams(this.stmt, bindParameters);
|
||||||
const rows: any[] = [];
|
const rows: any[] = [];
|
||||||
|
|
||||||
await this.db.execLock.acquire();
|
await this.execLock.acquire();
|
||||||
try {
|
try {
|
||||||
while (true) {
|
while (true) {
|
||||||
const stepResult = await this.stmt.stepSync();
|
const stepResult = await this.stmt.stepSync();
|
||||||
if (stepResult === STEP_IO) {
|
if (stepResult === STEP_IO) {
|
||||||
await this.db.db.ioLoopAsync();
|
await this.db.ioLoopAsync();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (stepResult === STEP_DONE) {
|
if (stepResult === STEP_DONE) {
|
||||||
@@ -375,7 +385,7 @@ class Statement {
|
|||||||
return rows;
|
return rows;
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
this.db.execLock.release();
|
this.execLock.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user