Skip to content

Commit

Permalink
Merge pull request #35 from Software-Developers-IRL/f/lastlink
Browse files Browse the repository at this point in the history
F/lastlink 0.0.2 initial working create table generator
  • Loading branch information
lastlink authored Oct 1, 2022
2 parents 936b24b + 4f35555 commit 5dfb1c8
Show file tree
Hide file tree
Showing 3 changed files with 181 additions and 88 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "little-mermaid-2-the-sql",
"version": "0.0.1",
"version": "0.0.2",
"description": "",
"main": "./lib/index.js",
"engines": {
Expand Down
173 changes: 89 additions & 84 deletions samples/chinook-database-2.0.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,121 +10,126 @@ sequenceDiagram
```mermaid
erDiagram
artists {
INTEGER ArtistId PK "'Artist' nullable"
NVARCHAR Name
Artist {
INTEGER ArtistId PK "NOT NULL"
NVARCHAR120 Name
}
employees {
INTEGER EmployeeId
NVARCHAR LastName
NVARCHAR FirstName
NVARCHAR Title
INTEGER ReportsTo
Employee {
INTEGER EmployeeId PK "NOT NULL"
NVARCHAR20 LastName "NOT NULL"
NVARCHAR20 FirstName "NOT NULL"
NVARCHAR30 Title
INTEGER ReportsTo FK
DATETIME BirthDate
DATETIME HireDate
NVARCHAR Address
NVARCHAR City
NVARCHAR State
NVARCHAR Country
NVARCHAR PostalCode
NVARCHAR Phone
NVARCHAR Fax
NVARCHAR Email
NVARCHAR70 Address
NVARCHAR40 City
NVARCHAR40 State
NVARCHAR40 Country
NVARCHAR10 PostalCode
NVARCHAR24 Phone
NVARCHAR24 Fax
NVARCHAR60 Email
}
genres {
INTEGER GenreId
NVARCHAR Name
Genre {
INTEGER GenreId PK "NOT NULL"
NVARCHAR120 Name
}
media_types {
INTEGER MediaTypeId
NVARCHAR Name
MediaType {
INTEGER MediaTypeId PK "NOT NULL"
NVARCHAR120 Name
}
playlists {
INTEGER PlaylistId
NVARCHAR Name
Playlist {
INTEGER PlaylistId PK "NOT NULL"
NVARCHAR120 Name
}
albums {
INTEGER AlbumId
NVARCHAR Title
INTEGER ArtistId
Album {
INTEGER AlbumId PK "NOT NULL"
NVARCHAR160 Title "NOT NULL"
INTEGER ArtistId FK "NOT NULL"
}
customers {
INTEGER CustomerId
NVARCHAR FirstName
NVARCHAR LastName
NVARCHAR Company
NVARCHAR Address
NVARCHAR City
NVARCHAR State
NVARCHAR Country
NVARCHAR PostalCode
NVARCHAR Phone
NVARCHAR Fax
NVARCHAR Email
INTEGER SupportRepId
Customer {
INTEGER CustomerId PK "NOT NULL"
NVARCHAR40 FirstName "NOT NULL"
NVARCHAR20 LastName "NOT NULL"
NVARCHAR80 Company
NVARCHAR70 Address
NVARCHAR40 City
NVARCHAR40 State
NVARCHAR40 Country
NVARCHAR10 PostalCode
NVARCHAR24 Phone
NVARCHAR24 Fax
NVARCHAR60 Email "NOT NULL"
INTEGER SupportRepId FK
}
invoices {
INTEGER InvoiceId
INTEGER CustomerId
DATETIME InvoiceDate
NVARCHAR BillingAddress
NVARCHAR BillingCity
NVARCHAR BillingState
NVARCHAR BillingCountry
NVARCHAR BillingPostalCode
NUMERIC Total
test_table {
INTEGER id PK "NOT NULL"
TEXT Field2_2 "'Field 2_2'"
INTEGER ArtistId FK "'Artist Id'"
}
tracks {
INTEGER TrackId
NVARCHAR Name
INTEGER AlbumId
INTEGER MediaTypeId
INTEGER GenreId
NVARCHAR Composer
INTEGER Milliseconds
INTEGER Bytes
NUMERIC UnitPrice
Invoice {
INTEGER InvoiceId PK "NOT NULL"
INTEGER CustomerId FK "NOT NULL"
DATETIME InvoiceDate "NOT NULL"
NVARCHAR70 BillingAddress
NVARCHAR40 BillingCity
NVARCHAR40 BillingState
NVARCHAR40 BillingCountry
NVARCHAR10 BillingPostalCode
NUMERIC10_2 Total "NOT NULL"
}
invoice_items {
INTEGER InvoiceLineId
INTEGER InvoiceId
INTEGER TrackId
NUMERIC UnitPrice
INTEGER Quantity
Track {
INTEGER TrackId PK "NOT NULL"
NVARCHAR200 Name "NOT NULL"
INTEGER AlbumId FK
INTEGER MediaTypeId FK "NOT NULL"
INTEGER GenreId FK
NVARCHAR220 Composer
INTEGER Milliseconds "NOT NULL"
INTEGER Bytes
NUMERIC10_2 UnitPrice "NOT NULL"
}
playlist_track {
INTEGER PlaylistId
INTEGER TrackId
InvoiceLine {
INTEGER InvoiceLineId PK "NOT NULL"
INTEGER InvoiceId FK "NOT NULL"
INTEGER TrackId FK "NOT NULL"
NUMERIC10_2 UnitPrice "NOT NULL"
INTEGER Quantity "NOT NULL"
}
artists ||--o{ albums : "foreign key"
PlaylistTrack {
INTEGER PlaylistId PK "NOT NULL"
INTEGER TrackId PK "NOT NULL"
}
employees ||--o{ customers : "foreign key"
employees ||--o{ employees : "foreign key"
Artist ||--o{ Album : "[Artist.ArtistId] to [Album.ArtistId]"
genres ||--o{ tracks : "foreign key"
Employee ||--o{ Customer : "[Employee.EmployeeId] to [Customer.SupportRepId]"
media_types ||--o{ tracks : "foreign key"
Artist ||--o{ test_table : "[Artist.ArtistId] to ['test_table'.'Artist Id']"
playlists ||--o{ playlist_track : "foreign key"
Customer ||--o{ Invoice : "[Customer.CustomerId] to [Invoice.CustomerId]"
albums ||--o{ tracks : "foreign key"
Album ||--o{ Track : "[Album.AlbumId] to [Track.AlbumId]"
Genre ||--o{ Track : "[Genre.GenreId] to [Track.GenreId]"
MediaType ||--o{ Track : "[MediaType.MediaTypeId] to [Track.MediaTypeId]"
customers ||--o{ invoices : "foreign key"
Invoice ||--o{ InvoiceLine : "[Invoice.InvoiceId] to [InvoiceLine.InvoiceId]"
Track ||--o{ InvoiceLine : "[Track.TrackId] to [InvoiceLine.TrackId]"
invoices ||--o{ invoice_items : "foreign key"
Playlist ||--o{ PlaylistTrack : "[Playlist.PlaylistId] to [PlaylistTrack.PlaylistId]"
Track ||--o{ PlaylistTrack : "[Track.TrackId] to [PlaylistTrack.TrackId]"
tracks ||--o{ invoice_items : "foreign key"
tracks ||--o{ playlist_track : "foreign key"
```
94 changes: 91 additions & 3 deletions src/generate-sql-ddl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ export class DbParser {
if (this.entities) {
for (const key in this.entities) {
if (Object.prototype.hasOwnProperty.call(this.entities, key)) {
const element = this.entities[key];
const entity = this.entities[key];
statementGeneration.push(this.createTable(key, entity));
}
}
}
Expand All @@ -71,11 +72,98 @@ export class DbParser {
// }
return statementGeneration.join("");
}
/**
* convert labels with start and end strings per database type
* @param label
* @returns
*/
private dbTypeEnds(label: string) {
let char1 = '"';
let char2 = '"';
if (this.dbType == "mysql") {
char1 = "`";
char2 = "`";
} else if (this.dbType == "sqlserver") {
char1 = "[";
char2 = "]";
}
return `${char1}${label}${char2}`;
}
/**
* generate create table statement
* @param entityKey
* @param entity
* @returns
*/
private createTable(entityKey: string, entity: DbEntityDefinition) {
let statement = `CREATE TABLE ${this.dbTypeEnds(entityKey)} (\n`;
// TODO: incorporate foreign keys using relationships
for (let i = 0; i < entity.attributes.length; i++) {
const attribute = entity.attributes[i];
if (attribute.attributeType && attribute.attributeName) {
// need to add parenthesis or commas
let columnType = attribute.attributeType.replace("_", ",");
let columnTypeLength = columnType.replace(/[^0-9,]/gim, "");
columnType = (
columnType.replace(/[^a-z]/gim, "") +
(columnTypeLength ? `(${columnTypeLength})` : "")
).trim();
if (attribute.attributeComment) {
// check if contains full column name
statement += `\t${this.dbTypeEnds(
attribute.attributeName
)} ${columnType} ${attribute.attributeComment}`;
} else {
statement += `\t${this.dbTypeEnds(
attribute.attributeName
)} ${columnType}`;
}
statement += i != entity.attributes.length - 1 ? ",\n" : "\n";
}
}

private createTable(tableName: string) {
return `CREATE TABLE ${tableName}`;
statement += `\n)`;
return statement;
}

/* database create table examples:
sqlite example:
CREATE TABLE [test_table] (
"id" INTEGER NOT NULL,
"Field 2_2" TEXT,
"Artist Id" INTEGER,
PRIMARY KEY("id"),
FOREIGN KEY("Artist Id") REFERENCES "Artist"("ArtistId") ON DELETE NO ACTION ON UPDATE NO ACTION
)
mysql example:
CREATE TABLE `test_table` (
`id` INTEGER NOT NULL,
`Field 2_2` TEXT,
`Artist Id` INTEGER,
PRIMARY KEY (`id`),
FOREIGN KEY (`Artist Id`) REFERENCES `Artist`(`ArtistId`)
);
postgres example:
CREATE TABLE "test_table" (
"id" INTEGER NOT NULL,
"Field 2_2" TEXT,
"Artist Id" INTEGER,
PRIMARY KEY ("id"),
FOREIGN KEY ("Artist Id"") REFERENCES "Artist"("ArtistId")
);
sql server example:
CREATE TABLE [test_table] (
[id] INTEGER NOT NULL,
[Field 2_2] TEXT,
[Artist Id] INTEGER,
PRIMARY KEY ([id]),
FOREIGN KEY ([Artist Id]) REFERENCES [Artist]([ArtistId])
);
*/

private createColumn(
tableName: string,
columnName: string,
Expand Down

0 comments on commit 5dfb1c8

Please sign in to comment.