Skip to content

Commit 59cf539

Browse files
committed
feat(stores): add PostgreSQL store and update store comparisons; remove Bun store
1 parent 47f5663 commit 59cf539

8 files changed

Lines changed: 120 additions & 151 deletions

File tree

docs/content/docs/guides/full-example.mdx

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,25 +26,36 @@ The example lives inside the Ctrl Plane module, so no separate `go.mod` is neede
2626

2727
## Step 1: Store selection
2828

29-
The example supports all four store backends via a single environment variable:
29+
The example supports all five store backends via a single environment variable:
3030

3131
```go
3232
func initStore(storeType string) (store.Store, error) {
3333
switch strings.ToLower(storeType) {
34-
case "bun":
35-
return bunstore.New(bunstore.Config{
36-
Driver: bunstore.Driver(envOrDefault("CP_BUN_DRIVER", "postgres")),
37-
DSN: envOrDefault("CP_BUN_DSN", "..."),
38-
})
34+
case "postgres":
35+
db, err := grove.Open(pgdriver.Open(envOrDefault("CP_PG_DSN", "postgres://localhost:5432/ctrlplane?sslmode=disable")))
36+
if err != nil {
37+
return nil, err
38+
}
39+
return pgstore.New(db), nil
40+
case "sqlite":
41+
db, err := grove.Open(sqlitedriver.Open(envOrDefault("CP_SQLITE_PATH", "ctrlplane.db")))
42+
if err != nil {
43+
return nil, err
44+
}
45+
return sqlitestore.New(db), nil
3946
case "badger":
4047
return badger.New(badger.Config{
4148
Path: envOrDefault("CP_BADGER_PATH", "./data/badger"),
4249
})
4350
case "mongo":
44-
return mongo.New(mongo.Config{
45-
URI: envOrDefault("CP_MONGO_URI", "mongodb://localhost:27017"),
46-
Database: envOrDefault("CP_MONGO_DATABASE", "ctrlplane"),
47-
})
51+
db, err := grove.Open(mongodriver.Open(
52+
envOrDefault("CP_MONGO_URI", "mongodb://localhost:27017"),
53+
envOrDefault("CP_MONGO_DATABASE", "ctrlplane"),
54+
))
55+
if err != nil {
56+
return nil, err
57+
}
58+
return mongostore.New(db), nil
4859
case "memory", "":
4960
return memory.New(), nil
5061
}
@@ -58,7 +69,7 @@ dataStore.Migrate(ctx)
5869
dataStore.Ping(ctx)
5970
```
6071

61-
See the [Memory](/docs/stores/memory), [Badger](/docs/stores/badger), [Bun](/docs/stores/bun), and [MongoDB](/docs/stores/mongo) store pages for configuration details.
72+
See the [Memory](/docs/stores/memory), [Badger](/docs/stores/badger), [PostgreSQL](/docs/stores/postgres), [SQLite](/docs/stores/sqlite), and [MongoDB](/docs/stores/mongo) store pages for configuration details.
6273

6374
## Step 2: Forge application
6475

@@ -190,8 +201,8 @@ go run ./examples/saas-platform
190201
### PostgreSQL
191202

192203
```bash
193-
CP_STORE=bun \
194-
CP_BUN_DSN="postgres://user:pass@localhost:5432/ctrlplane?sslmode=disable" \
204+
CP_STORE=postgres \
205+
CP_PG_DSN="postgres://user:pass@localhost:5432/ctrlplane?sslmode=disable" \
195206
go run ./examples/saas-platform
196207
```
197208

docs/content/docs/stores/badger.mdx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,10 @@ Secondary indexes use additional prefixes (`islg:` for instance slugs, `tslg:` f
8585

8686
## Comparison
8787

88-
| Feature | Memory | Badger | Bun | MongoDB |
89-
|---------|--------|--------|-----|---------|
90-
| Setup | None | Path only | DSN | URI |
91-
| Persistence | No | Yes | Yes | Yes |
92-
| Multi-process | No | No | Yes | Yes |
93-
| Query flexibility | Low | Low | High | High |
94-
| Best for | Tests | Embedded | Production SQL | Production NoSQL |
88+
| Feature | Memory | Badger | PostgreSQL | SQLite | MongoDB |
89+
|---------|--------|--------|------------|--------|---------|
90+
| Setup | None | Path only | DSN | File path | URI |
91+
| Persistence | No | Yes | Yes | Yes | Yes |
92+
| Multi-process | No | No | Yes | No | Yes |
93+
| Query flexibility | Low | Low | High | Medium | High |
94+
| Best for | Tests | Embedded KV | Production SQL | Embedded SQL | Production NoSQL |

docs/content/docs/stores/bun.mdx

Lines changed: 0 additions & 110 deletions
This file was deleted.

docs/content/docs/stores/memory.mdx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,10 @@ Secrets use a composite key `instanceID:key` for direct lookup by instance and k
6464

6565
## Comparison
6666

67-
| Feature | Memory | Badger | Bun | MongoDB |
68-
|---------|--------|--------|-----|---------|
69-
| Setup | None | Path only | DSN | URI |
70-
| Persistence | No | Yes | Yes | Yes |
71-
| Multi-process | No | No | Yes | Yes |
72-
| Query flexibility | Low | Low | High | High |
73-
| Best for | Tests | Embedded | Production SQL | Production NoSQL |
67+
| Feature | Memory | Badger | PostgreSQL | SQLite | MongoDB |
68+
|---------|--------|--------|------------|--------|---------|
69+
| Setup | None | Path only | DSN | File path | URI |
70+
| Persistence | No | Yes | Yes | Yes | Yes |
71+
| Multi-process | No | No | Yes | No | Yes |
72+
| Query flexibility | Low | Low | High | Medium | High |
73+
| Best for | Tests | Embedded KV | Production SQL | Embedded SQL | Production NoSQL |

docs/content/docs/stores/meta.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
22
"title": "Stores",
3-
"pages": ["memory", "badger", "bun", "sqlite", "mongo"]
3+
"pages": ["memory", "badger", "postgres", "sqlite", "mongo"]
44
}

docs/content/docs/stores/mongo.mdx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,11 @@ The MongoDB store uses 15 collections:
9393

9494
## Comparison
9595

96-
| Feature | Memory | Badger | SQLite | Bun (PostgreSQL) | MongoDB |
97-
|---------|--------|--------|--------|-------------------|---------|
98-
| Setup | None | Path only | File path | DSN | URI |
96+
| Feature | Memory | Badger | PostgreSQL | SQLite | MongoDB |
97+
|---------|--------|--------|------------|--------|---------|
98+
| Setup | None | Path only | DSN | File path | URI |
9999
| Persistence | No | Yes | Yes | Yes | Yes |
100-
| Multi-process | No | No | No | Yes | Yes |
101-
| Query flexibility | Low | Low | Medium | High | High |
102-
| Horizontal scaling | No | No | No | Read replicas | Sharding |
103-
| Best for | Tests | Embedded KV | Embedded SQL | Production SQL | Production NoSQL |
100+
| Multi-process | No | No | Yes | No | Yes |
101+
| Query flexibility | Low | Low | High | Medium | High |
102+
| Horizontal scaling | No | No | Read replicas | No | Sharding |
103+
| Best for | Tests | Embedded KV | Production SQL | Embedded SQL | Production NoSQL |
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
---
2+
title: PostgreSQL Store
3+
description: Production-grade PostgreSQL store using Grove ORM with pgdriver.
4+
---
5+
6+
The PostgreSQL store (`store/postgres`) uses the [Grove ORM](https://github.com/xraph/grove) with `pgdriver` to persist data in PostgreSQL. It is the recommended store for production SQL deployments.
7+
8+
## When to use
9+
10+
- **Production deployments** -- battle-tested SQL database with ACID transactions.
11+
- **PostgreSQL environments** -- full query power, JSON operators, CTEs.
12+
- **Multi-instance services** -- shared database for horizontal scaling.
13+
- **Teams familiar with SQL** -- leverage existing database expertise.
14+
15+
## Configuration
16+
17+
```go
18+
import (
19+
"github.com/xraph/grove"
20+
"github.com/xraph/grove/drivers/pgdriver"
21+
"github.com/xraph/ctrlplane/store/postgres"
22+
)
23+
24+
db, err := grove.Open(pgdriver.Open("postgres://user:pass@localhost:5432/ctrlplane?sslmode=disable"))
25+
if err != nil {
26+
log.Fatal(err)
27+
}
28+
29+
s := postgres.New(db)
30+
if err := s.Migrate(ctx); err != nil {
31+
log.Fatal(err)
32+
}
33+
```
34+
35+
### With the app
36+
37+
```go
38+
cp, err := app.New(
39+
app.WithStore(s),
40+
)
41+
```
42+
43+
## Internals
44+
45+
| Aspect | Detail |
46+
|--------|--------|
47+
| **Driver** | Grove ORM with `pgdriver` (PostgreSQL) |
48+
| **Migrations** | Grove migration orchestrator with programmatic migrations |
49+
| **Transactions** | PostgreSQL-level ACID transactions |
50+
| **Concurrency** | Full MVCC with row-level locking |
51+
| **Migrate** | Creates tables, indexes, constraints |
52+
| **Ping** | `db.Ping(ctx)` |
53+
| **Close** | Closes the database connection |
54+
55+
## Limitations
56+
57+
- **External dependency** -- requires a running PostgreSQL instance.
58+
- **Schema migrations** -- must run `Migrate()` before first use.
59+
60+
## Comparison
61+
62+
| Feature | Memory | Badger | PostgreSQL | SQLite | MongoDB |
63+
|---------|--------|--------|------------|--------|---------|
64+
| Setup | None | Path only | DSN | File path | URI |
65+
| Persistence | No | Yes | Yes | Yes | Yes |
66+
| Multi-process | No | No | Yes | No | Yes |
67+
| Query flexibility | Low | Low | High | Medium | High |
68+
| Best for | Tests | Embedded KV | Production SQL | Embedded SQL | Production NoSQL |

docs/content/docs/stores/sqlite.mdx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,10 @@ cp, err := app.New(
5757

5858
## Comparison
5959

60-
| Feature | Memory | Badger | SQLite | Bun (PostgreSQL) | MongoDB |
61-
|---------|--------|--------|--------|-------------------|---------|
62-
| Setup | None | Path only | File path | DSN | URI |
60+
| Feature | Memory | Badger | PostgreSQL | SQLite | MongoDB |
61+
|---------|--------|--------|------------|--------|---------|
62+
| Setup | None | Path only | DSN | File path | URI |
6363
| Persistence | No | Yes | Yes | Yes | Yes |
64-
| Multi-process | No | No | No | Yes | Yes |
65-
| Query flexibility | Low | Low | Medium | High | High |
66-
| Best for | Tests | Embedded KV | Embedded SQL | Production SQL | Production NoSQL |
64+
| Multi-process | No | No | Yes | No | Yes |
65+
| Query flexibility | Low | Low | High | Medium | High |
66+
| Best for | Tests | Embedded KV | Production SQL | Embedded SQL | Production NoSQL |

0 commit comments

Comments
 (0)