spindb 0.4.1 → 0.5.2
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/README.md +77 -100
- package/cli/commands/clone.ts +3 -1
- package/cli/commands/connect.ts +50 -24
- package/cli/commands/create.ts +237 -156
- package/cli/commands/delete.ts +3 -1
- package/cli/commands/list.ts +14 -3
- package/cli/commands/menu.ts +103 -46
- package/cli/commands/restore.ts +56 -19
- package/cli/commands/start.ts +30 -4
- package/cli/commands/stop.ts +3 -1
- package/cli/ui/prompts.ts +94 -31
- package/config/defaults.ts +40 -15
- package/config/engine-defaults.ts +84 -0
- package/config/os-dependencies.ts +68 -19
- package/config/paths.ts +77 -22
- package/core/binary-manager.ts +30 -5
- package/core/container-manager.ts +124 -60
- package/core/port-manager.ts +42 -31
- package/core/process-manager.ts +14 -6
- package/engines/index.ts +7 -2
- package/engines/mysql/binary-detection.ts +248 -0
- package/engines/mysql/index.ts +699 -0
- package/engines/postgresql/index.ts +13 -6
- package/package.json +4 -2
- package/types/index.ts +29 -5
package/README.md
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
# SpinDB
|
|
2
2
|
|
|
3
|
-
Spin up local PostgreSQL databases without Docker. A lightweight alternative to DBngin.
|
|
3
|
+
Spin up local PostgreSQL and MySQL databases without Docker. A lightweight alternative to DBngin.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
- **No Docker required** - Downloads
|
|
8
|
-
- **Multiple
|
|
7
|
+
- **No Docker required** - Downloads PostgreSQL binaries directly, uses system MySQL
|
|
8
|
+
- **Multiple engines** - PostgreSQL and MySQL support
|
|
9
|
+
- **Multiple containers** - Run multiple isolated database instances on different ports
|
|
9
10
|
- **Interactive menu** - Arrow-key navigation for all operations
|
|
10
11
|
- **Auto port management** - Automatically finds available ports
|
|
11
12
|
- **Clone containers** - Duplicate databases with all data
|
|
12
|
-
- **Backup restore** - Restore pg_dump backups
|
|
13
|
+
- **Backup restore** - Restore pg_dump/mysqldump backups
|
|
13
14
|
- **Custom database names** - Specify database name separate from container name
|
|
14
15
|
- **Engine management** - View installed PostgreSQL versions and free up disk space
|
|
15
|
-
- **Dynamic version selection** - Fetches
|
|
16
|
+
- **Dynamic version selection** - Fetches available PostgreSQL versions from Maven Central
|
|
16
17
|
|
|
17
18
|
## Installation
|
|
18
19
|
|
|
@@ -31,7 +32,8 @@ pnpm add -g spindb
|
|
|
31
32
|
spindb
|
|
32
33
|
|
|
33
34
|
# Or use commands directly
|
|
34
|
-
spindb create mydb
|
|
35
|
+
spindb create mydb # PostgreSQL (default)
|
|
36
|
+
spindb create mydb --engine mysql # MySQL
|
|
35
37
|
spindb list
|
|
36
38
|
spindb connect mydb
|
|
37
39
|
```
|
|
@@ -45,61 +47,71 @@ spindb connect mydb
|
|
|
45
47
|
| `spindb list` | List all containers |
|
|
46
48
|
| `spindb start [name]` | Start a container |
|
|
47
49
|
| `spindb stop [name]` | Stop a container |
|
|
48
|
-
| `spindb connect [name]` | Connect with psql |
|
|
50
|
+
| `spindb connect [name]` | Connect with psql/mysql shell |
|
|
49
51
|
| `spindb restore [name] [backup]` | Restore a backup file |
|
|
50
52
|
| `spindb clone [source] [target]` | Clone a container |
|
|
51
53
|
| `spindb delete [name]` | Delete a container |
|
|
52
54
|
| `spindb config show` | Show configuration |
|
|
53
|
-
| `spindb config detect` | Auto-detect
|
|
55
|
+
| `spindb config detect` | Auto-detect database tools |
|
|
54
56
|
| `spindb deps check` | Check status of client tools |
|
|
55
57
|
| `spindb deps install` | Install missing client tools |
|
|
56
58
|
|
|
57
|
-
##
|
|
59
|
+
## Supported Engines
|
|
60
|
+
|
|
61
|
+
### PostgreSQL 🐘
|
|
62
|
+
|
|
63
|
+
- Downloads binaries from [zonky.io](https://github.com/zonkyio/embedded-postgres-binaries)
|
|
64
|
+
- Versions: 14, 15, 16, 17
|
|
65
|
+
- Requires system client tools (psql, pg_dump, pg_restore) for some operations
|
|
58
66
|
|
|
59
|
-
|
|
67
|
+
### MySQL 🐬
|
|
68
|
+
|
|
69
|
+
- Uses system-installed MySQL (via Homebrew, apt, etc.)
|
|
70
|
+
- Version determined by system installation
|
|
71
|
+
- Requires: mysqld, mysql, mysqldump, mysqladmin
|
|
72
|
+
|
|
73
|
+
## How It Works
|
|
60
74
|
|
|
61
75
|
Data is stored in `~/.spindb/`:
|
|
62
76
|
```
|
|
63
77
|
~/.spindb/
|
|
64
|
-
├── bin/
|
|
65
|
-
│ └── postgresql-
|
|
66
|
-
├── containers/
|
|
67
|
-
│
|
|
68
|
-
│
|
|
69
|
-
│ ├──
|
|
70
|
-
│
|
|
71
|
-
└──
|
|
78
|
+
├── bin/ # PostgreSQL server binaries
|
|
79
|
+
│ └── postgresql-17-darwin-arm64/
|
|
80
|
+
├── containers/
|
|
81
|
+
│ ├── postgresql/ # PostgreSQL containers
|
|
82
|
+
│ │ └── mydb/
|
|
83
|
+
│ │ ├── container.json
|
|
84
|
+
│ │ ├── data/
|
|
85
|
+
│ │ └── postgres.log
|
|
86
|
+
│ └── mysql/ # MySQL containers
|
|
87
|
+
│ └── mydb/
|
|
88
|
+
│ ├── container.json
|
|
89
|
+
│ ├── data/
|
|
90
|
+
│ └── mysql.log
|
|
91
|
+
└── config.json
|
|
72
92
|
```
|
|
73
93
|
|
|
74
|
-
##
|
|
94
|
+
## Client Tools
|
|
75
95
|
|
|
76
|
-
SpinDB bundles the PostgreSQL **server**
|
|
96
|
+
SpinDB bundles the PostgreSQL **server** but not client tools. For `connect` and `restore` commands, you need client tools installed.
|
|
77
97
|
|
|
78
98
|
### Automatic Installation
|
|
79
99
|
|
|
80
|
-
SpinDB can check and install client tools automatically:
|
|
81
|
-
|
|
82
100
|
```bash
|
|
83
101
|
# Check status of all client tools
|
|
84
102
|
spindb deps check
|
|
85
103
|
|
|
86
|
-
# Install missing tools
|
|
104
|
+
# Install missing tools
|
|
87
105
|
spindb deps install
|
|
88
106
|
|
|
89
107
|
# Install for a specific engine
|
|
90
108
|
spindb deps install --engine postgresql
|
|
91
109
|
spindb deps install --engine mysql
|
|
92
|
-
|
|
93
|
-
# Install all missing dependencies for all engines
|
|
94
|
-
spindb deps install --all
|
|
95
|
-
|
|
96
|
-
# List all supported dependencies
|
|
97
|
-
spindb deps list
|
|
98
110
|
```
|
|
99
111
|
|
|
100
112
|
### Manual Installation
|
|
101
113
|
|
|
102
|
-
|
|
114
|
+
#### PostgreSQL
|
|
103
115
|
|
|
104
116
|
```bash
|
|
105
117
|
# macOS (Homebrew)
|
|
@@ -109,30 +121,21 @@ brew link --overwrite postgresql@17
|
|
|
109
121
|
# Ubuntu/Debian
|
|
110
122
|
sudo apt install postgresql-client
|
|
111
123
|
|
|
112
|
-
# CentOS/RHEL
|
|
113
|
-
sudo yum install postgresql
|
|
114
|
-
|
|
115
|
-
# Fedora
|
|
116
|
-
sudo dnf install postgresql
|
|
117
|
-
|
|
118
124
|
# Arch
|
|
119
125
|
sudo pacman -S postgresql-libs
|
|
120
|
-
|
|
121
|
-
# Or use Postgres.app (macOS)
|
|
122
|
-
# Client tools are automatically detected
|
|
123
126
|
```
|
|
124
127
|
|
|
125
|
-
|
|
128
|
+
#### MySQL
|
|
126
129
|
|
|
127
130
|
```bash
|
|
128
|
-
|
|
129
|
-
|
|
131
|
+
# macOS (Homebrew)
|
|
132
|
+
brew install mysql
|
|
130
133
|
|
|
131
|
-
|
|
134
|
+
# Ubuntu/Debian
|
|
135
|
+
sudo apt install mysql-server
|
|
132
136
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
spindb config set pg_restore /path/to/pg_restore
|
|
137
|
+
# Arch
|
|
138
|
+
sudo pacman -S mysql
|
|
136
139
|
```
|
|
137
140
|
|
|
138
141
|
## Supported Platforms
|
|
@@ -140,53 +143,31 @@ spindb config set pg_restore /path/to/pg_restore
|
|
|
140
143
|
- macOS (Apple Silicon & Intel)
|
|
141
144
|
- Linux (x64 & ARM64)
|
|
142
145
|
|
|
143
|
-
## Supported PostgreSQL Versions
|
|
144
|
-
|
|
145
|
-
- PostgreSQL 14
|
|
146
|
-
- PostgreSQL 15
|
|
147
|
-
- PostgreSQL 16
|
|
148
|
-
- PostgreSQL 17
|
|
149
|
-
|
|
150
146
|
## Examples
|
|
151
147
|
|
|
152
|
-
### Create
|
|
148
|
+
### Create databases
|
|
153
149
|
|
|
154
150
|
```bash
|
|
155
|
-
#
|
|
156
|
-
spindb create mydb --
|
|
151
|
+
# PostgreSQL with specific version and port
|
|
152
|
+
spindb create mydb --engine postgresql --version 16 --port 5433
|
|
153
|
+
|
|
154
|
+
# MySQL
|
|
155
|
+
spindb create mydb --engine mysql --port 3307
|
|
157
156
|
|
|
158
|
-
#
|
|
157
|
+
# With custom database name
|
|
159
158
|
spindb create mydb --database my_app_db
|
|
160
|
-
# Connection string: postgresql://postgres@localhost:5432/my_app_db
|
|
161
159
|
```
|
|
162
160
|
|
|
163
161
|
### Create and restore in one command
|
|
164
162
|
|
|
165
163
|
```bash
|
|
166
|
-
# Create
|
|
164
|
+
# Create and restore from a dump file
|
|
167
165
|
spindb create mydb --from ./backup.dump
|
|
168
166
|
|
|
169
|
-
# Create
|
|
167
|
+
# Create and pull from a remote database
|
|
170
168
|
spindb create mydb --from "postgresql://user:pass@remote-host:5432/production_db"
|
|
171
|
-
|
|
172
|
-
# With specific version and database name
|
|
173
|
-
spindb create mydb --pg-version 17 --database myapp --from ./backup.dump
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
The `--from` option auto-detects whether the location is a file path or connection string.
|
|
177
|
-
|
|
178
|
-
### Restore to an existing container
|
|
179
|
-
|
|
180
|
-
```bash
|
|
181
|
-
# Restore from a dump file (supports .sql, custom format, and tar format)
|
|
182
|
-
spindb restore mydb ./backup.dump -d myapp
|
|
183
|
-
|
|
184
|
-
# Or pull directly from a remote database
|
|
185
|
-
spindb restore mydb --from-url "postgresql://user:pass@remote-host:5432/production_db" -d myapp
|
|
186
169
|
```
|
|
187
170
|
|
|
188
|
-
The interactive menu (`spindb` → "Restore backup") also offers an option to create a new container as part of the restore flow.
|
|
189
|
-
|
|
190
171
|
### Clone for testing
|
|
191
172
|
|
|
192
173
|
```bash
|
|
@@ -200,63 +181,58 @@ spindb clone production-copy test-branch
|
|
|
200
181
|
spindb start test-branch
|
|
201
182
|
```
|
|
202
183
|
|
|
203
|
-
### Connect
|
|
184
|
+
### Connect to databases
|
|
204
185
|
|
|
205
186
|
```bash
|
|
206
|
-
# Interactive
|
|
187
|
+
# Interactive shell (auto-detects engine)
|
|
207
188
|
spindb connect mydb
|
|
208
189
|
|
|
209
|
-
# Or use
|
|
190
|
+
# Or use connection string directly
|
|
210
191
|
psql postgresql://postgres@localhost:5432/mydb
|
|
192
|
+
mysql -u root -h 127.0.0.1 -P 3306 mydb
|
|
211
193
|
```
|
|
212
194
|
|
|
213
195
|
### Manage installed engines
|
|
214
196
|
|
|
215
|
-
The Engines menu
|
|
197
|
+
The Engines menu shows installed PostgreSQL versions with disk usage:
|
|
216
198
|
|
|
217
199
|
```
|
|
218
200
|
ENGINE VERSION PLATFORM SIZE
|
|
219
201
|
────────────────────────────────────────────────────────
|
|
220
202
|
postgresql 17 darwin-arm64 45.2 MB
|
|
221
|
-
postgresql 16.9.0 darwin-arm64 44.8 MB
|
|
222
203
|
postgresql 16 darwin-arm64 44.8 MB
|
|
223
204
|
────────────────────────────────────────────────────────
|
|
224
|
-
|
|
205
|
+
2 version(s) 90.0 MB
|
|
225
206
|
```
|
|
226
207
|
|
|
227
|
-
##
|
|
228
|
-
|
|
229
|
-
Configuration is stored in `~/.spindb/config.json`. You can edit it directly or use the `config` commands:
|
|
208
|
+
## Running Tests
|
|
230
209
|
|
|
231
210
|
```bash
|
|
232
|
-
#
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
# Re-detect system tools
|
|
236
|
-
spindb config detect
|
|
211
|
+
# Run all tests (PostgreSQL + MySQL)
|
|
212
|
+
pnpm test
|
|
237
213
|
|
|
238
|
-
#
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
# Get path for scripting
|
|
242
|
-
spindb config path psql
|
|
214
|
+
# Run individual test suites
|
|
215
|
+
pnpm test:pg
|
|
216
|
+
pnpm test:mysql
|
|
243
217
|
```
|
|
244
218
|
|
|
245
219
|
## Troubleshooting
|
|
246
220
|
|
|
247
221
|
### Port already in use
|
|
248
222
|
|
|
249
|
-
SpinDB automatically finds an available port
|
|
223
|
+
SpinDB automatically finds an available port. You can also specify one:
|
|
250
224
|
|
|
251
225
|
```bash
|
|
252
226
|
spindb create mydb --port 5433
|
|
253
227
|
```
|
|
254
228
|
|
|
255
|
-
###
|
|
229
|
+
### Client tool not found
|
|
256
230
|
|
|
257
|
-
Install
|
|
231
|
+
Install client tools or configure the path:
|
|
258
232
|
|
|
259
233
|
```bash
|
|
234
|
+
spindb deps install
|
|
235
|
+
# or
|
|
260
236
|
spindb config set psql /path/to/psql
|
|
261
237
|
```
|
|
262
238
|
|
|
@@ -265,7 +241,8 @@ spindb config set psql /path/to/psql
|
|
|
265
241
|
Check the logs:
|
|
266
242
|
|
|
267
243
|
```bash
|
|
268
|
-
cat ~/.spindb/containers/mydb/postgres.log
|
|
244
|
+
cat ~/.spindb/containers/postgresql/mydb/postgres.log
|
|
245
|
+
cat ~/.spindb/containers/mysql/mydb/mysql.log
|
|
269
246
|
```
|
|
270
247
|
|
|
271
248
|
### Reset everything
|
package/cli/commands/clone.ts
CHANGED
|
@@ -58,7 +58,9 @@ export const cloneCommand = new Command('clone')
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
// Check source is stopped
|
|
61
|
-
const running = await processManager.isRunning(sourceName
|
|
61
|
+
const running = await processManager.isRunning(sourceName, {
|
|
62
|
+
engine: sourceConfig.engine,
|
|
63
|
+
})
|
|
62
64
|
if (running) {
|
|
63
65
|
console.error(
|
|
64
66
|
error(
|
package/cli/commands/connect.ts
CHANGED
|
@@ -4,14 +4,15 @@ import chalk from 'chalk'
|
|
|
4
4
|
import { containerManager } from '../../core/container-manager'
|
|
5
5
|
import { processManager } from '../../core/process-manager'
|
|
6
6
|
import { getEngine } from '../../engines'
|
|
7
|
+
import { getEngineDefaults } from '../../config/defaults'
|
|
7
8
|
import { promptContainerSelect } from '../ui/prompts'
|
|
8
9
|
import { error, warning, info } from '../ui/theme'
|
|
9
10
|
|
|
10
11
|
export const connectCommand = new Command('connect')
|
|
11
|
-
.description('Connect to a container with
|
|
12
|
+
.description('Connect to a container with database client')
|
|
12
13
|
.argument('[name]', 'Container name')
|
|
13
|
-
.option('-d, --database <name>', 'Database name'
|
|
14
|
-
.action(async (name: string | undefined, options: { database
|
|
14
|
+
.option('-d, --database <name>', 'Database name')
|
|
15
|
+
.action(async (name: string | undefined, options: { database?: string }) => {
|
|
15
16
|
try {
|
|
16
17
|
let containerName = name
|
|
17
18
|
|
|
@@ -50,8 +51,16 @@ export const connectCommand = new Command('connect')
|
|
|
50
51
|
process.exit(1)
|
|
51
52
|
}
|
|
52
53
|
|
|
54
|
+
const { engine: engineName } = config
|
|
55
|
+
const engineDefaults = getEngineDefaults(engineName)
|
|
56
|
+
|
|
57
|
+
// Default database: container's database or superuser
|
|
58
|
+
const database = options.database ?? config.database ?? engineDefaults.superuser
|
|
59
|
+
|
|
53
60
|
// Check if running
|
|
54
|
-
const running = await processManager.isRunning(containerName
|
|
61
|
+
const running = await processManager.isRunning(containerName, {
|
|
62
|
+
engine: engineName,
|
|
63
|
+
})
|
|
55
64
|
if (!running) {
|
|
56
65
|
console.error(
|
|
57
66
|
error(`Container "${containerName}" is not running. Start it first.`),
|
|
@@ -60,35 +69,52 @@ export const connectCommand = new Command('connect')
|
|
|
60
69
|
}
|
|
61
70
|
|
|
62
71
|
// Get engine
|
|
63
|
-
const engine = getEngine(
|
|
64
|
-
const connectionString = engine.getConnectionString(
|
|
65
|
-
config,
|
|
66
|
-
options.database,
|
|
67
|
-
)
|
|
72
|
+
const engine = getEngine(engineName)
|
|
73
|
+
const connectionString = engine.getConnectionString(config, database)
|
|
68
74
|
|
|
69
|
-
console.log(info(`Connecting to ${containerName}:${
|
|
75
|
+
console.log(info(`Connecting to ${containerName}:${database}...`))
|
|
70
76
|
console.log()
|
|
71
77
|
|
|
72
|
-
//
|
|
73
|
-
|
|
78
|
+
// Build client command based on engine
|
|
79
|
+
let clientCmd: string
|
|
80
|
+
let clientArgs: string[]
|
|
81
|
+
|
|
82
|
+
if (engineName === 'mysql') {
|
|
83
|
+
// MySQL: mysql -h 127.0.0.1 -P port -u root database
|
|
84
|
+
clientCmd = 'mysql'
|
|
85
|
+
clientArgs = [
|
|
86
|
+
'-h', '127.0.0.1',
|
|
87
|
+
'-P', String(config.port),
|
|
88
|
+
'-u', engineDefaults.superuser,
|
|
89
|
+
database,
|
|
90
|
+
]
|
|
91
|
+
} else {
|
|
92
|
+
// PostgreSQL: psql connection_string
|
|
93
|
+
clientCmd = 'psql'
|
|
94
|
+
clientArgs = [connectionString]
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const clientProcess = spawn(clientCmd, clientArgs, {
|
|
74
98
|
stdio: 'inherit',
|
|
75
99
|
})
|
|
76
100
|
|
|
77
|
-
|
|
101
|
+
clientProcess.on('error', (err: NodeJS.ErrnoException) => {
|
|
78
102
|
if (err.code === 'ENOENT') {
|
|
79
|
-
console.log(warning(
|
|
103
|
+
console.log(warning(`${clientCmd} not found on your system.`))
|
|
80
104
|
console.log()
|
|
81
|
-
console.log(
|
|
82
|
-
chalk.gray(
|
|
83
|
-
' Install PostgreSQL client tools or connect manually:',
|
|
84
|
-
),
|
|
85
|
-
)
|
|
105
|
+
console.log(chalk.gray(' Install client tools or connect manually:'))
|
|
86
106
|
console.log(chalk.cyan(` ${connectionString}`))
|
|
87
107
|
console.log()
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
chalk.
|
|
91
|
-
|
|
108
|
+
|
|
109
|
+
if (engineName === 'mysql') {
|
|
110
|
+
console.log(chalk.gray(' On macOS with Homebrew:'))
|
|
111
|
+
console.log(chalk.cyan(' brew install mysql-client'))
|
|
112
|
+
} else {
|
|
113
|
+
console.log(chalk.gray(' On macOS with Homebrew:'))
|
|
114
|
+
console.log(
|
|
115
|
+
chalk.cyan(' brew install libpq && brew link --force libpq'),
|
|
116
|
+
)
|
|
117
|
+
}
|
|
92
118
|
console.log()
|
|
93
119
|
} else {
|
|
94
120
|
console.error(error(err.message))
|
|
@@ -96,7 +122,7 @@ export const connectCommand = new Command('connect')
|
|
|
96
122
|
})
|
|
97
123
|
|
|
98
124
|
await new Promise<void>((resolve) => {
|
|
99
|
-
|
|
125
|
+
clientProcess.on('close', () => resolve())
|
|
100
126
|
})
|
|
101
127
|
} catch (err) {
|
|
102
128
|
const e = err as Error
|