{
- sidebarItems.map((item: SidebarItemProps , index : number) => (
+ sidebarItems.map((item: SidebarItemProps, index: number) => (
= ({ }) => {
{
- bottomSidebarItems.map((item: SidebarItemProps, index : number) => (
+ bottomSidebarItems.map((item: SidebarItemProps, index: number) => (
))
diff --git a/src/hooks/user-render-sql.tsx b/src/hooks/user-render-sql.tsx
index 74514c3..d9a64dd 100644
--- a/src/hooks/user-render-sql.tsx
+++ b/src/hooks/user-render-sql.tsx
@@ -10,6 +10,7 @@ import { format } from 'sql-formatter';
import { DatabaseDialect, getDatabaseByDialect } from "@/lib/database";
import { CircularDependencyError, fixCharsetPlacement, fixSQLiteColumnOrder } from "@/utils/render/render-uttils";
import { areArraysEqual } from "@/utils/utils";
+import { decomposeManyToMany } from "@/utils/relationship";
const parser = new Parser();
@@ -17,13 +18,19 @@ const parser = new Parser();
export const useRenderSql = (database: DatabaseType) => {
const [sql, setSql] = useState
("");
const { data_types } = useDatabaseOperations();
- const [circularDependency, setCircularDependency] = useState(undefined)
+ const [circularDependency, setCircularDependency] = useState(undefined) ;
+
useEffect(() => {
try {
- const dbAst: any = DatabaseToAst(database, data_types);
+
+ const decomposedDatabase = decomposeManyToMany(database) ;
+
+ const dbAst: any = DatabaseToAst(decomposedDatabase, data_types);
+
let sql: string = parser.sqlify(dbAst, {
database: getDatabaseByDialect(database.dialect).name
});
+
if (database.dialect != DatabaseDialect.SQLITE)
sql = fixCharsetPlacement(format(sql, { language: "sql" }));
else
@@ -49,7 +56,7 @@ export const useRenderSql = (database: DatabaseType) => {
})
}
- }, [database]);
+ }, [database , data_types]);
return { sql, circularDependency };
diff --git a/src/lib/data_types/mariadb_data_types.ts b/src/lib/data_types/mariadb_data_types.ts
new file mode 100644
index 0000000..b3b8aa9
--- /dev/null
+++ b/src/lib/data_types/mariadb_data_types.ts
@@ -0,0 +1,303 @@
+import { DataInsertType } from "../schemas/data-type-schema";
+
+export const MariaDbDataType: Partial[] = [
+ // ===== integer =====
+ {
+ id: 'ce8a95f3-c0eb-4700-aefa-3147fa21377a',
+ name: 'bit',
+ type: 'integer',
+ modifiers: ['length'] // BIT(M) where M is number of bits (1-64)
+ },
+
+ {
+ id: 'e2ff64e3-96b1-4896-8f92-1dbe5d8bd442',
+ name: 'integer',
+ type: 'integer',
+ modifiers: ['unsigned', 'zerofill', 'length', "auto_increment"], // Same as INT
+ synonyms: ['int']
+
+ },
+ {
+ id: '5b4d8b34-5f33-4660-9443-03ea2eef34fd',
+ name: 'tinyint',
+ type: 'integer',
+ modifiers: ['unsigned', 'zerofill', 'length', "auto_increment"] // TINYINT[(M)] [UNSIGNED] [ZEROFILL]
+ },
+ {
+ id: '6548ff67-1800-447b-8fbd-87003a43dc05',
+ name: 'smallint',
+ type: 'integer',
+ modifiers: ['unsigned', 'zerofill', 'length', "auto_increment"] // SMALLINT[(M)] [UNSIGNED] [ZEROFILL]
+ },
+ {
+ id: '5991fbbb-6180-4f4c-9f3f-af8f94931bae',
+ name: 'mediumint',
+ type: 'integer',
+ modifiers: ['unsigned', 'zerofill', 'length', "auto_increment"] // MEDIUMINT[(M)] [UNSIGNED] [ZEROFILL]
+ },
+ {
+ id: 'e7b9e8f8-6a87-4ee7-a411-af5775cd0b88',
+ name: 'bigint',
+ type: 'integer',
+ modifiers: ['unsigned', 'zerofill', 'length', "auto_increment"] // BIGINT[(M)] [UNSIGNED] [ZEROFILL]
+ },
+
+ // ===== numeric =====
+ {
+ id: '59abc150-6796-46ee-940c-88eb34eae619',
+ name: 'float',
+ type: 'numeric',
+ modifiers: ['precision', "scale", 'unsigned', 'zerofill'] // FLOAT[(M,D)] [UNSIGNED] [ZEROFILL]
+ },
+ {
+ id: '1ccdde6d-45ae-4ab8-9020-d0d123175037',
+ name: 'double',
+ type: 'numeric',
+ modifiers: ['precision', "scale", 'unsigned', 'zerofill'], // DOUBLE[(M,D)] [UNSIGNED] [ZEROFILL]
+ synonyms: ['double precision', 'real']
+
+ },
+
+ {
+ id: '3089e057-7ea0-4422-9f8b-b03c1c4aadb1',
+ name: 'decimal',
+ type: 'numeric',
+ modifiers: ['precision', "scale", 'unsigned', 'zerofill'], // DECIMAL[(M[,D])] [UNSIGNED] [ZEROFILL]
+ synonyms: ['dec', 'numeric', 'fixed']
+ },
+
+
+
+
+
+ {
+ id: '70c98043-ce75-4e17-8157-b4060b600cc0',
+ name: 'boolean',
+ type: 'boolean',
+ synonyms: ['bool'] // BOOLEAN and BOOL are both aliases for TINYINT(1)
+
+ // Alias for TINYINT(1)
+ },
+
+ // ===== date/time =====
+ {
+ id: 'bd2d44eb-d4dc-45bc-b1c8-39bff5c703a6',
+ name: 'date',
+ type: 'time',
+ // No modifiers
+ },
+ {
+ id: '2344419d-c226-42a3-bdf4-77e4181a7f81',
+ name: 'datetime',
+ type: 'time',
+ modifiers: ['precision'] // DATETIME[(fsp)], fsp = fractional seconds precision (0-6)
+ },
+ {
+ id: '2b2d6921-b364-4953-a94d-048c43037e35',
+ name: 'timestamp',
+ type: 'time',
+ modifiers: ['precision'] // TIMESTAMP[(fsp)], fsp = fractional seconds precision (0-6)
+ },
+ {
+ id: '6b40d621-d7c5-408e-b784-c839b6c36bed',
+ name: 'time',
+ type: 'time',
+ modifiers: ['precision'] // TIME[(fsp)], fsp = fractional seconds precision (0-6)
+ },
+ {
+ id: '2da3d963-ee00-4472-8b61-38b3f22bdeb6',
+ name: 'year',
+ type: 'time',
+ // YEAR[(2|4)], but 2-digit YEAR is deprecated
+ },
+
+ // ===== text =====
+ {
+ id: '3d1c4ddc-a71b-42c6-b935-abb571999055',
+ name: 'char',
+ type: 'text',
+ modifiers: ['length', 'charset', 'collate'] // CHAR[(M)] [CHARACTER SET charset] [COLLATE collation]
+ },
+
+ {
+ id: 'dfba8595-d9da-4efa-b5e7-a759c07a7984',
+ name: 'varchar',
+ type: 'text',
+ modifiers: ['length', 'charset', 'collate'], // VARCHAR(M) [CHARACTER SET charset] [COLLATE collation]
+ synonyms: ['nchar', 'national char']
+ },
+
+ {
+ id: '2dc7ba21-e477-47ff-b736-836f7a6586c6',
+ name: 'text',
+ type: 'text',
+ modifiers: ['charset', 'collate', "no_default", "no_unique"], // TEXT [CHARACTER SET charset] [COLLATE collation]
+ synonyms: ['nvarchar', 'national varchar']
+ },
+ {
+ id: '51467e54-6257-4431-b161-477aa74857d5',
+ name: 'tinytext',
+ type: 'text',
+ modifiers: ['charset', 'collate', "no_default", "no_unique"] // Same as TEXT
+ },
+ {
+ id: '62399f45-0a58-4b7e-826e-d40278399b19',
+ name: 'mediumtext',
+ type: 'text',
+ modifiers: ['charset', 'collate', "no_default", "no_unique"] // Same as TEXT
+ },
+ {
+ id: 'd0a90fad-ed80-43c5-9388-2e416cfa07dd',
+ name: 'longtext',
+ type: 'text',
+ modifiers: ['charset', 'collate', "no_default", "no_unique"] // Same as TEXT
+ },
+
+ // ===== binary (bytea) =====
+ {
+ id: '4c08fd5b-3744-44d1-a57a-e81290a1a29b',
+ name: 'blob',
+ type: 'binary',
+ modifiers: ["no_default", "no_unique"]
+ },
+ {
+ id: '8183a869-7c46-4bee-9560-e5965b824aba',
+ name: 'tinyblob',
+ type: 'binary',
+ modifiers: ["no_default", "no_unique"]
+ },
+ {
+ id: '3edc6207-e595-45c9-af0d-056b4d991b21',
+ name: 'mediumblob',
+ type: 'binary',
+ modifiers: ["no_default", "no_unique"]
+
+ },
+ {
+ id: 'c3cbe13f-38bf-4ef5-b448-ed9bda3c673b',
+ name: 'longblob',
+ type: 'binary',
+ modifiers: ["no_default", "no_unique"]
+ },
+ {
+ id: 'f2930d56-1903-4710-9c4c-d635123bfaec',
+ name: 'binary',
+ type: 'binary',
+ modifiers: ["no_default", 'length'] // BINARY(M)
+ },
+ {
+ id: '646d8483-d585-4b7c-8255-5bd36bf9240e',
+ name: 'varbinary',
+ type: 'binary',
+ modifiers: ["no_default", 'length'] // VARBINARY(M)
+ },
+
+ // ===== enum/set =====
+ {
+ id: '0c9fca72-ead9-4abc-8726-3074bb49c878',
+ name: 'enum',
+ type: 'enum',
+ modifiers: ['values'] // ENUM('value1','value2',...) [CHARACTER SET charset] [COLLATE collation]
+ },
+ {
+ id: '378b77b6-d27c-4bb1-beea-6f0423bd1776',
+ name: 'set',
+ type: 'enum',
+ modifiers: ['values'] // SET('value1','value2',...) [CHARACTER SET charset] [COLLATE collation]
+ },
+
+ // ===== json =====
+ {
+ id: '40222e5e-40a6-43a5-b5c6-2a89601ee30b',
+ name: 'json',
+ type: 'json',
+ modifiers: ["no_default", "no_unique"]
+ // No modifiers
+ },
+
+ // ===== spatial =====
+ // Spatial types generally don't have modifiers
+ {
+ id: '06c24cc7-0ad8-4e05-a2bd-c1b7fb881fa3',
+ name: 'geometry',
+ type: 'geometry',
+ modifiers: ["no_default", "no_unique"]
+
+ },
+ {
+ id: '8a3363e8-ebce-4ec1-b022-b18cf52a4769',
+ name: 'point',
+ type: 'geometry',
+ modifiers: ["no_default", "no_unique"]
+ },
+ {
+ id: '5018b1a6-6a62-4f58-9c49-fc96efeb1b38',
+ name: 'linestring',
+
+ type: 'geometry',
+ modifiers: ["no_default", "no_unique"]
+
+ },
+ {
+ id: '0edf91e8-4f10-41b1-9fc9-3c024c5f90c4',
+ name: 'polygon',
+
+ type: 'geometry',
+ modifiers: ["no_default", "no_unique"]
+
+ },
+ {
+ id: '0be92649-f626-4dc8-a163-c86643ca6687',
+ name: 'multipoint',
+
+ type: 'geometry',
+ modifiers: ["no_default", "no_unique"]
+
+ },
+ {
+ id: 'c996968e-a83b-44af-aca0-755865cd8825',
+ name: 'multilinestring',
+
+ type: 'geometry',
+ modifiers: ["no_default", "no_unique"]
+
+ },
+ {
+ id: '3fa4450a-78b1-4243-9faf-178c607ac092',
+ name: 'multipolygon',
+
+ type: 'geometry',
+ modifiers: ["no_default", "no_unique"]
+
+ },
+ {
+ id: '584bf784-3193-4534-8078-392558fc625f',
+ name: 'geometrycollection',
+
+ type: 'geometry',
+ modifiers: ["no_default", "no_unique"]
+
+ },
+
+ // ===== MariaDB-specific additions =====
+ {
+ id: '7e092014-b75f-4a62-b447-0c5d4af91bc7',
+ name: 'uuid',
+ type: 'uuid',
+ // No modifiers
+ },
+ {
+ id: 'd6483b02-4eaf-418d-ab00-1818ca40d749',
+ name: 'inet4',
+ type: 'network',
+ modifiers: ["no_default"]
+ // No modifiers
+ },
+ {
+ id: '90adf29b-e993-4215-8241-38dfb31a1139',
+ name: 'inet6',
+ type: 'network',
+ modifiers: ["no_default"]
+ // No modifiers
+ }
+];
\ No newline at end of file
diff --git a/src/lib/data_types/mysql_data_types.ts b/src/lib/data_types/mysql_data_types.ts
new file mode 100644
index 0000000..c9af836
--- /dev/null
+++ b/src/lib/data_types/mysql_data_types.ts
@@ -0,0 +1,241 @@
+import { DataInsertType } from "../schemas/data-type-schema";
+
+export const MysqlDataType : Partial[] = [
+ // ===== integer =====
+
+ {
+ id: '53a71e01-345e-4894-bc99-15148dadd1f5',
+ name: 'integer',
+ type: 'integer',
+ modifiers: ['length', 'unsigned', 'zerofill', "auto_increment"], // Same as INT
+ synonyms: ["int"]
+ },
+ {
+ id: '838da726-648b-4b39-b589-f07c6f9ad249',
+ name: 'tinyint',
+ type: 'integer',
+ modifiers: ['length', 'unsigned', 'zerofill', "auto_increment"] // TINYINT[(M)] [UNSIGNED] [ZEROFILL]
+ },
+ {
+ id: '244e63ba-b172-4af5-8b82-ffbf7fb98b37',
+ name: 'smallint',
+ type: 'integer',
+ modifiers: ['length', 'unsigned', 'zerofill', "auto_increment"] // SMALLINT[(M)] [UNSIGNED] [ZEROFILL]
+ },
+ {
+ id: 'f34a507e-d99d-4129-967b-16436580e23a',
+ name: 'mediumint',
+ type: 'integer',
+ modifiers: ['length', 'unsigned', 'zerofill', "auto_increment"] // MEDIUMINT[(M)] [UNSIGNED] [ZEROFILL]
+ },
+ {
+ id: '37f5a67a-5366-4b0a-aa2d-b94f7cae0c09',
+ name: 'bigint',
+ type: 'integer',
+ modifiers: ['length', 'unsigned', 'zerofill', "auto_increment"] // BIGINT[(M)] [UNSIGNED] [ZEROFILL]
+ },
+
+ // ===== numeric =====
+ {
+ id: '40183231-7a46-4f40-9b54-69a573ce61d1',
+ name: 'float',
+ type: 'numeric',
+ modifiers: ['precision', "scale", 'unsigned', 'zerofill'],
+ synonyms: ['float4']
+ },
+ {
+ id: 'b1b1ccf9-b349-453e-a3dd-1ca7751d27f1',
+ name: 'double',
+ type: 'numeric',
+ modifiers: ['precision', "scale", 'unsigned', 'zerofill'],
+ synonyms: ['double precision', 'real', 'float8']
+
+ },
+ {
+ id: '094e7c4c-ae7f-414f-b7aa-6d44e7f357c2',
+ name: 'decimal',
+ type: 'numeric',
+ modifiers: ['precision', "scale", 'unsigned', 'zerofill'],
+ synonyms: ['dec', 'numeric', 'fixed']
+ },
+
+
+ {
+ id: '73eac02b-27e6-4d74-a161-00809c85be01',
+ name: 'boolean',
+ type: 'boolean',
+ synonyms: ['bool'],
+ },
+
+ // ===== date =====
+ {
+ id: '8fb4b59c-ab26-4377-a329-aca5bce94ef7',
+ name: 'date',
+ type: 'time',
+ // No modifiers
+ },
+
+ // ===== timestamp =====
+ {
+ id: 'c53ab7b7-a453-4669-80c8-cad828e4c95d',
+ name: 'datetime',
+ type: 'time',
+ modifiers: ['precision'] // DATETIME[(fsp)], fsp = fractional seconds (0-6)
+ },
+ {
+ id: 'c2c12ebd-9e71-45d9-979b-868335fbf29a',
+ name: 'timestamp',
+ type: 'time',
+ modifiers: ['precision'] // TIMESTAMP[(fsp)], fsp = fractional seconds (0-6)
+ },
+
+ // ===== time =====
+ {
+ id: '0097a5e9-2e8b-46f8-a27b-229e05c0ad3e',
+ name: 'time',
+ type: 'time',
+ modifiers: ['precision'] // TIME[(fsp)], fsp = fractional seconds (0-6)
+ },
+ {
+ id: 'd22941e8-c036-4fda-b7b7-003e5e9d92d5',
+ name: 'year',
+ type: 'time',
+ // YEAR[(2|4)], but 2-digit YEAR is deprecated
+ },
+
+ {
+ id: "98bf3653-ef15-4528-8319-9053f7ce0b9a",
+ name: "char",
+ type: "text",
+ modifiers: ["length", "charset", "collate"],
+ synonyms: ["nchar", "national char"] // CHAR = NCHAR = NATIONAL CHAR
+ },
+ {
+ id: "e9b4026d-67bb-4478-812a-760a1312dcb3",
+ name: "varchar",
+ type: "text",
+ modifiers: ["length", "charset", "collate"] ,
+ synonyms: ["nvarchar", "national varchar"] // VARCHAR = NVARCHAR = NATIONAL VARCHAR
+
+ },
+ {
+ id: "1caa0a4a-fa8e-4ca1-85af-ed3355f91789",
+ name: "text",
+ type: "text",
+ modifiers: ["charset", "collate", "no_default", "no_unique"]
+ },
+ {
+ id: "04cb1391-b46b-452f-8e36-cd90fbbd0c9b",
+ name: "tinytext",
+ type: "text",
+ modifiers: ["charset", "collate", "no_default", "no_unique"]
+ },
+ {
+ id: "0eb12f0c-d9b9-4355-b097-cffb5174ec48",
+ name: "mediumtext",
+ type: "text",
+ modifiers: ["charset", "collate", "no_default", "no_unique"]
+ },
+ {
+ id: "3f7402aa-d1e4-416a-9f0c-39063a5253ef",
+ name: "longtext",
+ type: "text",
+ modifiers: ["charset", "collate", "no_default", "no_unique"]
+ },
+
+ // ===== binary =====
+ {
+ id: '9437b53d-3ad0-4079-9b51-afd433e91085',
+ name: 'binary',
+ type: 'binary',
+ modifiers: ["no_default", 'length'] // BINARY(M)
+ },
+ {
+ id: 'ccbc6f5f-07d4-43e2-b3e2-ca802e373a7b',
+ name: 'varbinary',
+ type: 'binary',
+ modifiers: ["no_default", 'length'] // VARBINARY(M)
+ },
+ {
+ id: '5f03ac95-b931-444f-9837-519a785cc098',
+ name: 'blob',
+ type: 'binary',
+ modifiers: ["no_default", "no_unique"]
+ // BLOB
+ },
+ {
+ id: '9d677b18-2a4a-435f-ac8a-4ba0ceef9148',
+ name: 'tinyblob',
+ type: 'binary',
+ modifiers: ["no_default", "no_unique"]
+ // TINYBLOB
+ },
+ {
+ id: 'ab7f73d6-bdaf-4485-a4da-d94467f157d7',
+ name: 'mediumblob',
+ type: 'binary',
+ modifiers: ["no_default", "no_unique"]
+ // MEDIUMBLOB
+ },
+ {
+ id: '9367631e-3e05-4b85-9937-9b7e80ac7430',
+ name: 'longblob',
+ type: 'binary',
+ modifiers: ["no_default", "no_unique"]
+ // LONGBLOB
+ },
+
+ // ===== enum =====
+ {
+ id: '0e964e0c-f1f0-4bfd-84f7-dd82f07973aa',
+ name: 'enum',
+ type: 'enum',
+ modifiers: ['values'] // ENUM('value1','value2',...) [CHARACTER SET charset] [COLLATE collation]
+ },
+ {
+ id: '793c840c-b11e-484d-aaed-c9bbdee4b422',
+ name: 'set',
+ type: 'enum',
+ modifiers: ['values'] // SET('value1','value2',...) [CHARACTER SET charset] [COLLATE collation]
+ },
+
+ // ===== json =====
+ {
+ id: '9c9efa25-4db9-44f8-905b-948608f9119f',
+ name: 'json',
+ type: 'json',
+ modifiers: ["no_default", "no_unique"]
+ // No modifiers
+ },
+
+ {
+ id: '821e41e2-c7d0-4a89-86cf-501df764eb15',
+ name: 'geometry',
+ type: 'geometry',
+ modifiers: ["no_default", "no_unique"]
+ },
+ {
+ id: '5de94b34-3a89-4650-98f6-8779bf0370db',
+ name: 'point',
+ type: 'geometry',
+ modifiers: ["no_default", "no_unique"]
+ },
+ {
+ id: '353225e7-0da6-4bdc-8fd9-101bf3c5b8f3',
+ name: 'linestring',
+ type: 'geometry',
+ modifiers: ["no_default", "no_unique"]
+ },
+ {
+ id: '71f34268-df34-448a-bf4f-95a67e03653c',
+ name: 'polygon',
+ type: 'geometry',
+ modifiers: ["no_default", "no_unique"]
+ },
+ {
+ id: '3ed65825-6bd3-4d3a-82aa-be8ff168d450',
+ name: 'geometrycollection',
+ type: 'geometry',
+ modifiers: ["no_default", "no_unique"]
+ }
+];
\ No newline at end of file
diff --git a/src/lib/data_types/postgres_data_types.ts b/src/lib/data_types/postgres_data_types.ts
new file mode 100644
index 0000000..2a89d66
--- /dev/null
+++ b/src/lib/data_types/postgres_data_types.ts
@@ -0,0 +1,62 @@
+import { DataInsertType } from "../schemas/data-type-schema";
+
+export const PostgresDataType: Partial[] = [
+ {
+ id: 'ee0289ee-8cc8-43c0-b67d-321cbc4585d1', name: 'smallint', type: 'integer', modifiers: ["auto_increment"],
+ synonyms: ['int2']
+ },
+ {
+ id: '96ca7315-2daf-489e-a5c6-1f6757dea9d9', name: 'integer', type: 'integer', modifiers: ["auto_increment"],
+ synonyms: ['int', 'int4']
+ },
+ {
+ id: 'e256e7b2-355a-45f4-aee7-6b39efa853a0', name: 'bigint', type: 'integer', modifiers: ["auto_increment"],
+ synonyms: ['int8']
+ },
+
+ { id: 'b11e83d0-57c4-45fd-8f7d-c09a94758af0', name: 'numeric', type: 'numeric', modifiers: ['precision', 'scale'], synonyms: ['decimal'] },
+ { id: '8c3e6086-6372-4ff1-a60c-7ca75f31d8e7', name: 'real', type: 'numeric', synonyms: ['float4', 'float'] },
+ { id: '3774463e-1076-4dcb-95e7-f695fa769899', name: 'double precision', type: 'numeric', synonyms: ['float8'] },
+ { id: 'd85b45d9-ea58-4d80-8589-b2489c64b6a9', name: 'money', type: 'numeric' },
+
+
+ { id: '0173eda2-1e61-45bd-99cc-6a1a8df93efa', name: 'varchar', type: 'text', modifiers: ['length'], synonyms: ['character varying'] },
+ { id: '87c39193-9592-488c-9864-8643cef6ce12', name: 'char', type: 'text', modifiers: ['length'], synonyms: ['character'] },
+ { id: 'ec45a87a-00dc-422a-ac05-578f9bf74fdb', name: 'text', type: 'text' },
+
+ { id: 'e75dbf56-41c4-4570-b141-e693b6fe1612', name: 'bytea', type: 'binary', modifiers: ["no_default"] },
+ { id: '1d7f3282-e377-4252-bd49-95277c9c637c', name: 'bit', type: 'binary', modifiers: ['length', 'no_default'] },
+ { id: 'bd35c546-89d2-407a-accc-101851f2b62d', name: 'varbit', type: 'binary', modifiers: ['length', "no_default"], synonyms: ['bit varying'] },
+
+ {
+ id: '11f5ce77-a0c8-44b0-9fbb-4a4b65140997', name: 'timestamp', type: 'time', modifiers: ['precision'], synonyms: [
+ 'timestamp without time zone',
+ 'timestamptz', // often mistaken but technically not equivalent
+ ]
+ },
+ { id: 'bd95631d-c1c4-4cc2-a715-b613369ab097', name: 'date', type: 'time', },
+ { id: 'ea3b2c12-931e-4c88-bda5-07efa36ae178', name: 'time', type: 'time', modifiers: ['precision'], synonyms: ['time without time zone'] },
+
+
+ { id: '3763db96-0ad8-45ef-8510-83000e398263', name: 'boolean', type: 'boolean', synonyms: ['bool'] },
+
+ { id: '5baecfc7-f76d-4184-bb10-586dfb95ac37', name: 'enum', type: 'enum', modifiers: ['values'] },
+
+ { id: "9660224d-cc98-4204-b4db-cbce58f1257d", name: 'point', type: 'geometric', modifiers: ["no_default"] },
+ { id: 'e390e7a6-6fcb-4417-91ec-f663db80e47f', name: 'line', type: 'geometric', modifiers: ["no_default"] },
+ { id: 'd6cc5854-f88c-4b92-98ce-7b4016022fe1', name: 'lseg', type: 'geometric', modifiers: ["no_default"] },
+ { id: '4ce5a962-0194-4298-91f6-4647b0a12b13', name: 'box', type: 'geometric', modifiers: ["no_default"] },
+ { id: 'b95eec3d-c6b1-40f0-8fe7-19b4a6212cfd', name: 'path', type: 'geometric', modifiers: ["no_default"] },
+ { id: 'b8de3385-798b-4b3b-983f-f3cc61c3c3ac', name: 'polygon', type: 'geometric', modifiers: ["no_default"] },
+ { id: '7b3db3bc-2334-4fe5-a5d7-1ad61f4cfb4f', name: 'circle', type: 'geometric', modifiers: ["no_default"] },
+
+ { id: 'f5ad8fc7-4dfb-4e58-b5f5-348a08354056', name: 'uuid', type: 'uuid', },
+ { id: 'a5dfb0db-377b-4ff7-b4c1-3c8e705d71aa', name: 'json', type: 'json', modifiers: ["no_default"] },
+ { id: '1a8e41ae-fc5e-4bd9-9919-960e07d7b3d4', name: 'jsonb', type: 'json', modifiers: ["no_default"] },
+ { id: 'e55e9dc4-4dd3-47f5-a9db-10c3b6f1295b', name: 'xml', type: 'xml', modifiers: ["no_default"] },
+ { id: '2a52974a-2b00-4cd8-8264-fd41e2f77683', name: 'cidr', type: 'network', modifiers: ["no_default"] },
+ { id: 'ac857b8e-8803-4635-ae2c-1be1c1aa8324', name: 'inet', type: 'network', modifiers: ["no_default"] },
+ { id: '83f9691a-1b12-4663-a24a-f019bb5f04c2', name: 'macaddr', type: 'network', modifiers: ["no_default"] },
+ { id: 'fdc52c94-6bd4-47d8-a5e7-6a43e5e517e9', name: 'tsvector', type: 'textsearch', modifiers: ["no_default"] },
+ { id: '1b06287e-7e9f-4a3f-8c61-5f0a18f7f91c', name: 'tsquery', type: 'textsearch', modifiers: ["no_default"] },
+];
diff --git a/src/lib/data_types/seed_datatypes.ts b/src/lib/data_types/seed_datatypes.ts
new file mode 100644
index 0000000..c478454
--- /dev/null
+++ b/src/lib/data_types/seed_datatypes.ts
@@ -0,0 +1,34 @@
+import { PowerSyncSQLiteDatabase } from "@powersync/drizzle-driver";
+import { data_types, DataInsertType } from "../schemas/data-type-schema";
+import { MysqlDataType } from "./mysql_data_types";
+import { PostgresDataType } from "./postgres_data_types";
+import { SqliteDataTypes } from "./sqlite_data_types";
+import { MariaDbDataType } from "./mariadb_data_types";
+import { DatabaseDialect } from "../database";
+
+
+
+
+
+export const seedDataTypes = async (db: any) => {
+ const existing = await db.query.data_types.findFirst();
+ if (!existing) {
+ // seeding data types .
+ return await db.insert(data_types).values([
+ ...mapToDataType(MysqlDataType , DatabaseDialect.MYSQL) ,
+ ...mapToDataType(PostgresDataType , DatabaseDialect.POSTGRES) ,
+ ...mapToDataType(SqliteDataTypes , DatabaseDialect.SQLITE) ,
+ ...mapToDataType(MariaDbDataType , DatabaseDialect.MARIADB)
+ ] as DataInsertType[])
+ }
+
+}
+
+const mapToDataType = (dataTypes: Partial[], dialect: DatabaseDialect): DataInsertType[] => {
+ return dataTypes.map((dataType: Partial) => ({
+ ...dataType,
+ dialect,
+ modifiers: dataType.modifiers ? JSON.stringify(dataType.modifiers) : undefined,
+ synonyms: dataType.synonyms ? JSON.stringify(dataType.synonyms) : undefined
+ } as DataInsertType))
+}
\ No newline at end of file
diff --git a/src/lib/data_types/sqlite_data_types.ts b/src/lib/data_types/sqlite_data_types.ts
new file mode 100644
index 0000000..4819fd5
--- /dev/null
+++ b/src/lib/data_types/sqlite_data_types.ts
@@ -0,0 +1,101 @@
+import { DataInsertType } from "../schemas/data-type-schema";
+
+export const SqliteDataTypes: Partial[] = [
+ // ===== INTEGER =====
+ {
+ id: 'dea77641-e050-4392-9c14-e53cafa1bcab', // using canonical 'integer'
+ name: 'integer',
+ type: 'integer',
+ modifiers: ['auto_increment'], // Only valid with PRIMARY KEY
+ synonyms: [
+ 'int',
+ 'tinyint',
+ 'smallint',
+ 'mediumint',
+ 'bigint',
+ 'unsigned big int',
+ 'int2',
+ 'int8'
+ ]
+ },
+
+ // ===== TEXT =====
+ {
+ id: '862ee99c-a1d9-4652-a35a-a545712d39db', // 'text'
+ name: 'text',
+ type: 'text',
+ modifiers: ['length'], // Length ignored but can exist in UI
+ synonyms: [
+ 'character',
+ 'varchar',
+ 'varying character',
+ 'nchar',
+ 'native character',
+ 'nvarchar',
+ 'clob'
+ ]
+ },
+
+ // ===== REAL =====
+ {
+ id: '79f8e7a8-b36b-488a-9703-aa7593dcdfa4', // 'real'
+ name: 'real',
+ type: 'numeric',
+ synonyms: [
+ 'float',
+ 'double',
+ 'double precision'
+ ]
+ },
+
+ // ===== NUMERIC =====
+ {
+ id: '36ea1bc0-8f4f-4d9d-9a74-31458a65062c', // 'numeric'
+ name: 'numeric',
+ type: 'numeric',
+ modifiers: ['precision'], // Precision/scale ignored
+ synonyms: [
+ 'decimal'
+ ]
+ },
+
+ // ===== BLOB =====
+ {
+ id: '577161ce-7085-4484-af44-d25304c8c63b', // 'blob'
+ name: 'blob',
+ type: 'binary',
+ modifiers: ["no_default", "no_unique"]
+ },
+
+ // ===== BOOLEAN =====
+ {
+ id: '263a800f-e6c1-4287-91ad-d6688cb9f1e1', // 'boolean'
+ name: 'boolean',
+ type: 'boolean'
+ },
+
+ // ===== DATE / TIME =====
+ {
+ id: 'c438e00b-f7f8-4343-807d-96a6a3fff1c4', // 'date'
+ name: 'date',
+ type: 'time'
+ },
+ {
+ id: 'ef9455e5-3d56-48bd-8ba6-4c4d13a72fb9', // 'time'
+ name: 'time',
+ type: 'time'
+ },
+ {
+ id: '0e2a61ea-05dc-4b67-ab84-04caac829d57', // 'datetime'
+ name: 'datetime',
+ type: 'time'
+ },
+
+ // ===== JSON =====
+ {
+ id: 'a8cdd25f-dbd5-4582-b42d-641e5862de01', // 'json'
+ name: 'json',
+ type: 'json',
+ modifiers: ["no_default", "no_unique"]
+ }
+];
\ No newline at end of file
diff --git a/src/lib/schemas/data-type-schema.ts b/src/lib/schemas/data-type-schema.ts
index 7794e55..c2f1d94 100644
--- a/src/lib/schemas/data-type-schema.ts
+++ b/src/lib/schemas/data-type-schema.ts
@@ -1,6 +1,7 @@
import { InferSelectModel, relations } from 'drizzle-orm';
import { sqliteTable, text } from 'drizzle-orm/sqlite-core';
import { fields } from './field-schema';
+import { DatabaseDialect } from '../database';
export const data_types = sqliteTable('data_types', {
@@ -28,4 +29,12 @@ export interface DataType extends InferSelectModel {
modifiers: string | null | any;
synonyms: string | null | any;
+};
+
+
+export interface DataInsertType extends InferSelectModel {
+
+ modifiers: string[] | null | any;
+ synonyms: string[] | null | any;
+ dialect: DatabaseDialect
};
\ No newline at end of file
diff --git a/src/pages/database/database-control-buttons.tsx b/src/pages/database/database-control-buttons.tsx
index 6ba1b21..9e19868 100644
--- a/src/pages/database/database-control-buttons.tsx
+++ b/src/pages/database/database-control-buttons.tsx
@@ -4,11 +4,9 @@ import { Button, cn, Divider, Navbar } from "@heroui/react";
import { useOnViewportChange, useReactFlow } from "@xyflow/react";
import { LayoutGrid, Redo, Scan, Undo, ZoomIn, ZoomOut } from "lucide-react";
-import { useCallback, useState } from "react";
+import { useCallback, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
-
-
interface DbControlButtons {
adjustPositions: () => void,
}
@@ -16,8 +14,8 @@ interface DbControlButtons {
const ZOOM_DURATION = 100
const DatabaseControlButtons: React.FC = ({ adjustPositions }) => {
- const { zoomIn, zoomOut, fitView , getZoom} = useReactFlow();
- console.log ()
+ const { zoomIn, zoomOut, fitView, getZoom } = useReactFlow();
+
const [zoom, setZoom] = useState(
`${Math.round(getZoom() * 100)}%`
);
@@ -53,7 +51,12 @@ const DatabaseControlButtons: React.FC = ({ adjustPositions })
maxZoom: 1,
})
}, []);
-
+
+
+
+
+
+
return (
{
const { open } = useModal();
- const syncStatus = usePowerSync();
+
const { t } = useTranslation();
const { resolvedTheme } = useTheme();
// Extract database state and operations
- const { database, getField, databases, isSwitchingDatabase, isLoading, isFetching, isSyncing } = useDatabase();
+ const { database, getField, databases, isSwitchingDatabase, isLoading, currentDatabaseId } = useDatabase();
const { updateTablePositions, deleteMultiTables, deleteMultiRelationships, createRelationship } = useDatabaseOperations();
@@ -77,38 +76,36 @@ const DatabasePage: React.FC = () => {
const edgeTypes = useMemo(() => ({ 'relationship-edge': Relationship }), []);
useEffect(() => {
-
- if (isSyncing)
+ if (isLoading)
return;
-
// no database selected , open (open database) Modal
if (!database && databases?.length > 0) {
+
open(Modals.OPEN_DATABASE, {
closable: false
})
}
- else if (databases.length == 0) {
+ else if (databases.length == 0) {
// there is no databases in the first place to select from ,
// we have to create a new one .
open(Modals.CREATE_DATABASE, {
closable: false
});
- }
- }, [database?.id, isSyncing])
-
- useEffect(() => {
- if (isSwitchingDatabase) {
- setNodes([]);
- setEdges([]);
} else {
fitView({
duration: 500
});
}
- }, [isSwitchingDatabase])
+ }, [database?.id, isLoading])
+
+ useEffect(() => {
+ setNodes([]);
+ setEdges([]);
+ }, [currentDatabaseId])
// Called when a connection is made between fields
const onConnect = useCallback(async (connection: Connection) => {
+
const sourceId: string | undefined = (connection.sourceHandle as string).split("_").pop();
const targetId: string = (connection.targetHandle as string).replace(TARGET_PREFIX, "");
@@ -125,7 +122,6 @@ const DatabasePage: React.FC = () => {
targetTableId,
sourceFieldId,
targetFieldId,
-
} as RelationshipInsertType);
} else {
@@ -150,9 +146,7 @@ const DatabasePage: React.FC = () => {
const nodeRemoveChanges: NodeRemoveChange[] = changes.filter((change: NodeChange) => change.type == "remove");
// Save new positions to the database
-
if (nodePositionChanges.length > 0)
-
updateTablePositions(nodePositionChanges.map((change: NodePositionChange) => ({
id: change.id,
posX: change.position?.x,
@@ -205,11 +199,12 @@ const DatabasePage: React.FC = () => {
useHighlightedEdges(nodes, relationships, edges);
const { isOverlapping, puls } = useOverlappingTables(tables);
+
return (
{
- (isSwitchingDatabase || isLoading || !(syncStatus.currentStatus as any).options.hasSynced) &&
+ (isSwitchingDatabase || isLoading) &&
}
diff --git a/src/pages/database/db-controller/sql-preview.tsx b/src/pages/database/db-controller/sql-preview.tsx
index dae367c..8570834 100644
--- a/src/pages/database/db-controller/sql-preview.tsx
+++ b/src/pages/database/db-controller/sql-preview.tsx
@@ -23,22 +23,7 @@ interface SqlPreviewProps {
}
-
-const sqlExample : string = `
-CREATE TABLE projects (
- id INTEGER PRIMARY KEY,
- name VARCHAR(100) NOT NULL
-);
-
-CREATE TABLE tasks (
- id INTEGER PRIMARY KEY,
- title VARCHAR(100) NOT NULL,
- project_id INT,
-
- FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE RESTRICT
-);
-
-`
+
const SqlPreview: React.FC
= ({ tableFilterIds }) => {
@@ -60,13 +45,6 @@ const SqlPreview: React.FC = ({ tableFilterIds }) => {
const { t } = useTranslation();
useEffect(() => {
-
- const parser = new Parser() ;
- const ast = parser.astify(sqlExample , {
- database : "MySql"
- }) ;
-
- console.log (ast)
if (circularDependency)
addToast({
title: t("db_controller.circular_dependency.title"),
diff --git a/src/pages/database/db-controller/tables-controller/table-accordion-item/field/field-default-value.tsx b/src/pages/database/db-controller/tables-controller/table-accordion-item/field/field-default-value.tsx
index 4072a03..280742e 100644
--- a/src/pages/database/db-controller/tables-controller/table-accordion-item/field/field-default-value.tsx
+++ b/src/pages/database/db-controller/tables-controller/table-accordion-item/field/field-default-value.tsx
@@ -83,6 +83,7 @@ const fieldDefautlValue: React.FC = ({ field }) => {
multiSelect: field.type?.type == DataTypes.ENUM && field.type?.name == "set"
}
}, [field]);
+
const [selectedValues, setSelectedValues] = useState(() => {
if (!field.defaultValue)
return []
@@ -98,7 +99,6 @@ const fieldDefautlValue: React.FC = ({ field }) => {
if (field.values && field.values.length > 0) {
try {
const jsonValues: string[] = JSON.parse(field.values);
-
setValues(jsonValues);
} catch (error) {
setValues([]);
diff --git a/src/pages/database/db-controller/tables-controller/table-accordion-item/field/field-item.tsx b/src/pages/database/db-controller/tables-controller/table-accordion-item/field/field-item.tsx
index 6ae63d7..033d1f7 100644
--- a/src/pages/database/db-controller/tables-controller/table-accordion-item/field/field-item.tsx
+++ b/src/pages/database/db-controller/tables-controller/table-accordion-item/field/field-item.tsx
@@ -51,11 +51,11 @@ const FieldItem: React.FC = ({ field }) => {
} as FieldType);
}
const updateFieldType = (key: Key | null) => {
-
+
const dataType: DataType | undefined = data_types.find((dataTypes: DataType) => dataTypes.id == key);
if (!dataType)
return;
-
+
if (key != null) {
editField({
id: field.id,
diff --git a/src/pages/database/db-controller/tables-controller/table-accordion-item/index/indexes-list.tsx b/src/pages/database/db-controller/tables-controller/table-accordion-item/index/indexes-list.tsx
index b072b39..2084b0c 100644
--- a/src/pages/database/db-controller/tables-controller/table-accordion-item/index/indexes-list.tsx
+++ b/src/pages/database/db-controller/tables-controller/table-accordion-item/index/indexes-list.tsx
@@ -35,9 +35,8 @@ const IndexesList: React.FC = ({ indices, fields, tableId }) =
return (
{
- indices.map((index: IndexType) =>
)
+ indices.map((index: IndexType) =>
)
}
-