pgterra 0.1.2 → 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.
Files changed (4) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +179 -50
  3. package/dist/index.js +8256 -2292
  4. package/package.json +11 -7
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Terra Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,69 +1,93 @@
1
- # pgterra
2
-
3
- Declarative schema management for Postgres. Define your desired schema, pgterra handles the migrations.
4
-
5
- ## Quick Start
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
6
22
 
7
23
  ```bash
8
24
  npm install -g pgterra
9
25
  ```
10
26
 
11
- ## How it works
27
+ ## Usage
12
28
 
13
- **1. Start with a schema:**
29
+ **1. Create schema.sql:**
14
30
 
15
31
  ```sql
16
- -- schema.sql
17
32
  CREATE TABLE users (
18
33
  id SERIAL PRIMARY KEY,
19
- email VARCHAR(255) NOT NULL UNIQUE,
20
- created_at TIMESTAMP DEFAULT NOW()
34
+ email VARCHAR(255) NOT NULL UNIQUE
21
35
  );
22
36
  ```
23
37
 
38
+ **2. Preview changes:**
39
+
40
+ ```bash
41
+ terra plan
42
+ ```
43
+
44
+ **3. Apply:**
45
+
24
46
  ```bash
25
- pgterra apply # Creates the table
47
+ terra apply
26
48
  ```
27
49
 
28
- **2. Update your schema declaratively:**
50
+ **4. Update schema.sql:**
29
51
 
30
52
  ```sql
31
- -- schema.sql
32
53
  CREATE TABLE users (
33
54
  id SERIAL PRIMARY KEY,
34
55
  email VARCHAR(255) NOT NULL UNIQUE,
35
- full_name VARCHAR(200) NOT NULL, -- new column
36
- is_active BOOLEAN DEFAULT true, -- another new column
37
- created_at TIMESTAMP DEFAULT NOW()
56
+ name VARCHAR(100) NOT NULL, -- added
57
+ active BOOLEAN DEFAULT true -- added
38
58
  );
39
59
 
40
- CREATE TABLE posts ( -- new table
60
+ CREATE TABLE posts ( -- added
41
61
  id SERIAL PRIMARY KEY,
42
62
  title VARCHAR(255) NOT NULL,
43
- user_id INTEGER REFERENCES users(id),
44
- created_at TIMESTAMP DEFAULT NOW()
63
+ user_id INTEGER NOT NULL,
64
+ CONSTRAINT fk_user FOREIGN KEY (user_id) REFERENCES users(id)
45
65
  );
66
+
67
+ CREATE INDEX idx_user_email ON users (LOWER(email)); -- added
46
68
  ```
47
69
 
48
- **3. pgterra calculates the migration:**
70
+ **5. Terra generates the ALTER statements:**
49
71
 
50
72
  ```bash
51
- $ pgterra plan
52
- 📋 Analyzing schema changes...
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))
53
78
 
54
- Planned changes:
55
- 1. ALTER TABLE users ADD COLUMN full_name VARCHAR(200) NOT NULL
56
- 2. ALTER TABLE users ADD COLUMN is_active BOOLEAN DEFAULT true
57
- 3. CREATE TABLE posts (id SERIAL PRIMARY KEY, title VARCHAR(255) NOT NULL, user_id INTEGER REFERENCES users(id), created_at TIMESTAMP DEFAULT NOW())
58
-
59
- $ pgterra apply # Applies the changes safely
79
+ $ terra apply
60
80
  ```
61
81
 
62
- **That's it.** No migration files, no manual ALTER statements, no dependency ordering. Just define what you want.
63
-
64
82
  ## Configuration
65
83
 
66
- Set your database connection:
84
+ Database connection via `DATABASE_URL` or individual variables:
85
+
86
+ ```bash
87
+ export DATABASE_URL="postgres://user:password@localhost:5432/mydb"
88
+ ```
89
+
90
+ Or:
67
91
 
68
92
  ```bash
69
93
  export DB_HOST=localhost
@@ -73,37 +97,142 @@ export DB_USER=postgres
73
97
  export DB_PASSWORD=password
74
98
  ```
75
99
 
76
- ## Features
100
+ ## What's supported
101
+
102
+ **Tables & Columns:**
103
+ All PostgreSQL column types, default values, NOT NULL constraints
104
+
105
+ **Functions & Procedures:**
106
+ User-defined functions and procedures with full PostgreSQL feature support
107
+
108
+ **Triggers:**
109
+ Table triggers with BEFORE/AFTER/INSTEAD OF timing
110
+
111
+ **Sequences:**
112
+ Custom sequences with configurable properties
113
+
114
+ **Constraints:**
115
+ ```sql
116
+ -- Primary keys
117
+ id SERIAL PRIMARY KEY
118
+
119
+ -- Foreign keys with actions
120
+ CONSTRAINT fk_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
121
+
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)
128
+ ```
129
+
130
+ **Indexes:**
131
+ ```sql
132
+ -- Basic
133
+ CREATE INDEX idx_email ON users (email);
134
+
135
+ -- Partial
136
+ CREATE INDEX idx_active_users ON users (email) WHERE active = true;
137
+
138
+ -- Expression
139
+ CREATE INDEX idx_lower_email ON users (LOWER(email));
140
+
141
+ -- Concurrent (built automatically when safe)
142
+ ```
143
+
144
+ **ENUM types:**
145
+ ```sql
146
+ CREATE TYPE status AS ENUM ('pending', 'active', 'inactive');
147
+
148
+ CREATE TABLE users (
149
+ id SERIAL PRIMARY KEY,
150
+ status status NOT NULL
151
+ );
152
+ ```
153
+
154
+ **Views:**
155
+ ```sql
156
+ CREATE VIEW active_users AS
157
+ SELECT id, email FROM users WHERE active = true;
158
+
159
+ CREATE MATERIALIZED VIEW user_stats AS
160
+ SELECT COUNT(*) as total FROM users;
161
+ ```
162
+
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;
171
+ ```
77
172
 
78
- - ✅ Tables, columns, and data types
79
- - ✅ Primary keys, foreign keys, check constraints, unique constraints
80
- - Indexes (btree, gin, gist, partial, expression-based)
81
- - ✅ ENUM types
82
- - ✅ Dependency resolution for complex schemas
83
- - Data-safe migrations with validation
84
- - ✅ Destructive operation protection
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
+ $$;
180
+ ```
181
+
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
+ ```
85
201
 
86
- ## Why declarative?
202
+ **Sequences:**
203
+ ```sql
204
+ CREATE SEQUENCE custom_id_seq
205
+ START 1000
206
+ INCREMENT 1
207
+ CACHE 20;
208
+ ```
87
209
 
88
- Like Terraform for infrastructure, pgterra lets you define *what* you want, not *how* to get there:
210
+ ## Commands
89
211
 
90
- - **Version control your complete schema** - not scattered migration files
91
- - **No migration ordering issues** - pgterra handles dependencies
92
- - **Easier code reviews** - see the full schema state, not just changes
93
- - **Safe schema changes** - preview before applying, with rollback support
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
217
+ ```
94
218
 
95
219
  ## Development
96
220
 
221
+ Requires [Bun](https://bun.sh):
222
+
97
223
  ```bash
98
- git clone https://github.com/elitan/pgterra.git
99
- cd pgterra
224
+ git clone https://github.com/elitan/terra.git
225
+ cd terra
100
226
  bun install
101
227
 
102
- # Set up test database connection
103
- export DATABASE_URL="postgres://user:password@localhost:5432/test_db"
228
+ # Start test database
229
+ docker compose up -d
104
230
 
105
231
  # Run tests
232
+ export DATABASE_URL="postgres://test_user:test_password@localhost:5487/sql_terraform_test"
106
233
  bun test
107
234
  ```
108
235
 
109
- **Note:** Tests require a `DATABASE_URL` environment variable pointing to a PostgreSQL database. The tests will create and drop tables as needed, so use a dedicated test database.
236
+ ## License
237
+
238
+ MIT