diff --git a/src/operations/operators.ts b/src/operations/operators.ts index 98246916..f67377f4 100644 --- a/src/operations/operators.ts +++ b/src/operations/operators.ts @@ -117,7 +117,7 @@ export function dropOperatorFamily( const ifExistsStr = ifExists ? ' IF EXISTS' : ''; const cascadeStr = cascade ? ' CASCADE' : ''; - return `DROP OPERATOR FAMILY ${ifExistsStr} ${operatorFamilyNameStr} USING ${indexMethod}${cascadeStr};`; + return `DROP OPERATOR FAMILY${ifExistsStr} ${operatorFamilyNameStr} USING ${indexMethod}${cascadeStr};`; }; return _drop; @@ -240,7 +240,7 @@ export function dropOperatorClass( const ifExistsStr = ifExists ? ' IF EXISTS' : ''; const cascadeStr = cascade ? ' CASCADE' : ''; - return `DROP OPERATOR CLASS ${ifExistsStr} ${operatorClassNameStr} USING ${indexMethod}${cascadeStr};`; + return `DROP OPERATOR CLASS${ifExistsStr} ${operatorClassNameStr} USING ${indexMethod}${cascadeStr};`; }; return _drop; diff --git a/test/operations/operators/addToOperatorFamily.spec.ts b/test/operations/operators/addToOperatorFamily.spec.ts new file mode 100644 index 00000000..680f5bce --- /dev/null +++ b/test/operations/operators/addToOperatorFamily.spec.ts @@ -0,0 +1,185 @@ +import { describe, expect, it } from 'vitest'; +import { addToOperatorFamily } from '../../../src/operations/operators'; +import { options1 } from '../../utils'; + +describe('operations', () => { + describe('operators', () => { + describe('addToOperatorFamily', () => { + const addToOperatorFamilyFn = addToOperatorFamily(options1); + + it('should return a function', () => { + expect(addToOperatorFamilyFn).toBeTypeOf('function'); + }); + + it.todo('should return sql statement', () => { + const statement = addToOperatorFamilyFn('integer_ops', 'btree', [ + { + name: '<', + number: 1, + type: 'operator', + params: [{ type: 'int4' }, { type: 'int2' }], + }, + { + name: '<=', + number: 2, + type: 'operator', + params: [{ type: 'int4' }, { type: 'int2' }], + }, + { + name: '=', + number: 3, + type: 'operator', + params: [{ type: 'int4' }, { type: 'int2' }], + }, + { + name: '>=', + number: 4, + type: 'operator', + params: [{ type: 'int4' }, { type: 'int2' }], + }, + { + name: '>', + number: 5, + type: 'operator', + params: [{ type: 'int4' }, { type: 'int2' }], + }, + { + name: 'btint42cmp', + number: 1, + type: 'function', + params: [{ type: 'int4' }, { type: 'int2' }], + }, + ]); + + expect(statement).toBeTypeOf('string'); + expect(statement).toStrictEqual( + `ALTER OPERATOR FAMILY "integer_ops" USING btree ADD + OPERATOR 1 "<"(int4, int2), + OPERATOR 2 "<="(int4, int2), + OPERATOR 3 "="(int4, int2), + OPERATOR 4 ">="(int4, int2), + OPERATOR 5 ">"(int4, int2), + FUNCTION 1 "btint42cmp"(int4, int2);` + ); + }); + + it.todo('should return sql statement with schema', () => { + const statement = addToOperatorFamilyFn( + { name: 'integer_ops', schema: 'myschema' }, + 'btree', + [ + { + name: '<', + number: 1, + type: 'operator', + params: [{ type: 'int4' }, { type: 'int2' }], + }, + { + name: '<=', + number: 2, + type: 'operator', + params: [{ type: 'int4' }, { type: 'int2' }], + }, + { + name: '=', + number: 3, + type: 'operator', + params: [{ type: 'int4' }, { type: 'int2' }], + }, + { + name: '>=', + number: 4, + type: 'operator', + params: [{ type: 'int4' }, { type: 'int2' }], + }, + { + name: '>', + number: 5, + type: 'operator', + params: [{ type: 'int4' }, { type: 'int2' }], + }, + { + name: 'btint42cmp', + number: 1, + type: 'function', + params: [{ type: 'int4' }, { type: 'int2' }], + }, + ] + ); + + expect(statement).toBeTypeOf('string'); + expect(statement).toStrictEqual( + `ALTER OPERATOR FAMILY "myschema"."integer_ops" USING btree ADD + OPERATOR 1 "<"(int4, int2), + OPERATOR 2 "<="(int4, int2), + OPERATOR 3 "="(int4, int2), + OPERATOR 4 ">="(int4, int2), + OPERATOR 5 ">"(int4, int2), + FUNCTION 1 "btint42cmp"(int4, int2);` + ); + }); + + describe('reverse', () => { + it('should contain a reverse function', () => { + expect(addToOperatorFamilyFn.reverse).toBeTypeOf('function'); + }); + + it.todo('should return sql statement', () => { + const statement = addToOperatorFamilyFn.reverse( + 'integer_ops', + 'btree', + [ + { + name: '<', + number: 1, + type: 'operator', + params: [{ type: 'int4' }, { type: 'int2' }], + }, + { + name: '<=', + number: 2, + type: 'operator', + params: [{ type: 'int4' }, { type: 'int2' }], + }, + { + name: '=', + number: 3, + type: 'operator', + params: [{ type: 'int4' }, { type: 'int2' }], + }, + { + name: '>=', + number: 4, + type: 'operator', + params: [{ type: 'int4' }, { type: 'int2' }], + }, + { + name: '>', + number: 5, + type: 'operator', + params: [{ type: 'int4' }, { type: 'int2' }], + }, + { + name: 'btint42cmp', + number: 1, + type: 'function', + params: [{ type: 'int4' }, { type: 'int2' }], + }, + ] + ); + + expect(statement).toBeTypeOf('string'); + expect(statement).toBe( + `ALTER OPERATOR FAMILY "integer_ops" USING btree DROP + OPERATOR 1 "<"(int4, int2), + OPERATOR 2 "<="(int4, int2), + OPERATOR 3 "="(int4, int2), + OPERATOR 4 ">="(int4, int2), + OPERATOR 5 ">"(int4, int2), + FUNCTION 1 "btint42cmp"(int4, int2);` + ); + }); + }); + }); + }); +}); diff --git a/test/operations/operators/createOperator.spec.ts b/test/operations/operators/createOperator.spec.ts new file mode 100644 index 00000000..14f4e26e --- /dev/null +++ b/test/operations/operators/createOperator.spec.ts @@ -0,0 +1,80 @@ +import { describe, expect, it } from 'vitest'; +import { createOperator } from '../../../src/operations/operators'; +import { options1 } from '../../utils'; + +describe('operations', () => { + describe('operators', () => { + describe('createOperator', () => { + const createOperatorFn = createOperator(options1); + + it('should return a function', () => { + expect(createOperatorFn).toBeTypeOf('function'); + }); + + it('should return sql statement', () => { + const statement = createOperatorFn('===', { + left: 'box', + right: 'box', + procedure: 'area_equal_function', + }); + + expect(statement).toBeTypeOf('string'); + expect(statement).toStrictEqual( + 'CREATE OPERATOR === (PROCEDURE = "area_equal_function", LEFTARG = "box", RIGHTARG = "box");' + ); + }); + + it('should return sql statement with operatorOptions', () => { + const statement = createOperatorFn('===', { + left: 'box', + right: 'box', + procedure: 'area_equal_function', + commutator: '===', + negator: '!==', + restrict: 'area_restriction_function', + join: 'area_join_function', + hashes: true, + merges: true, + }); + + expect(statement).toBeTypeOf('string'); + expect(statement).toStrictEqual( + 'CREATE OPERATOR === (PROCEDURE = "area_equal_function", LEFTARG = "box", RIGHTARG = "box", COMMUTATOR = ===, NEGATOR = !==, RESTRICT = "area_restriction_function", JOIN = "area_join_function", HASHES, MERGES);' + ); + }); + + it('should return sql statement with schema', () => { + const statement = createOperatorFn( + { name: '===', schema: 'myschema' }, + { + left: 'box', + right: 'box', + procedure: 'area_equal_function', + } + ); + + expect(statement).toBeTypeOf('string'); + expect(statement).toStrictEqual( + 'CREATE OPERATOR myschema.=== (PROCEDURE = "area_equal_function", LEFTARG = "box", RIGHTARG = "box");' + ); + }); + + describe('reverse', () => { + it('should contain a reverse function', () => { + expect(createOperatorFn.reverse).toBeTypeOf('function'); + }); + + it('should return sql statement', () => { + const statement = createOperatorFn.reverse('===', { + left: 'box', + right: 'box', + procedure: 'area_equal_function', + }); + + expect(statement).toBeTypeOf('string'); + expect(statement).toBe('DROP OPERATOR ===("box", "box");'); + }); + }); + }); + }); +}); diff --git a/test/operations/operators/createOperatorClass.spec.ts b/test/operations/operators/createOperatorClass.spec.ts new file mode 100644 index 00000000..1178618d --- /dev/null +++ b/test/operations/operators/createOperatorClass.spec.ts @@ -0,0 +1,51 @@ +import { describe, expect, it } from 'vitest'; +import { createOperatorClass } from '../../../src/operations/operators'; +import { options1 } from '../../utils'; + +describe('operations', () => { + describe('operators', () => { + describe('createOperatorClass', () => { + const createOperatorClassFn = createOperatorClass(options1); + + it('should return a function', () => { + expect(createOperatorClassFn).toBeTypeOf('function'); + }); + + it.todo('should return sql statement', () => { + const statement = createOperatorClassFn( + 'gist__int_ops', + '_int4', + 'gist', + [ + { + name: '&&', + number: 3, + type: 'operator', + }, + ], + { + default: true, + } + ); + + expect(statement).toBeTypeOf('string'); + expect(statement).toStrictEqual( + `CREATE OPERATOR CLASS "gist__int_ops" DEFAULT FOR TYPE "_int4" USING "gist" AS + FUNCTION 3 "&&"();` + ); + }); + + it.todo('should return sql statement with operatorOptions', () => {}); + + it.todo('should return sql statement with schema', () => {}); + + describe('reverse', () => { + it('should contain a reverse function', () => { + expect(createOperatorClassFn.reverse).toBeTypeOf('function'); + }); + + it.todo('should return sql statement', () => {}); + }); + }); + }); +}); diff --git a/test/operations/operators/createOperatorFamily.spec.ts b/test/operations/operators/createOperatorFamily.spec.ts new file mode 100644 index 00000000..2eb6221a --- /dev/null +++ b/test/operations/operators/createOperatorFamily.spec.ts @@ -0,0 +1,67 @@ +import { describe, expect, it } from 'vitest'; +import { createOperatorFamily } from '../../../src/operations/operators'; +import { options1 } from '../../utils'; + +describe('operations', () => { + describe('operators', () => { + describe('createOperatorFamily', () => { + const createOperatorFamilyFn = createOperatorFamily(options1); + + it('should return a function', () => { + expect(createOperatorFamilyFn).toBeTypeOf('function'); + }); + + it('should return sql statement', () => { + const statement = createOperatorFamilyFn('integer_ops', 'btree'); + + expect(statement).toBeTypeOf('string'); + expect(statement).toStrictEqual( + 'CREATE OPERATOR FAMILY "integer_ops" USING btree;' + ); + }); + + it('should return sql statement with operatorFamilyOptions', () => { + // TODO @Shinigami92 2024-03-08: originally there are no options: https://www.postgresql.org/docs/current/sql-createopfamily.html + const statement = createOperatorFamilyFn('integer_ops', 'btree', { + ifExists: true, + cascade: true, + }); + + expect(statement).toBeTypeOf('string'); + expect(statement).toStrictEqual( + 'CREATE OPERATOR FAMILY "integer_ops" USING btree;' + ); + }); + + it('should return sql statement with schema', () => { + const statement = createOperatorFamilyFn( + { name: 'integer_ops', schema: 'myschema' }, + 'btree' + ); + + expect(statement).toBeTypeOf('string'); + expect(statement).toStrictEqual( + 'CREATE OPERATOR FAMILY "myschema"."integer_ops" USING btree;' + ); + }); + + describe('reverse', () => { + it('should contain a reverse function', () => { + expect(createOperatorFamilyFn.reverse).toBeTypeOf('function'); + }); + + it('should return sql statement', () => { + const statement = createOperatorFamilyFn.reverse( + 'integer_ops', + 'btree' + ); + + expect(statement).toBeTypeOf('string'); + expect(statement).toBe( + 'DROP OPERATOR FAMILY "integer_ops" USING btree;' + ); + }); + }); + }); + }); +}); diff --git a/test/operations/operators/dropOperator.spec.ts b/test/operations/operators/dropOperator.spec.ts new file mode 100644 index 00000000..efe305b8 --- /dev/null +++ b/test/operations/operators/dropOperator.spec.ts @@ -0,0 +1,40 @@ +import { describe, expect, it } from 'vitest'; +import { dropOperator } from '../../../src/operations/operators'; +import { options1 } from '../../utils'; + +describe('operations', () => { + describe('operators', () => { + describe('dropOperator', () => { + const dropOperatorFn = dropOperator(options1); + + it('should return a function', () => { + expect(dropOperatorFn).toBeTypeOf('function'); + }); + + it('should return sql statement', () => { + const statement = dropOperatorFn('^', { + left: 'integer', + right: 'integer', + }); + + expect(statement).toBeTypeOf('string'); + expect(statement).toStrictEqual( + 'DROP OPERATOR ^("integer", "integer");' + ); + }); + + it('should return sql statement with dropOptions', () => { + const statement = dropOperatorFn('~', { + right: 'bit', + ifExists: true, + cascade: true, + }); + + expect(statement).toBeTypeOf('string'); + expect(statement).toStrictEqual( + 'DROP OPERATOR IF EXISTS ~("none", "bit") CASCADE;' + ); + }); + }); + }); +}); diff --git a/test/operations/operators/dropOperatorClass.spec.ts b/test/operations/operators/dropOperatorClass.spec.ts new file mode 100644 index 00000000..8b737c94 --- /dev/null +++ b/test/operations/operators/dropOperatorClass.spec.ts @@ -0,0 +1,36 @@ +import { describe, expect, it } from 'vitest'; +import { dropOperatorClass } from '../../../src/operations/operators'; +import { options1 } from '../../utils'; + +describe('operations', () => { + describe('operators', () => { + describe('dropOperatorClass', () => { + const dropOperatorClassFn = dropOperatorClass(options1); + + it('should return a function', () => { + expect(dropOperatorClassFn).toBeTypeOf('function'); + }); + + it('should return sql statement', () => { + const statement = dropOperatorClassFn('widget_ops', 'btree'); + + expect(statement).toBeTypeOf('string'); + expect(statement).toStrictEqual( + 'DROP OPERATOR CLASS "widget_ops" USING btree;' + ); + }); + + it('should return sql statement with dropOptions', () => { + const statement = dropOperatorClassFn('widget_ops', 'btree', { + ifExists: true, + cascade: true, + }); + + expect(statement).toBeTypeOf('string'); + expect(statement).toStrictEqual( + 'DROP OPERATOR CLASS IF EXISTS "widget_ops" USING btree CASCADE;' + ); + }); + }); + }); +}); diff --git a/test/operations/operators/dropOperatorFamily.spec.ts b/test/operations/operators/dropOperatorFamily.spec.ts new file mode 100644 index 00000000..a74dc901 --- /dev/null +++ b/test/operations/operators/dropOperatorFamily.spec.ts @@ -0,0 +1,36 @@ +import { describe, expect, it } from 'vitest'; +import { dropOperatorFamily } from '../../../src/operations/operators'; +import { options1 } from '../../utils'; + +describe('operations', () => { + describe('operators', () => { + describe('dropOperatorFamily', () => { + const dropOperatorFamilyFn = dropOperatorFamily(options1); + + it('should return a function', () => { + expect(dropOperatorFamilyFn).toBeTypeOf('function'); + }); + + it('should return sql statement', () => { + const statement = dropOperatorFamilyFn('float_ops', 'btree'); + + expect(statement).toBeTypeOf('string'); + expect(statement).toStrictEqual( + 'DROP OPERATOR FAMILY "float_ops" USING btree;' + ); + }); + + it('should return sql statement with dropOptions', () => { + const statement = dropOperatorFamilyFn('float_ops', 'btree', { + ifExists: true, + cascade: true, + }); + + expect(statement).toBeTypeOf('string'); + expect(statement).toStrictEqual( + 'DROP OPERATOR FAMILY IF EXISTS "float_ops" USING btree CASCADE;' + ); + }); + }); + }); +}); diff --git a/test/operations/operators/removeFromOperatorFamily.spec.ts b/test/operations/operators/removeFromOperatorFamily.spec.ts new file mode 100644 index 00000000..a52f7f10 --- /dev/null +++ b/test/operations/operators/removeFromOperatorFamily.spec.ts @@ -0,0 +1,83 @@ +import { describe, expect, it } from 'vitest'; +import { removeFromOperatorFamily } from '../../../src/operations/operators'; +import { options1 } from '../../utils'; + +describe('operations', () => { + describe('operators', () => { + describe('removeFromOperatorFamily', () => { + const removeFromOperatorFamilyFn = removeFromOperatorFamily(options1); + + it('should return a function', () => { + expect(removeFromOperatorFamilyFn).toBeTypeOf('function'); + }); + + it.todo('should return sql statement', () => { + // TODO @Shinigami92 2024-03-08: looks like type is flipped + const statement = removeFromOperatorFamilyFn('integer_ops', 'btree', [ + { + name: '', + type: 'operator', + number: 1, + params: [{ type: 'int4' }, { type: 'int2' }], + }, + { + name: '', + type: 'operator', + number: 2, + params: [{ type: 'int4' }, { type: 'int2' }], + }, + { + name: '', + type: 'function', + number: 1, + params: [{ type: 'int4' }, { type: 'int2' }], + }, + ]); + + expect(statement).toBeTypeOf('string'); + expect(statement).toStrictEqual( + `ALTER OPERATOR FAMILY "integer_ops" USING btree DROP + OPERATOR 1 ""(int4, int2), + OPERATOR 2 ""(int4, int2), + FUNCTION 1 ""(int4, int2);` + ); + }); + + it.todo('should return sql statement with schema', () => { + // TODO @Shinigami92 2024-03-08: looks like type is flipped + const statement = removeFromOperatorFamilyFn( + { name: 'integer_ops', schema: 'myschema' }, + 'btree', + [ + { + name: '', + type: 'operator', + number: 1, + params: [{ type: 'int4' }, { type: 'int2' }], + }, + { + name: '', + type: 'operator', + number: 2, + params: [{ type: 'int4' }, { type: 'int2' }], + }, + { + name: '', + type: 'function', + number: 1, + params: [{ type: 'int4' }, { type: 'int2' }], + }, + ] + ); + + expect(statement).toBeTypeOf('string'); + expect(statement).toStrictEqual( + `ALTER OPERATOR FAMILY "myschema"."integer_ops" USING btree DROP + OPERATOR 1 ""(int4, int2), + OPERATOR 2 ""(int4, int2), + FUNCTION 1 ""(int4, int2);` + ); + }); + }); + }); +}); diff --git a/test/operations/operators/renameOperatorClass.spec.ts b/test/operations/operators/renameOperatorClass.spec.ts new file mode 100644 index 00000000..09a458b8 --- /dev/null +++ b/test/operations/operators/renameOperatorClass.spec.ts @@ -0,0 +1,60 @@ +import { describe, expect, it } from 'vitest'; +import { renameOperatorClass } from '../../../src/operations/operators'; +import { options1 } from '../../utils'; + +describe('operations', () => { + describe('operators', () => { + describe('renameOperatorClass', () => { + const renameOperatorClassFn = renameOperatorClass(options1); + + it('should return a function', () => { + expect(renameOperatorClassFn).toBeTypeOf('function'); + }); + + it('should return sql statement', () => { + const statement = renameOperatorClassFn( + 'gist__int_ops', + 'gist', + 'gist__int_ops_new' + ); + + expect(statement).toBeTypeOf('string'); + expect(statement).toStrictEqual( + 'ALTER OPERATOR CLASS "gist__int_ops" USING gist RENAME TO "gist__int_ops_new";' + ); + }); + + it('should return sql statement with schema', () => { + const statement = renameOperatorClassFn( + { name: 'gist__int_ops', schema: 'myschema' }, + 'gist', + { name: 'gist__int_ops_new', schema: 'myschema' } + ); + + expect(statement).toBeTypeOf('string'); + expect(statement).toStrictEqual( + 'ALTER OPERATOR CLASS "myschema"."gist__int_ops" USING gist RENAME TO "myschema"."gist__int_ops_new";' + ); + }); + + describe('reverse', () => { + it('should contain a reverse function', () => { + expect(renameOperatorClassFn.reverse).toBeTypeOf('function'); + }); + + it('should return sql statement', () => { + const statement = renameOperatorClassFn.reverse( + 'gist__int_ops', + 'gist', + 'gist__int_ops_new' + ); + + expect(statement).toBeTypeOf('string'); + expect(statement).toBe( + 'ALTER OPERATOR CLASS "gist__int_ops_new" USING gist RENAME TO "gist__int_ops";' + ); + }); + }); + }); + }); +}); diff --git a/test/operations/operators/renameOperatorFamily.spec.ts b/test/operations/operators/renameOperatorFamily.spec.ts new file mode 100644 index 00000000..d24eb374 --- /dev/null +++ b/test/operations/operators/renameOperatorFamily.spec.ts @@ -0,0 +1,60 @@ +import { describe, expect, it } from 'vitest'; +import { renameOperatorFamily } from '../../../src/operations/operators'; +import { options1 } from '../../utils'; + +describe('operations', () => { + describe('operators', () => { + describe('renameOperatorFamily', () => { + const renameOperatorFamilyFn = renameOperatorFamily(options1); + + it('should return a function', () => { + expect(renameOperatorFamilyFn).toBeTypeOf('function'); + }); + + it('should return sql statement', () => { + const statement = renameOperatorFamilyFn( + 'integer_ops', + 'btree', + 'integer_ops_new' + ); + + expect(statement).toBeTypeOf('string'); + expect(statement).toStrictEqual( + 'ALTER OPERATOR FAMILY "integer_ops" USING btree RENAME TO "integer_ops_new";' + ); + }); + + it('should return sql statement with schema', () => { + const statement = renameOperatorFamilyFn( + { name: 'integer_ops', schema: 'myschema' }, + 'btree', + { name: 'integer_ops_new', schema: 'myschema' } + ); + + expect(statement).toBeTypeOf('string'); + expect(statement).toStrictEqual( + 'ALTER OPERATOR FAMILY "myschema"."integer_ops" USING btree RENAME TO "myschema"."integer_ops_new";' + ); + }); + + describe('reverse', () => { + it('should contain a reverse function', () => { + expect(renameOperatorFamilyFn.reverse).toBeTypeOf('function'); + }); + + it('should return sql statement', () => { + const statement = renameOperatorFamilyFn.reverse( + 'integer_ops', + 'btree', + 'integer_ops_new' + ); + + expect(statement).toBeTypeOf('string'); + expect(statement).toBe( + 'ALTER OPERATOR FAMILY "integer_ops_new" USING btree RENAME TO "integer_ops";' + ); + }); + }); + }); + }); +}); diff --git a/vitest.config.ts b/vitest.config.ts index bd545278..f5b5c740 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -10,10 +10,10 @@ export default defineConfig({ include: ['src'], reportOnFailure: true, thresholds: { - lines: 55, - statements: 50, - functions: 53, - branches: 80, + lines: 57, + statements: 57, + functions: 57, + branches: 82, }, }, reporters: process.env.CI_PREFLIGHT