pgterra 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +166 -472
- package/dist/index.js +106644 -59
- package/package.json +53 -37
package/README.md
CHANGED
|
@@ -1,544 +1,238 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="assets/readme-hero.png" alt="Terra - Declarative PostgreSQL schema management" />
|
|
3
|
+
<br />
|
|
4
|
+
<br />
|
|
5
|
+
<a href="https://github.com/elitan/terra/blob/main/LICENSE">
|
|
6
|
+
<img alt="MIT License" src="https://img.shields.io/github/license/elitan/terra" />
|
|
7
|
+
</a>
|
|
8
|
+
<a href="https://github.com/elitan/terra/stargazers">
|
|
9
|
+
<img alt="GitHub Stars" src="https://img.shields.io/github/stars/elitan/terra?style=social" />
|
|
10
|
+
</a>
|
|
11
|
+
<br />
|
|
12
|
+
<a href="https://x.com/elitasson">
|
|
13
|
+
<img alt="Twitter Follow" src="https://img.shields.io/twitter/follow/elitasson?style=social" />
|
|
14
|
+
</a>
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
<br />
|
|
18
|
+
|
|
19
|
+
Declarative PostgreSQL schema management. Write CREATE statements, Terra generates the migrations.
|
|
20
|
+
|
|
21
|
+
## Install
|
|
2
22
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
## 🔍 Overview
|
|
6
|
-
|
|
7
|
-
PGTerra follows a declarative approach where you define your **desired database state** in a `schema.sql` file, and the tool automatically figures out what changes are needed to bring your database to that state. No more writing manual migration scripts - just describe what you want and let PGTerra handle the rest!
|
|
8
|
-
|
|
9
|
-
### Key Concepts
|
|
10
|
-
|
|
11
|
-
- **Declarative, Not Imperative**: You describe WHAT you want, not HOW to get there
|
|
12
|
-
- **State-Based Management**: Compare current vs desired state and generate minimal changes
|
|
13
|
-
- **Safety First**: Preview changes with `plan` before applying them
|
|
14
|
-
- **Idempotent Operations**: Running the same schema multiple times is safe
|
|
15
|
-
|
|
16
|
-
## 🏗️ How It Works
|
|
17
|
-
|
|
18
|
-
```mermaid
|
|
19
|
-
graph TD
|
|
20
|
-
A["schema.sql<br/>(Desired State)"] --> B["Schema Parser"]
|
|
21
|
-
C["PostgreSQL Database<br/>(Current State)"] --> D["Database Inspector"]
|
|
22
|
-
|
|
23
|
-
B --> E["Desired Schema<br/>(Parsed Objects)"]
|
|
24
|
-
D --> F["Current Schema<br/>(Queried Objects)"]
|
|
25
|
-
|
|
26
|
-
E --> G["Schema Differ"]
|
|
27
|
-
F --> G
|
|
28
|
-
|
|
29
|
-
G --> H["Migration Plan<br/>(SQL Statements)"]
|
|
30
|
-
|
|
31
|
-
H --> I{"Command Type"}
|
|
32
|
-
I -->|plan| J["Display Changes"]
|
|
33
|
-
I -->|apply| K["Execute Changes"]
|
|
34
|
-
|
|
35
|
-
K --> L["Updated Database"]
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
### Architecture Components
|
|
39
|
-
|
|
40
|
-
#### 1. **Schema Parser**
|
|
41
|
-
|
|
42
|
-
- Converts your `schema.sql` file into structured objects
|
|
43
|
-
- Uses `sql-parser-cst` for robust SQL parsing
|
|
44
|
-
- Handles CREATE TABLE statements with columns, constraints, and data types
|
|
45
|
-
|
|
46
|
-
#### 2. **Database Inspector**
|
|
47
|
-
|
|
48
|
-
- Queries the current database structure using PostgreSQL's `information_schema`
|
|
49
|
-
- Extracts table definitions, column details, constraints, and metadata
|
|
50
|
-
- Normalizes database state into the same format as parsed schema
|
|
51
|
-
|
|
52
|
-
#### 3. **Schema Differ**
|
|
53
|
-
|
|
54
|
-
- Compares desired vs current state
|
|
55
|
-
- Generates optimized migration plan with proper operation ordering
|
|
56
|
-
- Handles complex scenarios like type conversions, constraint changes, and data preservation
|
|
57
|
-
|
|
58
|
-
#### 4. **Migration Planner & Executor**
|
|
59
|
-
|
|
60
|
-
- Orchestrates the diffing process safely
|
|
61
|
-
- Executes SQL statements with proper error handling
|
|
62
|
-
- Provides detailed feedback on changes applied
|
|
63
|
-
|
|
64
|
-
## 🔄 Step-by-Step Process
|
|
65
|
-
|
|
66
|
-
```mermaid
|
|
67
|
-
sequenceDiagram
|
|
68
|
-
participant CLI as CLI Command<br/>(plan/apply)
|
|
69
|
-
participant SS as Schema Service
|
|
70
|
-
participant SP as Schema Parser
|
|
71
|
-
participant DI as Database Inspector
|
|
72
|
-
participant SD as Schema Differ
|
|
73
|
-
participant ME as Migration Executor
|
|
74
|
-
participant DB as PostgreSQL Database
|
|
75
|
-
|
|
76
|
-
CLI->>SS: plan("schema.sql")
|
|
77
|
-
SS->>SP: parseSchemaFile("schema.sql")
|
|
78
|
-
SP->>SP: Parse CREATE TABLE statements
|
|
79
|
-
SP-->>SS: Desired Schema (Table[])
|
|
80
|
-
|
|
81
|
-
SS->>DB: Connect
|
|
82
|
-
SS->>DI: getCurrentSchema(client)
|
|
83
|
-
DI->>DB: Query information_schema
|
|
84
|
-
DB-->>DI: Table metadata
|
|
85
|
-
DI-->>SS: Current Schema (Table[])
|
|
86
|
-
|
|
87
|
-
SS->>SD: generateMigrationPlan(desired, current)
|
|
88
|
-
SD->>SD: Compare schemas
|
|
89
|
-
SD->>SD: Generate SQL statements
|
|
90
|
-
SD-->>SS: Migration Plan
|
|
91
|
-
|
|
92
|
-
alt Command is "plan"
|
|
93
|
-
SS->>CLI: Display changes
|
|
94
|
-
else Command is "apply"
|
|
95
|
-
SS->>ME: executePlan(client, plan)
|
|
96
|
-
ME->>DB: Execute SQL statements
|
|
97
|
-
DB-->>ME: Success/Failure
|
|
98
|
-
ME-->>SS: Results
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
SS->>DB: Disconnect
|
|
23
|
+
```bash
|
|
24
|
+
npm install -g pgterra
|
|
102
25
|
```
|
|
103
26
|
|
|
104
|
-
##
|
|
27
|
+
## Usage
|
|
105
28
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
### Starting Point: Empty Database
|
|
109
|
-
|
|
110
|
-
```sql
|
|
111
|
-
-- Database has no tables
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
### Define Desired State: `schema.sql`
|
|
29
|
+
**1. Create schema.sql:**
|
|
115
30
|
|
|
116
31
|
```sql
|
|
117
32
|
CREATE TABLE users (
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
name VARCHAR(100) NOT NULL,
|
|
121
|
-
created_at TIMESTAMP DEFAULT NOW()
|
|
33
|
+
id SERIAL PRIMARY KEY,
|
|
34
|
+
email VARCHAR(255) NOT NULL UNIQUE
|
|
122
35
|
);
|
|
123
36
|
```
|
|
124
37
|
|
|
125
|
-
|
|
38
|
+
**2. Preview changes:**
|
|
126
39
|
|
|
127
40
|
```bash
|
|
128
|
-
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
**Output:**
|
|
132
|
-
|
|
41
|
+
terra plan
|
|
133
42
|
```
|
|
134
|
-
📋 Analyzing schema changes...
|
|
135
|
-
📝 Found 1 change(s) to apply:
|
|
136
43
|
|
|
137
|
-
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
### Apply Changes
|
|
44
|
+
**3. Apply:**
|
|
141
45
|
|
|
142
46
|
```bash
|
|
143
|
-
|
|
47
|
+
terra apply
|
|
144
48
|
```
|
|
145
49
|
|
|
146
|
-
**
|
|
147
|
-
|
|
148
|
-
## 🔄 Schema Evolution Example
|
|
149
|
-
|
|
150
|
-
Now let's modify the existing table:
|
|
151
|
-
|
|
152
|
-
### Current Database State:
|
|
50
|
+
**4. Update schema.sql:**
|
|
153
51
|
|
|
154
52
|
```sql
|
|
155
53
|
CREATE TABLE users (
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
54
|
+
id SERIAL PRIMARY KEY,
|
|
55
|
+
email VARCHAR(255) NOT NULL UNIQUE,
|
|
56
|
+
name VARCHAR(100) NOT NULL, -- added
|
|
57
|
+
active BOOLEAN DEFAULT true -- added
|
|
160
58
|
);
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
### Update Desired State: `schema.sql`
|
|
164
59
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
created_at TIMESTAMP DEFAULT NOW(),
|
|
171
|
-
is_active BOOLEAN DEFAULT true -- new column
|
|
60
|
+
CREATE TABLE posts ( -- added
|
|
61
|
+
id SERIAL PRIMARY KEY,
|
|
62
|
+
title VARCHAR(255) NOT NULL,
|
|
63
|
+
user_id INTEGER NOT NULL,
|
|
64
|
+
CONSTRAINT fk_user FOREIGN KEY (user_id) REFERENCES users(id)
|
|
172
65
|
);
|
|
173
|
-
```
|
|
174
66
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
```sql
|
|
178
|
-
ALTER TABLE users ADD COLUMN full_name VARCHAR(200) NOT NULL;
|
|
179
|
-
ALTER TABLE users ADD COLUMN is_active BOOLEAN DEFAULT true;
|
|
180
|
-
ALTER TABLE users DROP COLUMN name;
|
|
67
|
+
CREATE INDEX idx_user_email ON users (LOWER(email)); -- added
|
|
181
68
|
```
|
|
182
69
|
|
|
183
|
-
**
|
|
184
|
-
|
|
185
|
-
- Detected the new `full_name` column
|
|
186
|
-
- Added the new `is_active` column with default
|
|
187
|
-
- Removed the old `name` column
|
|
188
|
-
- Preserved all existing data
|
|
70
|
+
**5. Terra generates the ALTER statements:**
|
|
189
71
|
|
|
190
|
-
|
|
72
|
+
```bash
|
|
73
|
+
$ terra plan
|
|
74
|
+
ALTER TABLE users ADD COLUMN name VARCHAR(100) NOT NULL
|
|
75
|
+
ALTER TABLE users ADD COLUMN active BOOLEAN DEFAULT true
|
|
76
|
+
CREATE TABLE posts (...)
|
|
77
|
+
CREATE INDEX idx_user_email ON users (LOWER(email))
|
|
191
78
|
|
|
192
|
-
|
|
79
|
+
$ terra apply
|
|
80
|
+
```
|
|
193
81
|
|
|
194
|
-
|
|
82
|
+
## Configuration
|
|
195
83
|
|
|
196
|
-
|
|
197
|
-
-- Before: age VARCHAR(10)
|
|
198
|
-
-- After: age INTEGER
|
|
84
|
+
Database connection via `DATABASE_URL` or individual variables:
|
|
199
85
|
|
|
200
|
-
|
|
201
|
-
|
|
86
|
+
```bash
|
|
87
|
+
export DATABASE_URL="postgres://user:password@localhost:5432/mydb"
|
|
202
88
|
```
|
|
203
89
|
|
|
204
|
-
|
|
90
|
+
Or:
|
|
205
91
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
C --> D["Set New Default"]
|
|
213
|
-
D --> E["Add/Drop NOT NULL"]
|
|
214
|
-
|
|
215
|
-
F["Complex Example:"] --> G["VARCHAR → INTEGER<br/>with new DEFAULT"]
|
|
216
|
-
G --> H["1. DROP DEFAULT"]
|
|
217
|
-
H --> I["2. ALTER TYPE USING"]
|
|
218
|
-
I --> J["3. SET DEFAULT"]
|
|
219
|
-
J --> K["4. SET NOT NULL"]
|
|
92
|
+
```bash
|
|
93
|
+
export DB_HOST=localhost
|
|
94
|
+
export DB_PORT=5432
|
|
95
|
+
export DB_NAME=mydb
|
|
96
|
+
export DB_USER=postgres
|
|
97
|
+
export DB_PASSWORD=password
|
|
220
98
|
```
|
|
221
99
|
|
|
222
|
-
|
|
100
|
+
## What's supported
|
|
223
101
|
|
|
224
|
-
|
|
102
|
+
**Tables & Columns:**
|
|
103
|
+
All PostgreSQL column types, default values, NOT NULL constraints
|
|
225
104
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
3. Set new defaults
|
|
229
|
-
4. Modify NULL/NOT NULL constraints
|
|
105
|
+
**Functions & Procedures:**
|
|
106
|
+
User-defined functions and procedures with full PostgreSQL feature support
|
|
230
107
|
|
|
231
|
-
|
|
108
|
+
**Triggers:**
|
|
109
|
+
Table triggers with BEFORE/AFTER/INSTEAD OF timing
|
|
232
110
|
|
|
233
|
-
|
|
111
|
+
**Sequences:**
|
|
112
|
+
Custom sequences with configurable properties
|
|
234
113
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
114
|
+
**Constraints:**
|
|
115
|
+
```sql
|
|
116
|
+
-- Primary keys
|
|
117
|
+
id SERIAL PRIMARY KEY
|
|
238
118
|
|
|
239
|
-
|
|
119
|
+
-- Foreign keys with actions
|
|
120
|
+
CONSTRAINT fk_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
240
121
|
|
|
241
|
-
|
|
242
|
-
|
|
122
|
+
-- Check constraints
|
|
123
|
+
CONSTRAINT check_positive CHECK (quantity > 0)
|
|
124
|
+
|
|
125
|
+
-- Unique constraints
|
|
126
|
+
email VARCHAR(255) UNIQUE
|
|
127
|
+
CONSTRAINT unique_email UNIQUE (email, domain)
|
|
243
128
|
```
|
|
244
129
|
|
|
245
|
-
|
|
130
|
+
**Indexes:**
|
|
131
|
+
```sql
|
|
132
|
+
-- Basic
|
|
133
|
+
CREATE INDEX idx_email ON users (email);
|
|
246
134
|
|
|
247
|
-
|
|
135
|
+
-- Partial
|
|
136
|
+
CREATE INDEX idx_active_users ON users (email) WHERE active = true;
|
|
248
137
|
|
|
249
|
-
|
|
138
|
+
-- Expression
|
|
139
|
+
CREATE INDEX idx_lower_email ON users (LOWER(email));
|
|
250
140
|
|
|
251
|
-
|
|
252
|
-
bun run cli plan
|
|
141
|
+
-- Concurrent (built automatically when safe)
|
|
253
142
|
```
|
|
254
143
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
144
|
+
**ENUM types:**
|
|
145
|
+
```sql
|
|
146
|
+
CREATE TYPE status AS ENUM ('pending', 'active', 'inactive');
|
|
258
147
|
|
|
259
|
-
|
|
260
|
-
|
|
148
|
+
CREATE TABLE users (
|
|
149
|
+
id SERIAL PRIMARY KEY,
|
|
150
|
+
status status NOT NULL
|
|
151
|
+
);
|
|
261
152
|
```
|
|
262
153
|
|
|
263
|
-
|
|
154
|
+
**Views:**
|
|
155
|
+
```sql
|
|
156
|
+
CREATE VIEW active_users AS
|
|
157
|
+
SELECT id, email FROM users WHERE active = true;
|
|
264
158
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
bun run cli apply --file custom-schema.sql
|
|
159
|
+
CREATE MATERIALIZED VIEW user_stats AS
|
|
160
|
+
SELECT COUNT(*) as total FROM users;
|
|
268
161
|
```
|
|
269
162
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
"port": 5432,
|
|
279
|
-
"database": "myapp",
|
|
280
|
-
"username": "postgres",
|
|
281
|
-
"password": "password"
|
|
282
|
-
}
|
|
283
|
-
}
|
|
163
|
+
**Functions:**
|
|
164
|
+
```sql
|
|
165
|
+
CREATE FUNCTION calculate_total(quantity INT, price DECIMAL)
|
|
166
|
+
RETURNS DECIMAL
|
|
167
|
+
AS $$
|
|
168
|
+
SELECT quantity * price
|
|
169
|
+
$$
|
|
170
|
+
LANGUAGE SQL IMMUTABLE;
|
|
284
171
|
```
|
|
285
172
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
│ ├── core/
|
|
294
|
-
│ │ ├── database/ # Database connection & client
|
|
295
|
-
│ │ ├── migration/ # Migration planning & execution
|
|
296
|
-
│ │ └── schema/ # Schema parsing, inspection, diffing
|
|
297
|
-
│ ├── types/ # TypeScript type definitions
|
|
298
|
-
│ └── utils/ # Shared utilities
|
|
299
|
-
├── schema.sql # Your database schema definition
|
|
300
|
-
└── README.md
|
|
173
|
+
**Procedures:**
|
|
174
|
+
```sql
|
|
175
|
+
CREATE PROCEDURE archive_old_posts(days_old INT)
|
|
176
|
+
LANGUAGE SQL
|
|
177
|
+
AS $$
|
|
178
|
+
DELETE FROM posts WHERE created_at < NOW() - INTERVAL '1 day' * days_old;
|
|
179
|
+
$$;
|
|
301
180
|
```
|
|
302
181
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
J --> N["Check What Changed"]
|
|
330
|
-
N --> O["Data Type"]
|
|
331
|
-
N --> P["Default Value"]
|
|
332
|
-
N --> Q["Nullable"]
|
|
333
|
-
|
|
334
|
-
O --> R["ALTER COLUMN TYPE<br/>(with USING if needed)"]
|
|
335
|
-
P --> S["SET/DROP DEFAULT"]
|
|
336
|
-
Q --> T["SET/DROP NOT NULL"]
|
|
337
|
-
|
|
338
|
-
R --> U["Order Operations<br/>Carefully"]
|
|
339
|
-
S --> U
|
|
340
|
-
T --> U
|
|
341
|
-
|
|
342
|
-
U --> V["Final SQL Statements"]
|
|
182
|
+
**Triggers:**
|
|
183
|
+
```sql
|
|
184
|
+
-- First create a trigger function
|
|
185
|
+
CREATE FUNCTION update_modified_timestamp()
|
|
186
|
+
RETURNS TRIGGER
|
|
187
|
+
AS $$
|
|
188
|
+
BEGIN
|
|
189
|
+
NEW.modified_at = NOW();
|
|
190
|
+
RETURN NEW;
|
|
191
|
+
END;
|
|
192
|
+
$$
|
|
193
|
+
LANGUAGE plpgsql;
|
|
194
|
+
|
|
195
|
+
-- Then create the trigger
|
|
196
|
+
CREATE TRIGGER set_modified_timestamp
|
|
197
|
+
BEFORE UPDATE ON users
|
|
198
|
+
FOR EACH ROW
|
|
199
|
+
EXECUTE FUNCTION update_modified_timestamp();
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
**Sequences:**
|
|
203
|
+
```sql
|
|
204
|
+
CREATE SEQUENCE custom_id_seq
|
|
205
|
+
START 1000
|
|
206
|
+
INCREMENT 1
|
|
207
|
+
CACHE 20;
|
|
343
208
|
```
|
|
344
209
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
Tables and columns are represented as TypeScript interfaces:
|
|
210
|
+
## Commands
|
|
348
211
|
|
|
349
|
-
```
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
default?: string;
|
|
355
|
-
primary?: boolean;
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
interface Table {
|
|
359
|
-
name: string;
|
|
360
|
-
columns: Column[];
|
|
361
|
-
}
|
|
212
|
+
```bash
|
|
213
|
+
terra plan # Preview changes
|
|
214
|
+
terra plan -f custom.sql # Use custom schema file
|
|
215
|
+
terra apply # Apply changes
|
|
216
|
+
terra apply -f custom.sql # Apply from custom file
|
|
362
217
|
```
|
|
363
218
|
|
|
364
|
-
##
|
|
365
|
-
|
|
366
|
-
```mermaid
|
|
367
|
-
graph LR
|
|
368
|
-
A["Declarative<br/>Approach"] --> B["You describe<br/>WHAT you want"]
|
|
369
|
-
B --> C["Tool figures out<br/>HOW to get there"]
|
|
219
|
+
## Development
|
|
370
220
|
|
|
371
|
-
|
|
372
|
-
E --> F["Generate minimal<br/>change set"]
|
|
221
|
+
Requires [Bun](https://bun.sh):
|
|
373
222
|
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
## 🚦 Current Status & Roadmap
|
|
379
|
-
|
|
380
|
-
### ✅ **Implemented Features**
|
|
223
|
+
```bash
|
|
224
|
+
git clone https://github.com/elitan/terra.git
|
|
225
|
+
cd terra
|
|
226
|
+
bun install
|
|
381
227
|
|
|
382
|
-
|
|
228
|
+
# Start test database
|
|
229
|
+
docker compose up -d
|
|
383
230
|
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
231
|
+
# Run tests
|
|
232
|
+
export DATABASE_URL="postgres://test_user:test_password@localhost:5487/sql_terraform_test"
|
|
233
|
+
bun test
|
|
234
|
+
```
|
|
387
235
|
|
|
388
|
-
|
|
236
|
+
## License
|
|
389
237
|
|
|
390
|
-
|
|
391
|
-
- ✅ **Column Removal** - Remove columns while preserving data
|
|
392
|
-
- ✅ **Column Type Changes** - Convert between compatible data types
|
|
393
|
-
- ✅ **Default Values** - Handle columns with default values and constraints
|
|
394
|
-
- ✅ **Nullable Constraints** - Manage NOT NULL/NULL constraints
|
|
395
|
-
|
|
396
|
-
#### **Advanced Type Conversions**
|
|
397
|
-
|
|
398
|
-
- ✅ **String Type Conversions** - VARCHAR ↔ TEXT with length handling
|
|
399
|
-
- ✅ **Numeric Type Conversions** - INTEGER ↔ BIGINT, DECIMAL precision changes
|
|
400
|
-
- ✅ **Boolean Type Conversions** - All PostgreSQL boolean representations
|
|
401
|
-
- ✅ **Smart USING Clauses** - Automatic type conversion logic
|
|
402
|
-
- ✅ **Unicode Support** - Full Unicode, emoji, and multi-byte character handling
|
|
403
|
-
|
|
404
|
-
#### **Data Integrity & Safety**
|
|
405
|
-
|
|
406
|
-
- ✅ **Data Preservation** - All migrations preserve existing data
|
|
407
|
-
- ✅ **Operation Ordering** - Smart ordering to avoid constraint conflicts
|
|
408
|
-
- ✅ **Boundary Value Testing** - Edge cases for all data types
|
|
409
|
-
- ✅ **Large Dataset Support** - Performance-tested with large tables
|
|
410
|
-
|
|
411
|
-
#### **Performance & Reliability**
|
|
412
|
-
|
|
413
|
-
- ✅ **Performance Monitoring** - Benchmark tracking and regression detection
|
|
414
|
-
- ✅ **Concurrent Operations** - Lock management and concurrent access
|
|
415
|
-
- ✅ **Memory Efficiency** - Optimized for large datasets
|
|
416
|
-
- ✅ **Error Handling** - Graceful handling of edge cases and failures
|
|
417
|
-
|
|
418
|
-
#### **CLI & Tooling**
|
|
419
|
-
|
|
420
|
-
- ✅ **Plan Command** - Preview changes before applying
|
|
421
|
-
- ✅ **Apply Command** - Execute migrations safely
|
|
422
|
-
- ✅ **Schema File Support** - Custom schema file paths
|
|
423
|
-
- ✅ **Database Configuration** - Connection management
|
|
424
|
-
- ✅ **Comprehensive Testing** - 20+ test suites covering edge cases
|
|
425
|
-
|
|
426
|
-
### 🔄 **In Progress**
|
|
427
|
-
|
|
428
|
-
#### **Primary Key Support**
|
|
429
|
-
|
|
430
|
-
- 🔄 **Primary Key Detection** - Currently handles SERIAL PRIMARY KEY
|
|
431
|
-
- 🔄 **Composite Primary Keys** - Multi-column primary keys
|
|
432
|
-
- 🔄 **Primary Key Changes** - Adding/removing/modifying primary keys
|
|
433
|
-
|
|
434
|
-
### 📋 **Planned Features**
|
|
435
|
-
|
|
436
|
-
#### **Core Schema Objects**
|
|
437
|
-
|
|
438
|
-
- [ ] **Indexes**
|
|
439
|
-
- B-tree, GIN, GiST, BRIN, Hash indexes
|
|
440
|
-
- Unique, partial, expression indexes
|
|
441
|
-
- Concurrent creation and REINDEX operations
|
|
442
|
-
- [ ] **Advanced Constraints**
|
|
443
|
-
- Foreign Keys with CASCADE/RESTRICT/SET NULL actions
|
|
444
|
-
- Unique Constraints (multi-column)
|
|
445
|
-
- Check Constraints with custom expressions
|
|
446
|
-
- DEFERRABLE constraints
|
|
447
|
-
|
|
448
|
-
#### **Advanced PostgreSQL Features**
|
|
449
|
-
|
|
450
|
-
- [ ] **Sequences**
|
|
451
|
-
- Custom sequences with start/increment/min/max
|
|
452
|
-
- Sequence ownership and dependencies
|
|
453
|
-
- [ ] **Views & Materialized Views**
|
|
454
|
-
- Standard view creation and OR REPLACE
|
|
455
|
-
- Materialized view management and refresh
|
|
456
|
-
- [ ] **Custom Types**
|
|
457
|
-
- ENUMs with value management
|
|
458
|
-
- Composite Types for complex data structures
|
|
459
|
-
- Domain types with constraints
|
|
460
|
-
|
|
461
|
-
#### **Functions & Triggers**
|
|
462
|
-
|
|
463
|
-
- [ ] **Stored Functions/Procedures**
|
|
464
|
-
- PL/pgSQL and SQL functions
|
|
465
|
-
- Parameter and return type management
|
|
466
|
-
- Function versioning (OR REPLACE)
|
|
467
|
-
- [ ] **Triggers**
|
|
468
|
-
- BEFORE/AFTER/INSTEAD OF triggers
|
|
469
|
-
- Row-level and statement-level triggers
|
|
470
|
-
- Trigger enabling/disabling
|
|
471
|
-
|
|
472
|
-
#### **Database Administration**
|
|
473
|
-
|
|
474
|
-
- [ ] **Extensions**
|
|
475
|
-
- Enable/disable PostgreSQL extensions
|
|
476
|
-
- Extension version management
|
|
477
|
-
- [ ] **Roles & Security**
|
|
478
|
-
- User and role management
|
|
479
|
-
- Permission grants and revokes
|
|
480
|
-
- Role membership hierarchy
|
|
481
|
-
- [ ] **Schema Namespaces**
|
|
482
|
-
- Multi-schema support
|
|
483
|
-
- Schema ownership and search paths
|
|
484
|
-
- [ ] **Tablespaces**
|
|
485
|
-
- Custom tablespace management
|
|
486
|
-
- Table and index tablespace assignment
|
|
487
|
-
|
|
488
|
-
#### **Enhanced Features**
|
|
489
|
-
|
|
490
|
-
- [ ] **Comments & Documentation**
|
|
491
|
-
- Object-level comments and descriptions
|
|
492
|
-
- Schema documentation generation
|
|
493
|
-
- [ ] **Advanced Rules**
|
|
494
|
-
- Query rewrite rules
|
|
495
|
-
- Rule creation and management
|
|
496
|
-
- [ ] **Event Triggers**
|
|
497
|
-
- DDL event triggers
|
|
498
|
-
- Database-level event handling
|
|
499
|
-
|
|
500
|
-
#### **Tooling & DevEx Improvements**
|
|
501
|
-
|
|
502
|
-
- [ ] **Configuration Management**
|
|
503
|
-
- Multiple environment support
|
|
504
|
-
- Configuration file formats (JSON/YAML)
|
|
505
|
-
- [ ] **Migration History**
|
|
506
|
-
- Track applied migrations
|
|
507
|
-
- Rollback capabilities
|
|
508
|
-
- [ ] **Schema Validation**
|
|
509
|
-
- Pre-migration validation
|
|
510
|
-
- Dependency checking
|
|
511
|
-
- [ ] **Import/Export**
|
|
512
|
-
- Import from existing databases
|
|
513
|
-
- Export current schema to files
|
|
514
|
-
|
|
515
|
-
### 📊 **Current Test Coverage**
|
|
516
|
-
|
|
517
|
-
The project has comprehensive test coverage with **20+ test suites** covering:
|
|
518
|
-
|
|
519
|
-
- **Table Operations**: 6 core scenarios
|
|
520
|
-
- **Column Operations**: 15+ test suites
|
|
521
|
-
- **Type Conversions**: String, Numeric, Boolean edge cases
|
|
522
|
-
- **Performance Testing**: Large datasets, concurrent operations
|
|
523
|
-
- **Unicode Support**: Emoji, multi-byte characters, escape sequences
|
|
524
|
-
- **Data Integrity**: Boundary values, NULL handling, constraint management
|
|
525
|
-
|
|
526
|
-
### 🎯 **Next Milestones**
|
|
527
|
-
|
|
528
|
-
**v0.2.0 - Primary Key & Index Support**
|
|
529
|
-
|
|
530
|
-
- Complete primary key constraint management
|
|
531
|
-
- Basic index creation and management
|
|
532
|
-
- Performance improvements for large schemas
|
|
533
|
-
|
|
534
|
-
**v0.3.0 - Foreign Keys & Advanced Constraints**
|
|
535
|
-
|
|
536
|
-
- Foreign key relationships with actions
|
|
537
|
-
- Unique and check constraints
|
|
538
|
-
- Constraint dependency resolution
|
|
539
|
-
|
|
540
|
-
**v0.4.0 - Views & Functions**
|
|
541
|
-
|
|
542
|
-
- Standard and materialized views
|
|
543
|
-
- Basic stored function support
|
|
544
|
-
- Enhanced schema validation
|
|
238
|
+
MIT
|