How DrawDB Handles Custom Data Types and Enumerations: A Complete Technical Guide
DrawDB treats custom data types and enumerations as first-class schema elements that can be defined, edited, and rendered just like built-in column types through a centralized registry system and React hooks.
DrawDB provides a flexible type system that allows users to extend beyond built-in column types by defining custom data types and enumerations directly within the diagram editor. According to the drawdb-io/drawdb source code, these custom definitions are managed through a combination of centralized registries, React hooks for state management, and serialization utilities that ensure round-trip safety. Understanding how DrawDB handles custom data types and enumerations reveals a well-architected system designed for extensibility and portability across different SQL dialects.
The Architecture of Custom Type Management
DrawDB implements custom data types through a layered architecture that separates the type registry from state management and persistence logic.
Central Registry in datatypes.js
The foundation of the type system resides in src/data/datatypes.js, which exports an array of objects describing every supported column type. Each object contains properties such as name, label, icon, and default options. Custom types are dynamically added to this array at runtime, maintaining the exact same shape as built-in types to ensure UI consistency.
React Hooks for Dynamic Type Handling
State management for custom types is handled by src/hooks/useTypes.js. This hook reads the central registry, merges any user-defined types stored in the diagram's metadata, and exposes immutable actions including addCustomType, removeCustomType, and updateCustomType. By using this hook, React components re-render only when the type list changes, ensuring optimal performance while keeping the UI synchronized with persisted diagram data.
Enumeration State Management
Enumerations receive specialized treatment through src/hooks/useEnums.js, which treats enums as a special category of custom type named enum. The hook provides createEnum for initialization, plus addEnumValue, updateEnumValue, and deleteEnum for manipulating the list of possible values. Enumeration definitions are serialized under a dedicated enums field in the diagram JSON, separate from standard custom types.
Defining Custom Data Types Programmatically
Adding a new custom type requires calling the addCustomType function exposed by the useTypes hook. The new type immediately appears in the column-type selector alongside native types.
import { useTypes } from '@/hooks/useTypes';
// Inside a component or utility
const { addCustomType } = useTypes();
addCustomType({
name: 'uuid',
label: 'UUID',
icon: '🔑',
default: () => 'uuid_generate_v4()',
});
This pattern demonstrates the uniform data shape principle: custom types share the same object schema as built-in types, which simplifies both UI rendering in the column selector and export logic across SQL dialects.
Managing Enumerations in DrawDB
Enumerations are created and populated through the useEnums hook, which manages the lifecycle of enum definitions from creation to value assignment.
import { useEnums } from '@/hooks/useEnums';
const { createEnum, addEnumValue, updateEnumValue, deleteEnum } = useEnums();
// Create an enum called "status"
const enumId = createEnum('status');
// Add possible values
addEnumValue(enumId, 'PENDING');
addEnumValue(enumId, 'ACTIVE');
addEnumValue(enumId, 'ARCHIVED');
Once defined, the enum appears in the column-type dropdown. When selected for a column, the enum editor component—wired through useEnums—allows users to edit the list of possible values via the dedicated UI.
Persistence and SQL Export
Custom types and enums survive the full save-reload-export cycle through specialized serialization and export utilities.
Serializing Custom Definitions
src/utils/customTypes.js contains helpers that convert custom type definitions (including enums) to and from the diagram JSON format. These functions ensure round-trip safety: when a diagram is saved locally or to a backend, the customTypes and enums fields are included in the payload. Re-opening the diagram restores the exact same definitions without information loss.
Exporting to PostgreSQL
When exporting diagrams to PostgreSQL, src/utils/exportSQL/postgres.js generates appropriate CREATE TYPE statements for enumerations using the serialization helpers.
import { exportPostgres } from '@/utils/exportSQL/postgres';
const sql = exportPostgres(diagram);
// `sql` contains statements such as:
// CREATE TYPE "status" AS ENUM ('PENDING','ACTIVE','ARCHIVED');
The export logic accesses the enum definitions stored in the diagram metadata and renders them according to PostgreSQL syntax, while other SQL dialects receive appropriate equivalent statements based on their specific type systems.
Summary
- Centralized registry:
src/data/datatypes.jsmaintains the master list of built-in and custom types with a uniform object schema. - Hooks-driven state:
useTypes.jsanduseEnums.jsexpose immutable actions that keep React components synchronized with type definitions. - First-class enumerations: Enums are managed as a distinct category with dedicated creation and value-manipulation functions.
- Round-trip persistence:
src/utils/customTypes.jsensures custom types survive save, reload, and export operations without data loss. - Dialect-aware export: SQL generators in
src/utils/exportSQL/convert enums and custom types to appropriate statements for PostgreSQL, MySQL, SQLite, and other supported databases.
Frequently Asked Questions
How does DrawDB store custom type definitions?
DrawDB stores custom type definitions within the diagram's JSON payload under the customTypes field, while enumerations are stored separately under the enums field. The serialization helpers in src/utils/customTypes.js handle conversion between the runtime registry format and the persisted JSON structure, ensuring that all type metadata—including icons, labels, and default values—is preserved when saving to local storage or remote backends.
Can enumerations be exported to all supported SQL dialects?
Yes, enumerations can be exported to all supported SQL dialects, though the generated syntax varies by database. PostgreSQL exports use CREATE TYPE ... AS ENUM (...) statements as implemented in src/utils/exportSQL/postgres.js, while MySQL and SQLite export logic may map enums to constraint checks or native enum types depending on the target dialect's capabilities. Each exporter in the src/utils/exportSQL/ directory contains dialect-specific logic for rendering custom types appropriately.
What happens to custom types when a diagram is shared or reloaded?
Custom types and enumerations remain intact during sharing and reloading operations because they are serialized as part of the diagram's metadata. When a diagram JSON is loaded, the useTypes and useEnums hooks automatically merge the persisted definitions back into the working registry. This round-trip safety guarantees that collaborators opening a shared diagram see the exact same custom type definitions and enum values as the original creator.
How do I programmatically add a custom type in DrawDB?
Programmatically adding a custom type requires importing and calling addCustomType from the useTypes hook, passing an object with name, label, icon, and default properties. The type immediately becomes available in the column-type selector throughout the application, and the change persists when the diagram is saved because the hook automatically updates the diagram's metadata store.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →