@cubicweb/client
Advanced tools
Comparing version 1.9.0 to 2.0.0
import { Schema } from "../schema/classes/Schema"; | ||
import { RQLParams, ResultSet, CurrentUser } from "./Api"; | ||
import Transaction from "./Transaction"; | ||
import { Transaction, TransactionBackend, TransactionResult } from "./Transaction"; | ||
/** | ||
@@ -9,2 +9,3 @@ * Class used to communicate with a CubicWeb instance's API. | ||
private api; | ||
private transactionBackend; | ||
/** | ||
@@ -17,3 +18,5 @@ * Class used to communicate with a CubicWeb instance's API. | ||
*/ | ||
constructor(apiUrl: string); | ||
constructor(apiUrl: string, { transactionBackend: transactionBackend, }: { | ||
transactionBackend?: TransactionBackend; | ||
}); | ||
get apiUrl(): string; | ||
@@ -49,13 +52,7 @@ /** | ||
/** | ||
* Creates a new transaction and exposes the Transaction object in the given callback. | ||
* Use this callback to execute RQL requests as part of the transaction. | ||
* Once the callback's end is reached, the transaction is automatically committed. | ||
* Note that any exception thrown by the callback will lead to the | ||
* transaction being rolled back. | ||
* | ||
* @param callback Function to execute transaction requests in. | ||
* @returns The promise returned by the callback | ||
* @param transaction Transaction to execute | ||
* @returns A promise fulfilled when the transaction is completed | ||
*/ | ||
transaction<T>(callback: (tr: Transaction) => Promise<T>): Promise<T>; | ||
executeTransaction(transaction: Transaction): Promise<TransactionResult>; | ||
} | ||
//# sourceMappingURL=Client.d.ts.map |
@@ -17,3 +17,3 @@ "use strict"; | ||
const Api_1 = __importDefault(require("./Api")); | ||
const Transaction_1 = __importDefault(require("./Transaction")); | ||
const Transaction_1 = require("./Transaction"); | ||
/** | ||
@@ -30,4 +30,10 @@ * Class used to communicate with a CubicWeb instance's API. | ||
*/ | ||
constructor(apiUrl) { | ||
constructor(apiUrl, { transactionBackend: transactionBackend, }) { | ||
this.api = new Api_1.default(apiUrl); | ||
if (transactionBackend === undefined) { | ||
this.transactionBackend = new Transaction_1.NativeTransactionBackend(); | ||
} | ||
else { | ||
this.transactionBackend = transactionBackend; | ||
} | ||
} | ||
@@ -83,29 +89,8 @@ get apiUrl() { | ||
/** | ||
* Creates a new transaction and exposes the Transaction object in the given callback. | ||
* Use this callback to execute RQL requests as part of the transaction. | ||
* Once the callback's end is reached, the transaction is automatically committed. | ||
* Note that any exception thrown by the callback will lead to the | ||
* transaction being rolled back. | ||
* | ||
* @param callback Function to execute transaction requests in. | ||
* @returns The promise returned by the callback | ||
* @param transaction Transaction to execute | ||
* @returns A promise fulfilled when the transaction is completed | ||
*/ | ||
transaction(callback) { | ||
executeTransaction(transaction) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const transaction = new Transaction_1.default(this.api); | ||
yield transaction.begin(); | ||
let result; | ||
try { | ||
result = yield callback(transaction); | ||
} | ||
catch (error) { | ||
if (!transaction.isClosed()) { | ||
yield transaction.rollback(); | ||
} | ||
throw error; | ||
} | ||
if (!transaction.isClosed()) { | ||
yield transaction.commit(); | ||
} | ||
return result; | ||
return yield this.transactionBackend.execute(transaction); | ||
}); | ||
@@ -112,0 +97,0 @@ } |
@@ -1,57 +0,31 @@ | ||
import Api, { RQLParams } from "./Api"; | ||
/** | ||
* Class used to handle CubicWeb's transactions. | ||
* A transaction allows to execute several RQL requests without altering the database until all | ||
* changes are committed. | ||
* | ||
* You should never have to create this object yourself. | ||
* Instead, retrieve this object from the methods in the `Client` class. | ||
*/ | ||
export default class Transaction { | ||
private api; | ||
private _uuid; | ||
private _closed; | ||
/** | ||
* Class used to handle CubicWeb's transactions. | ||
* A transaction allows to execute several RQL requests without altering the database until all | ||
* changes are committed. | ||
* | ||
* You should never have to create this object yourself. | ||
* Instead, retrieve this object from the methods in the `Client` class. | ||
* | ||
* @param api The API object used to communicate with the CubicWeb backend. | ||
*/ | ||
constructor(api: Api); | ||
/** | ||
* @returns True if the connection is closed. | ||
*/ | ||
isClosed(): boolean; | ||
/** | ||
* This transaction unique identifier. | ||
*/ | ||
get uuid(): string | null; | ||
/** | ||
* Begins a new transaction an retrieves the associated uuid. | ||
*/ | ||
begin(): Promise<void>; | ||
/** | ||
* Executes the given query and waits for the response. | ||
* Make sure you called `begin` before using this method. | ||
* As this is a transaction changes will only be applied when you call the `commit` method. | ||
* | ||
* @param query The RQL query to send | ||
* @param params The additional parameters for the request | ||
* @returns A promise with the request's result set | ||
*/ | ||
execute(query: string, params?: RQLParams): Promise<import("./Api").ResultSet | null>; | ||
/** | ||
* Commits the transaction to apply all the RQL queries sent with `execute`. | ||
*/ | ||
commit(): Promise<void>; | ||
/** | ||
* Rollbacks all the queries sent with `execute` and closes the transaction. | ||
*/ | ||
rollback(): Promise<void>; | ||
private preventUsageIfClosed; | ||
import { ResultSet } from "./Api"; | ||
export declare class Transaction { | ||
private _queries; | ||
push(query: string, params: Record<string, string | number | TransactionQueryRef>): TransactionQuery; | ||
get queries(): ReadonlyArray<TransactionQuery>; | ||
} | ||
export declare class TransactionResult { | ||
private resultSets; | ||
constructor(resultSets: ReadonlyArray<ResultSet>); | ||
resolve(ref: TransactionQueryRef): string | number | boolean | null; | ||
} | ||
export interface TransactionQueryRef { | ||
queryIndex: number; | ||
row: number; | ||
column: number; | ||
} | ||
export declare class TransactionQuery { | ||
readonly query: string; | ||
readonly params: Record<string, string | number | TransactionQueryRef>; | ||
readonly index: number; | ||
constructor(query: string, params: Record<string, string | number | TransactionQueryRef>, index: number); | ||
ref(row?: number, column?: number): TransactionQueryRef; | ||
} | ||
export declare function isTransactionQueryRef(value: string | number | TransactionQueryRef): value is TransactionQueryRef; | ||
export interface TransactionBackend { | ||
execute(transaction: Transaction): Promise<TransactionResult>; | ||
} | ||
export declare class NativeTransactionBackend { | ||
execute(): Promise<TransactionResult>; | ||
} | ||
//# sourceMappingURL=Transaction.d.ts.map |
@@ -12,90 +12,54 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const Errors_1 = require("../Errors"); | ||
/** | ||
* Class used to handle CubicWeb's transactions. | ||
* A transaction allows to execute several RQL requests without altering the database until all | ||
* changes are committed. | ||
* | ||
* You should never have to create this object yourself. | ||
* Instead, retrieve this object from the methods in the `Client` class. | ||
*/ | ||
exports.NativeTransactionBackend = exports.isTransactionQueryRef = exports.TransactionQuery = exports.TransactionResult = exports.Transaction = void 0; | ||
class Transaction { | ||
/** | ||
* Class used to handle CubicWeb's transactions. | ||
* A transaction allows to execute several RQL requests without altering the database until all | ||
* changes are committed. | ||
* | ||
* You should never have to create this object yourself. | ||
* Instead, retrieve this object from the methods in the `Client` class. | ||
* | ||
* @param api The API object used to communicate with the CubicWeb backend. | ||
*/ | ||
constructor(api) { | ||
this.api = api; | ||
this._uuid = null; | ||
this._closed = false; | ||
constructor() { | ||
this._queries = []; | ||
} | ||
/** | ||
* @returns True if the connection is closed. | ||
*/ | ||
isClosed() { | ||
return this._closed; | ||
push(query, params) { | ||
const stackedQuery = new TransactionQuery(query, params, this._queries.length); | ||
this._queries.push(stackedQuery); | ||
return stackedQuery; | ||
} | ||
/** | ||
* This transaction unique identifier. | ||
*/ | ||
get uuid() { | ||
return this._uuid; | ||
get queries() { | ||
return this._queries; | ||
} | ||
/** | ||
* Begins a new transaction an retrieves the associated uuid. | ||
*/ | ||
begin() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
this._closed = false; | ||
this._uuid = yield this.api.transactionBegin(); | ||
}); | ||
} | ||
exports.Transaction = Transaction; | ||
class TransactionResult { | ||
constructor(resultSets) { | ||
this.resultSets = resultSets; | ||
} | ||
/** | ||
* Executes the given query and waits for the response. | ||
* Make sure you called `begin` before using this method. | ||
* As this is a transaction changes will only be applied when you call the `commit` method. | ||
* | ||
* @param query The RQL query to send | ||
* @param params The additional parameters for the request | ||
* @returns A promise with the request's result set | ||
*/ | ||
execute(query, params = {}) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
this.preventUsageIfClosed(); | ||
return yield this.api.transactionExecute(this.uuid, query, params); | ||
}); | ||
resolve(ref) { | ||
return this.resultSets[ref.queryIndex][ref.row][ref.column]; | ||
} | ||
/** | ||
* Commits the transaction to apply all the RQL queries sent with `execute`. | ||
*/ | ||
commit() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
this.preventUsageIfClosed(); | ||
yield this.api.transactionCommit(this.uuid); | ||
this._closed = true; | ||
}); | ||
} | ||
exports.TransactionResult = TransactionResult; | ||
class TransactionQuery { | ||
constructor(query, params, index) { | ||
this.query = query; | ||
this.params = params; | ||
this.index = index; | ||
} | ||
/** | ||
* Rollbacks all the queries sent with `execute` and closes the transaction. | ||
*/ | ||
rollback() { | ||
ref(row = 0, column = 0) { | ||
return { | ||
queryIndex: this.index, | ||
row, | ||
column, | ||
}; | ||
} | ||
} | ||
exports.TransactionQuery = TransactionQuery; | ||
function isTransactionQueryRef(value) { | ||
return (typeof value === "object" && | ||
["queryIndex", "row", "column"].every((key) => Object.keys(value).includes(key))); | ||
} | ||
exports.isTransactionQueryRef = isTransactionQueryRef; | ||
class NativeTransactionBackend { | ||
execute() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
this.preventUsageIfClosed(); | ||
yield this.api.transactionRollback(this.uuid); | ||
this._closed = true; | ||
throw new Error("NativeTransactionBackend.execute not yet implemented."); | ||
}); | ||
} | ||
preventUsageIfClosed() { | ||
if (this.isClosed()) { | ||
throw new Errors_1.TransactionClosedError(); | ||
} | ||
} | ||
} | ||
exports.default = Transaction; | ||
exports.NativeTransactionBackend = NativeTransactionBackend; | ||
//# sourceMappingURL=Transaction.js.map |
@@ -12,4 +12,4 @@ export * from "./schema/raw/Constraints"; | ||
export { default as Client } from "./api/Client"; | ||
export { default as Transaction } from "./api/Transaction"; | ||
export * from "./api/Transaction"; | ||
export { RQLQuery, RQLParams, RqlRow, ResultSet, ApiErrorResponse, } from "./api/Api"; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -20,3 +20,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Transaction = exports.Client = void 0; | ||
exports.Client = void 0; | ||
// Raw Schema | ||
@@ -37,4 +37,3 @@ __exportStar(require("./schema/raw/Constraints"), exports); | ||
Object.defineProperty(exports, "Client", { enumerable: true, get: function () { return __importDefault(Client_1).default; } }); | ||
var Transaction_1 = require("./api/Transaction"); | ||
Object.defineProperty(exports, "Transaction", { enumerable: true, get: function () { return __importDefault(Transaction_1).default; } }); | ||
__exportStar(require("./api/Transaction"), exports); | ||
//# sourceMappingURL=index.js.map |
@@ -5,3 +5,3 @@ { | ||
"author": "Logilab", | ||
"version": "1.9.0", | ||
"version": "2.0.0", | ||
"license": "LGPL-3.0-or-later", | ||
@@ -8,0 +8,0 @@ "main": "lib/index.js", |
import { Schema } from "../schema/classes/Schema"; | ||
import Api, { RQLParams, ResultSet, CurrentUser } from "./Api"; | ||
import Transaction from "./Transaction"; | ||
import { | ||
NativeTransactionBackend, | ||
Transaction, | ||
TransactionBackend, | ||
TransactionResult, | ||
} from "./Transaction"; | ||
@@ -10,2 +15,3 @@ /** | ||
private api: Api; | ||
private transactionBackend: TransactionBackend; | ||
@@ -19,4 +25,14 @@ /** | ||
*/ | ||
constructor(apiUrl: string) { | ||
constructor( | ||
apiUrl: string, | ||
{ | ||
transactionBackend: transactionBackend, | ||
}: { transactionBackend?: TransactionBackend } | ||
) { | ||
this.api = new Api(apiUrl); | ||
if (transactionBackend === undefined) { | ||
this.transactionBackend = new NativeTransactionBackend(); | ||
} else { | ||
this.transactionBackend = transactionBackend; | ||
} | ||
} | ||
@@ -70,29 +86,10 @@ | ||
/** | ||
* Creates a new transaction and exposes the Transaction object in the given callback. | ||
* Use this callback to execute RQL requests as part of the transaction. | ||
* Once the callback's end is reached, the transaction is automatically committed. | ||
* Note that any exception thrown by the callback will lead to the | ||
* transaction being rolled back. | ||
* | ||
* @param callback Function to execute transaction requests in. | ||
* @returns The promise returned by the callback | ||
* @param transaction Transaction to execute | ||
* @returns A promise fulfilled when the transaction is completed | ||
*/ | ||
async transaction<T>(callback: (tr: Transaction) => Promise<T>): Promise<T> { | ||
const transaction = new Transaction(this.api); | ||
await transaction.begin(); | ||
let result: T; | ||
try { | ||
result = await callback(transaction); | ||
} catch (error) { | ||
if (!transaction.isClosed()) { | ||
await transaction.rollback(); | ||
} | ||
throw error; | ||
} | ||
if (!transaction.isClosed()) { | ||
await transaction.commit(); | ||
} | ||
return result; | ||
async executeTransaction( | ||
transaction: Transaction | ||
): Promise<TransactionResult> { | ||
return await this.transactionBackend.execute(transaction); | ||
} | ||
} |
@@ -1,87 +0,76 @@ | ||
import { TransactionClosedError } from "../Errors"; | ||
import Api, { RQLParams } from "./Api"; | ||
import { ResultSet } from "./Api"; | ||
/** | ||
* Class used to handle CubicWeb's transactions. | ||
* A transaction allows to execute several RQL requests without altering the database until all | ||
* changes are committed. | ||
* | ||
* You should never have to create this object yourself. | ||
* Instead, retrieve this object from the methods in the `Client` class. | ||
*/ | ||
export default class Transaction { | ||
private _uuid: string | null = null; | ||
private _closed = false; | ||
export class Transaction { | ||
private _queries: Array<TransactionQuery> = []; | ||
/** | ||
* Class used to handle CubicWeb's transactions. | ||
* A transaction allows to execute several RQL requests without altering the database until all | ||
* changes are committed. | ||
* | ||
* You should never have to create this object yourself. | ||
* Instead, retrieve this object from the methods in the `Client` class. | ||
* | ||
* @param api The API object used to communicate with the CubicWeb backend. | ||
*/ | ||
constructor(private api: Api) {} | ||
/** | ||
* @returns True if the connection is closed. | ||
*/ | ||
isClosed() { | ||
return this._closed; | ||
push( | ||
query: string, | ||
params: Record<string, string | number | TransactionQueryRef> | ||
): TransactionQuery { | ||
const stackedQuery = new TransactionQuery( | ||
query, | ||
params, | ||
this._queries.length | ||
); | ||
this._queries.push(stackedQuery); | ||
return stackedQuery; | ||
} | ||
/** | ||
* This transaction unique identifier. | ||
*/ | ||
get uuid() { | ||
return this._uuid; | ||
get queries(): ReadonlyArray<TransactionQuery> { | ||
return this._queries; | ||
} | ||
} | ||
/** | ||
* Begins a new transaction an retrieves the associated uuid. | ||
*/ | ||
async begin() { | ||
this._closed = false; | ||
this._uuid = await this.api.transactionBegin(); | ||
} | ||
export class TransactionResult { | ||
constructor(private resultSets: ReadonlyArray<ResultSet>) {} | ||
/** | ||
* Executes the given query and waits for the response. | ||
* Make sure you called `begin` before using this method. | ||
* As this is a transaction changes will only be applied when you call the `commit` method. | ||
* | ||
* @param query The RQL query to send | ||
* @param params The additional parameters for the request | ||
* @returns A promise with the request's result set | ||
*/ | ||
async execute(query: string, params: RQLParams = {}) { | ||
this.preventUsageIfClosed(); | ||
return await this.api.transactionExecute(this.uuid, query, params); | ||
resolve(ref: TransactionQueryRef) { | ||
return this.resultSets[ref.queryIndex][ref.row][ref.column]; | ||
} | ||
} | ||
/** | ||
* Commits the transaction to apply all the RQL queries sent with `execute`. | ||
*/ | ||
async commit() { | ||
this.preventUsageIfClosed(); | ||
await this.api.transactionCommit(this.uuid); | ||
this._closed = true; | ||
} | ||
export interface TransactionQueryRef { | ||
queryIndex: number; | ||
row: number; | ||
column: number; | ||
} | ||
/** | ||
* Rollbacks all the queries sent with `execute` and closes the transaction. | ||
*/ | ||
async rollback() { | ||
this.preventUsageIfClosed(); | ||
await this.api.transactionRollback(this.uuid); | ||
this._closed = true; | ||
export class TransactionQuery { | ||
constructor( | ||
public readonly query: string, | ||
public readonly params: Record< | ||
string, | ||
string | number | TransactionQueryRef | ||
>, | ||
public readonly index: number | ||
) {} | ||
ref(row = 0, column = 0): TransactionQueryRef { | ||
return { | ||
queryIndex: this.index, | ||
row, | ||
column, | ||
}; | ||
} | ||
} | ||
private preventUsageIfClosed(): asserts this is { uuid: string } { | ||
if (this.isClosed()) { | ||
throw new TransactionClosedError(); | ||
} | ||
export function isTransactionQueryRef( | ||
value: string | number | TransactionQueryRef | ||
): value is TransactionQueryRef { | ||
return ( | ||
typeof value === "object" && | ||
["queryIndex", "row", "column"].every((key) => | ||
Object.keys(value).includes(key) | ||
) | ||
); | ||
} | ||
export interface TransactionBackend { | ||
execute(transaction: Transaction): Promise<TransactionResult>; | ||
} | ||
export class NativeTransactionBackend { | ||
async execute(): Promise<TransactionResult> { | ||
throw new Error("NativeTransactionBackend.execute not yet implemented."); | ||
} | ||
} |
@@ -18,3 +18,3 @@ // Raw Schema | ||
export { default as Client } from "./api/Client"; | ||
export { default as Transaction } from "./api/Transaction"; | ||
export * from "./api/Transaction"; | ||
export { | ||
@@ -21,0 +21,0 @@ RQLQuery, |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
134844
2729