or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

ast-compilation.mdcollections-utilities.mdconfig-data.mdcore-language.mddependency-management.mdindex.mdio-file-processing.mdjson-processing.mdsql-database.mdtemplate-engines.mdtesting-apis.mdtime-date.mdtransform-annotations.mdxml-processing.md

sql-database.mddocs/

0

# SQL Database Operations

1

2

Comprehensive database connectivity, query execution, and data manipulation through the Groovy SQL API. Provides simplified database access with automatic resource management, transaction support, and result set navigation.

3

4

## Capabilities

5

6

### Database Connection and Configuration

7

8

Create and manage database connections with automatic resource cleanup.

9

10

```java { .api }

11

/**

12

* Main class for database operations with automatic connection management

13

*/

14

class Sql {

15

/**

16

* Create Sql instance with JDBC URL and credentials

17

*/

18

static Sql newInstance(String url, String user, String password, String driver) throws SQLException;

19

20

/**

21

* Create Sql instance with JDBC URL only

22

*/

23

static Sql newInstance(String url) throws SQLException;

24

25

/**

26

* Create Sql instance from existing Connection

27

*/

28

static Sql newInstance(Connection connection);

29

30

/**

31

* Create Sql instance from DataSource

32

*/

33

static Sql newInstance(DataSource dataSource);

34

35

/**

36

* Create Sql instance with Properties configuration

37

*/

38

static Sql newInstance(Properties properties) throws SQLException;

39

40

/**

41

* Close the database connection and clean up resources

42

*/

43

void close() throws SQLException;

44

45

/**

46

* Get the underlying JDBC Connection

47

*/

48

Connection getConnection();

49

50

/**

51

* Check if connection is closed

52

*/

53

boolean isClosed() throws SQLException;

54

}

55

```

56

57

**Usage Examples:**

58

59

```groovy

60

import groovy.sql.Sql

61

62

// Connect with full credentials

63

def sql = Sql.newInstance("jdbc:h2:mem:testdb",

64

"sa",

65

"",

66

"org.h2.Driver")

67

68

// Connect with DataSource (recommended for production)

69

import javax.sql.DataSource

70

import org.apache.commons.dbcp2.BasicDataSource

71

72

def dataSource = new BasicDataSource()

73

dataSource.url = "jdbc:postgresql://localhost:5432/mydb"

74

dataSource.username = "user"

75

dataSource.password = "password"

76

dataSource.driverClassName = "org.postgresql.Driver"

77

78

def sql = Sql.newInstance(dataSource)

79

80

// Always close when done

81

try {

82

// database operations

83

} finally {

84

sql.close()

85

}

86

87

// Or use with try-with-resources pattern

88

Sql.withInstance("jdbc:h2:mem:testdb", "sa", "", "org.h2.Driver") { sql ->

89

// database operations - connection automatically closed

90

}

91

```

92

93

### Query Execution and Result Processing

94

95

Execute SQL queries and process results with various iteration patterns.

96

97

```java { .api }

98

/**

99

* Query execution methods for retrieving data

100

*/

101

class Sql {

102

/**

103

* Execute query and return all rows as List of GroovyRowResult

104

*/

105

List<GroovyRowResult> rows(String sql) throws SQLException;

106

List<GroovyRowResult> rows(String sql, List params) throws SQLException;

107

List<GroovyRowResult> rows(String sql, Object... params) throws SQLException;

108

List<GroovyRowResult> rows(String sql, Map params) throws SQLException;

109

110

/**

111

* Execute query and iterate over each row

112

*/

113

void eachRow(String sql, Closure closure) throws SQLException;

114

void eachRow(String sql, List params, Closure closure) throws SQLException;

115

void eachRow(String sql, Map params, Closure closure) throws SQLException;

116

117

/**

118

* Execute query and return first row only

119

*/

120

GroovyRowResult firstRow(String sql) throws SQLException;

121

GroovyRowResult firstRow(String sql, List params) throws SQLException;

122

GroovyRowResult firstRow(String sql, Map params) throws SQLException;

123

124

/**

125

* Execute prepared statement with result set processing

126

*/

127

void query(String sql, Closure closure) throws SQLException;

128

void query(String sql, List params, Closure closure) throws SQLException;

129

}

130

131

/**

132

* Row result that provides map-like and object-like access to column data

133

*/

134

interface GroovyRowResult extends Map<String, Object> {

135

/**

136

* Get column value by name (case-insensitive)

137

*/

138

Object getProperty(String columnName);

139

140

/**

141

* Get column value by index (0-based)

142

*/

143

Object getAt(int columnIndex);

144

145

/**

146

* Convert row to Map

147

*/

148

Map<String, Object> toRowResult();

149

}

150

```

151

152

**Usage Examples:**

153

154

```groovy

155

import groovy.sql.Sql

156

157

def sql = Sql.newInstance("jdbc:h2:mem:testdb", "sa", "", "org.h2.Driver")

158

159

// Create sample table and data

160

sql.execute("""

161

CREATE TABLE employees (

162

id INT PRIMARY KEY,

163

name VARCHAR(50),

164

department VARCHAR(30),

165

salary DECIMAL(10,2)

166

)

167

""")

168

169

sql.execute("INSERT INTO employees VALUES (1, 'Alice', 'Engineering', 85000)")

170

sql.execute("INSERT INTO employees VALUES (2, 'Bob', 'Marketing', 65000)")

171

sql.execute("INSERT INTO employees VALUES (3, 'Carol', 'Engineering', 90000)")

172

173

// Query all rows

174

def employees = sql.rows("SELECT * FROM employees ORDER BY name")

175

employees.each { row ->

176

println "${row.name} (${row.department}): \$${row.salary}"

177

}

178

179

// Query with parameters (safe from SQL injection)

180

def engineers = sql.rows("SELECT * FROM employees WHERE department = ?", ["Engineering"])

181

assert engineers.size() == 2

182

183

// Query with named parameters

184

def highEarners = sql.rows("""

185

SELECT * FROM employees

186

WHERE salary > :minSalary

187

ORDER BY salary DESC

188

""", [minSalary: 80000])

189

190

// Iterate over large result sets efficiently

191

sql.eachRow("SELECT * FROM employees") { row ->

192

println "Processing employee: ${row.name}"

193

// Process one row at a time - memory efficient

194

}

195

196

// Get single row

197

def employee = sql.firstRow("SELECT * FROM employees WHERE id = ?", [1])

198

if (employee) {

199

println "Found: ${employee.name}"

200

}

201

202

// Access columns by index or name

203

employees.each { row ->

204

println "ID: ${row[0]}" // By index

205

println "Name: ${row.name}" // By property name

206

println "Dept: ${row['department']}" // By map key

207

}

208

209

sql.close()

210

```

211

212

### Data Modification Operations

213

214

Insert, update, and delete operations with parameter binding and batch processing.

215

216

```java { .api }

217

/**

218

* Data modification methods

219

*/

220

class Sql {

221

/**

222

* Execute UPDATE, INSERT, or DELETE statement

223

*/

224

int executeUpdate(String sql) throws SQLException;

225

int executeUpdate(String sql, List params) throws SQLException;

226

int executeUpdate(String sql, Map params) throws SQLException;

227

228

/**

229

* Execute any SQL statement

230

*/

231

boolean execute(String sql) throws SQLException;

232

boolean execute(String sql, List params) throws SQLException;

233

234

/**

235

* Execute INSERT and return generated keys

236

*/

237

List<GroovyRowResult> executeInsert(String sql) throws SQLException;

238

List<GroovyRowResult> executeInsert(String sql, List params) throws SQLException;

239

240

/**

241

* Batch operations for efficient bulk processing

242

*/

243

int[] withBatch(String sql, Closure closure) throws SQLException;

244

int[] withBatch(int batchSize, String sql, Closure closure) throws SQLException;

245

}

246

```

247

248

**Usage Examples:**

249

250

```groovy

251

import groovy.sql.Sql

252

253

def sql = Sql.newInstance("jdbc:h2:mem:testdb", "sa", "", "org.h2.Driver")

254

255

// Insert single record

256

def rowsAffected = sql.executeUpdate("""

257

INSERT INTO employees (id, name, department, salary)

258

VALUES (?, ?, ?, ?)

259

""", [4, "Dave", "Sales", 55000])

260

261

assert rowsAffected == 1

262

263

// Insert with named parameters

264

sql.executeUpdate("""

265

INSERT INTO employees (id, name, department, salary)

266

VALUES (:id, :name, :dept, :salary)

267

""", [id: 5, name: "Eve", dept: "HR", salary: 70000])

268

269

// Update records

270

def updated = sql.executeUpdate("""

271

UPDATE employees

272

SET salary = salary * 1.1

273

WHERE department = ?

274

""", ["Engineering"])

275

276

println "Updated $updated engineering salaries"

277

278

// Delete records

279

def deleted = sql.executeUpdate("DELETE FROM employees WHERE salary < ?", [60000])

280

281

// Insert and get generated keys

282

def keys = sql.executeInsert("""

283

INSERT INTO employees (name, department, salary)

284

VALUES (?, ?, ?)

285

""", ["Frank", "IT", 75000])

286

287

keys.each { key ->

288

println "Generated ID: ${key[0]}"

289

}

290

291

// Batch processing for bulk operations

292

def newEmployees = [

293

[name: "Grace", dept: "Finance", salary: 68000],

294

[name: "Henry", dept: "Operations", salary: 62000],

295

[name: "Iris", dept: "Legal", salary: 95000]

296

]

297

298

sql.withBatch("INSERT INTO employees (name, department, salary) VALUES (?, ?, ?)") { stmt ->

299

newEmployees.each { emp ->

300

stmt.addBatch([emp.name, emp.dept, emp.salary])

301

}

302

}

303

304

sql.close()

305

```

306

307

### Transaction Management

308

309

Handle database transactions with automatic rollback on exceptions.

310

311

```java { .api }

312

/**

313

* Transaction management methods

314

*/

315

class Sql {

316

/**

317

* Execute closure within a database transaction

318

*/

319

void withTransaction(Closure closure) throws SQLException;

320

321

/**

322

* Begin a new transaction

323

*/

324

void begin() throws SQLException;

325

326

/**

327

* Commit current transaction

328

*/

329

void commit() throws SQLException;

330

331

/**

332

* Rollback current transaction

333

*/

334

void rollback() throws SQLException;

335

336

/**

337

* Check if currently in a transaction

338

*/

339

boolean isInTransaction();

340

341

/**

342

* Set auto-commit mode

343

*/

344

void setAutoCommit(boolean autoCommit) throws SQLException;

345

}

346

```

347

348

**Usage Examples:**

349

350

```groovy

351

import groovy.sql.Sql

352

353

def sql = Sql.newInstance("jdbc:h2:mem:testdb", "sa", "", "org.h2.Driver")

354

355

// Automatic transaction management

356

sql.withTransaction {

357

sql.executeUpdate("UPDATE accounts SET balance = balance - 100 WHERE id = ?", [1])

358

sql.executeUpdate("UPDATE accounts SET balance = balance + 100 WHERE id = ?", [2])

359

360

// If any exception occurs, transaction is automatically rolled back

361

def balance = sql.firstRow("SELECT balance FROM accounts WHERE id = ?", [1])

362

if (balance.balance < 0) {

363

throw new RuntimeException("Insufficient funds")

364

}

365

// Transaction commits automatically if no exception

366

}

367

368

// Manual transaction control

369

try {

370

sql.begin()

371

372

sql.executeUpdate("INSERT INTO audit_log VALUES (?, ?)", [new Date(), "Operation started"])

373

sql.executeUpdate("UPDATE critical_data SET status = 'processing'")

374

375

// Simulate complex operation

376

performComplexOperation()

377

378

sql.executeUpdate("UPDATE critical_data SET status = 'completed'")

379

sql.commit()

380

381

} catch (Exception e) {

382

sql.rollback()

383

println "Transaction rolled back: ${e.message}"

384

}

385

386

sql.close()

387

```

388

389

### DataSet Operations

390

391

Object-relational mapping-like operations for working with database tables.

392

393

```java { .api }

394

/**

395

* DataSet provides table-like operations on database tables

396

*/

397

class DataSet {

398

/**

399

* Create DataSet for specific table

400

*/

401

DataSet(Sql sql, String tableName);

402

403

/**

404

* Add new row to the dataset/table

405

*/

406

void add(Map<String, Object> values);

407

408

/**

409

* Find all rows matching criteria

410

*/

411

DataSet findAll(Closure criteria);

412

413

/**

414

* Iterate over all rows in dataset

415

*/

416

void each(Closure closure);

417

418

/**

419

* Get first row matching criteria

420

*/

421

GroovyRowResult firstRow();

422

423

/**

424

* Get all rows as List

425

*/

426

List<GroovyRowResult> rows();

427

}

428

```

429

430

**Usage Examples:**

431

432

```groovy

433

import groovy.sql.Sql

434

import groovy.sql.DataSet

435

436

def sql = Sql.newInstance("jdbc:h2:mem:testdb", "sa", "", "org.h2.Driver")

437

438

// Create DataSet for employees table

439

def employees = new DataSet(sql, "employees")

440

441

// Add new employees

442

employees.add(name: "John", department: "IT", salary: 72000)

443

employees.add(name: "Jane", department: "IT", salary: 78000)

444

445

// Find IT employees

446

def itEmployees = employees.findAll { it.department == "IT" }

447

itEmployees.each { emp ->

448

println "${emp.name}: \$${emp.salary}"

449

}

450

451

// Iterate over all employees

452

employees.each { employee ->

453

if (employee.salary > 75000) {

454

println "High earner: ${employee.name}"

455

}

456

}

457

458

sql.close()

459

```

460

461

### Connection Pooling and Advanced Configuration

462

463

Configure connection pooling and advanced database settings.

464

465

**Usage Examples:**

466

467

```groovy

468

import groovy.sql.Sql

469

import org.apache.commons.dbcp2.BasicDataSource

470

471

// Configure connection pool

472

def setupDataSource() {

473

def dataSource = new BasicDataSource()

474

dataSource.url = "jdbc:postgresql://localhost:5432/production"

475

dataSource.username = "app_user"

476

dataSource.password = "secure_password"

477

dataSource.driverClassName = "org.postgresql.Driver"

478

479

// Connection pool settings

480

dataSource.initialSize = 5

481

dataSource.maxTotal = 20

482

dataSource.maxIdle = 10

483

dataSource.minIdle = 5

484

dataSource.maxWaitMillis = 30000

485

486

// Connection validation

487

dataSource.validationQuery = "SELECT 1"

488

dataSource.testOnBorrow = true

489

dataSource.testWhileIdle = true

490

491

return dataSource

492

}

493

494

def dataSource = setupDataSource()

495

496

// Use pooled connections

497

Sql.withInstance(dataSource) { sql ->

498

// Database operations using pooled connection

499

def results = sql.rows("SELECT COUNT(*) as total FROM orders WHERE status = 'completed'")

500

println "Completed orders: ${results[0].total}"

501

}

502

503

// Connection is automatically returned to pool

504

```

505

506

## Types

507

508

### Core SQL Types

509

510

```java { .api }

511

/**

512

* Row result interface providing multiple access patterns

513

*/

514

interface GroovyRowResult extends Map<String, Object> {

515

/**

516

* Get column value by property-style access

517

*/

518

Object getProperty(String columnName);

519

520

/**

521

* Get column value by array-style access

522

*/

523

Object getAt(int columnIndex);

524

Object getAt(String columnName);

525

526

/**

527

* Convert to standard Map

528

*/

529

Map<String, Object> toRowResult();

530

531

/**

532

* Get column metadata

533

*/

534

ResultSetMetaData getMetaData();

535

}

536

537

/**

538

* Exception thrown for SQL-related errors

539

*/

540

class SQLException extends Exception {

541

String getSQLState();

542

int getErrorCode();

543

SQLException getNextException();

544

}

545

```

546

547

### DataSet Types

548

549

```java { .api }

550

/**

551

* Table-like abstraction over SQL operations

552

*/

553

class DataSet {

554

/**

555

* The underlying Sql instance

556

*/

557

Sql getSql();

558

559

/**

560

* The table name this DataSet represents

561

*/

562

String getTableName();

563

564

/**

565

* Add row to dataset

566

*/

567

void add(Map<String, Object> values);

568

569

/**

570

* Find rows matching criteria

571

*/

572

DataSet findAll(Closure criteria);

573

574

/**

575

* Iterate over rows

576

*/

577

void each(Closure closure);

578

579

/**

580

* Get first matching row

581

*/

582

GroovyRowResult firstRow();

583

584

/**

585

* Get all rows

586

*/

587

List<GroovyRowResult> rows();

588

}

589

```