or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

binary-resolution.mdcli-utilities.mddatabase-operations.mdengine-commands.mderror-handling.mdgenerators.mdindex.mdsyntax-highlighting.mdtracing.mdutilities.md

database-operations.mddocs/

0

# Database Operations

1

2

The database operations domain provides essential database connectivity testing and management functionality across different database providers, utilizing the Prisma schema engine for reliable database interactions.

3

4

## Functions

5

6

### Database Connectivity

7

8

#### `canConnectToDatabase(connectionString, cwd?, schemaEnginePath?)`

9

10

Tests database connectivity using the provided connection string to verify that the database is accessible and properly configured.

11

12

```typescript { .api }

13

function canConnectToDatabase(

14

connectionString: string,

15

cwd?: string,

16

schemaEnginePath?: string

17

): Promise<ConnectionResult>

18

```

19

20

**Parameters:**

21

- `connectionString: string` - Database connection string (URL format)

22

- `cwd?: string` - Working directory (default: process.cwd())

23

- `schemaEnginePath?: string` - Optional path to schema engine binary

24

25

**Returns:** `Promise<ConnectionResult>` - True if successful connection, error object if failed

26

27

**ConnectionResult Type:**

28

```typescript { .api }

29

type ConnectionResult = true | { error: string; code?: string }

30

```

31

32

**Example:**

33

```typescript

34

// Test PostgreSQL connection

35

const result = await canConnectToDatabase(

36

'postgresql://user:password@localhost:5432/mydb'

37

)

38

39

if (result === true) {

40

console.log('✓ Database connection successful')

41

} else {

42

console.error('✗ Database connection failed:', result.error)

43

if (result.code) {

44

console.error('Error code:', result.code)

45

}

46

}

47

48

// Test with custom working directory and engine path

49

const customResult = await canConnectToDatabase(

50

'mysql://user:pass@localhost:3306/testdb',

51

'./my-project',

52

'/custom/path/to/schema-engine'

53

)

54

```

55

56

**Supported Database Providers:**

57

- PostgreSQL (`postgresql://`)

58

- MySQL (`mysql://`)

59

- SQLite (`file:./dev.db`)

60

- SQL Server (`sqlserver://`)

61

- MongoDB (`mongodb://`)

62

- CockroachDB (`cockroachdb://`)

63

64

### Database Management

65

66

#### `createDatabase(connectionString, cwd?, schemaEnginePath?)`

67

68

Creates a database if it doesn't already exist. This is useful for setting up new environments or ensuring database availability.

69

70

```typescript { .api }

71

function createDatabase(

72

connectionString: string,

73

cwd?: string,

74

schemaEnginePath?: string

75

): Promise<boolean>

76

```

77

78

**Parameters:**

79

- `connectionString: string` - Database connection string

80

- `cwd?: string` - Working directory (default: process.cwd())

81

- `schemaEnginePath?: string` - Optional path to schema engine binary

82

83

**Returns:** `Promise<boolean>` - True if database was created, false if it already existed

84

85

**Example:**

86

```typescript

87

// Create PostgreSQL database

88

const wasCreated = await createDatabase(

89

'postgresql://user:password@localhost:5432/new_database'

90

)

91

92

if (wasCreated) {

93

console.log('✓ Database created successfully')

94

} else {

95

console.log('ℹ Database already exists')

96

}

97

98

// Create SQLite database

99

const sqliteCreated = await createDatabase('file:./new_app.db')

100

console.log(sqliteCreated ? 'SQLite database created' : 'SQLite database exists')

101

```

102

103

**Behavior by Provider:**

104

- **PostgreSQL/MySQL/SQL Server:** Creates database on the server

105

- **SQLite:** Creates database file if it doesn't exist

106

- **MongoDB:** Creates database on first document insertion

107

- **CockroachDB:** Creates database in the cluster

108

109

#### `dropDatabase(connectionString, cwd?, schemaEnginePath?)`

110

111

Drops/deletes a database completely. **Use with extreme caution** as this operation is irreversible.

112

113

```typescript { .api }

114

function dropDatabase(

115

connectionString: string,

116

cwd?: string,

117

schemaEnginePath?: string

118

): Promise<boolean>

119

```

120

121

**Parameters:**

122

- `connectionString: string` - Database connection string

123

- `cwd?: string` - Working directory (default: process.cwd())

124

- `schemaEnginePath?: string` - Optional path to schema engine binary

125

126

**Returns:** `Promise<boolean>` - True if database was dropped successfully

127

128

**Example:**

129

```typescript

130

// ⚠️ DANGEROUS: This will permanently delete the database

131

const confirm = await askUserConfirmation('Are you sure you want to drop the database?')

132

133

if (confirm) {

134

const wasDropped = await dropDatabase(

135

'postgresql://user:password@localhost:5432/old_database'

136

)

137

138

if (wasDropped) {

139

console.log('✓ Database dropped successfully')

140

} else {

141

console.error('✗ Failed to drop database')

142

}

143

}

144

145

// Drop test database safely

146

const testDropped = await dropDatabase('file:./test.db')

147

console.log(testDropped ? 'Test database cleaned up' : 'Test database not found')

148

```

149

150

## Types and Interfaces

151

152

### Schema Engine Types

153

154

#### `SchemaEngineLogLine`

155

156

Log line format from schema engine stderr output, used for debugging database operations.

157

158

```typescript { .api }

159

interface SchemaEngineLogLine {

160

timestamp: string // ISO timestamp

161

level: LogLevel // Log level (INFO, ERROR, DEBUG, WARN)

162

fields: LogFields // Log fields including message

163

target: string // Log target module

164

}

165

```

166

167

**LogLevel:**

168

```typescript { .api }

169

type LogLevel = 'INFO' | 'ERROR' | 'DEBUG' | 'WARN'

170

```

171

172

**LogFields:**

173

```typescript { .api }

174

interface LogFields {

175

message: string // Main log message

176

[key: string]: any // Additional context fields

177

}

178

```

179

180

#### `SchemaEngineExitCode`

181

182

Exit codes returned by the schema engine for different operation results.

183

184

```typescript { .api }

185

enum SchemaEngineExitCode {

186

Success = 0, // Normal successful exit

187

Error = 1, // Abnormal exit with error

188

Panic = 101 // Panic exit (internal error)

189

}

190

```

191

192

## Examples

193

194

### Database Setup and Validation Workflow

195

196

```typescript

197

import {

198

canConnectToDatabase,

199

createDatabase,

200

dropDatabase

201

} from '@prisma/internals'

202

203

async function setupDatabaseEnvironment(connectionString: string) {

204

console.log('Setting up database environment...')

205

206

try {

207

// 1. Test initial connectivity (might fail if database doesn't exist)

208

console.log('Testing initial connectivity...')

209

const initialConnection = await canConnectToDatabase(connectionString)

210

211

if (initialConnection === true) {

212

console.log('✓ Database already exists and is accessible')

213

return true

214

}

215

216

// 2. If connection failed, try to create the database

217

console.log('Creating database...')

218

const wasCreated = await createDatabase(connectionString)

219

220

if (wasCreated) {

221

console.log('✓ Database created successfully')

222

} else {

223

console.log('ℹ Database already existed')

224

}

225

226

// 3. Test connectivity after creation

227

console.log('Testing connectivity after creation...')

228

const finalConnection = await canConnectToDatabase(connectionString)

229

230

if (finalConnection === true) {

231

console.log('✓ Database is ready for use')

232

return true

233

} else {

234

throw new Error(`Database creation succeeded but connection failed: ${finalConnection.error}`)

235

}

236

237

} catch (error) {

238

console.error('Database setup failed:', error)

239

throw error

240

}

241

}

242

243

// Usage

244

await setupDatabaseEnvironment('postgresql://user:pass@localhost:5432/myapp')

245

```

246

247

### Multi-Environment Database Management

248

249

```typescript

250

import {

251

canConnectToDatabase,

252

createDatabase,

253

dropDatabase

254

} from '@prisma/internals'

255

256

interface DatabaseConfig {

257

name: string

258

url: string

259

temporary?: boolean

260

}

261

262

async function manageMultipleDatabases(configs: DatabaseConfig[]) {

263

const results = []

264

265

for (const config of configs) {

266

console.log(`\nProcessing ${config.name}...`)

267

268

try {

269

// Test connectivity

270

const canConnect = await canConnectToDatabase(config.url)

271

272

if (canConnect === true) {

273

console.log(`✓ ${config.name}: Connected successfully`)

274

results.push({ name: config.name, status: 'connected' })

275

} else {

276

console.log(`⚠ ${config.name}: Connection failed - ${canConnect.error}`)

277

278

// Try to create if it doesn't exist

279

console.log(`Creating ${config.name}...`)

280

const created = await createDatabase(config.url)

281

282

if (created) {

283

console.log(`✓ ${config.name}: Created successfully`)

284

results.push({ name: config.name, status: 'created' })

285

} else {

286

console.log(`ℹ ${config.name}: Already existed, but connection still fails`)

287

results.push({ name: config.name, status: 'error', error: canConnect.error })

288

}

289

}

290

291

} catch (error) {

292

console.error(`✗ ${config.name}: Fatal error - ${error.message}`)

293

results.push({ name: config.name, status: 'fatal', error: error.message })

294

}

295

}

296

297

// Cleanup temporary databases

298

for (const config of configs.filter(c => c.temporary)) {

299

try {

300

console.log(`\nCleaning up temporary database: ${config.name}`)

301

await dropDatabase(config.url)

302

console.log(`✓ ${config.name}: Cleaned up`)

303

} catch (error) {

304

console.warn(`⚠ Failed to cleanup ${config.name}: ${error.message}`)

305

}

306

}

307

308

return results

309

}

310

311

// Usage with different database types

312

const databases: DatabaseConfig[] = [

313

{

314

name: 'Production PostgreSQL',

315

url: 'postgresql://user:pass@prod.example.com:5432/myapp'

316

},

317

{

318

name: 'Development MySQL',

319

url: 'mysql://dev:pass@localhost:3306/myapp_dev'

320

},

321

{

322

name: 'Test SQLite',

323

url: 'file:./test.db',

324

temporary: true

325

},

326

{

327

name: 'CI PostgreSQL',

328

url: 'postgresql://postgres:postgres@localhost:5432/ci_test',

329

temporary: true

330

}

331

]

332

333

const results = await manageMultipleDatabases(databases)

334

console.log('\nDatabase Management Summary:')

335

results.forEach(result => {

336

console.log(`${result.name}: ${result.status}`)

337

})

338

```

339

340

### Database Health Check Utility

341

342

```typescript

343

import { canConnectToDatabase } from '@prisma/internals'

344

345

interface HealthCheckResult {

346

database: string

347

status: 'healthy' | 'unhealthy' | 'error'

348

responseTime?: number

349

error?: string

350

timestamp: Date

351

}

352

353

async function performHealthCheck(

354

databases: { name: string; url: string }[]

355

): Promise<HealthCheckResult[]> {

356

console.log('Performing database health checks...')

357

358

const results = await Promise.allSettled(

359

databases.map(async (db) => {

360

const startTime = Date.now()

361

362

try {

363

const canConnect = await canConnectToDatabase(db.url)

364

const responseTime = Date.now() - startTime

365

366

if (canConnect === true) {

367

return {

368

database: db.name,

369

status: 'healthy' as const,

370

responseTime,

371

timestamp: new Date()

372

}

373

} else {

374

return {

375

database: db.name,

376

status: 'unhealthy' as const,

377

responseTime,

378

error: canConnect.error,

379

timestamp: new Date()

380

}

381

}

382

} catch (error) {

383

return {

384

database: db.name,

385

status: 'error' as const,

386

error: error.message,

387

timestamp: new Date()

388

}

389

}

390

})

391

)

392

393

return results.map(result =>

394

result.status === 'fulfilled' ? result.value : {

395

database: 'unknown',

396

status: 'error' as const,

397

error: 'Promise rejected',

398

timestamp: new Date()

399

}

400

)

401

}

402

403

// Usage

404

const healthResults = await performHealthCheck([

405

{ name: 'Primary DB', url: 'postgresql://user:pass@db1.example.com:5432/app' },

406

{ name: 'Read Replica', url: 'postgresql://user:pass@db2.example.com:5432/app' },

407

{ name: 'Cache DB', url: 'redis://localhost:6379' }

408

])

409

410

// Generate health report

411

console.log('\n=== Database Health Report ===')

412

healthResults.forEach(result => {

413

const statusIcon = result.status === 'healthy' ? '✓' :

414

result.status === 'unhealthy' ? '⚠' : '✗'

415

416

console.log(`${statusIcon} ${result.database}: ${result.status.toUpperCase()}`)

417

418

if (result.responseTime) {

419

console.log(` Response Time: ${result.responseTime}ms`)

420

}

421

422

if (result.error) {

423

console.log(` Error: ${result.error}`)

424

}

425

426

console.log(` Checked: ${result.timestamp.toISOString()}`)

427

})

428

429

// Set exit code based on health

430

const hasUnhealthy = healthResults.some(r => r.status !== 'healthy')

431

if (hasUnhealthy) {

432

process.exit(1)

433

}

434

```

435

436

### Environment-Specific Database Operations

437

438

```typescript

439

import {

440

canConnectToDatabase,

441

createDatabase,

442

dropDatabase

443

} from '@prisma/internals'

444

445

class DatabaseManager {

446

constructor(private baseUrl: string) {}

447

448

private getDatabaseUrl(environment: string, suffix?: string): string {

449

const dbName = suffix ? `myapp_${environment}_${suffix}` : `myapp_${environment}`

450

return this.baseUrl.replace(/\/[^\/]*$/, `/${dbName}`)

451

}

452

453

async setupEnvironment(environment: string): Promise<void> {

454

const mainDbUrl = this.getDatabaseUrl(environment)

455

456

console.log(`Setting up ${environment} environment...`)

457

458

// Create main database

459

await this.ensureDatabase(mainDbUrl, `${environment} main database`)

460

461

// Create test database for this environment

462

if (environment !== 'production') {

463

const testDbUrl = this.getDatabaseUrl(environment, 'test')

464

await this.ensureDatabase(testDbUrl, `${environment} test database`)

465

}

466

}

467

468

async teardownEnvironment(environment: string): Promise<void> {

469

if (environment === 'production') {

470

throw new Error('Cannot teardown production environment')

471

}

472

473

console.log(`Tearing down ${environment} environment...`)

474

475

const mainDbUrl = this.getDatabaseUrl(environment)

476

const testDbUrl = this.getDatabaseUrl(environment, 'test')

477

478

try {

479

await dropDatabase(testDbUrl)

480

console.log(`✓ Dropped ${environment} test database`)

481

} catch (error) {

482

console.warn(`⚠ Could not drop ${environment} test database: ${error.message}`)

483

}

484

485

try {

486

await dropDatabase(mainDbUrl)

487

console.log(`✓ Dropped ${environment} main database`)

488

} catch (error) {

489

console.warn(`⚠ Could not drop ${environment} main database: ${error.message}`)

490

}

491

}

492

493

private async ensureDatabase(url: string, description: string): Promise<void> {

494

const canConnect = await canConnectToDatabase(url)

495

496

if (canConnect === true) {

497

console.log(`✓ ${description}: Already exists and accessible`)

498

return

499

}

500

501

console.log(`Creating ${description}...`)

502

const wasCreated = await createDatabase(url)

503

504

if (wasCreated) {

505

console.log(`✓ ${description}: Created successfully`)

506

} else {

507

console.log(`ℹ ${description}: Already existed`)

508

}

509

510

// Verify connectivity after creation

511

const finalCheck = await canConnectToDatabase(url)

512

if (finalCheck !== true) {

513

throw new Error(`Failed to connect to ${description} after creation: ${finalCheck.error}`)

514

}

515

}

516

}

517

518

// Usage

519

const dbManager = new DatabaseManager('postgresql://user:pass@localhost:5432/template')

520

521

// Setup development environment

522

await dbManager.setupEnvironment('development')

523

524

// Setup staging environment

525

await dbManager.setupEnvironment('staging')

526

527

// Cleanup old feature branch environment

528

await dbManager.teardownEnvironment('feature_auth_v2')

529

```