chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 12:32:25 +08:00
commit e014feafe1
2285 changed files with 1131979 additions and 0 deletions
@@ -0,0 +1,33 @@
# Node Client Integration Tests
## Install
```
$ npm install
```
## Run node tests
To run the node tests, you must make sure you have Doltgres installed on your computer and
have run `npm install`. Then update your Doltgres config by running:
```shell
sh ../postgres-client-tests-entrypoint.sh
```
And then you can run the tests using the `run-tests.sh` script, which sets up the database, runs the SQL server, runs the provided `.js` test file against the running server, and then tears down the database.
For example, you can run the `workbench.js` tests by running:
```shell
sh run-tests.sh workbench.js
```
## Workbench stability tests
The tests in `workbenchTests` were written to enforce the stability of the [SQL
workbench](https://github.com/dolthub/dolt-workbench). The workbench uses many Doltgres
system tables, functions, and procedures, and any changes to these interfaces can break
the workbench. @tbantle22 will be tagged in any GitHub PR that updates those files to
ensure appropriate workbench updates are made for Doltgres changes that break these
queries.
@@ -0,0 +1,28 @@
import pkg from "pg";
const { Client } = pkg;
export class Database {
constructor(config) {
this.client = new Client(config);
this.client.connect();
}
query(sql, args) {
return new Promise((resolve, reject) => {
this.client.query(sql, args, (err, rows) => {
if (err) return reject(err);
return resolve(rows);
});
});
}
close() {
this.client.end((err) => {
if (err) {
console.error(err);
} else {
console.log("db connection closed");
}
});
}
}
@@ -0,0 +1,591 @@
export const countFields = [
{
name: "count",
tableID: 0,
columnID: 1,
dataTypeID: 20,
dataTypeSize: 20,
dataTypeModifier: -1,
format: "text",
},
];
export const doltAddFields = [
{
name: "dolt_add",
tableID: 0,
columnID: 1,
dataTypeID: 1009,
dataTypeSize: -1,
dataTypeModifier: -1,
format: "text",
},
];
export const doltResetFields = [
{
name: "dolt_reset",
tableID: 0,
columnID: 1,
dataTypeID: 1009,
dataTypeSize: -1,
dataTypeModifier: -1,
format: "text",
},
];
export const doltBranchFields = [
{
name: "dolt_branch",
tableID: 0,
columnID: 1,
dataTypeID: 1009,
dataTypeSize: -1,
dataTypeModifier: -1,
format: "text",
},
];
export const doltCheckoutFields = [
{
name: "dolt_checkout",
tableID: 0,
columnID: 1,
dataTypeID: 1009,
dataTypeSize: -1,
dataTypeModifier: -1,
format: "text",
},
];
export const doltCleanFields = [
{
name: "dolt_clean",
tableID: 0,
columnID: 1,
dataTypeID: 1009,
dataTypeSize: -1,
dataTypeModifier: -1,
format: "text",
},
];
export const doltCommitFields = [
{
name: "dolt_commit",
tableID: 0,
columnID: 1,
dataTypeID: 1009,
dataTypeSize: -1,
dataTypeModifier: -1,
format: "text",
},
];
export const doltSchemasFields = [
{
name: "type",
tableID: 0,
columnID: 1,
dataTypeID: 1043,
dataTypeSize: 256,
dataTypeModifier: -1,
format: "text",
},
{
name: "name",
tableID: 0,
columnID: 2,
dataTypeID: 1043,
dataTypeSize: 256,
dataTypeModifier: -1,
format: "text",
},
{
name: "fragment",
tableID: 0,
columnID: 3,
dataTypeID: 25,
dataTypeSize: -1,
dataTypeModifier: -1,
format: "text",
},
{
name: "extra",
tableID: 0,
columnID: 4,
dataTypeID: 114,
dataTypeSize: -1,
dataTypeModifier: -1,
format: "text",
},
{
name: "sql_mode",
tableID: 0,
columnID: 5,
dataTypeID: 1043,
dataTypeSize: 1024,
dataTypeModifier: -1,
format: "text",
},
];
export const doltDocsFields = [
{
name: "doc_name",
tableID: 0,
columnID: 1,
dataTypeID: 25,
dataTypeSize: -1,
dataTypeModifier: -1,
format: "text",
},
{
name: "doc_text",
tableID: 0,
columnID: 2,
dataTypeID: 25,
dataTypeSize: -1,
dataTypeModifier: -1,
format: "text",
},
];
export const doltStatusFields = [
{
name: "table_name",
tableID: 0,
columnID: 1,
dataTypeID: 25,
dataTypeSize: -1,
dataTypeModifier: -1,
format: "text",
},
{
name: "staged",
tableID: 0,
columnID: 2,
dataTypeID: 16,
dataTypeSize: 1,
dataTypeModifier: -1,
format: "text",
},
{
name: "status",
tableID: 0,
columnID: 3,
dataTypeID: 25,
dataTypeSize: -1,
dataTypeModifier: -1,
format: "text",
},
];
export const doltTagFields = [
{
name: "dolt_tag",
tableID: 0,
columnID: 1,
dataTypeID: 1009,
dataTypeSize: -1,
dataTypeModifier: -1,
format: "text",
},
];
export const doltTagsFields = [
{
name: "tag_name",
tableID: 0,
columnID: 1,
dataTypeID: 25,
dataTypeSize: -4,
dataTypeModifier: -1,
format: "text",
},
{
name: "tag_hash",
tableID: 0,
columnID: 2,
dataTypeID: 25,
dataTypeSize: -4,
dataTypeModifier: -1,
format: "text",
},
{
name: "tagger",
tableID: 0,
columnID: 3,
dataTypeID: 25,
dataTypeSize: -4,
dataTypeModifier: -1,
format: "text",
},
{
name: "email",
tableID: 0,
columnID: 4,
dataTypeID: 25,
dataTypeSize: -4,
dataTypeModifier: -1,
format: "text",
},
{
name: "date",
tableID: 0,
columnID: 5,
dataTypeID: 1114,
dataTypeSize: 26,
dataTypeModifier: -1,
format: "text",
},
{
name: "message",
tableID: 0,
columnID: 6,
dataTypeID: 25,
dataTypeSize: -4,
dataTypeModifier: -1,
format: "text",
},
];
export const infoSchemaKeyColumnUsageFields = [
{
name: "CONSTRAINT_CATALOG",
tableID: 0,
columnID: 1,
dataTypeID: 1043,
dataTypeSize: 192,
dataTypeModifier: -1,
format: "text",
},
{
name: "CONSTRAINT_SCHEMA",
tableID: 0,
columnID: 2,
dataTypeID: 1043,
dataTypeSize: 192,
dataTypeModifier: -1,
format: "text",
},
{
name: "CONSTRAINT_NAME",
tableID: 0,
columnID: 3,
dataTypeID: 1043,
dataTypeSize: 192,
dataTypeModifier: -1,
format: "text",
},
{
name: "TABLE_CATALOG",
tableID: 0,
columnID: 4,
dataTypeID: 1043,
dataTypeSize: 192,
dataTypeModifier: -1,
format: "text",
},
{
name: "TABLE_SCHEMA",
tableID: 0,
columnID: 5,
dataTypeID: 1043,
dataTypeSize: 192,
dataTypeModifier: -1,
format: "text",
},
{
name: "TABLE_NAME",
tableID: 0,
columnID: 6,
dataTypeID: 1043,
dataTypeSize: 192,
dataTypeModifier: -1,
format: "text",
},
{
name: "COLUMN_NAME",
tableID: 0,
columnID: 7,
dataTypeID: 1043,
dataTypeSize: 192,
dataTypeModifier: -1,
format: "text",
},
{
name: "ORDINAL_POSITION",
tableID: 0,
columnID: 8,
dataTypeID: 26,
dataTypeSize: 10,
dataTypeModifier: -1,
format: "text",
},
{
name: "POSITION_IN_UNIQUE_CONSTRAINT",
tableID: 0,
columnID: 9,
dataTypeID: 26,
dataTypeSize: 10,
dataTypeModifier: -1,
format: "text",
},
{
name: "REFERENCED_TABLE_SCHEMA",
tableID: 0,
columnID: 10,
dataTypeID: 1043,
dataTypeSize: 192,
dataTypeModifier: -1,
format: "text",
},
{
name: "REFERENCED_TABLE_NAME",
tableID: 0,
columnID: 11,
dataTypeID: 1043,
dataTypeSize: 192,
dataTypeModifier: -1,
format: "text",
},
{
name: "REFERENCED_COLUMN_NAME",
tableID: 0,
columnID: 12,
dataTypeID: 1043,
dataTypeSize: 192,
dataTypeModifier: -1,
format: "text",
},
];
export const schemaNameField = {
name: "schema_name",
tableID: 0,
columnID: 1,
dataTypeID: 1043,
dataTypeSize: 256,
dataTypeModifier: 68,
format: "text",
};
export const pgTablesFields = [
{
name: "schemaname",
tableID: 0,
columnID: 1,
dataTypeID: 19,
dataTypeSize: 64,
dataTypeModifier: -1,
format: "text",
},
{
name: "tablename",
tableID: 0,
columnID: 2,
dataTypeID: 19,
dataTypeSize: 64,
dataTypeModifier: -1,
format: "text",
},
];
export const doltDiffStatFields = [
{
name: "table_name",
tableID: 0,
columnID: 1,
dataTypeID: 25,
dataTypeSize: -1,
dataTypeModifier: -1,
format: "text",
},
{
name: "rows_unmodified",
tableID: 0,
columnID: 2,
dataTypeID: 20,
dataTypeSize: 20,
dataTypeModifier: -1,
format: "text",
},
{
name: "rows_added",
tableID: 0,
columnID: 3,
dataTypeID: 20,
dataTypeSize: 20,
dataTypeModifier: -1,
format: "text",
},
{
name: "rows_deleted",
tableID: 0,
columnID: 4,
dataTypeID: 20,
dataTypeSize: 20,
dataTypeModifier: -1,
format: "text",
},
{
name: "rows_modified",
tableID: 0,
columnID: 5,
dataTypeID: 20,
dataTypeSize: 20,
dataTypeModifier: -1,
format: "text",
},
{
name: "cells_added",
tableID: 0,
columnID: 6,
dataTypeID: 20,
dataTypeSize: 20,
dataTypeModifier: -1,
format: "text",
},
{
name: "cells_deleted",
tableID: 0,
columnID: 7,
dataTypeID: 20,
dataTypeSize: 20,
dataTypeModifier: -1,
format: "text",
},
{
name: "cells_modified",
tableID: 0,
columnID: 8,
dataTypeID: 20,
dataTypeSize: 20,
dataTypeModifier: -1,
format: "text",
},
{
name: "old_row_count",
tableID: 0,
columnID: 9,
dataTypeID: 20,
dataTypeSize: 20,
dataTypeModifier: -1,
format: "text",
},
{
name: "new_row_count",
tableID: 0,
columnID: 10,
dataTypeID: 20,
dataTypeSize: 20,
dataTypeModifier: -1,
format: "text",
},
{
name: "old_cell_count",
tableID: 0,
columnID: 11,
dataTypeID: 20,
dataTypeSize: 20,
dataTypeModifier: -1,
format: "text",
},
{
name: "new_cell_count",
tableID: 0,
columnID: 12,
dataTypeID: 20,
dataTypeSize: 20,
dataTypeModifier: -1,
format: "text",
},
];
export const doltDiffSummaryFields = [
{
name: "from_table_name",
tableID: 0,
columnID: 1,
dataTypeID: 25,
dataTypeSize: -1,
dataTypeModifier: -1,
format: "text",
},
{
name: "to_table_name",
tableID: 0,
columnID: 2,
dataTypeID: 25,
dataTypeSize: -1,
dataTypeModifier: -1,
format: "text",
},
{
name: "diff_type",
tableID: 0,
columnID: 3,
dataTypeID: 25,
dataTypeSize: -4,
dataTypeModifier: -1,
format: "text",
},
{
name: "data_change",
tableID: 0,
columnID: 4,
dataTypeID: 21,
dataTypeSize: 4,
dataTypeModifier: -1,
format: "text",
},
{
name: "schema_change",
tableID: 0,
columnID: 5,
dataTypeID: 21,
dataTypeSize: 4,
dataTypeModifier: -1,
format: "text",
},
];
export const doltSchemaDiffFields = [
{
name: "from_table_name",
tableID: 0,
columnID: 1,
dataTypeID: 25,
dataTypeSize: -1,
dataTypeModifier: -1,
format: "text",
},
{
name: "to_table_name",
tableID: 0,
columnID: 2,
dataTypeID: 25,
dataTypeSize: -1,
dataTypeModifier: -1,
format: "text",
},
{
name: "from_create_statement",
tableID: 0,
columnID: 3,
dataTypeID: 25,
dataTypeSize: -4,
dataTypeModifier: -1,
format: "text",
},
{
name: "to_create_statement",
tableID: 0,
columnID: 4,
dataTypeID: 25,
dataTypeSize: -4,
dataTypeModifier: -1,
format: "text",
},
];
@@ -0,0 +1,64 @@
const args = process.argv.slice(2);
const user = args[0];
const port = args[1];
const version = args[2];
export const dbName = "postgres";
export function getArgs() {
return { user, port };
}
export function getDoltgresVersion() {
return version;
}
export function getConfig() {
const { user, port } = getArgs();
return {
host: "localhost",
port: port,
database: dbName,
user: user,
password: "password",
};
}
export function assertEqualRows(test, data) {
const expected = test.res;
const resultStr = JSON.stringify(data);
const result = JSON.parse(resultStr);
if (!assertQueryResult(test.q, expected, data, test.matcher)) {
console.log("Query:", test.q);
console.log("Results:", result);
console.log("Expected:", expected);
throw new Error("Query failed");
} else {
console.log("Query succeeded:", test.q);
}
}
export function assertQueryResult(q, expected, data, matcher) {
if (matcher) {
return matcher(data, expected);
}
if (q.toLowerCase().includes("dolt_commit")) {
if (data.rows.length !== 1) return false;
const hash = data.rows[0].dolt_commit[0];
if (hash.length !== 32) {
console.log("Invalid hash for dolt_commit:", hash);
return false;
}
expected.rows[0].dolt_commit = data.rows[0].dolt_commit;
}
// Does partial matching of actual and expected results.
const partialRes = {
command: data.command,
rowCount: data.rowCount,
oid: data.oid,
rows: data.rows,
fields: data.fields,
};
return JSON.stringify(expected) === JSON.stringify(partialRes);
}
+208
View File
@@ -0,0 +1,208 @@
import { Database } from "./database.js";
import { assertEqualRows, getConfig } from "./helpers.js";
import {
doltAddFields,
doltCheckoutFields,
doltCommitFields,
countFields,
} from "./fields.js";
import { mergeMatcher } from "./workbenchTests/matchers.js";
const tests = [
{
q: "create table test (pk int, value int, primary key(pk))",
res: {
command: "CREATE",
rowCount: null,
oid: null,
rows: [],
fields: [],
},
},
{
q: "select * from test",
res: {
command: "SELECT",
rowCount: 0,
oid: null,
rows: [],
fields: [
{
name: "pk",
tableID: 0, // TODO: need to be filled? Got 16859 from Postgres
columnID: 1,
dataTypeID: 23,
dataTypeSize: 4,
dataTypeModifier: -1,
format: "text",
},
{
name: "value",
tableID: 0, // TODO: need to be filled? Got 16859 from Postgres
columnID: 2,
dataTypeID: 23,
dataTypeSize: 4,
dataTypeModifier: -1,
format: "text",
},
],
},
},
{
q: "insert into test (pk, value) values (0,0)",
res: {
command: "INSERT",
rowCount: 1,
oid: 0,
rows: [],
fields: [],
},
},
{
q: "select * from test",
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [{ pk: 0, value: 0 }],
fields: [
{
name: "pk",
tableID: 0,
columnID: 1,
dataTypeID: 23,
dataTypeSize: 4,
dataTypeModifier: -1,
format: "text",
},
{
name: "value",
tableID: 0,
columnID: 2,
dataTypeID: 23,
dataTypeSize: 4,
dataTypeModifier: -1,
format: "text",
},
],
},
},
{
q: "select dolt_add('-A');",
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [{ dolt_add: ["0"] }],
fields: doltAddFields,
},
},
{
q: "select dolt_commit('-m', 'my commit')",
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [{ dolt_commit: [""] }],
fields: doltCommitFields,
},
},
{
q: "select COUNT(*) FROM dolt.log",
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [{ count: "3" }],
fields: countFields,
},
},
{
q: "select dolt_checkout('-b', 'mybranch')",
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [{ dolt_checkout: ["0", "Switched to branch 'mybranch'"] }],
fields: doltCheckoutFields,
},
},
{
q: "insert into test (pk, value) values (1,1),(2,3)",
res: {
command: "INSERT",
rowCount: 2,
oid: 0,
rows: [],
fields: [],
},
},
{
q: "select dolt_commit('-a', '-m', 'my commit2')",
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [{ dolt_commit: [""] }],
fields: doltCommitFields,
},
},
{
q: "select dolt_checkout('main')",
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [{ dolt_checkout: ["0", "Switched to branch 'main'"] }],
fields: doltCheckoutFields,
},
},
{
q: "select dolt_merge('mybranch')",
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [
{
dolt_merge: ["", "1", "0", "merge successful"],
},
],
fields: [],
},
matcher: mergeMatcher,
},
{
q: "select COUNT(*) FROM dolt.log",
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [{ count: "4" }],
fields: countFields,
},
},
];
async function main() {
const database = new Database(getConfig());
await Promise.all(
tests.map((test) => {
return database
.query(test.q)
.then((data) => {
assertEqualRows(test, data);
})
.catch((err) => {
console.error(err);
process.exit(1);
});
})
);
database.close();
process.exit(0);
}
main();
@@ -0,0 +1,86 @@
import knex from "knex";
import wtfnode from "wtfnode";
import { Socket } from "net";
import { getConfig, getDoltgresVersion } from "./helpers.js";
const db = knex({
client: "pg",
version: getDoltgresVersion(),
connection: getConfig(),
});
async function createTable() {
const val = await db.schema.createTable("test2", (table) => {
table.integer("id").primary();
table.integer("foo");
});
return val;
}
// upsert runs INSERT ... ON CONFLICT UPDATE statement, which is not yet supported in Doltgres. (TODO)
async function upsert(table, data) {
const val = await db(table).insert(data).onConflict().merge();
return val;
}
async function insert(table, data) {
const val = await db(table).insert(data);
return val;
}
async function select() {
const val = await db.select("id", "foo").from("test2");
return val;
}
async function main() {
await createTable();
await Promise.all([
insert("test2", { id: 1, foo: 1 }),
insert("test2", { id: 2, foo: 2 }),
]);
const expectedResult = JSON.stringify([
{ id: 1, foo: 1 },
{ id: 2, foo: 2 },
]);
const result = await select();
if (JSON.stringify(result) !== expectedResult) {
console.log("Results:", result);
console.log("Expected:", expectedResult);
process.exit(1);
}
await db.destroy();
// cc: https://github.com/dolthub/dolt/issues/3752
setTimeout(async () => {
const sockets = await getOpenSockets();
if (sockets.length > 0) {
wtfnode.dump();
process.exit(1);
}
}, 3000);
}
// cc: https://github.com/myndzi/wtfnode/blob/master/index.js#L457
async function getOpenSockets() {
const sockets = [];
process._getActiveHandles().forEach(function (h) {
// handles can be null now? early exit to guard against this
if (!h) {
return;
}
if (h instanceof Socket) {
if (h.fd == null && h.localAddress && !h.destroyed) {
sockets.push(h);
}
}
});
return sockets;
}
main();
+771
View File
@@ -0,0 +1,771 @@
{
"name": "node",
"version": "1.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "node",
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"knex": "^2.5.1",
"pg": "^8.12.0",
"pg-copy-streams": "^6.0.6",
"pg-promise": "^11.6.0",
"wtfnode": "^0.9.2"
}
},
"node_modules/assert-options": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/assert-options/-/assert-options-0.8.1.tgz",
"integrity": "sha512-5lNGRB5g5i2bGIzb+J1QQE1iKU/WEMVBReFIc5pPDWjcPj23otPL0eI6PB2v7QPi0qU6Mhym5D3y0ZiSIOf3GA==",
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/colorette": {
"version": "2.0.19",
"resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz",
"integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ=="
},
"node_modules/commander": {
"version": "10.0.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
"integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
"engines": {
"node": ">=14"
}
},
"node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"dependencies": {
"ms": "2.1.2"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/escalade": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
"integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
"engines": {
"node": ">=6"
}
},
"node_modules/esm": {
"version": "3.2.25",
"resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz",
"integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==",
"engines": {
"node": ">=6"
}
},
"node_modules/function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
},
"node_modules/get-package-type": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz",
"integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==",
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/getopts": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/getopts/-/getopts-2.3.0.tgz",
"integrity": "sha512-5eDf9fuSXwxBL6q5HX+dhDj+dslFGWzU5thZ9kNKUkcPtaPdatmUFKwHFrLb/uf/WpA4BHET+AX3Scl56cAjpA=="
},
"node_modules/has": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
"dependencies": {
"function-bind": "^1.1.1"
},
"engines": {
"node": ">= 0.4.0"
}
},
"node_modules/interpret": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz",
"integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==",
"engines": {
"node": ">= 0.10"
}
},
"node_modules/is-core-module": {
"version": "2.12.1",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz",
"integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==",
"dependencies": {
"has": "^1.0.3"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/knex": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/knex/-/knex-2.5.1.tgz",
"integrity": "sha512-z78DgGKUr4SE/6cm7ku+jHvFT0X97aERh/f0MUKAKgFnwCYBEW4TFBqtHWFYiJFid7fMrtpZ/gxJthvz5mEByA==",
"dependencies": {
"colorette": "2.0.19",
"commander": "^10.0.0",
"debug": "4.3.4",
"escalade": "^3.1.1",
"esm": "^3.2.25",
"get-package-type": "^0.1.0",
"getopts": "2.3.0",
"interpret": "^2.2.0",
"lodash": "^4.17.21",
"pg-connection-string": "2.6.1",
"rechoir": "^0.8.0",
"resolve-from": "^5.0.0",
"tarn": "^3.0.2",
"tildify": "2.0.0"
},
"bin": {
"knex": "bin/cli.js"
},
"engines": {
"node": ">=12"
},
"peerDependenciesMeta": {
"better-sqlite3": {
"optional": true
},
"mysql": {
"optional": true
},
"mysql2": {
"optional": true
},
"pg": {
"optional": true
},
"pg-native": {
"optional": true
},
"sqlite3": {
"optional": true
},
"tedious": {
"optional": true
}
}
},
"node_modules/lodash": {
"version": "4.18.1",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz",
"integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q=="
},
"node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"node_modules/obuf": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz",
"integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg=="
},
"node_modules/path-parse": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
},
"node_modules/pg": {
"version": "8.12.0",
"resolved": "https://registry.npmjs.org/pg/-/pg-8.12.0.tgz",
"integrity": "sha512-A+LHUSnwnxrnL/tZ+OLfqR1SxLN3c/pgDztZ47Rpbsd4jUytsTtwQo/TLPRzPJMp/1pbhYVhH9cuSZLAajNfjQ==",
"dependencies": {
"pg-connection-string": "^2.6.4",
"pg-pool": "^3.6.2",
"pg-protocol": "^1.6.1",
"pg-types": "^2.1.0",
"pgpass": "1.x"
},
"engines": {
"node": ">= 8.0.0"
},
"optionalDependencies": {
"pg-cloudflare": "^1.1.1"
},
"peerDependencies": {
"pg-native": ">=3.0.1"
},
"peerDependenciesMeta": {
"pg-native": {
"optional": true
}
}
},
"node_modules/pg-cloudflare": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz",
"integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==",
"optional": true
},
"node_modules/pg-connection-string": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.1.tgz",
"integrity": "sha512-w6ZzNu6oMmIzEAYVw+RLK0+nqHPt8K3ZnknKi+g48Ak2pr3dtljJW3o+D/n2zzCG07Zoe9VOX3aiKpj+BN0pjg=="
},
"node_modules/pg-copy-streams": {
"version": "6.0.6",
"resolved": "https://registry.npmjs.org/pg-copy-streams/-/pg-copy-streams-6.0.6.tgz",
"integrity": "sha512-Z+Dd2C2NIDTsjyFKmc6a9QLlpM8tjpERx+43RSx0WmL7j3uNChERi3xSvZUL0hWJ1oRUn4S3fhyt3apdSrTyKQ==",
"dependencies": {
"obuf": "^1.1.2"
}
},
"node_modules/pg-int8": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz",
"integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==",
"engines": {
"node": ">=4.0.0"
}
},
"node_modules/pg-minify": {
"version": "1.6.3",
"resolved": "https://registry.npmjs.org/pg-minify/-/pg-minify-1.6.3.tgz",
"integrity": "sha512-NoSsPqXxbkD8RIe+peQCqiea4QzXgosdTKY8p7PsbbGsh2F8TifDj/vJxfuR8qJwNYrijdSs7uf0tAe6WOyCsQ==",
"engines": {
"node": ">=12.0.0"
}
},
"node_modules/pg-pool": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.2.tgz",
"integrity": "sha512-Htjbg8BlwXqSBQ9V8Vjtc+vzf/6fVUuak/3/XXKA9oxZprwW3IMDQTGHP+KDmVL7rtd+R1QjbnCFPuTHm3G4hg==",
"peerDependencies": {
"pg": ">=8.0"
}
},
"node_modules/pg-promise": {
"version": "11.6.0",
"resolved": "https://registry.npmjs.org/pg-promise/-/pg-promise-11.6.0.tgz",
"integrity": "sha512-NDRPMfkv3ia89suWlJ4iGvP6X5YFrLJ2+9AIVISeBFFZ29Eb4FNXX9JaVb1p1OrpQkE2yT7igmXPL7UYQhk+6A==",
"dependencies": {
"assert-options": "0.8.1",
"pg": "8.11.5",
"pg-minify": "1.6.3",
"spex": "3.3.0"
},
"engines": {
"node": ">=14.0"
}
},
"node_modules/pg-promise/node_modules/pg": {
"version": "8.11.5",
"resolved": "https://registry.npmjs.org/pg/-/pg-8.11.5.tgz",
"integrity": "sha512-jqgNHSKL5cbDjFlHyYsCXmQDrfIX/3RsNwYqpd4N0Kt8niLuNoRNH+aazv6cOd43gPh9Y4DjQCtb+X0MH0Hvnw==",
"dependencies": {
"pg-connection-string": "^2.6.4",
"pg-pool": "^3.6.2",
"pg-protocol": "^1.6.1",
"pg-types": "^2.1.0",
"pgpass": "1.x"
},
"engines": {
"node": ">= 8.0.0"
},
"optionalDependencies": {
"pg-cloudflare": "^1.1.1"
},
"peerDependencies": {
"pg-native": ">=3.0.1"
},
"peerDependenciesMeta": {
"pg-native": {
"optional": true
}
}
},
"node_modules/pg-promise/node_modules/pg-connection-string": {
"version": "2.6.4",
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.4.tgz",
"integrity": "sha512-v+Z7W/0EO707aNMaAEfiGnGL9sxxumwLl2fJvCQtMn9Fxsg+lPpPkdcyBSv/KFgpGdYkMfn+EI1Or2EHjpgLCA=="
},
"node_modules/pg-protocol": {
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.1.tgz",
"integrity": "sha512-jPIlvgoD63hrEuihvIg+tJhoGjUsLPn6poJY9N5CnlPd91c2T18T/9zBtLxZSb1EhYxBRoZJtzScCaWlYLtktg=="
},
"node_modules/pg-types": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz",
"integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==",
"dependencies": {
"pg-int8": "1.0.1",
"postgres-array": "~2.0.0",
"postgres-bytea": "~1.0.0",
"postgres-date": "~1.0.4",
"postgres-interval": "^1.1.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/pg/node_modules/pg-connection-string": {
"version": "2.6.4",
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.4.tgz",
"integrity": "sha512-v+Z7W/0EO707aNMaAEfiGnGL9sxxumwLl2fJvCQtMn9Fxsg+lPpPkdcyBSv/KFgpGdYkMfn+EI1Or2EHjpgLCA=="
},
"node_modules/pgpass": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz",
"integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==",
"dependencies": {
"split2": "^4.1.0"
}
},
"node_modules/postgres-array": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz",
"integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==",
"engines": {
"node": ">=4"
}
},
"node_modules/postgres-bytea": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz",
"integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/postgres-date": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz",
"integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/postgres-interval": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz",
"integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==",
"dependencies": {
"xtend": "^4.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/rechoir": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz",
"integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==",
"dependencies": {
"resolve": "^1.20.0"
},
"engines": {
"node": ">= 10.13.0"
}
},
"node_modules/resolve": {
"version": "1.22.2",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz",
"integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==",
"dependencies": {
"is-core-module": "^2.11.0",
"path-parse": "^1.0.7",
"supports-preserve-symlinks-flag": "^1.0.0"
},
"bin": {
"resolve": "bin/resolve"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/resolve-from": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
"integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
"engines": {
"node": ">=8"
}
},
"node_modules/spex": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/spex/-/spex-3.3.0.tgz",
"integrity": "sha512-VNiXjFp6R4ldPbVRYbpxlD35yRHceecVXlct1J4/X80KuuPnW2AXMq3sGwhnJOhKkUsOxAT6nRGfGE5pocVw5w==",
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/split2": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
"integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
"engines": {
"node": ">= 10.x"
}
},
"node_modules/supports-preserve-symlinks-flag": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/tarn": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/tarn/-/tarn-3.0.2.tgz",
"integrity": "sha512-51LAVKUSZSVfI05vjPESNc5vwqqZpbXCsU+/+wxlOrUjk2SnFTt97v9ZgQrD4YmxYW1Px6w2KjaDitCfkvgxMQ==",
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/tildify": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/tildify/-/tildify-2.0.0.tgz",
"integrity": "sha512-Cc+OraorugtXNfs50hU9KS369rFXCfgGLpfCfvlc+Ud5u6VWmUQsOAa9HbTvheQdYnrdJqqv1e5oIqXppMYnSw==",
"engines": {
"node": ">=8"
}
},
"node_modules/wtfnode": {
"version": "0.9.2",
"resolved": "https://registry.npmjs.org/wtfnode/-/wtfnode-0.9.2.tgz",
"integrity": "sha512-AzGy/MOGmzufyHDKHwuZeuqaqslGIPuwxDAhdmUUJ91Ak22Ynxry8quXNR/cZZIaSs5T+C+LNS3W9AcMzJXhMw==",
"bin": {
"wtfnode": "proxy.js"
}
},
"node_modules/xtend": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
"engines": {
"node": ">=0.4"
}
}
},
"dependencies": {
"assert-options": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/assert-options/-/assert-options-0.8.1.tgz",
"integrity": "sha512-5lNGRB5g5i2bGIzb+J1QQE1iKU/WEMVBReFIc5pPDWjcPj23otPL0eI6PB2v7QPi0qU6Mhym5D3y0ZiSIOf3GA=="
},
"colorette": {
"version": "2.0.19",
"resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz",
"integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ=="
},
"commander": {
"version": "10.0.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
"integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug=="
},
"debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"requires": {
"ms": "2.1.2"
}
},
"escalade": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
"integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw=="
},
"esm": {
"version": "3.2.25",
"resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz",
"integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA=="
},
"function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
},
"get-package-type": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz",
"integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q=="
},
"getopts": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/getopts/-/getopts-2.3.0.tgz",
"integrity": "sha512-5eDf9fuSXwxBL6q5HX+dhDj+dslFGWzU5thZ9kNKUkcPtaPdatmUFKwHFrLb/uf/WpA4BHET+AX3Scl56cAjpA=="
},
"has": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
"requires": {
"function-bind": "^1.1.1"
}
},
"interpret": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz",
"integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw=="
},
"is-core-module": {
"version": "2.12.1",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz",
"integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==",
"requires": {
"has": "^1.0.3"
}
},
"knex": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/knex/-/knex-2.5.1.tgz",
"integrity": "sha512-z78DgGKUr4SE/6cm7ku+jHvFT0X97aERh/f0MUKAKgFnwCYBEW4TFBqtHWFYiJFid7fMrtpZ/gxJthvz5mEByA==",
"requires": {
"colorette": "2.0.19",
"commander": "^10.0.0",
"debug": "4.3.4",
"escalade": "^3.1.1",
"esm": "^3.2.25",
"get-package-type": "^0.1.0",
"getopts": "2.3.0",
"interpret": "^2.2.0",
"lodash": "^4.17.21",
"pg-connection-string": "2.6.1",
"rechoir": "^0.8.0",
"resolve-from": "^5.0.0",
"tarn": "^3.0.2",
"tildify": "2.0.0"
}
},
"lodash": {
"version": "4.18.1",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz",
"integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q=="
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"obuf": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz",
"integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg=="
},
"path-parse": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
},
"pg": {
"version": "8.12.0",
"resolved": "https://registry.npmjs.org/pg/-/pg-8.12.0.tgz",
"integrity": "sha512-A+LHUSnwnxrnL/tZ+OLfqR1SxLN3c/pgDztZ47Rpbsd4jUytsTtwQo/TLPRzPJMp/1pbhYVhH9cuSZLAajNfjQ==",
"requires": {
"pg-cloudflare": "^1.1.1",
"pg-connection-string": "^2.6.4",
"pg-pool": "^3.6.2",
"pg-protocol": "^1.6.1",
"pg-types": "^2.1.0",
"pgpass": "1.x"
},
"dependencies": {
"pg-connection-string": {
"version": "2.6.4",
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.4.tgz",
"integrity": "sha512-v+Z7W/0EO707aNMaAEfiGnGL9sxxumwLl2fJvCQtMn9Fxsg+lPpPkdcyBSv/KFgpGdYkMfn+EI1Or2EHjpgLCA=="
}
}
},
"pg-cloudflare": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz",
"integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==",
"optional": true
},
"pg-connection-string": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.1.tgz",
"integrity": "sha512-w6ZzNu6oMmIzEAYVw+RLK0+nqHPt8K3ZnknKi+g48Ak2pr3dtljJW3o+D/n2zzCG07Zoe9VOX3aiKpj+BN0pjg=="
},
"pg-copy-streams": {
"version": "6.0.6",
"resolved": "https://registry.npmjs.org/pg-copy-streams/-/pg-copy-streams-6.0.6.tgz",
"integrity": "sha512-Z+Dd2C2NIDTsjyFKmc6a9QLlpM8tjpERx+43RSx0WmL7j3uNChERi3xSvZUL0hWJ1oRUn4S3fhyt3apdSrTyKQ==",
"requires": {
"obuf": "^1.1.2"
}
},
"pg-int8": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz",
"integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw=="
},
"pg-minify": {
"version": "1.6.3",
"resolved": "https://registry.npmjs.org/pg-minify/-/pg-minify-1.6.3.tgz",
"integrity": "sha512-NoSsPqXxbkD8RIe+peQCqiea4QzXgosdTKY8p7PsbbGsh2F8TifDj/vJxfuR8qJwNYrijdSs7uf0tAe6WOyCsQ=="
},
"pg-pool": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.2.tgz",
"integrity": "sha512-Htjbg8BlwXqSBQ9V8Vjtc+vzf/6fVUuak/3/XXKA9oxZprwW3IMDQTGHP+KDmVL7rtd+R1QjbnCFPuTHm3G4hg==",
"requires": {}
},
"pg-promise": {
"version": "11.6.0",
"resolved": "https://registry.npmjs.org/pg-promise/-/pg-promise-11.6.0.tgz",
"integrity": "sha512-NDRPMfkv3ia89suWlJ4iGvP6X5YFrLJ2+9AIVISeBFFZ29Eb4FNXX9JaVb1p1OrpQkE2yT7igmXPL7UYQhk+6A==",
"requires": {
"assert-options": "0.8.1",
"pg": "8.11.5",
"pg-minify": "1.6.3",
"spex": "3.3.0"
},
"dependencies": {
"pg": {
"version": "8.11.5",
"resolved": "https://registry.npmjs.org/pg/-/pg-8.11.5.tgz",
"integrity": "sha512-jqgNHSKL5cbDjFlHyYsCXmQDrfIX/3RsNwYqpd4N0Kt8niLuNoRNH+aazv6cOd43gPh9Y4DjQCtb+X0MH0Hvnw==",
"requires": {
"pg-cloudflare": "^1.1.1",
"pg-connection-string": "^2.6.4",
"pg-pool": "^3.6.2",
"pg-protocol": "^1.6.1",
"pg-types": "^2.1.0",
"pgpass": "1.x"
}
},
"pg-connection-string": {
"version": "2.6.4",
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.4.tgz",
"integrity": "sha512-v+Z7W/0EO707aNMaAEfiGnGL9sxxumwLl2fJvCQtMn9Fxsg+lPpPkdcyBSv/KFgpGdYkMfn+EI1Or2EHjpgLCA=="
}
}
},
"pg-protocol": {
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.1.tgz",
"integrity": "sha512-jPIlvgoD63hrEuihvIg+tJhoGjUsLPn6poJY9N5CnlPd91c2T18T/9zBtLxZSb1EhYxBRoZJtzScCaWlYLtktg=="
},
"pg-types": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz",
"integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==",
"requires": {
"pg-int8": "1.0.1",
"postgres-array": "~2.0.0",
"postgres-bytea": "~1.0.0",
"postgres-date": "~1.0.4",
"postgres-interval": "^1.1.0"
}
},
"pgpass": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz",
"integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==",
"requires": {
"split2": "^4.1.0"
}
},
"postgres-array": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz",
"integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA=="
},
"postgres-bytea": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz",
"integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w=="
},
"postgres-date": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz",
"integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q=="
},
"postgres-interval": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz",
"integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==",
"requires": {
"xtend": "^4.0.0"
}
},
"rechoir": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz",
"integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==",
"requires": {
"resolve": "^1.20.0"
}
},
"resolve": {
"version": "1.22.2",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz",
"integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==",
"requires": {
"is-core-module": "^2.11.0",
"path-parse": "^1.0.7",
"supports-preserve-symlinks-flag": "^1.0.0"
}
},
"resolve-from": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
"integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw=="
},
"spex": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/spex/-/spex-3.3.0.tgz",
"integrity": "sha512-VNiXjFp6R4ldPbVRYbpxlD35yRHceecVXlct1J4/X80KuuPnW2AXMq3sGwhnJOhKkUsOxAT6nRGfGE5pocVw5w=="
},
"split2": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
"integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg=="
},
"supports-preserve-symlinks-flag": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="
},
"tarn": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/tarn/-/tarn-3.0.2.tgz",
"integrity": "sha512-51LAVKUSZSVfI05vjPESNc5vwqqZpbXCsU+/+wxlOrUjk2SnFTt97v9ZgQrD4YmxYW1Px6w2KjaDitCfkvgxMQ=="
},
"tildify": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/tildify/-/tildify-2.0.0.tgz",
"integrity": "sha512-Cc+OraorugtXNfs50hU9KS369rFXCfgGLpfCfvlc+Ud5u6VWmUQsOAa9HbTvheQdYnrdJqqv1e5oIqXppMYnSw=="
},
"wtfnode": {
"version": "0.9.2",
"resolved": "https://registry.npmjs.org/wtfnode/-/wtfnode-0.9.2.tgz",
"integrity": "sha512-AzGy/MOGmzufyHDKHwuZeuqaqslGIPuwxDAhdmUUJ91Ak22Ynxry8quXNR/cZZIaSs5T+C+LNS3W9AcMzJXhMw=="
},
"xtend": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="
}
}
}
@@ -0,0 +1,20 @@
{
"name": "node",
"version": "1.0.0",
"node": ">=16.9",
"description": "A simple node command line utility to show how to connect a node application to a Doltgres database using the PostgreSQL connector.",
"main": "index.js",
"type": "module",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"knex": "^2.5.1",
"pg": "^8.12.0",
"pg-copy-streams": "^6.0.6",
"pg-promise": "^11.6.0",
"wtfnode": "^0.9.2"
}
}
@@ -0,0 +1,13 @@
#!/bin/sh
source ../helpers.bash
echo "Running $1 tests"
start_doltgres_server
query_server -c "CREATE TABLE IF NOT EXISTS test_table(pk int)" -t
query_server -c "DELETE FROM test_table" -t
query_server -c "INSERT INTO test_table VALUES (1)" -t
cd ..
DOLTGRES_VERSION=$( doltgres --version | sed -nre 's/^[^0-9]*(([0-9]+\.)*[0-9]+).*/\1/p' )
node $1 $USER $PORT $DOLTGRES_VERSION $PWD/testdata
teardown_doltgres_repo
@@ -0,0 +1,4 @@
id,info,test_pk
4,string for 4,1
5,string for 5,0
6,string for 6,0
1 id info test_pk
2 4 string for 4 1
3 5 string for 5 0
4 6 string for 6 0
@@ -0,0 +1,4 @@
id|info|test_pk
10|string for 10|0
11|string for 11|0
12|string for 12|0
@@ -0,0 +1,14 @@
import { Database } from "./database.js";
import { getConfig } from "./helpers.js";
import runWorkbenchTests from "./workbenchTests/index.js";
async function workbench() {
const database = new Database(getConfig());
await runWorkbenchTests(database);
database.close();
process.exit(0);
}
workbench();
@@ -0,0 +1,152 @@
import {
countFields,
doltBranchFields,
doltCheckoutFields,
doltStatusFields,
doltCommitFields,
} from "../fields.js";
import { branchesMatcher } from "./matchers.js";
import { dbName } from "../helpers.js";
export const branchTests = [
{
q: `SELECT DOLT_BRANCH($1::text, $2::text)`, // TODO: Should work without casts
p: ["mybranch", "main"],
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [{ dolt_branch: ["0"] }],
fields: doltBranchFields,
},
},
{
q: `USE '${dbName}/mybranch';`,
res: {
command: "SET",
rowCount: null,
oid: null,
rows: [],
fields: [],
},
},
{
q: `create table test (pk int, "value" int, primary key(pk));`,
res: {
command: "CREATE",
rowCount: null,
oid: null,
rows: [],
fields: [],
},
},
{
q: `SELECT * FROM dolt.status;`,
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [
{
table_name: "public.test",
staged: false,
status: "new table",
},
],
fields: doltStatusFields,
},
},
{
q: `SELECT DOLT_COMMIT('-Am', $1::text, '--author', $2::text);`,
p: ["Create table test", "Dolt <dolt@dolthub.com>"],
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [{ dolt_commit: "" }],
fields: doltCommitFields,
},
},
{
q: `SELECT * FROM dolt.branches LIMIT 200`,
res: {
rows: [
{
name: "main",
hash: "",
latest_committer: "postgres",
latest_committer_email: "postgres@127.0.0.1",
latest_commit_date: "",
latest_commit_message: "CREATE DATABASE",
remote: "",
branch: "",
dirty: 1,
},
{
name: "mybranch",
hash: "",
latest_committer: "Dolt",
latest_committer_email: "dolt@dolthub.com",
latest_commit_date: "",
latest_commit_message: "Create table test",
remote: "",
branch: "",
dirty: 0,
},
],
},
matcher: branchesMatcher,
},
{
q: `SELECT DOLT_CHECKOUT('-b', $1::text)`,
p: ["branch-to-delete"],
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [{ dolt_checkout: ["0", "Switched to branch 'branch-to-delete'"] }],
fields: doltCheckoutFields,
},
},
{
q: `SELECT COUNT(*) FROM dolt.branches LIMIT 200`,
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [{ count: "3" }],
fields: countFields,
},
},
{
q: `USE '${dbName}/main';`,
res: {
command: "SET",
rowCount: null,
oid: null,
rows: [],
fields: [],
},
},
{
q: `SELECT DOLT_BRANCH('-D', $1::text)`,
p: ["branch-to-delete"],
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [{ dolt_branch: ["0"] }],
fields: doltBranchFields,
},
},
{
q: `SELECT COUNT(*) FROM dolt.branches LIMIT 200`,
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [{ count: "2" }],
fields: countFields,
},
},
];
@@ -0,0 +1,86 @@
import { doltCleanFields } from "../fields.js";
import { dbName } from "../helpers.js";
export const databaseTests = [
{
q: `USE '${dbName}/main';`,
res: {
command: "SET",
rowCount: null,
oid: null,
rows: [],
fields: [],
},
},
{
q: `SELECT DOLT_CLEAN('test_table')`,
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [{ dolt_clean: ["0"] }],
fields: doltCleanFields,
},
},
{
q: `SELECT datname FROM pg_database;`,
res: {
command: "SELECT",
rowCount: 2,
oid: null,
rows: [{ datname: dbName }, { datname: `${dbName}/main` }],
fields: [
{
name: "datname",
tableID: 0,
columnID: 0,
dataTypeID: 19,
dataTypeSize: 64,
dataTypeModifier: -1,
format: "text",
},
],
},
},
{
q: `CREATE DATABASE "new_db";`,
res: {
command: "CREATE",
rowCount: null,
oid: null,
rows: [],
fields: [],
},
},
{
q: `SELECT datname FROM pg_database;`,
res: {
command: "SELECT",
rowCount: 3,
oid: null,
rows: [
{ datname: "new_db" },
{ datname: dbName },
{ datname: `${dbName}/main` },
],
fields: [
{
name: "datname",
tableID: 0,
columnID: 0,
dataTypeID: 19,
dataTypeSize: 64,
dataTypeModifier: -1,
format: "text",
},
],
},
},
{
q: `SELECT dolt_version();`,
res: [{ "dolt_version()": "0.0.0" }],
matcher: (data) => {
return data.rows[0].dolt_version.length > 0;
},
},
];
@@ -0,0 +1,780 @@
import {
doltCommitFields,
doltDiffStatFields,
doltDiffSummaryFields,
doltSchemaDiffFields,
doltStatusFields,
pgTablesFields,
} from "../fields.js";
import { diffRowsMatcher, patchRowsMatcher } from "./matchers.js";
export const diffTests = [
{
q: "UPDATE test SET value=1 WHERE pk=0",
res: {
command: "UPDATE",
rowCount: 1,
oid: null,
rows: [],
fields: [],
},
},
{
q: "DROP TABLE test_info",
res: {
command: "DROP",
rowCount: null,
oid: null,
rows: [],
fields: [],
},
},
{
q: `CREATE SCHEMA anotherschema;`,
res: {
command: "CREATE",
rowCount: null,
oid: null,
rows: [],
fields: [],
},
},
{
q: `create table anotherschema.testanother (pk int, "value" int, primary key(pk));`,
res: {
command: "CREATE",
rowCount: null,
oid: null,
rows: [],
fields: [],
},
},
{
q: "INSERT INTO anotherschema.testanother VALUES (1, 2)",
res: {
command: "INSERT",
rowCount: 1,
oid: 0,
rows: [],
fields: [],
},
},
{
q: `SELECT * FROM dolt.status ORDER BY table_name;`,
res: {
command: "SELECT",
rowCount: 5,
oid: null,
rows: [
{ table_name: "anotherschema", staged: false, status: "new schema" },
{
table_name: "anotherschema.testanother",
staged: false,
status: "new table",
},
{
table_name: "public.dolt_schemas",
staged: false,
status: "new table",
},
{ table_name: "public.test", staged: false, status: "modified" },
{ table_name: "public.test_info", staged: false, status: "deleted" },
],
fields: doltStatusFields,
},
},
{
q: "SELECT * FROM dolt_diff_summary('HEAD', 'WORKING') ORDER BY to_table_name;", // TODO: Prepared not working
res: {
command: "SELECT",
rowCount: 4,
oid: null,
rows: [
{
from_table_name: "public.test_info",
to_table_name: "",
diff_type: "dropped",
data_change: 1,
schema_change: 1,
},
{
from_table_name: "",
to_table_name: "anotherschema.testanother",
diff_type: "added",
data_change: 1,
schema_change: 1,
},
{
from_table_name: "",
to_table_name: "public.dolt_schemas",
diff_type: "added",
data_change: 1,
schema_change: 1,
},
{
from_table_name: "public.test",
to_table_name: "public.test",
diff_type: "modified",
data_change: 1,
schema_change: 0,
},
],
fields: doltDiffSummaryFields,
},
},
{
q: "SELECT * FROM dolt_diff_summary('HEAD', 'WORKING', 'test')",
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [
{
from_table_name: "public.test",
to_table_name: "public.test",
diff_type: "modified",
data_change: 1,
schema_change: 0,
},
],
fields: doltDiffSummaryFields,
},
},
{
// TODO: What if a table with same name but different schema exists in different schema?
q: "SELECT * FROM dolt_diff_summary('HEAD', 'WORKING', 'testanother')",
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [
{
from_table_name: "",
to_table_name: "anotherschema.testanother",
diff_type: "added",
data_change: 1,
schema_change: 1,
},
],
fields: doltDiffSummaryFields,
},
},
{
q: "SELECT * FROM dolt_diff_stat('HEAD', 'WORKING') ORDER BY table_name",
res: {
command: "SELECT",
rowCount: 4,
oid: null,
rows: [
{
table_name: "anotherschema.testanother",
rows_unmodified: "0",
rows_added: "1",
rows_deleted: "0",
rows_modified: "0",
cells_added: "2",
cells_deleted: "0",
cells_modified: "0",
old_row_count: "0",
new_row_count: "1",
old_cell_count: "0",
new_cell_count: "2",
},
{
table_name: "public.dolt_schemas",
rows_unmodified: "0",
rows_added: "1",
rows_deleted: "0",
rows_modified: "0",
cells_added: "5",
cells_deleted: "0",
cells_modified: "0",
old_row_count: "0",
new_row_count: "1",
old_cell_count: "0",
new_cell_count: "5",
},
{
table_name: "public.test",
rows_unmodified: "2",
rows_added: "0",
rows_deleted: "0",
rows_modified: "1",
cells_added: "0",
cells_deleted: "0",
cells_modified: "1",
old_row_count: "3",
new_row_count: "3",
old_cell_count: "6",
new_cell_count: "6",
},
{
table_name: "public.test_info",
rows_unmodified: "0",
rows_added: "0",
rows_deleted: "1",
rows_modified: "0",
cells_added: "0",
cells_deleted: "3",
cells_modified: "0",
old_row_count: "1",
new_row_count: "0",
old_cell_count: "3",
new_cell_count: "0",
},
],
fields: doltDiffStatFields,
},
},
{
q: "SELECT * FROM dolt_diff_stat('HEAD', 'WORKING', 'test_info')",
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [
{
table_name: "public.test_info",
rows_unmodified: "0",
rows_added: "0",
rows_deleted: "1",
rows_modified: "0",
cells_added: "0",
cells_deleted: "3",
cells_modified: "0",
old_row_count: "1",
new_row_count: "0",
old_cell_count: "3",
new_cell_count: "0",
},
],
fields: doltDiffStatFields,
},
},
{
q: "SELECT * FROM dolt_diff_stat('HEAD', 'WORKING', 'testanother')",
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [
{
table_name: "anotherschema.testanother",
rows_unmodified: "0",
rows_added: "1",
rows_deleted: "0",
rows_modified: "0",
cells_added: "2",
cells_deleted: "0",
cells_modified: "0",
old_row_count: "0",
new_row_count: "1",
old_cell_count: "0",
new_cell_count: "2",
},
],
fields: doltDiffStatFields,
},
},
{
q: "SELECT * FROM DOLT_DIFF('HEAD', 'WORKING', 'test') ORDER BY to_pk ASC, from_pk ASC LIMIT 10 OFFSET 0",
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [
{
to_pk: 0,
to_value: 1,
to_commit: "WORKING",
to_commit_date: "2023-03-09T07:44:47.670Z",
from_pk: 0,
from_value: 0,
from_commit: "HEAD",
from_commit_date: "2023-03-09T07:44:47.488Z",
diff_type: "modified",
},
],
fields: [],
},
matcher: diffRowsMatcher,
},
{
q: "SELECT * FROM DOLT_DIFF('HEAD', 'WORKING', 'test_info') ORDER BY to_id ASC, from_id ASC LIMIT 10 OFFSET 0",
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [
{
to_id: null,
to_info: null,
to_test_pk: null,
to_commit: "WORKING",
to_commit_date: "2023-03-09T07:53:48.614Z",
from_id: 1,
from_info: "info about test pk 0",
from_test_pk: 0,
from_commit: "HEAD",
from_commit_date: "2023-03-09T07:53:48.284Z",
diff_type: "removed",
},
],
fields: [],
},
matcher: diffRowsMatcher,
},
{
q: "SELECT * FROM DOLT_DIFF('HEAD', 'WORKING', 'testanother') ORDER BY to_pk ASC, from_pk ASC LIMIT 10 OFFSET 0",
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [
{
to_pk: 1,
to_value: 2,
to_commit: "WORKING",
to_commit_date: "2024-10-03T04:33:43.486Z",
from_pk: null,
from_value: null,
from_commit: "HEAD",
from_commit_date: "2024-10-03T04:33:43.430Z",
diff_type: "added",
},
],
fields: [],
},
matcher: diffRowsMatcher,
},
{
q: "SELECT * FROM DOLT_DIFF('HEAD', 'WORKING', 'dolt_schemas') ORDER BY to_name ASC, from_name ASC LIMIT 10 OFFSET 0",
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [
{
to_type: "view",
to_name: "myview",
to_fragment: "CREATE VIEW myview AS SELECT * FROM test",
to_extra: { CreatedAt: 0 },
to_sql_mode:
"NO_ENGINE_SUBSTITUTION,ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES",
to_commit: "WORKING",
to_commit_date: "2023-03-09T07:56:29.035Z",
from_type: null,
from_name: null,
from_fragment: null,
from_extra: null,
from_sql_mode: null,
from_commit: "HEAD",
from_commit_date: "2023-03-09T07:56:28.841Z",
diff_type: "added",
},
],
fields: [],
},
matcher: diffRowsMatcher,
},
{
skip: true, // TODO: Order is not consistent
q: "SELECT * FROM DOLT_PATCH('HEAD', 'WORKING') WHERE diff_type = 'schema'",
res: {
command: "SELECT",
rowCount: 3,
oid: null,
rows: [
{
statement_order: "1",
from_commit_hash: "",
to_commit_hash: "WORKING",
table_name: "test_info",
diff_type: "schema",
statement: "DROP TABLE `test_info`;",
},
// TODO: Should `CREATE SCHEMA` statement be included here?
{
statement_order: "2",
from_commit_hash: "r6g8g61k89dpgb3cuks70jfnavr6b1q0",
to_commit_hash: "WORKING",
table_name: "testanother",
diff_type: "schema",
statement:
"CREATE TABLE `testanother` (\n" +
" `pk` integer NOT NULL,\n" +
" `value` integer,\n" +
" PRIMARY KEY (`pk`)\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin;",
},
{
statement_order: "4", // TODO: Why is this 4?
from_commit_hash: "",
to_commit_hash: "WORKING",
table_name: "dolt_schemas",
diff_type: "schema",
statement:
"CREATE TABLE `dolt_schemas` (\n" + // TODO: No backticks
" `type` varchar(64) COLLATE utf8mb4_0900_ai_ci NOT NULL,\n" +
" `name` varchar(64) COLLATE utf8mb4_0900_ai_ci NOT NULL,\n" +
" `fragment` longtext,\n" +
" `extra` json,\n" +
" `sql_mode` varchar(256) COLLATE utf8mb4_0900_ai_ci,\n" +
" PRIMARY KEY (`type`,`name`)\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin;",
},
],
fields: [],
},
matcher: patchRowsMatcher,
},
{
q: "SELECT * FROM DOLT_PATCH('HEAD', 'WORKING', 'test_info') WHERE diff_type = 'schema'",
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [
{
statement_order: "1",
from_commit_hash: "",
to_commit_hash: "WORKING",
table_name: "public.test_info",
diff_type: "schema",
statement: "DROP TABLE `test_info`;", // TODO: No backticks
},
],
},
matcher: patchRowsMatcher,
},
{
q: "SELECT * FROM DOLT_SCHEMA_DIFF('HEAD', 'WORKING') ORDER BY to_table_name;",
res: {
command: "SELECT",
rowCount: 3,
oid: null,
rows: [
{
from_table_name: "public.test_info",
to_table_name: "",
from_create_statement:
"CREATE TABLE `test_info` (\n" + // TODO: No backticks
" `id` integer NOT NULL,\n" +
" `info` varchar(255),\n" +
" `test_pk` integer,\n" +
" PRIMARY KEY (`id`),\n" +
" KEY `test_info_test_pk_fkey` (`test_pk`),\n" +
" CONSTRAINT `test_info_test_pk_fkey` FOREIGN KEY (`test_pk`) REFERENCES `test` (`pk`) ON DELETE NO ACTION ON UPDATE NO ACTION\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin;",
to_create_statement: "",
},
{
from_table_name: "",
to_table_name: "anotherschema.testanother",
from_create_statement: "",
to_create_statement:
"CREATE TABLE `testanother` (\n" +
" `pk` integer NOT NULL,\n" +
" `value` integer,\n" +
" PRIMARY KEY (`pk`)\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin;",
},
{
from_table_name: "",
to_table_name: "public.dolt_schemas",
from_create_statement: "",
to_create_statement:
"CREATE TABLE `dolt_schemas` (\n" + // TODO: No backticks
" `type` varchar(64) COLLATE utf8mb4_0900_ai_ci NOT NULL,\n" +
" `name` varchar(64) COLLATE utf8mb4_0900_ai_ci NOT NULL,\n" +
" `fragment` longtext,\n" +
" `extra` json,\n" +
" `sql_mode` varchar(256) COLLATE utf8mb4_0900_ai_ci,\n" +
" PRIMARY KEY (`type`,`name`)\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin;",
},
],
fields: doltSchemaDiffFields,
},
},
{
q: "SELECT * FROM DOLT_SCHEMA_DIFF('HEAD', 'WORKING', 'test_info')",
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [
{
from_table_name: "public.test_info",
to_table_name: "",
from_create_statement:
"CREATE TABLE `test_info` (\n" + // TODO: No backticks
" `id` integer NOT NULL,\n" +
" `info` varchar(255),\n" +
" `test_pk` integer,\n" +
" PRIMARY KEY (`id`),\n" +
" KEY `test_info_test_pk_fkey` (`test_pk`),\n" +
" CONSTRAINT `test_info_test_pk_fkey` FOREIGN KEY (`test_pk`) REFERENCES `test` (`pk`) ON DELETE NO ACTION ON UPDATE NO ACTION\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin;",
to_create_statement: "",
},
],
fields: doltSchemaDiffFields,
},
},
{
q: "SELECT * FROM DOLT_SCHEMA_DIFF('HEAD', 'WORKING', 'testanother')",
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [
{
from_table_name: "",
to_table_name: "anotherschema.testanother",
from_create_statement: "",
to_create_statement:
"CREATE TABLE `testanother` (\n" +
" `pk` integer NOT NULL,\n" +
" `value` integer,\n" +
" PRIMARY KEY (`pk`)\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin;",
},
],
fields: doltSchemaDiffFields,
},
},
{
q: `SELECT DOLT_COMMIT('-A', '-m', $1::text)`,
p: ["Make some changes on branch"],
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [{ dolt_commit: "" }],
fields: doltCommitFields,
},
},
// Three dot
{
q: "SELECT * FROM dolt_diff_summary('main...HEAD') ORDER BY to_table_name",
res: {
command: "SELECT",
rowCount: 4,
oid: null,
rows: [
{
from_table_name: "public.test_info",
to_table_name: "",
diff_type: "dropped",
data_change: 1,
schema_change: 1,
},
{
from_table_name: "",
to_table_name: "anotherschema.testanother",
diff_type: "added",
data_change: 1,
schema_change: 1,
},
{
from_table_name: "",
to_table_name: "public.dolt_schemas",
diff_type: "added",
data_change: 1,
schema_change: 1,
},
{
from_table_name: "public.test",
to_table_name: "public.test",
diff_type: "modified",
data_change: 1,
schema_change: 0,
},
],
fields: doltDiffSummaryFields,
},
},
{
q: "SELECT * FROM dolt_diff_summary('main...HEAD', 'test')",
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [
{
from_table_name: "public.test",
to_table_name: "public.test",
diff_type: "modified",
data_change: 1,
schema_change: 0,
},
],
fields: doltDiffSummaryFields,
},
},
{
q: "SELECT * FROM dolt_diff_stat('main...HEAD') ORDER BY table_name;",
res: {
command: "SELECT",
rowCount: 4,
oid: null,
rows: [
{
table_name: "anotherschema.testanother",
rows_unmodified: "0",
rows_added: "1",
rows_deleted: "0",
rows_modified: "0",
cells_added: "2",
cells_deleted: "0",
cells_modified: "0",
old_row_count: "0",
new_row_count: "1",
old_cell_count: "0",
new_cell_count: "2",
},
{
table_name: "public.dolt_schemas",
rows_unmodified: "0",
rows_added: "1",
rows_deleted: "0",
rows_modified: "0",
cells_added: "5",
cells_deleted: "0",
cells_modified: "0",
old_row_count: "0",
new_row_count: "1",
old_cell_count: "0",
new_cell_count: "5",
},
{
table_name: "public.test",
rows_unmodified: "2",
rows_added: "0",
rows_deleted: "0",
rows_modified: "1",
cells_added: "0",
cells_deleted: "0",
cells_modified: "1",
old_row_count: "3",
new_row_count: "3",
old_cell_count: "6",
new_cell_count: "6",
},
{
table_name: "public.test_info",
rows_unmodified: "0",
rows_added: "0",
rows_deleted: "1",
rows_modified: "0",
cells_added: "0",
cells_deleted: "3",
cells_modified: "0",
old_row_count: "1",
new_row_count: "0",
old_cell_count: "3",
new_cell_count: "0",
},
],
fields: doltDiffStatFields,
},
},
{
q: "SELECT * FROM dolt_diff_stat('main...HEAD', 'test_info')",
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [
{
table_name: "public.test_info",
rows_unmodified: "0",
rows_added: "0",
rows_deleted: "1",
rows_modified: "0",
cells_added: "0",
cells_deleted: "3",
cells_modified: "0",
old_row_count: "1",
new_row_count: "0",
old_cell_count: "3",
new_cell_count: "0",
},
],
fields: doltDiffStatFields,
},
},
{
skip: true, // TODO: Order not consistent
q: "SELECT * FROM DOLT_PATCH('main...HEAD') WHERE diff_type = 'schema'",
res: {
command: "SELECT",
rowCount: 4,
oid: null,
rows: [
{
statement_order: "1",
from_commit_hash: "",
to_commit_hash: "",
table_name: "public.test_info",
diff_type: "schema",
statement: "DROP TABLE `test_info`;",
},
{
statement_order: "2",
from_commit_hash: "",
to_commit_hash: "",
table_name: "anotherschema.testanother",
diff_type: "schema",
statement:
"CREATE TABLE `testanother` (\n" +
" `pk` integer NOT NULL,\n" +
" `value` integer,\n" +
" PRIMARY KEY (`pk`)\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin;",
},
// TODO: `CREATE SCHEMA` here?
{
statement_order: "4", // TODO: why
from_commit_hash: "",
to_commit_hash: "",
table_name: "public.dolt_schemas",
diff_type: "schema",
statement:
"CREATE TABLE `dolt_schemas` (\n" +
" `type` varchar(64) COLLATE utf8mb4_0900_ai_ci NOT NULL,\n" +
" `name` varchar(64) COLLATE utf8mb4_0900_ai_ci NOT NULL,\n" +
" `fragment` longtext,\n" +
" `extra` json,\n" +
" `sql_mode` varchar(256) COLLATE utf8mb4_0900_ai_ci,\n" +
" PRIMARY KEY (`type`,`name`)\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin;",
},
],
fields: [],
},
matcher: patchRowsMatcher,
},
{
q: "SELECT * FROM DOLT_PATCH('main...HEAD', 'test_info') WHERE diff_type = 'schema'",
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [
{
statement_order: "1",
from_commit_hash: "",
to_commit_hash: "",
table_name: "public.test_info",
diff_type: "schema",
statement: "DROP TABLE `test_info`;",
},
],
fields: [],
},
matcher: patchRowsMatcher,
},
];
@@ -0,0 +1,157 @@
import {
doltCommitFields,
doltDocsFields,
doltStatusFields,
} from "../fields.js";
const readmeText = `# README
## My List
- Item 1
- Item 2
`;
const updatedReadmeText = `${readmeText}-Item 3`;
export const docsTests = [
{
q: "select * from dolt.docs",
res: {
command: "SELECT",
rowCount: 0,
oid: null,
rows: [],
fields: doltDocsFields,
},
},
{
q: "INSERT INTO dolt.docs VALUES ($1, $2);",
p: ["README.md", readmeText],
res: {
command: "INSERT",
rowCount: 1,
oid: 0,
rows: [],
fields: [],
},
},
{
q: `select * from dolt.docs where doc_name=$1`,
p: ["README.md"],
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [{ doc_name: "README.md", doc_text: readmeText }],
fields: doltDocsFields,
},
},
{
q: "INSERT INTO dolt.docs VALUES ($1, $2) ON CONFLICT (doc_name) DO UPDATE SET doc_text = $2",
p: ["README.md", updatedReadmeText],
res: {
command: "INSERT",
rowCount: 2, // TODO: This should be 1, but there's a bug in the GMS iterators that overcounts
oid: 0,
rows: [],
fields: [],
},
},
{
q: `select * from dolt.docs where doc_name=$1`,
p: ["README.md"],
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [{ doc_name: "README.md", doc_text: updatedReadmeText }],
fields: doltDocsFields,
},
},
{
q: `SELECT * FROM dolt.status`,
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [{ table_name: "dolt.docs", staged: false, status: "new table" }],
fields: doltStatusFields,
},
},
{
q: `SELECT DOLT_COMMIT('-A', '-m', $1::text)`,
p: ["Add dolt.docs table"],
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [{ dolt_commit: "" }],
fields: doltCommitFields,
},
},
{
q: `select * from dolt.docs where doc_name=$1`,
p: ["README.md"],
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [{ doc_name: "README.md", doc_text: updatedReadmeText }],
fields: doltDocsFields,
},
},
{
q: "DELETE FROM dolt.docs WHERE doc_name=$1",
p: ["README.md"],
res: {
command: "DELETE",
rowCount: 1,
oid: null,
rows: [],
fields: [],
},
},
{
q: `select * from dolt.docs where doc_name=$1`,
p: ["README.md"],
res: {
command: "SELECT",
rowCount: 0,
oid: null,
rows: [],
fields: doltDocsFields,
},
},
{
q: `SET SEARCH_PATH = 'public,';`,
res: {
command: "SET",
rowCount: null,
oid: null,
rows: [],
fields: [],
},
},
{
q: `select * from dolt.docs where doc_name=$1`,
p: ["README.md"],
res: {
command: "SELECT",
rowCount: 0,
oid: null,
rows: [],
fields: doltDocsFields,
},
},
{
q: `SELECT DOLT_COMMIT('-A', '-m', $1::text)`,
p: ["Remove README"],
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [{ dolt_commit: "" }],
fields: doltCommitFields,
},
},
];
@@ -0,0 +1,75 @@
import fs from "fs";
import { pipeline } from "stream/promises";
import { from as copyFrom } from "pg-copy-streams";
import path from "path";
import { branchTests } from "./branches.js";
import { databaseTests } from "./databases.js";
import { docsTests } from "./docs.js";
import { logTests } from "./logs.js";
import { assertEqualRows } from "../helpers.js";
import { mergeTests } from "./merge.js";
import { tableTests } from "./table.js";
import { schemaTests } from "./schemas.js";
import { tagsTests } from "./tags.js";
import { viewsTests } from "./views.js";
import { diffTests } from "./diffs.js";
const args = process.argv.slice(2);
const testDataPath = args[3];
export default async function runWorkbenchTests(database) {
await runTests(database, databaseTests, "database");
await runTests(database, branchTests, "branches");
await runTests(database, schemaTests, "schemas");
await runTests(database, logTests, "logs");
await runTests(database, mergeTests, "merge");
await runTests(database, tableTests, "tables");
await runTests(database, docsTests, "docs");
await runTests(database, tagsTests, "tags");
await runTests(database, viewsTests, "views");
await runTests(database, diffTests, "diffs");
}
async function runTests(database, tests, name) {
console.log("Running tests for", name);
await Promise.all(
tests.map(async (test) => {
if (test.skip) return;
if (test.file) {
const filePath = path.resolve(testDataPath, test.file);
try {
// TODO: Is it possible to test the COPY FROM output?
const ingestStream = database.client.query(copyFrom(test.q));
const sourceStream = fs.createReadStream(filePath);
await pipeline([sourceStream, ingestStream]);
} catch (err) {
console.log("Query errored:", test.q);
console.error(err);
process.exit(1);
}
return;
}
return database
.query(test.q, test.p)
.then((data) => {
assertEqualRows(test, data);
})
.catch((err) => {
if (test.expectedErr) {
if (err.message.includes(test.expectedErr)) {
return;
} else {
console.log("Query error did not match expected:", test.q);
}
} else {
console.log("Query errored:", test.q);
}
console.error(err);
process.exit(1);
});
})
);
}
@@ -0,0 +1,105 @@
import { logsMatcher } from "./matchers.js";
import { dbName } from "../helpers.js";
export const logTests = [
{
q: `SELECT * FROM DOLT_LOG('main', '--parents') LIMIT 10 OFFSET 0;`, // TODO: Prepared not working
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [
{
commit_hash: "",
committer: "postgres",
email: "postgres@127.0.0.1",
date: "",
message: "CREATE DATABASE",
parents: ["3orrg69ou1loj2ph21guie3r2lf8bsab"],
},
{
commit_hash: "",
committer: "Dolt System Account",
email: "doltuser@dolthub.com",
date: "",
message: "Initialize data repository",
parents: [],
},
],
fields: [],
},
matcher: logsMatcher,
},
{
q: `USE '${dbName}/mybranch';`,
res: {
command: "SET",
rowCount: null,
oid: null,
rows: [],
fields: [],
},
},
{
q: `SELECT * FROM dolt.log;`, // TODO: If we decide to implement AS OF, use here instead of USE statement above and below
res: {
command: "SELECT",
rowCount: 2,
oid: null,
rows: [
{
commit_hash: "",
committer: "Dolt",
email: "dolt@dolthub.com",
date: "",
message: "Create table test",
},
{
commit_hash: "",
committer: "postgres",
email: "postgres@127.0.0.1",
date: "",
message: "CREATE DATABASE",
},
{
commit_hash: "",
committer: "Dolt System Account",
email: "doltuser@dolthub.com",
date: "",
message: "Initialize data repository",
},
],
},
matcher: logsMatcher,
},
{
q: `USE '${dbName}/main';`,
res: {
command: "SET",
rowCount: null,
oid: null,
rows: [],
fields: [],
},
},
{
q: `SELECT * FROM DOLT_LOG('main..mybranch', '--parents')`, // TODO: Prepared not working
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [
{
commit_hash: "",
committer: "Dolt",
email: "dolt@dolthub.com",
date: "",
message: "Create table test",
parents: [""],
},
],
fields: [],
},
matcher: logsMatcher,
},
];
@@ -0,0 +1,173 @@
function matcher(rows, exp, exceptionKeys, getExceptionIsValid) {
// Row lengths match
if (rows.length !== exp.length) {
console.log("row lengths don't match", rows.length, exp.length);
return false;
}
for (let i = 0; i < rows.length; i++) {
const rowKeys = Object.keys(rows[i]);
const expKeys = Object.keys(exp[i]);
// Row key lengths match
if (rowKeys.length !== expKeys.length) {
console.log(
"row key lengths don't match",
rowKeys.length,
expKeys.length
);
return false;
}
// Row key values match
for (let j = 0; j < rowKeys.length; j++) {
const rowKey = rowKeys[j];
// Check if key has an exception function
if (exceptionKeys.includes(rowKey)) {
const isValid = getExceptionIsValid(rows[i], rowKey, exp[i]);
if (!isValid) {
console.log("exception was not valid for key:", rowKey);
return false;
}
} else {
// Compare cell values
const cellVal = JSON.stringify(rows[i][rowKey]);
const expCellVal = JSON.stringify(exp[i][rowKey]);
if (cellVal !== expCellVal) {
console.log("values don't match", cellVal, expCellVal);
return false;
}
}
}
}
return true;
}
function commitHashIsValid(commit) {
return commit === "STAGED" || commit === "WORKING" || commit.length === 32;
}
function dateIsValid(date) {
return JSON.stringify(date).length > 0;
}
export function branchesMatcher(data, exp) {
const exceptionKeys = ["hash", "latest_commit_date"];
function getExceptionIsValid(row, key) {
const val = row[key];
switch (key) {
case "hash":
return commitHashIsValid(val);
case "latest_commit_date":
return dateIsValid(val);
default:
return false;
}
}
return matcher(data.rows, exp.rows, exceptionKeys, getExceptionIsValid);
}
export function logsMatcher(data, exp) {
const exceptionKeys = ["commit_hash", "date", "parents"];
function getExceptionIsValid(row, key, expRow) {
const val = row[key];
switch (key) {
case "commit_hash":
return commitHashIsValid(val);
case "date":
return dateIsValid(val);
case "parents":
const numParents = val.split(", ").filter((v) => !!v.length).length;
const expParents = expRow.parents.length;
return numParents === expParents;
default:
return false;
}
}
return matcher(data.rows, exp.rows, exceptionKeys, getExceptionIsValid);
}
export function mergeBaseMatcher(data) {
if (data.rows.length !== 1) {
return false;
}
return commitHashIsValid(data.rows[0].dolt_merge_base);
}
export function mergeMatcher(data, exp) {
if (data.rows.length !== 1) {
console.log("Rows length not 1", data.rows.length);
return false;
}
const row = data.rows[0].dolt_merge;
const expRow = exp.rows[0].dolt_merge;
// Check valid commit hash
if (!commitHashIsValid(row[0])) {
console.log("Invalid commit hash", row[0]);
return false;
}
// Check the rest of the fields
for (let i = 1; i < row.length; i++) {
if (row[i] !== expRow[i]) {
console.log("Values don't match", row[i], expRow[i]);
return false;
}
}
return true;
}
export function tagsMatcher(data, exp) {
const exceptionKeys = ["tag_hash", "date"];
function getExceptionIsValid(row, key) {
const val = row[key];
switch (key) {
case "tag_hash":
return commitHashIsValid(val);
case "date":
return dateIsValid(val);
default:
return false;
}
}
return matcher(data.rows, exp.rows, exceptionKeys, getExceptionIsValid);
}
export function diffRowsMatcher(data, exp) {
const exceptionKeys = ["to_commit_date", "from_commit_date"];
function getExceptionIsValid(row, key) {
const val = row[key];
switch (key) {
case "to_commit_date":
case "from_commit_date":
return dateIsValid(val);
default:
return false;
}
}
return matcher(data.rows, exp.rows, exceptionKeys, getExceptionIsValid);
}
export function patchRowsMatcher(data, exp) {
const exceptionKeys = ["to_commit_hash", "from_commit_hash"];
function getExceptionIsValid(row, key) {
const val = row[key];
switch (key) {
case "to_commit_hash":
case "from_commit_hash":
return commitHashIsValid(val);
default:
return false;
}
}
return matcher(data.rows, exp.rows, exceptionKeys, getExceptionIsValid);
}
@@ -0,0 +1,87 @@
import { doltStatusFields } from "../fields.js";
import { logsMatcher, mergeBaseMatcher, mergeMatcher } from "./matchers.js";
export const mergeTests = [
{
q: `SELECT DOLT_MERGE_BASE($1::text, $2::text);`,
p: ["mybranch", "main"],
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [{ dolt_merge_base: "" }],
fields: [],
},
matcher: mergeBaseMatcher,
},
{
q: `SELECT * FROM dolt.status`,
res: {
command: "SELECT",
rowCount: 0,
oid: null,
rows: [],
fields: doltStatusFields,
},
},
{
q: `SELECT DOLT_MERGE($1::text, '--no-ff', '-m', $2::text)`,
p: ["mybranch", "Merge mybranch into main"],
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [
{
dolt_merge: ["", "0", "0", "merge successful"],
},
],
fields: [],
},
matcher: mergeMatcher,
},
{
q: `SELECT * FROM DOLT_LOG('main', '--parents') LIMIT 10 OFFSET 0;`, // TODO: Prepared not working
res: {
command: "SELECT",
rowCount: 4,
oid: null,
rows: [
{
commit_hash: "",
message: "Merge mybranch into main",
committer: "postgres",
email: "postgres@127.0.0.1",
date: "",
parents: ["", ""],
},
{
commit_hash: "",
committer: "Dolt",
email: "dolt@dolthub.com",
date: "",
message: "Create table test",
parents: [""],
},
{
commit_hash: "",
committer: "postgres",
email: "postgres@127.0.0.1",
date: "",
message: "CREATE DATABASE",
parents: [""],
},
{
commit_hash: "",
committer: "Dolt System Account",
email: "doltuser@dolthub.com",
date: "",
message: "Initialize data repository",
parents: [],
},
],
fields: [],
},
matcher: logsMatcher,
},
];
@@ -0,0 +1,197 @@
import {
doltBranchFields,
doltStatusFields,
doltCommitFields,
schemaNameField,
pgTablesFields,
} from "../fields.js";
import { dbName } from "../helpers.js";
export const schemaTests = [
{
q: `SELECT DOLT_BRANCH($1::text, $2::text)`, // TODO: Should work without casts
p: ["schemabranch", "main"],
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [{ dolt_branch: ["0"] }],
fields: doltBranchFields,
},
},
{
q: `USE '${dbName}/schemabranch';`,
res: {
command: "SET",
rowCount: null,
oid: null,
rows: [],
fields: [],
},
},
{
q: `create table testpub (pk int, "value" int, primary key(pk));`,
res: {
command: "CREATE",
rowCount: null,
oid: null,
rows: [],
fields: [],
},
},
{
q: `SELECT DOLT_COMMIT('-Am', $1::text, '--author', $2::text);`,
p: ["Create table testpub", "Dolt <dolt@dolthub.com>"],
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [{ dolt_commit: "" }],
fields: doltCommitFields,
},
},
{
q: `CREATE SCHEMA testschema;`,
res: {
command: "CREATE",
rowCount: null,
oid: null,
rows: [],
fields: [],
},
},
{
q: `SET SEARCH_PATH = 'testschema';`,
res: {
command: "SET",
rowCount: null,
oid: null,
rows: [],
fields: [],
},
},
{
q: `create table test2 (pk int, "value" int, primary key(pk));`,
res: {
command: "CREATE",
rowCount: null,
oid: null,
rows: [],
fields: [],
},
},
{
q: `SELECT * FROM dolt.status;`,
res: {
command: "SELECT",
rowCount: 2,
oid: null,
rows: [
{
table_name: "testschema.test2",
staged: false,
status: "new table",
},
{ table_name: "testschema", staged: false, status: "new schema" },
],
fields: doltStatusFields,
},
},
{
q: `SELECT schema_name FROM information_schema.schemata WHERE catalog_name = $1;`,
p: [`${dbName}/schemabranch`],
res: {
command: "SELECT",
rowCount: 5,
oid: null,
rows: [
{ schema_name: "dolt" },
{ schema_name: "pg_catalog" },
{ schema_name: "public" },
{ schema_name: "testschema" },
{ schema_name: "information_schema" },
],
fields: [schemaNameField],
},
},
{
q: `SELECT DOLT_COMMIT('-Am', $1::text, '--author', $2::text);`,
p: ["Create table test2", "Dolt <dolt@dolthub.com>"],
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [{ dolt_commit: "" }],
fields: doltCommitFields,
},
},
{
q: `SELECT schemaname, tablename FROM pg_catalog.pg_tables where schemaname=$1;`,
p: ["testschema"],
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [{ schemaname: "testschema", tablename: "test2" }],
fields: pgTablesFields,
},
},
{
q: `SET SEARCH_PATH = 'public';`,
res: {
command: "SET",
rowCount: null,
oid: null,
rows: [],
fields: [],
},
},
{
q: `SELECT schemaname, tablename FROM pg_catalog.pg_tables where schemaname=$1;`,
p: ["public"],
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [{ schemaname: "public", tablename: "testpub" }],
fields: pgTablesFields,
},
},
{
q: `USE '${dbName}/main';`,
res: {
command: "SET",
rowCount: null,
oid: null,
rows: [],
fields: [],
},
},
{
q: `SELECT schema_name FROM information_schema.schemata WHERE catalog_name = $1;`,
p: [`${dbName}/main`],
res: {
command: "SELECT",
rowCount: 4,
oid: null,
rows: [
{ schema_name: "dolt" },
{ schema_name: "pg_catalog" },
{ schema_name: "public" },
{ schema_name: "information_schema" },
],
fields: [schemaNameField],
},
},
{
q: `SELECT schemaname, tablename FROM pg_catalog.pg_tables where schemaname=$1;`,
p: ["public"],
res: {
command: "SELECT",
rowCount: 0,
oid: null,
rows: [],
fields: pgTablesFields,
},
},
];
@@ -0,0 +1,455 @@
import { dbName } from "../helpers.js";
import {
doltAddFields,
doltCheckoutFields,
doltCommitFields,
doltDiffStatFields,
doltResetFields,
doltStatusFields,
infoSchemaKeyColumnUsageFields,
} from "../fields.js";
const testInfoFields = [
{
name: "id",
tableID: 0,
columnID: 0,
dataTypeID: 23,
dataTypeSize: 4,
dataTypeModifier: -1,
format: "text",
},
{
name: "info",
tableID: 0,
columnID: 0,
dataTypeID: 1043,
dataTypeSize: 1020,
dataTypeModifier: 259,
format: "text",
},
{
name: "test_pk",
tableID: 0,
columnID: 0,
dataTypeID: 23,
dataTypeSize: 4,
dataTypeModifier: -1,
format: "text",
},
];
export const tableTests = [
{
q: "SET search_path TO DEFAULT",
res: {
command: "SET",
rowCount: null,
oid: null,
rows: [],
fields: [],
},
},
{
q: "INSERT INTO test VALUES (0, 0), (1, 1), (2,2)",
res: {
command: "INSERT",
rowCount: 3,
oid: 0,
rows: [],
fields: [],
},
},
{
q: `CREATE UNIQUE INDEX test_idx ON test (pk, value)`,
res: {
command: "CREATE",
rowCount: null,
oid: null,
rows: [],
fields: [],
},
},
{
q: `SELECT ordinal_position, column_name, udt_name as data_type, is_nullable, column_default FROM information_schema.columns WHERE table_catalog=$1 AND table_schema = $2 AND table_name = $3;`,
p: [`${dbName}/main`, "public", "test"],
res: {
command: "SELECT",
rowCount: 2,
oid: null,
rows: [
{
ordinal_position: 1,
column_name: "pk",
data_type: "int4",
is_nullable: "NO",
column_default: null,
},
{
ordinal_position: 2,
column_name: "value",
data_type: "int4",
is_nullable: "YES",
column_default: null,
},
],
fields: [
{
name: "ordinal_position",
tableID: 0,
columnID: 0,
dataTypeID: 23,
dataTypeSize: 4,
dataTypeModifier: -1,
format: "text",
},
{
name: "column_name",
tableID: 0,
columnID: 0,
dataTypeID: 1043,
dataTypeSize: 256,
dataTypeModifier: 68,
format: "text",
},
{
name: "data_type",
tableID: 0,
columnID: 0,
dataTypeID: 1043,
dataTypeSize: 256,
dataTypeModifier: 68,
format: "text",
},
{
name: "is_nullable",
tableID: 0,
columnID: 0,
dataTypeID: 1043,
dataTypeSize: 12,
dataTypeModifier: 7,
format: "text",
},
{
name: "column_default",
tableID: 0,
columnID: 0,
dataTypeID: 25,
dataTypeSize: -1,
dataTypeModifier: -1,
format: "text",
},
],
},
},
{
q: `SELECT DOLT_COMMIT('-A', '-m', $1::text)`,
p: ["Add some rows and a column index"],
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [{ dolt_commit: [""] }],
fields: doltCommitFields,
},
},
{
skip: true, // TODO: ORDER BY is not yet supported
q: `SELECT
table_name, index_name, comment, non_unique, GROUP_CONCAT(column_name ORDER BY seq_in_index) AS COLUMNS
FROM information_schema.statistics
WHERE table_catalog=$1 AND table_schema=$2 AND table_name=$3 AND index_name!='PRIMARY'
GROUP BY index_name;`,
p: [`${dbName}/main`, "public", "test"],
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [
{
TABLE_NAME: "test",
INDEX_NAME: "test_idx",
COMMENT: "",
NON_UNIQUE: 0,
COLUMNS: "pk,value",
},
],
},
},
{
q: "CREATE TABLE test_info (id int, info varchar(255), test_pk int, primary key(id), foreign key (test_pk) references test(pk))",
res: {
command: "CREATE",
rowCount: null,
oid: null,
rows: [],
fields: [],
},
},
{
q: "INSERT INTO test_info VALUES (1, 'info about test pk 0', 0)",
res: {
command: "INSERT",
rowCount: 1,
oid: 0,
rows: [],
fields: [],
},
},
{
q: `SELECT DOLT_COMMIT('-A', '-m', $1::text)`,
p: ["Add test_info with foreign key"],
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [{ dolt_commit: [""] }],
fields: doltCommitFields,
},
},
{
q: `SELECT "table_schema", "table_name" FROM "information_schema"."tables" WHERE "table_schema" = $1 AND "table_catalog" = $2;`,
p: ["public", `${dbName}/main`],
res: {
command: "SELECT",
rowCount: 2,
oid: null,
rows: [
{ table_schema: "public", table_name: "test" },
{ table_schema: "public", table_name: "test_info" },
],
fields: [
{
name: "table_schema",
tableID: 0,
columnID: 0,
dataTypeID: 1043,
dataTypeSize: 256,
dataTypeModifier: 68,
format: "text",
},
{
name: "table_name",
tableID: 0,
columnID: 0,
dataTypeID: 1043,
dataTypeSize: 256,
dataTypeModifier: 68,
format: "text",
},
],
},
},
{
q: `SELECT * FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE table_name=$1 AND table_schema=$2 AND table_catalog=$3 AND referenced_table_schema IS NOT NULL`,
p: ["test_info", "public", `${dbName}/main`],
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [
{
CONSTRAINT_CATALOG: `${dbName}/main`,
CONSTRAINT_SCHEMA: "public",
CONSTRAINT_NAME: "test_info_test_pk_fkey",
TABLE_CATALOG: `${dbName}/main`,
TABLE_SCHEMA: "public",
TABLE_NAME: "test_info",
COLUMN_NAME: "test_pk",
ORDINAL_POSITION: 1,
POSITION_IN_UNIQUE_CONSTRAINT: 1,
REFERENCED_TABLE_SCHEMA: `${dbName}/main`,
REFERENCED_TABLE_NAME: "test",
REFERENCED_COLUMN_NAME: "pk",
},
],
fields: infoSchemaKeyColumnUsageFields,
},
},
{
q: `SELECT * FROM "public"."test_info" "public.test_info" ORDER BY id ASC LIMIT 10;`,
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [{ id: 1, info: "info about test pk 0", test_pk: 0 }],
fields: testInfoFields,
},
},
{
q: `USE '${dbName}/main'`,
res: {
command: "SET",
rowCount: null,
oid: null,
rows: [],
fields: [],
},
},
// Copy from tests
{
q: `SELECT * FROM dolt.status`,
res: {
command: "SELECT",
rowCount: 0,
oid: null,
rows: [],
fields: doltStatusFields,
},
},
{
q: `COPY "test_info" FROM STDIN WITH (FORMAT csv, HEADER TRUE);`,
file: "insert_test_info.csv",
res: { command: "COPY", rowCount: 3, oid: null, rows: [], fields: [] },
},
{
q: "SELECT * FROM test_info",
res: {
command: "SELECT",
rowCount: 4,
oid: null,
rows: [
{ id: 1, info: "info about test pk 0", test_pk: 0 },
{ id: 4, info: "string for 4", test_pk: 1 },
{ id: 5, info: "string for 5", test_pk: 0 },
{ id: 6, info: "string for 6", test_pk: 0 },
],
fields: testInfoFields,
},
},
{
q: "SELECT * FROM dolt_diff_stat('HEAD', 'WORKING')", // TODO: Prepared not working
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [
{
table_name: "public.test_info",
rows_unmodified: "1",
rows_added: "3",
rows_deleted: "0",
rows_modified: "0",
cells_added: "9",
cells_deleted: "0",
cells_modified: "0",
old_row_count: "1",
new_row_count: "4",
old_cell_count: "3",
new_cell_count: "12",
},
],
fields: doltDiffStatFields,
},
},
{
q: `COPY "test_info" FROM STDIN WITH (FORMAT csv, HEADER TRUE, DELIMITER '|');`,
file: "insert_test_info.psv",
res: { command: "COPY", rowCount: 3, oid: null, rows: [], fields: [] },
},
{
skip: true,
q: "SELECT * FROM dolt_diff_stat('HEAD', 'WORKING')",
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [
{
table_name: "public.test_info",
rows_unmodified: 0,
rows_added: 3,
rows_deleted: 0,
rows_modified: 1,
cells_added: 9,
cells_deleted: 0,
cells_modified: 1,
old_row_count: 1,
new_row_count: 4,
old_cell_count: 3,
new_cell_count: 12,
},
],
fields: doltDiffStatFields,
},
},
// Add and revert load data changes
{
q: `SELECT * FROM dolt.status`,
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [
{ table_name: "public.test_info", staged: false, status: "modified" },
],
fields: doltStatusFields,
},
},
{
q: "SELECT DOLT_ADD('.')",
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [{ dolt_add: ["0"] }],
fields: doltAddFields,
},
},
{
q: `SELECT * FROM dolt.status`,
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [
{ table_name: "public.test_info", staged: true, status: "modified" },
],
fields: doltStatusFields,
},
},
{
q: "SELECT DOLT_RESET('test_info');",
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [{ dolt_reset: ["0"] }],
fields: doltResetFields,
},
},
{
q: `SELECT * FROM dolt.status`,
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [
{ table_name: "public.test_info", staged: false, status: "modified" },
],
fields: doltStatusFields,
},
},
{
q: "SELECT DOLT_CHECKOUT('test_info')",
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [{ dolt_checkout: ["0"] }],
fields: doltCheckoutFields,
},
},
{
q: `SELECT * FROM dolt.status`,
res: {
command: "SELECT",
rowCount: 0,
oid: null,
rows: [],
fields: doltStatusFields,
},
},
];
@@ -0,0 +1,121 @@
import { doltTagFields, doltTagsFields } from "../fields.js";
import { tagsMatcher } from "./matchers.js";
export const tagsTests = [
{
q: "SELECT * FROM dolt.tags ORDER BY date DESC",
res: {
command: "SELECT",
rowCount: 0,
oid: null,
rows: [],
fields: doltTagsFields,
},
},
{
q: `SELECT DOLT_TAG($1::text, $2::text);`,
p: ["mytag", "main"],
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [{ dolt_tag: ["0"] }],
fields: doltTagFields,
},
},
{
q: "SELECT * FROM dolt.tags ORDER BY date DESC",
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [
{
tag_name: "mytag",
message: "",
tagger: "Dolt System Account",
email: "doltuser@dolthub.com",
tag_hash: "",
date: "",
},
],
fields: doltTagsFields,
},
matcher: tagsMatcher,
},
{
q: `SELECT DOLT_TAG('-m', $1::text, $2::text, $3::text)`,
p: ["latest release", "mytagnew", "main"],
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [{ dolt_tag: ["0"] }],
fields: doltTagFields,
},
},
{
q: "SELECT * FROM dolt.tags ORDER BY date DESC",
res: {
command: "SELECT",
rowCount: 2,
oid: null,
rows: [
{
tag_name: "mytagnew",
message: "latest release",
tagger: "Dolt System Account",
email: "doltuser@dolthub.com",
tag_hash: "",
date: "",
},
{
tag_name: "mytag",
message: "",
tagger: "Dolt System Account",
email: "doltuser@dolthub.com",
tag_hash: "",
date: "",
},
],
fields: doltTagsFields,
},
matcher: tagsMatcher,
},
{
q: `SELECT DOLT_TAG('-d', $1::text)`,
p: ["mytagnew"],
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [{ dolt_tag: ["0"] }],
fields: doltTagFields,
},
},
{
q: "SELECT * FROM dolt.tags ORDER BY date DESC",
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [
{
tag_name: "mytag",
message: "",
tagger: "Dolt System Account",
email: "doltuser@dolthub.com",
tag_hash: "",
date: "",
},
],
fields: doltTagsFields,
},
matcher: tagsMatcher,
},
{
q: `SELECT DOLT_COMMIT('-A', '-m', $1::text)`,
p: ["Add a tag"],
expectedErr: "nothing to commit",
},
];
@@ -0,0 +1,196 @@
import {
doltCheckoutFields,
doltSchemasFields,
pgTablesFields,
} from "../fields.js";
export const viewsTests = [
{
q: "SELECT DOLT_CHECKOUT('-b', $1::text);",
p: ["more-updates"],
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [{ dolt_checkout: ["0", "Switched to branch 'more-updates'"] }],
fields: doltCheckoutFields,
},
},
{
q: "SELECT * FROM dolt_schemas LIMIT 10 OFFSET 0;",
res: {
command: "SELECT",
rowCount: 0,
oid: null,
rows: [],
fields: doltSchemasFields,
},
},
{
q: "CREATE VIEW myview AS SELECT * FROM test;",
res: {
command: "CREATE",
rowCount: null,
oid: null,
rows: [],
fields: [],
},
},
{
q: "SELECT * FROM dolt_schemas LIMIT 10 OFFSET 0",
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [
{
type: "view",
name: "myview",
fragment: "CREATE VIEW myview AS SELECT * FROM test",
extra: { CreatedAt: 0 },
sql_mode:
"NO_ENGINE_SUBSTITUTION,ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES",
},
],
fields: doltSchemasFields,
},
},
{
// Excludes views
q: "SELECT schemaname, tablename FROM pg_catalog.pg_tables where schemaname=$1;",
p: ["public"],
res: {
command: "SELECT",
rowCount: 2,
oid: null,
rows: [
{
schemaname: "public",
tablename: "test",
},
{
schemaname: "public",
tablename: "test_info",
},
],
fields: pgTablesFields,
},
},
{
// Includes views
q: "SELECT table_name FROM INFORMATION_SCHEMA.views WHERE table_schema = $1;",
p: ["public"],
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [{ table_name: "myview" }],
fields: [
{
name: "table_name",
tableID: 0,
columnID: 0,
dataTypeID: 1043,
dataTypeSize: 256,
dataTypeModifier: 68,
format: "text",
},
],
},
},
{
// Includes views
q: "SELECT viewname FROM pg_catalog.pg_views WHERE schemaname=$1;",
p: ["public"],
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [{ viewname: "myview" }],
fields: [
{
name: "viewname",
tableID: 0,
columnID: 0,
dataTypeID: 19,
dataTypeSize: 64,
dataTypeModifier: -1,
format: "text",
},
],
},
},
{
// Includes tables and views
q: "SELECT table_schema, table_name, table_type FROM INFORMATION_SCHEMA.tables WHERE table_schema = $1;",
p: ["public"],
res: {
command: "SELECT",
rowCount: 3,
oid: null,
rows: [
{ table_schema: "public", table_name: "myview", table_type: "VIEW" },
{
table_schema: "public",
table_name: "test",
table_type: "BASE TABLE",
},
{
table_schema: "public",
table_name: "test_info",
table_type: "BASE TABLE",
},
],
fields: [
{
name: "table_schema",
tableID: 0,
columnID: 0,
dataTypeID: 1043,
dataTypeSize: 256,
dataTypeModifier: 68,
format: "text",
},
{
name: "table_name",
tableID: 0,
columnID: 0,
dataTypeID: 1043,
dataTypeSize: 256,
dataTypeModifier: 68,
format: "text",
},
{
name: "table_type",
tableID: 0,
columnID: 0,
dataTypeID: 25,
dataTypeSize: -1,
dataTypeModifier: -1,
format: "text",
},
],
},
},
{
q: `SELECT pg_get_viewdef($1::regclass, true)`,
p: ["myview"],
res: {
command: "SELECT",
rowCount: 1,
oid: null,
rows: [{ pg_get_viewdef: "SELECT * FROM test" }],
fields: [
{
name: "pg_get_viewdef",
tableID: 0,
columnID: 0,
dataTypeID: 25,
dataTypeSize: -1,
dataTypeModifier: -1,
format: "text",
},
],
},
},
];