Skip to content

Commit 7e726e3

Browse files
committed
update basic SQL commands to be more handy; add tests for SQL commands
1 parent b6e9a80 commit 7e726e3

File tree

7 files changed

+169
-100
lines changed

7 files changed

+169
-100
lines changed

src/client.ts

Lines changed: 26 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ import State from './state';
1313
import * as interfaces from './interfaces';
1414
import { verifyInclusion, verifyDualProof } from './verification'
1515
import { CLIENT_INIT_PREFIX, DEFAULT_DATABASE, DEFAULT_ROOTPATH } from './consts'
16-
import Parameters from '../types/parameters'
16+
import { getSQLValue } from './common';
17+
import Parameters, { SQLValue } from '../types/parameters'
1718

1819
class ImmudbClient {
1920
public state: State;
@@ -1652,27 +1653,15 @@ class ImmudbClient {
16521653
}
16531654
}
16541655

1655-
async SQLExec ({ sql, paramsList, nowait }: Parameters.SQLExec): Promise<schemaTypes.SQLExecResult.AsObject | undefined > {
1656+
async SQLExec ({ sql, params = {}, nowait = false }: Parameters.SQLExec): Promise<schemaTypes.SQLExecResult.AsObject | undefined > {
16561657
try {
16571658
const req = new schemaTypes.SQLExecRequest();
16581659

1659-
const sqlParamsList = paramsList.map(({ name, value = null }) => {
1660+
const sqlParamsList = Object.entries(params).map(([name, value]) => {
16601661
const param = new schemaTypes.NamedParam();
16611662

16621663
param.setName(name)
1663-
1664-
if (value !== null) {
1665-
const sqlValue = new schemaTypes.SQLValue();
1666-
const { pb_null, n, s, b, bs } = value;
1667-
1668-
sqlValue.setNull(pb_null);
1669-
sqlValue.setN(n);
1670-
sqlValue.setS(s);
1671-
sqlValue.setB(b);
1672-
sqlValue.setBs(bs);
1673-
1674-
param.setValue(sqlValue)
1675-
}
1664+
param.setValue(getSQLValue(value))
16761665

16771666
return param;
16781667
});
@@ -1687,67 +1676,29 @@ class ImmudbClient {
16871676

16881677
reject(err)
16891678
} else {
1690-
const ctxsList = res
1691-
.getCtxsList()
1692-
.map(txMetadata => ({
1693-
id: txMetadata.getId(),
1694-
prevalh: util.getAlh(txMetadata),
1695-
ts: txMetadata.getTs(),
1696-
nentries: txMetadata.getNentries(),
1697-
eh: txMetadata.getEh(),
1698-
bltxid: txMetadata.getBltxid(),
1699-
blroot: txMetadata.getBlroot(),
1700-
}))
1701-
const dtxsList = res
1702-
.getCtxsList()
1703-
.map(txMetadata => ({
1704-
id: txMetadata.getId(),
1705-
prevalh: util.getAlh(txMetadata),
1706-
ts: txMetadata.getTs(),
1707-
nentries: txMetadata.getNentries(),
1708-
eh: txMetadata.getEh(),
1709-
bltxid: txMetadata.getBltxid(),
1710-
blroot: txMetadata.getBlroot(),
1711-
}))
1712-
1713-
resolve({
1714-
ctxsList,
1715-
dtxsList,
1716-
})
1679+
resolve(res.toObject())
17171680
}
17181681
}))
17191682
} catch(err) {
17201683
console.error(err);
17211684
}
17221685
}
17231686

1724-
async SQLQuery ({ sql, paramsList, reusesnapshot }: Parameters.SQLQuery): Promise<schemaTypes.SQLQueryResult.AsObject | undefined> {
1687+
async SQLQuery ({ sql, params = {}, reusesnapshot = false }: Parameters.SQLQuery): Promise<Array<Array<SQLValue>> | undefined> {
17251688
try {
17261689
const req = new schemaTypes.SQLQueryRequest();
17271690

1728-
const sqlParamsList = paramsList.map(({ name, value = null }) => {
1691+
const sqlParamsList = Object.entries(params).map(([name, value]) => {
17291692
const param = new schemaTypes.NamedParam();
17301693

17311694
param.setName(name)
1732-
1733-
if (value !== null) {
1734-
const sqlValue = new schemaTypes.SQLValue();
1735-
const { pb_null, n, s, b, bs } = value;
1736-
1737-
sqlValue.setNull(pb_null);
1738-
sqlValue.setN(n);
1739-
sqlValue.setS(s);
1740-
sqlValue.setB(b);
1741-
sqlValue.setBs(bs);
1742-
1743-
param.setValue(sqlValue)
1744-
}
1695+
param.setValue(getSQLValue(value))
17451696

17461697
return param;
17471698
});
17481699

1749-
req.setSql(sql);
17501700
req.setParamsList(sqlParamsList);
1701+
req.setSql(sql);
17511702
req.setReusesnapshot(reusesnapshot);
17521703

17531704
return new Promise((resolve, reject) => this.client.sQLQuery(req, this._metadata, (err, res) => {
@@ -1756,26 +1707,23 @@ class ImmudbClient {
17561707

17571708
reject(err)
17581709
} else {
1759-
const columnsList = res
1760-
.getColumnsList()
1761-
.map(column => column.toObject());
1762-
const rowsList = res
1710+
resolve(
1711+
res
17631712
.getRowsList()
1764-
.map(row => {
1765-
const valuesList = row
1766-
.getValuesList()
1767-
.map(value => value.toObject());
1768-
1769-
return {
1770-
columnsList: row.getColumnsList(),
1771-
valuesList
1772-
}
1773-
});
1774-
1775-
resolve({
1776-
columnsList,
1777-
rowsList,
1778-
})
1713+
.map(row => row
1714+
.getValuesList()
1715+
.map(value => value.hasNull()
1716+
? value.getNull()
1717+
: value.hasS()
1718+
? value.getS()
1719+
: value.hasN()
1720+
? value.getN()
1721+
: value.hasB()
1722+
? value.getB()
1723+
: value.hasBs()
1724+
? value.getBs_asU8()
1725+
: null)
1726+
))
17791727
}
17801728
}))
17811729
} catch(err) {

src/common.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import * as schemaTypes from './proto/schema_pb';
2+
import * as google_protobuf_struct_pb from "google-protobuf/google/protobuf/struct_pb";
3+
import { SQLValue } from '../types/parameters';
4+
5+
export const getSQLValue = (value: SQLValue = null) => {
6+
const sqlValue = new schemaTypes.SQLValue();
7+
8+
if (value === null) {
9+
sqlValue.setNull(google_protobuf_struct_pb.NullValue.NULL_VALUE);
10+
}
11+
12+
if (typeof value === 'number') {
13+
sqlValue.setN(value);
14+
}
15+
16+
if (typeof value === 'string') {
17+
sqlValue.setS(value);
18+
}
19+
20+
if (typeof value === 'boolean') {
21+
sqlValue.setB(value);
22+
}
23+
24+
if (ArrayBuffer.isView(value)) {
25+
sqlValue.setBs(value);
26+
}
27+
28+
return sqlValue;
29+
}

tests/tap-parallel-not-ok/client.ts

Lines changed: 90 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const {
1313
IMMUDB_PWD = 'immudb',
1414
} = process.env;
1515

16-
tap.test('database management', async t => {
16+
tap.test('[DATABASE MANAGEMENT]', async t => {
1717
const config: Config = {
1818
host: IMMUDB_HOST,
1919
port: IMMUDB_PORT,
@@ -57,8 +57,8 @@ tap.test('database management', async t => {
5757
const fourthResponse = await immudbClient.set(fourthRequestData);
5858

5959
if (fourthResponse) {
60-
t.equal(fourthResponse.bltxid, 0);
61-
t.equal(fourthResponse.id, 1);
60+
t.equal(fourthResponse.bltxid, 1);
61+
t.equal(fourthResponse.id, 2);
6262
} else {
6363
t.fail('Failed to set');
6464
}
@@ -88,7 +88,7 @@ tap.test('database management', async t => {
8888
}
8989
});
9090

91-
tap.test('user management', async t => {
91+
tap.test('[USER MANAGEMENT]', async t => {
9292
const config: Config = {
9393
host: IMMUDB_HOST,
9494
port: IMMUDB_PORT,
@@ -158,7 +158,7 @@ tap.test('user management', async t => {
158158
}
159159
});
160160

161-
tap.test('operations', async t => {
161+
tap.test('[OPERATIONS]: Regular', async t => {
162162
const config: Config = {
163163
host: IMMUDB_HOST,
164164
port: IMMUDB_PORT,
@@ -234,7 +234,7 @@ tap.test('operations', async t => {
234234
await immudbClient.verifiedSetReference(verifiedSetReferenceRequest)
235235

236236
// test: safely set a reference to an inserted key
237-
const verifiedSetReferenceAtRequest = { key: referenceKey, referencedKey: key, attx: 1 }
237+
const verifiedSetReferenceAtRequest = { key: referenceKey, referencedKey: key, attx: 0 }
238238
await immudbClient.verifiedSetReferenceAt(verifiedSetReferenceAtRequest)
239239

240240
// // test: count keys having the specified value
@@ -311,9 +311,8 @@ tap.test('operations', async t => {
311311
key: `${key}${key}`,
312312
value: `${value}${value}`,
313313
};
314-
let verifiedSetResponse
315314
try {
316-
verifiedSetResponse = await immudbClient.verifiedSet(verifiedSetRequest);
315+
await immudbClient.verifiedSet(verifiedSetRequest);
317316
} catch(err) {
318317
t.fail(err)
319318
}
@@ -328,7 +327,7 @@ tap.test('operations', async t => {
328327
value: `${value}1`,
329328
};
330329
try {
331-
verifiedSetResponse = await immudbClient.verifiedSet(verifiedSetRequest);
330+
await immudbClient.verifiedSet(verifiedSetRequest);
332331
} catch(err) {
333332
t.fail(err)
334333
}
@@ -340,7 +339,7 @@ tap.test('operations', async t => {
340339
value: `${value}2`,
341340
};
342341
try {
343-
verifiedSetResponse = await immudbClient.verifiedSet(verifiedSetRequest);
342+
await immudbClient.verifiedSet(verifiedSetRequest);
344343
} catch(err) {
345344
t.fail(err)
346345
}
@@ -390,7 +389,7 @@ tap.test('operations', async t => {
390389
await immudbClient.zAdd(verifiedZAddRequest)
391390

392391
// test: safely set a secondary index on a key at a specific transaction
393-
const verifiedZAddAtRequest = { set: 'test', score: 32, key, attx: 1 }
392+
const verifiedZAddAtRequest = { set: 'test', score: 32, key, attx: 0 }
394393
await immudbClient.zAddAt(verifiedZAddAtRequest)
395394

396395
t.end();
@@ -399,7 +398,86 @@ tap.test('operations', async t => {
399398
}
400399
});
401400

402-
tap.test('batches', async t => {
401+
tap.test('[OPERATIONS]: SQL', async t => {
402+
const config: Config = {
403+
host: IMMUDB_HOST,
404+
port: IMMUDB_PORT,
405+
autoLogin: false,
406+
};
407+
const immudbClient = await ImmudbClient.getInstance(config);
408+
try {
409+
const rand = 1;
410+
const testDB = 'testdb';
411+
412+
// test: login using the specified username and password
413+
const loginRequest: Parameters.Login = {
414+
user: IMMUDB_USER,
415+
password: IMMUDB_PWD,
416+
};
417+
await immudbClient.login(
418+
loginRequest
419+
);
420+
421+
const listDatabasesResponse = await immudbClient.listDatabases()
422+
if (listDatabasesResponse) {
423+
const { databasesList } = listDatabasesResponse
424+
425+
// let dbExists = false
426+
const dbExists = databasesList.some(({ databasename }) => databasename === testDB)
427+
428+
if (!dbExists) {
429+
// test: create database
430+
const createDatabaseRequest: Parameters.CreateDatabase = { databasename: testDB };
431+
432+
await immudbClient.createDatabase(createDatabaseRequest);
433+
}
434+
}
435+
436+
// test: use database just created
437+
const useDatabaseRequest: Parameters.UseDatabase = { databasename: testDB };
438+
await immudbClient.useDatabase(useDatabaseRequest);
439+
440+
const tableName = `table${ Math.floor(Math.random() * 101) }`
441+
442+
await immudbClient.SQLExec({
443+
sql: `create table ${ tableName } (id integer, name varchar, primary key id);`,
444+
})
445+
446+
const sqlExecParams = [
447+
{
448+
id: 1,
449+
name: 'Joe'
450+
},
451+
{
452+
id: 2,
453+
name: 'Joe'
454+
},
455+
{
456+
id: 3,
457+
name: 'Adam'
458+
},
459+
]
460+
for (const params of sqlExecParams) {
461+
await immudbClient.SQLExec({
462+
sql: `insert into ${ tableName } (id, name) values (@id, @name);`,
463+
params
464+
})
465+
}
466+
467+
await immudbClient.SQLQuery({
468+
sql: `select id,name from ${ tableName } where name=@name;`,
469+
params: {
470+
name: 'Joe',
471+
}
472+
})
473+
474+
t.end();
475+
} catch (err) {
476+
t.error(err);
477+
}
478+
});
479+
480+
tap.test('[BATCHES]', async t => {
403481
const config: Config = {
404482
host: IMMUDB_HOST,
405483
port: IMMUDB_PORT,

tests/tap-parallel-not-ok/tx.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import tap from 'tap'
22

3-
import { Tx, digestTXe } from '../../src/tx'
3+
import { digestTXe } from '../../src/tx'
44

55
tap.test('tx-related functions', async t => {
66
try {

0 commit comments

Comments
 (0)