Support sqlite and oracle connectors#750
Support sqlite and oracle connectors#750HungKNguyen wants to merge 7 commits intoholistics:masterfrom
Conversation
|
Hi @HungKNguyen, could you check if your If your |
@nguyenalter I'm not seeing any protection on the branch, are you having trouble pushing? Maybe you can double check the origin? |
When I try to push my commit to your forked repository, It shows 403 error: git push HungKNguyen HEAD:master
remote: Permission to hungknguyen/dbml.git denied to nguyenalter.
fatal: unable to access 'https://github.com/hungknguyen/dbml/': The requested URL returned error: 403I think you can either:
@HungKNguyen please look into this, thank you for your time. |
@nguyenalter I just added you as a collaborator, thank you for your time as well |
nguyenalter
left a comment
There was a problem hiding this comment.
Please also update the description in packages/dbml-cli/src/cli/index.js (see TODO) to introduce your new sqlite and oracle options
| @@ -0,0 +1,481 @@ | |||
| import * as oracledb from 'oracledb'; | |||
There was a problem hiding this comment.
Please help add a comment to reference https://node-oracledb.readthedocs.io/en/latest/user_guide/installation.html#quickstart so we can check the doc more easily
| // Parse connection string to extract connection details | ||
| // Expected format: user/password@hostname/servicename | ||
| const regex = /^(.*?)\/(.*)@(.*)$/; | ||
| const match = connection.match(regex); | ||
|
|
||
| if (!match) { | ||
| throw new Error('Invalid Oracle connection string format. Expected: user/password@hostname/servicename'); | ||
| } | ||
|
|
||
| const [, user, password, connectionString] = match; | ||
|
|
||
| // Set connection options | ||
| const connectionConfig: oracledb.ConnectionAttributes = { | ||
| user, | ||
| password, | ||
| connectString: connectionString, | ||
| }; |
There was a problem hiding this comment.
Please move the parse connection string to a dedicated method, e.g:
parseConnectionString = (connection) => config| @@ -0,0 +1,389 @@ | |||
| import type { Database } from 'better-sqlite3'; | |||
There was a problem hiding this comment.
Please help add https://github.com/WiseLibs/better-sqlite3/blob/master/docs/api.md#api to the start of this file for future reference
| try { | ||
| return new DatabaseConstructor(connection, { readonly: true, fileMustExist: true }); |
There was a problem hiding this comment.
To ensure the db is connected successfully, please try to run a simple query like this:
| try { | |
| return new DatabaseConstructor(connection, { readonly: true, fileMustExist: true }); | |
| try { | |
| const db = new DatabaseConstructor(connection, { readonly: true, fileMustExist: true }); | |
| db.exec('SELECT 1'); | |
| return db; |
| DATA_PRECISION, | ||
| DATA_SCALE, | ||
| NULLABLE, | ||
| DATA_DEFAULT, |
There was a problem hiding this comment.
https://docs.oracle.com/en/database/oracle/oracle-database/23/refrn/ALL_TAB_COLUMNS.html
Oracle DB v23 introduces DATA_DEFAULT_VC to get default value for the column. Could you improve the logic to retrieve the default value since using DATA_DEFAULT will always return the LONG type which will infer as number. This will cause expression like current_timestamp to be treated as number when converting to DBML which is incorrect.
My suggestion is to use DATA_DEFAULT_VC for Oracle DB >= 23 and fallback to DATA_DEFAULT for older versions.
| return { | ||
| name: COLUMN_NAME, | ||
| type: actualType, | ||
| dbdefault: getDbDefault(DATA_DEFAULT, defaultValueType), |
There was a problem hiding this comment.
You must ignore column with IDENTITY_COLUMN === 'YES' because it is mapped to increment option, we don't want to use the default auto-generated value from Oracle here.
| dbdefault: getDbDefault(DATA_DEFAULT, defaultValueType), | |
| dbdefault: `IDENTITY_COLUMN === 'YES' ? null : getDbDefault(DATA_DEFAULT, defaultValueType), |
| SELECT | ||
| I.TABLE_NAME, | ||
| I.INDEX_NAME, | ||
| I.INDEX_TYPE, | ||
| I.UNIQUENESS, | ||
| IC.COLUMN_NAME, | ||
| IC.COLUMN_POSITION | ||
| FROM ALL_INDEXES I | ||
| JOIN ALL_IND_COLUMNS IC ON I.INDEX_NAME = IC.INDEX_NAME AND I.OWNER = IC.INDEX_OWNER | ||
| WHERE I.OWNER = :schemaName | ||
| ORDER BY I.TABLE_NAME, I.INDEX_NAME, IC.COLUMN_POSITION |
There was a problem hiding this comment.
Oracle will auto add index for primary key so you will need to exclude those auto-generated indexes from the DBML.
| SELECT | |
| I.TABLE_NAME, | |
| I.INDEX_NAME, | |
| I.INDEX_TYPE, | |
| I.UNIQUENESS, | |
| IC.COLUMN_NAME, | |
| IC.COLUMN_POSITION | |
| FROM ALL_INDEXES I | |
| JOIN ALL_IND_COLUMNS IC ON I.INDEX_NAME = IC.INDEX_NAME AND I.OWNER = IC.INDEX_OWNER | |
| WHERE I.OWNER = :schemaName | |
| ORDER BY I.TABLE_NAME, I.INDEX_NAME, IC.COLUMN_POSITION | |
| SELECT | |
| I.TABLE_NAME, | |
| I.INDEX_NAME, | |
| I.INDEX_TYPE, | |
| I.UNIQUENESS, | |
| IC.COLUMN_NAME, | |
| IC.COLUMN_POSITION | |
| FROM ALL_INDEXES I | |
| JOIN ALL_IND_COLUMNS IC ON I.INDEX_NAME = IC.INDEX_NAME AND I.OWNER = IC.INDEX_OWNER | |
| JOIN ALL_CONSTRAINTS C ON I.INDEX_NAME = C.INDEX_NAME AND I.OWNER = C.OWNER AND C.CONSTRAINT_TYPE != 'P' | |
| WHERE I.OWNER = :schemaName | |
| ORDER BY I.TABLE_NAME, I.INDEX_NAME, IC.COLUMN_POSITION |
Continuation of #748
Changed the base branch to allow edits by maintainers