Skip to content
This repository was archived by the owner on Jun 26, 2021. It is now read-only.

Commit

Permalink
Quering wip
Browse files Browse the repository at this point in the history
  • Loading branch information
typeofweb committed Apr 14, 2020
1 parent 05d08c7 commit 6da09ca
Show file tree
Hide file tree
Showing 12 changed files with 585 additions and 237 deletions.
2 changes: 1 addition & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
"semi": true,
"singleQuote": true,
"trailingComma": "all",
"printWidth": 100
"printWidth": 80
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"jest": "25.3.0",
"jest-extended": "0.11.5",
"lint-staged": "10.1.3",
"pg-sql2": "4.5.0",
"ts-jest": "25.3.1",
"typescript": "3.8.3"
},
Expand Down
36 changes: 36 additions & 0 deletions src/__tests__/generated/models.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* AUTOMATICALLY GENERATED
* DO NOT MODIFY
* ANY CHANGES WILL BE OVERWRITTEN
*/

export const Invoice = {
name: 'invoice',
columns: {
id: { type: 'int4', notNull: true },
value: { type: 'float4', notNull: true },
addedAt: { type: 'date', notNull: true },
},
} as const;

export const User = {
name: 'user',
columns: {
id: { type: 'int4', notNull: true },
email: { type: 'text', notNull: true },
name: { type: 'text', notNull: false },
boolColumn: { type: 'bool', notNull: true },
charColumn: { type: 'bpchar', notNull: false },
dateColumn: { type: 'date', notNull: true },
float4Column: { type: 'float4', notNull: false },
float8Column: { type: 'float8', notNull: true },
int2Column: { type: 'int2', notNull: false },
int4Column: { type: 'int4', notNull: true },
int8Column: { type: 'int8', notNull: false },
numericColumn: { type: 'numeric', notNull: true },
textColumn: { type: 'text', notNull: false },
timestampColumn: { type: 'timestamp', notNull: true },
timestamptzColumn: { type: 'timestamptz', notNull: false },
varcharColumn: { type: 'varchar', notNull: true },
},
} as const;
254 changes: 205 additions & 49 deletions src/__tests__/test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import 'jest-extended';
import { sql, pgp, getDbConnection } from '../generator/db';
import { sql, pgp, getDbConnection } from '../db';
import {
getTablesSchemas,
schemaToTableObj,
Expand All @@ -9,6 +9,8 @@ import {
} from '../generator';
import Path from 'path';
import { compileTypeScriptCode } from './tsCompiler';
import { Gostek, Op } from '../querybuilder/querybuilder';
import { User } from './generated/models';

describe('unit tests', () => {
describe('schemaToTableObj', () => {
Expand Down Expand Up @@ -71,11 +73,11 @@ describe('unit tests', () => {
}),
).toEqual(
`
export const User = {
name: 'user',
columns: { id: { type: 'int4', notNull: true }, name: { type: 'text', notNull: false } },
} as const;
`.trimStart(),
export const User = {
name: 'user',
columns: { id: { type: 'int4', notNull: true }, name: { type: 'text', notNull: false } },
} as const;
`.trimStart(),
);
});

Expand All @@ -93,14 +95,14 @@ export const User = {
),
).toEqual(
`
export const User = {
name: 'user',
columns: {
id: { type: 'int4', notNull: true },
name: { type: 'text', notNull: false },
},
} as const;
`.trimStart(),
export const User = {
name: 'user',
columns: {
id: { type: 'int4', notNull: true },
name: { type: 'text', notNull: false },
},
} as const;
`.trimStart(),
);
});
});
Expand All @@ -126,41 +128,58 @@ describe('integration tests', () => {
afterEach(drop);
afterAll(() => pgp.end());

it('reads postgres version', async () => {
expect(await getPostgresVersion(db)).toBeGreaterThanOrEqual(120000);
});
describe('generator', () => {
it('reads postgres version', async () => {
expect(await getPostgresVersion(db)).toBeGreaterThanOrEqual(120000);
});

it('correctly reads schema for table user', async () => {
const result = await getTablesSchemas(db);

const userSchema = result.find((i) => i.tableName === 'user');
expect(userSchema).toBeDefined();

expect(userSchema!.schema).toIncludeSameMembers([
{ column_name: 'id', is_nullable: 'NO', udt_name: 'int4' },
{ column_name: 'email', is_nullable: 'NO', udt_name: 'text' },
{ column_name: 'name', is_nullable: 'YES', udt_name: 'text' },
{ column_name: 'boolColumn', is_nullable: 'NO', udt_name: 'bool' },
{ column_name: 'charColumn', is_nullable: 'YES', udt_name: 'bpchar' },
{ column_name: 'dateColumn', is_nullable: 'NO', udt_name: 'date' },
{ column_name: 'float4Column', is_nullable: 'YES', udt_name: 'float4' },
{ column_name: 'float8Column', is_nullable: 'NO', udt_name: 'float8' },
{ column_name: 'int2Column', is_nullable: 'YES', udt_name: 'int2' },
{ column_name: 'int4Column', is_nullable: 'NO', udt_name: 'int4' },
{ column_name: 'int8Column', is_nullable: 'YES', udt_name: 'int8' },
{ column_name: 'numericColumn', is_nullable: 'NO', udt_name: 'numeric' },
{ column_name: 'textColumn', is_nullable: 'YES', udt_name: 'text' },
{ column_name: 'timestampColumn', is_nullable: 'NO', udt_name: 'timestamp' },
{ column_name: 'timestamptzColumn', is_nullable: 'YES', udt_name: 'timestamptz' },
{ column_name: 'varcharColumn', is_nullable: 'NO', udt_name: 'varchar' },
]);
});
it('correctly reads schema for table user', async () => {
const result = await getTablesSchemas(db);

const userSchema = result.find((i) => i.tableName === 'user');
expect(userSchema).toBeDefined();

expect(userSchema!.schema).toIncludeSameMembers([
{ column_name: 'id', is_nullable: 'NO', udt_name: 'int4' },
{ column_name: 'email', is_nullable: 'NO', udt_name: 'text' },
{ column_name: 'name', is_nullable: 'YES', udt_name: 'text' },
{ column_name: 'boolColumn', is_nullable: 'NO', udt_name: 'bool' },
{ column_name: 'charColumn', is_nullable: 'YES', udt_name: 'bpchar' },
{ column_name: 'dateColumn', is_nullable: 'NO', udt_name: 'date' },
{ column_name: 'float4Column', is_nullable: 'YES', udt_name: 'float4' },
{ column_name: 'float8Column', is_nullable: 'NO', udt_name: 'float8' },
{ column_name: 'int2Column', is_nullable: 'YES', udt_name: 'int2' },
{ column_name: 'int4Column', is_nullable: 'NO', udt_name: 'int4' },
{ column_name: 'int8Column', is_nullable: 'YES', udt_name: 'int8' },
{
column_name: 'numericColumn',
is_nullable: 'NO',
udt_name: 'numeric',
},
{ column_name: 'textColumn', is_nullable: 'YES', udt_name: 'text' },
{
column_name: 'timestampColumn',
is_nullable: 'NO',
udt_name: 'timestamp',
},
{
column_name: 'timestamptzColumn',
is_nullable: 'YES',
udt_name: 'timestamptz',
},
{
column_name: 'varcharColumn',
is_nullable: 'NO',
udt_name: 'varchar',
},
]);
});

it('generates valid TS code for all schemas', async () => {
const code = await generateTSCodeForAllSchemas(db);
it('generates valid TS code for all schemas', async () => {
const code = await generateTSCodeForAllSchemas(db);

expect(code).toEqual(
`
expect(code).toEqual(
`
/**
* AUTOMATICALLY GENERATED
* DO NOT MODIFY
Expand Down Expand Up @@ -198,9 +217,146 @@ export const User = {
},
} as const;
`.trimLeft(),
);
);

const compiled = compileTypeScriptCode(code);
expect(compiled.errors).toHaveLength(0);
});
});

const compiled = compileTypeScriptCode(code);
expect(compiled.errors).toHaveLength(0);
describe.only('querybuilder', () => {
it('builds queries', () => {
expect(Gostek.from(User).select('*').getQuery()).toEqual({
text: 'SELECT * FROM "user" ',
values: [],
});

expect(Gostek.from(User).select(['id']).getQuery()).toEqual({
text: 'SELECT "user"."id" FROM "user" ',
values: [],
});

expect(
Gostek.from(User)
.select(['id'])
.select('*')
.where(['name', Op.$eq, 'Michał'])
.getQuery(),
).toEqual({
text: 'SELECT * FROM "user" WHERE "name" = $1',
values: ['Michał'],
});

expect(
Gostek.from(User)
.select(['id', 'name'])
.where(['id', Op.$in, [1, 2, 3]])
.getQuery(),
).toEqual({
text:
'SELECT "user"."id", "user"."name" FROM "user" WHERE "id" in ($1,$2,$3)',
values: [1, 2, 3],
});
});

it('runs queries', async () => {
const nowWithoutTimezone = new Date('2020-04-13T22:00:00.000Z');
nowWithoutTimezone.setMinutes(nowWithoutTimezone.getTimezoneOffset());
const one = {
id: 1,
email: '[email protected]',
name: 'Michał',
boolColumn: false,
charColumn: '',
dateColumn: new Date('2020-04-12T22:00:00.000Z'),
float4Column: null,
float8Column: 3.14,
int2Column: null,
int4Column: 11,
int8Column: null,
numericColumn: '50.50',
textColumn: 'some text',
timestampColumn: nowWithoutTimezone,
timestamptzColumn: new Date('2020-04-13T22:00:00.000Z'),
varcharColumn: '',
};
const two = {
id: 33,
email: '[email protected]',
name: 'Kasia',
boolColumn: false,
charColumn: '',
dateColumn: new Date('2020-04-12T22:00:00.000Z'),
float4Column: null,
float8Column: 3.14,
int2Column: null,
int4Column: 11,
int8Column: null,
numericColumn: '50.50',
textColumn: 'some text',
timestampColumn: nowWithoutTimezone,
timestamptzColumn: new Date('2020-04-13T22:00:00.000Z'),
varcharColumn: '',
};

await db.none(`INSERT INTO "user" VALUES (
1,
'[email protected]',
'Michał',
false,
'',
'2020-04-13T22:00:00.000Z',
NULL,
3.14,
NULL,
11,
NULL,
50.50,
'some text',
'2020-04-13T22:00:00.000Z',
'2020-04-13T22:00:00.000Z',
''
);`);
await db.none(`INSERT INTO "user" VALUES (
33,
'[email protected]',
'Kasia',
false,
'',
'2020-04-13T22:00:00.000Z',
NULL,
3.14,
NULL,
11,
NULL,
50.50,
'some text',
'2020-04-13T22:00:00.000Z',
'2020-04-13T22:00:00.000Z',
''
);`);
expect(
await Gostek.from(User).select('*').execute(db),
).toIncludeAllMembers([one, two]);

expect(
await Gostek.from(User).select(['id']).execute(db),
).toIncludeAllMembers([{ id: one.id }, { id: two.id }]);

expect(
await Gostek.from(User)
.select(['id'])
.select('*')
.where(['name', Op.$eq, 'Michał'])
.execute(db),
).toIncludeAllMembers([one]);

expect(
await Gostek.from(User)
.select(['id', 'name'])
.where(['id', Op.$in, [1, 2, 3]])
.execute(db),
).toIncludeAllMembers([{ id: one.id, name: one.name }]);
});
});
});
3 changes: 2 additions & 1 deletion src/cli.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env node
import Path from 'path';
import Fs from 'fs';
import { getDbConnection, pgp } from './generator/db';
import { getDbConnection, pgp } from './db';
import { generateTSCodeForAllSchemas } from './generator';

const pkgPath = Path.resolve(process.cwd(), 'package.json');
Expand All @@ -11,6 +11,7 @@ if (!Fs.existsSync(pkgPath)) {
);
}

// @todo config
const connectionOptions = {
user: 'test',
database: 'test',
Expand Down
File renamed without changes.
Loading

0 comments on commit 6da09ca

Please sign in to comment.