-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: move extension creation to core
- Loading branch information
Showing
9 changed files
with
216 additions
and
72 deletions.
There are no files selected for viewing
12 changes: 10 additions & 2 deletions
12
examples/node-sequelize/migrations/20250110064304-add_timescale_extension.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,20 @@ | ||
'use strict'; | ||
|
||
const { TimescaleDB } = require('@timescaledb/core'); | ||
|
||
const extension = TimescaleDB.createExtension(); | ||
|
||
/** @type {import('sequelize-cli').Migration} */ | ||
module.exports = { | ||
async up(queryInterface) { | ||
await queryInterface.sequelize.query('CREATE EXTENSION IF NOT EXISTS timescaledb;'); | ||
const sql = extension.up().build(); | ||
|
||
await queryInterface.sequelize.query(sql); | ||
}, | ||
|
||
async down(queryInterface) { | ||
await queryInterface.sequelize.query('DROP EXTENSION IF EXISTS timescaledb;'); | ||
const sql = extension.down().build(); | ||
|
||
await queryInterface.sequelize.query(sql); | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import { CreateExtensionOptions, CreateExtensionOptionsSchema } from '@timescaledb/schemas'; | ||
import { ExtensionErrors } from './errors'; | ||
|
||
class ExtensionUpBuilder { | ||
private options?: CreateExtensionOptions; | ||
private statements: string[] = []; | ||
|
||
constructor(options?: CreateExtensionOptions) { | ||
this.options = options; | ||
} | ||
|
||
public build(): string { | ||
const stmt = `CREATE EXTENSION IF NOT EXISTS timescaledb${this?.options?.should_cascade ? ' CASCADE' : ''};`; | ||
this.statements.push(stmt); | ||
|
||
return this.statements.join('\n'); | ||
} | ||
} | ||
|
||
class ExtensionDownBuilder { | ||
private options?: CreateExtensionOptions; | ||
private statements: string[] = []; | ||
|
||
constructor(options?: CreateExtensionOptions) { | ||
this.options = options; | ||
} | ||
|
||
public build(): string { | ||
const stmt = `DROP EXTENSION IF EXISTS timescaledb${this?.options?.should_cascade ? ' CASCADE' : ''};`; | ||
this.statements.push(stmt); | ||
|
||
return this.statements.join('\n'); | ||
} | ||
} | ||
|
||
export class Extension { | ||
private options?: CreateExtensionOptions; | ||
|
||
constructor(options?: CreateExtensionOptions) { | ||
if (options) { | ||
try { | ||
this.options = CreateExtensionOptionsSchema.parse(options); | ||
} catch (error) { | ||
const e = error as Error; | ||
throw new Error(ExtensionErrors.INVALID_OPTIONS + ' ' + e.message); | ||
} | ||
} | ||
} | ||
|
||
public up(): ExtensionUpBuilder { | ||
return new ExtensionUpBuilder(this.options); | ||
} | ||
|
||
public down(): ExtensionDownBuilder { | ||
return new ExtensionDownBuilder(this.options); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`Extension down should drop an extension 1`] = `"DROP EXTENSION IF EXISTS timescaledb;"`; | ||
|
||
exports[`Extension down should drop an extension with cascade 1`] = `"DROP EXTENSION IF EXISTS timescaledb CASCADE;"`; | ||
|
||
exports[`Extension up should create an extension 1`] = `"CREATE EXTENSION IF NOT EXISTS timescaledb;"`; | ||
|
||
exports[`Extension up should create an extension with cascade 1`] = `"CREATE EXTENSION IF NOT EXISTS timescaledb CASCADE;"`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import { describe, it } from '@jest/globals'; | ||
import { TimescaleDB, ExtensionErrors } from '../src'; | ||
|
||
describe('Extension', () => { | ||
it('should fail when creating an extension without invalid options', () => { | ||
expect(() => { | ||
TimescaleDB.createExtension({ | ||
// @ts-expect-error | ||
invalidOption: 'invalid', | ||
}); | ||
}).toThrow(ExtensionErrors.INVALID_OPTIONS); | ||
}); | ||
|
||
describe('up', () => { | ||
it('should create an extension', () => { | ||
const extension = TimescaleDB.createExtension(); | ||
const sql = extension.up().build(); | ||
|
||
expect(sql).toMatchSnapshot(); | ||
}); | ||
|
||
it('should create an extension with cascade', () => { | ||
const extension = TimescaleDB.createExtension({ | ||
should_cascade: true, | ||
}); | ||
const sql = extension.up().build(); | ||
|
||
expect(sql).toMatchSnapshot(); | ||
}); | ||
}); | ||
|
||
describe('down', () => { | ||
it('should drop an extension', () => { | ||
const extension = TimescaleDB.createExtension(); | ||
const sql = extension.down().build(); | ||
|
||
expect(sql).toMatchSnapshot(); | ||
}); | ||
|
||
it('should drop an extension with cascade', () => { | ||
const extension = TimescaleDB.createExtension({ | ||
should_cascade: true, | ||
}); | ||
const sql = extension.down().build(); | ||
|
||
expect(sql).toMatchSnapshot(); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { z } from 'zod'; | ||
|
||
export const CreateExtensionOptionsSchema = z | ||
.object({ | ||
should_cascade: z.boolean().optional(), | ||
version: z.string().optional(), | ||
}) | ||
.strict(); | ||
export type CreateExtensionOptions = z.infer<typeof CreateExtensionOptionsSchema>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.