or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

changelog.mdcommand-framework.mdconfiguration.mddatabase-operations.mddatabase-support.mddiff-comparison.mdexceptions.mdindex.md

changelog.mddocs/

0

# Changelog Management

1

2

This document covers Liquibase's changelog and changeset management system, including changelog parsing, changeset definition, and change types.

3

4

## Imports

5

6

```java { .api }

7

import liquibase.changelog.DatabaseChangeLog;

8

import liquibase.changelog.ChangeSet;

9

import liquibase.changelog.ChangeLogParameters;

10

import liquibase.change.Change;

11

12

// Core change types

13

import liquibase.change.core.*;

14

15

// Context and label filtering

16

import liquibase.Contexts;

17

import liquibase.Labels;

18

import liquibase.LabelExpression;

19

20

// Validation

21

import liquibase.exception.ValidationErrors;

22

import liquibase.exception.LiquibaseException;

23

24

// Database

25

import liquibase.database.Database;

26

27

import java.util.List;

28

import java.util.Set;

29

```

30

31

## DatabaseChangeLog Class

32

33

The DatabaseChangeLog represents a complete changelog containing multiple changesets.

34

35

### File Management

36

37

```java { .api }

38

/**

39

* Get the physical file path of the changelog

40

* @return Physical file path

41

*/

42

public String getPhysicalFilePath()

43

44

/**

45

* Set the physical file path

46

* @param physicalFilePath Physical path to the changelog file

47

*/

48

public void setPhysicalFilePath(String physicalFilePath)

49

50

/**

51

* Get the logical file path used for includes

52

* @return Logical file path

53

*/

54

public String getLogicalFilePath()

55

56

/**

57

* Set the logical file path for includes

58

* @param logicalFilePath Logical path for changelog references

59

*/

60

public void setLogicalFilePath(String logicalFilePath)

61

```

62

63

### ChangeSet Management

64

65

```java { .api }

66

/**

67

* Get all changesets in the changelog

68

* @return List of all changesets

69

*/

70

public List<ChangeSet> getChangeSets()

71

72

/**

73

* Add a changeset to the changelog

74

* @param changeSet ChangeSet to add

75

*/

76

public void addChangeSet(ChangeSet changeSet)

77

78

/**

79

* Find specific changeset by identifiers

80

* @param path File path

81

* @param author Changeset author

82

* @param id Changeset ID

83

* @return ChangeSet if found, null otherwise

84

*/

85

public ChangeSet getChangeSet(String path, String author, String id)

86

```

87

88

### Validation

89

90

```java { .api }

91

/**

92

* Validate changelog against database

93

* @param database Target database

94

* @param contexts Execution contexts for filtering

95

* @param labelExpression Label expression for filtering

96

* @throws LiquibaseException if validation fails

97

*/

98

public void validate(Database database, Contexts contexts, LabelExpression labelExpression) throws LiquibaseException

99

100

/**

101

* Validate multiple changelogs

102

* @param database Target database

103

* @param changeLogsToValidate Changelogs to validate

104

* @return ValidationErrors containing any validation issues

105

*/

106

public ValidationErrors validate(Database database, DatabaseChangeLog... changeLogsToValidate)

107

```

108

109

### Parameters

110

111

```java { .api }

112

/**

113

* Get changelog parameters

114

* @return ChangeLogParameters instance

115

*/

116

public ChangeLogParameters getChangeLogParameters()

117

118

/**

119

* Set changelog parameters

120

* @param changeLogParameters Parameters to set

121

*/

122

public void setChangeLogParameters(ChangeLogParameters changeLogParameters)

123

```

124

125

## ChangeSet Class

126

127

The ChangeSet represents a single changeset containing one or more changes.

128

129

### Identification Properties

130

131

```java { .api }

132

/**

133

* Get unique changeset ID

134

* @return Changeset ID

135

*/

136

public String getId()

137

138

/**

139

* Get changeset author

140

* @return Author name

141

*/

142

public String getAuthor()

143

144

/**

145

* Get file path containing this changeset

146

* @return File path

147

*/

148

public String getFilePath()

149

```

150

151

### Execution Control Properties

152

153

```java { .api }

154

/**

155

* Get execution contexts for this changeset

156

* @return Contexts object

157

*/

158

public Contexts getContexts()

159

160

/**

161

* Get execution labels for this changeset

162

* @return Labels object

163

*/

164

public Labels getLabels()

165

166

/**

167

* Get target database types for this changeset

168

* @return Set of database type names

169

*/

170

public Set<String> getDbms()

171

172

/**

173

* Check if changeset should re-run when changed

174

* @return true if runOnChange is enabled

175

*/

176

public Boolean getRunOnChange()

177

178

/**

179

* Check if changeset should always run

180

* @return true if runAlways is enabled

181

*/

182

public Boolean getRunAlways()

183

184

/**

185

* Check if changeset should fail on error

186

* @return true if failOnError is enabled (default)

187

*/

188

public Boolean getFailOnError()

189

```

190

191

### Change Management

192

193

```java { .api }

194

/**

195

* Get list of changes in this changeset

196

* @return List of Change objects

197

*/

198

public List<Change> getChanges()

199

200

/**

201

* Add a change to this changeset

202

* @param change Change to add

203

*/

204

public void addChange(Change change)

205

```

206

207

### Rollback Management

208

209

```java { .api }

210

/**

211

* Get rollback changes for this changeset

212

* @return List of rollback changes

213

*/

214

public List<Change> getRollback()

215

216

/**

217

* Add a rollback change

218

* @param change Rollback change to add

219

*/

220

public void addRollbackChange(Change change)

221

```

222

223

## Core Change Types

224

225

### Table Operations

226

227

Create, modify, and drop tables:

228

229

```java { .api }

230

// Create table

231

public class CreateTableChange extends AbstractChange {

232

public void setTableName(String tableName)

233

public void setSchemaName(String schemaName)

234

public void setCatalogName(String catalogName)

235

public void addColumn(ColumnConfig column)

236

}

237

238

// Drop table

239

public class DropTableChange extends AbstractChange {

240

public void setTableName(String tableName)

241

public void setSchemaName(String schemaName)

242

public void setCatalogName(String catalogName)

243

public void setCascadeConstraints(Boolean cascadeConstraints)

244

}

245

246

// Rename table

247

public class RenameTableChange extends AbstractChange {

248

public void setOldTableName(String oldTableName)

249

public void setNewTableName(String newTableName)

250

public void setSchemaName(String schemaName)

251

public void setCatalogName(String catalogName)

252

}

253

```

254

255

### Column Operations

256

257

Add, modify, and drop columns:

258

259

```java { .api }

260

// Add column

261

public class AddColumnChange extends AbstractChange {

262

public void setTableName(String tableName)

263

public void setSchemaName(String schemaName)

264

public void addColumn(ColumnConfig column)

265

}

266

267

// Drop column

268

public class DropColumnChange extends AbstractChange {

269

public void setTableName(String tableName)

270

public void setColumnName(String columnName)

271

public void setSchemaName(String schemaName)

272

}

273

274

// Modify data type

275

public class ModifyDataTypeChange extends AbstractChange {

276

public void setTableName(String tableName)

277

public void setColumnName(String columnName)

278

public void setNewDataType(String newDataType)

279

public void setSchemaName(String schemaName)

280

}

281

282

// Rename column

283

public class RenameColumnChange extends AbstractChange {

284

public void setTableName(String tableName)

285

public void setOldColumnName(String oldColumnName)

286

public void setNewColumnName(String newColumnName)

287

public void setColumnDataType(String columnDataType)

288

public void setSchemaName(String schemaName)

289

}

290

```

291

292

### Constraint Operations

293

294

Manage various database constraints:

295

296

```java { .api }

297

// Add primary key

298

public class AddPrimaryKeyChange extends AbstractChange {

299

public void setTableName(String tableName)

300

public void setColumnNames(String columnNames)

301

public void setConstraintName(String constraintName)

302

public void setSchemaName(String schemaName)

303

}

304

305

// Drop primary key

306

public class DropPrimaryKeyChange extends AbstractChange {

307

public void setTableName(String tableName)

308

public void setConstraintName(String constraintName)

309

public void setSchemaName(String schemaName)

310

}

311

312

// Add foreign key

313

public class AddForeignKeyConstraintChange extends AbstractChange {

314

public void setBaseTableName(String baseTableName)

315

public void setBaseColumnNames(String baseColumnNames)

316

public void setReferencedTableName(String referencedTableName)

317

public void setReferencedColumnNames(String referencedColumnNames)

318

public void setConstraintName(String constraintName)

319

public void setOnDelete(String onDelete)

320

public void setOnUpdate(String onUpdate)

321

}

322

323

// Drop foreign key

324

public class DropForeignKeyConstraintChange extends AbstractChange {

325

public void setBaseTableName(String baseTableName)

326

public void setConstraintName(String constraintName)

327

public void setBaseTableSchemaName(String baseTableSchemaName)

328

}

329

330

// Add unique constraint

331

public class AddUniqueConstraintChange extends AbstractChange {

332

public void setTableName(String tableName)

333

public void setColumnNames(String columnNames)

334

public void setConstraintName(String constraintName)

335

public void setSchemaName(String schemaName)

336

}

337

338

// Drop unique constraint

339

public class DropUniqueConstraintChange extends AbstractChange {

340

public void setTableName(String tableName)

341

public void setConstraintName(String constraintName)

342

public void setSchemaName(String schemaName)

343

}

344

345

// Add not null constraint

346

public class AddNotNullConstraintChange extends AbstractChange {

347

public void setTableName(String tableName)

348

public void setColumnName(String columnName)

349

public void setColumnDataType(String columnDataType)

350

public void setDefaultNullValue(String defaultNullValue)

351

public void setSchemaName(String schemaName)

352

}

353

354

// Drop not null constraint

355

public class DropNotNullConstraintChange extends AbstractChange {

356

public void setTableName(String tableName)

357

public void setColumnName(String columnName)

358

public void setColumnDataType(String columnDataType)

359

public void setSchemaName(String schemaName)

360

}

361

```

362

363

### Index Operations

364

365

Create and drop database indexes:

366

367

```java { .api }

368

// Create index

369

public class CreateIndexChange extends AbstractChange {

370

public void setTableName(String tableName)

371

public void setIndexName(String indexName)

372

public void addColumn(ColumnConfig column)

373

public void setUnique(Boolean unique)

374

public void setSchemaName(String schemaName)

375

}

376

377

// Drop index

378

public class DropIndexChange extends AbstractChange {

379

public void setTableName(String tableName)

380

public void setIndexName(String indexName)

381

public void setSchemaName(String schemaName)

382

}

383

```

384

385

### Data Operations

386

387

Manipulate table data:

388

389

```java { .api }

390

// Insert data

391

public class InsertDataChange extends AbstractChange {

392

public void setTableName(String tableName)

393

public void addColumn(ColumnConfig column)

394

public void setSchemaName(String schemaName)

395

}

396

397

// Update data

398

public class UpdateDataChange extends AbstractChange {

399

public void setTableName(String tableName)

400

public void addColumn(ColumnConfig column)

401

public void addWhereParam(ColumnConfig whereParam)

402

public void setWhere(String where)

403

public void setSchemaName(String schemaName)

404

}

405

406

// Delete data

407

public class DeleteDataChange extends AbstractChange {

408

public void setTableName(String tableName)

409

public void addWhereParam(ColumnConfig whereParam)

410

public void setWhere(String where)

411

public void setSchemaName(String schemaName)

412

}

413

414

// Load data from file

415

public class LoadDataChange extends AbstractChange {

416

public void setTableName(String tableName)

417

public void setFile(String file)

418

public void setRelativeToChangelogFile(Boolean relativeToChangelogFile)

419

public void setEncoding(String encoding)

420

public void setSeparator(String separator)

421

public void setQuotchar(String quotchar)

422

public void addColumn(LoadDataColumnConfig column)

423

}

424

425

// Load and update data

426

public class LoadUpdateDataChange extends AbstractChange {

427

public void setTableName(String tableName)

428

public void setFile(String file)

429

public void setPrimaryKey(String primaryKey)

430

public void addColumn(LoadDataColumnConfig column)

431

}

432

```

433

434

### View and Procedure Operations

435

436

Manage views and stored procedures:

437

438

```java { .api }

439

// Create view

440

public class CreateViewChange extends AbstractChange {

441

public void setViewName(String viewName)

442

public void setSelectQuery(String selectQuery)

443

public void setSchemaName(String schemaName)

444

public void setReplaceIfExists(Boolean replaceIfExists)

445

}

446

447

// Drop view

448

public class DropViewChange extends AbstractChange {

449

public void setViewName(String viewName)

450

public void setSchemaName(String schemaName)

451

}

452

453

// Create stored procedure

454

public class CreateProcedureChange extends AbstractChange {

455

public void setProcedureName(String procedureName)

456

public void setProcedureText(String procedureText)

457

public void setSchemaName(String schemaName)

458

}

459

460

// Drop stored procedure

461

public class DropProcedureChange extends AbstractChange {

462

public void setProcedureName(String procedureName)

463

public void setSchemaName(String schemaName)

464

}

465

```

466

467

### SQL Operations

468

469

Execute custom SQL:

470

471

```java { .api }

472

// Execute raw SQL

473

public class SQLChange extends AbstractChange {

474

public void setSql(String sql)

475

public void setEndDelimiter(String endDelimiter)

476

public void setSplitStatements(Boolean splitStatements)

477

public void setStripComments(Boolean stripComments)

478

}

479

480

// Execute SQL from file

481

public class SQLFileChange extends AbstractChange {

482

public void setPath(String path)

483

public void setRelativeToChangelogFile(Boolean relativeToChangelogFile)

484

public void setEncoding(String encoding)

485

public void setEndDelimiter(String endDelimiter)

486

public void setSplitStatements(Boolean splitStatements)

487

}

488

```

489

490

## Example Usage

491

492

### Creating a DatabaseChangeLog Programmatically

493

494

```java { .api }

495

import liquibase.changelog.DatabaseChangeLog;

496

import liquibase.changelog.ChangeSet;

497

import liquibase.change.core.CreateTableChange;

498

import liquibase.change.ColumnConfig;

499

500

// Create changelog

501

DatabaseChangeLog changelog = new DatabaseChangeLog();

502

changelog.setPhysicalFilePath("db/changelog/programmatic-changelog.xml");

503

504

// Create changeset

505

ChangeSet changeSet = new ChangeSet(

506

"1", // id

507

"admin", // author

508

false, // alwaysRun

509

false, // runOnChange

510

"db/changelog/programmatic-changelog.xml", // filePath

511

null, // contextFilter

512

null, // dbmsList

513

null, // labels

514

true, // runInTransaction

515

null, // objectQuotingStrategy

516

changelog // changeLog

517

);

518

519

// Create table change

520

CreateTableChange createTable = new CreateTableChange();

521

createTable.setTableName("users");

522

createTable.setSchemaName("public");

523

524

// Add columns

525

ColumnConfig idColumn = new ColumnConfig();

526

idColumn.setName("id");

527

idColumn.setType("BIGINT");

528

idColumn.setAutoIncrement(true);

529

ColumnConfig constraints = new ColumnConfig.ConstraintsConfig();

530

constraints.setPrimaryKey(true);

531

constraints.setNullable(false);

532

idColumn.setConstraints(constraints);

533

createTable.addColumn(idColumn);

534

535

ColumnConfig nameColumn = new ColumnConfig();

536

nameColumn.setName("name");

537

nameColumn.setType("VARCHAR(255)");

538

ColumnConfig nameConstraints = new ColumnConfig.ConstraintsConfig();

539

nameConstraints.setNullable(false);

540

nameColumn.setConstraints(nameConstraints);

541

createTable.addColumn(nameColumn);

542

543

ColumnConfig emailColumn = new ColumnConfig();

544

emailColumn.setName("email");

545

emailColumn.setType("VARCHAR(255)");

546

ColumnConfig emailConstraints = new ColumnConfig.ConstraintsConfig();

547

emailConstraints.setUnique(true);

548

emailColumn.setConstraints(emailConstraints);

549

createTable.addColumn(emailColumn);

550

551

// Add change to changeset

552

changeSet.addChange(createTable);

553

554

// Add changeset to changelog

555

changelog.addChangeSet(changeSet);

556

```

557

558

### Complete Changeset with Multiple Changes

559

560

```java { .api }

561

// Create comprehensive changeset

562

ChangeSet complexChangeSet = new ChangeSet(

563

"2", "admin", false, false,

564

"db/changelog/complex-changes.xml",

565

null, null, null, true, null, changelog

566

);

567

568

// Add table

569

CreateTableChange createOrdersTable = new CreateTableChange();

570

createOrdersTable.setTableName("orders");

571

createOrdersTable.setSchemaName("public");

572

573

ColumnConfig orderIdColumn = new ColumnConfig();

574

orderIdColumn.setName("order_id");

575

orderIdColumn.setType("BIGINT");

576

orderIdColumn.setAutoIncrement(true);

577

ColumnConfig orderIdConstraints = new ColumnConfig.ConstraintsConfig();

578

orderIdConstraints.setPrimaryKey(true);

579

orderIdColumn.setConstraints(orderIdConstraints);

580

createOrdersTable.addColumn(orderIdColumn);

581

582

ColumnConfig userIdColumn = new ColumnConfig();

583

userIdColumn.setName("user_id");

584

userIdColumn.setType("BIGINT");

585

ColumnConfig userIdConstraints = new ColumnConfig.ConstraintsConfig();

586

userIdConstraints.setNullable(false);

587

userIdColumn.setConstraints(userIdConstraints);

588

createOrdersTable.addColumn(userIdColumn);

589

590

complexChangeSet.addChange(createOrdersTable);

591

592

// Add foreign key

593

AddForeignKeyConstraintChange addFK = new AddForeignKeyConstraintChange();

594

addFK.setBaseTableName("orders");

595

addFK.setBaseColumnNames("user_id");

596

addFK.setReferencedTableName("users");

597

addFK.setReferencedColumnNames("id");

598

addFK.setConstraintName("fk_orders_user_id");

599

addFK.setOnDelete("CASCADE");

600

601

complexChangeSet.addChange(addFK);

602

603

// Add index

604

CreateIndexChange createIndex = new CreateIndexChange();

605

createIndex.setTableName("orders");

606

createIndex.setIndexName("idx_orders_user_id");

607

ColumnConfig indexColumn = new ColumnConfig();

608

indexColumn.setName("user_id");

609

createIndex.addColumn(indexColumn);

610

611

complexChangeSet.addChange(createIndex);

612

613

// Insert sample data

614

InsertDataChange insertData = new InsertDataChange();

615

insertData.setTableName("users");

616

ColumnConfig nameData = new ColumnConfig();

617

nameData.setName("name");

618

nameData.setValue("John Doe");

619

insertData.addColumn(nameData);

620

ColumnConfig emailData = new ColumnConfig();

621

emailData.setName("email");

622

emailData.setValue("john.doe@example.com");

623

insertData.addColumn(emailData);

624

625

complexChangeSet.addChange(insertData);

626

627

changelog.addChangeSet(complexChangeSet);

628

```

629

630

### Changeset with Context and Labels

631

632

```java { .api }

633

// Create changeset with filtering

634

ChangeSet filteredChangeSet = new ChangeSet(

635

"3", "developer", false, false,

636

"db/changelog/dev-changes.xml",

637

"development,testing", // contexts

638

null, // dbms

639

"feature-auth,version-2.0", // labels

640

true, null, changelog

641

);

642

643

// Add development-specific change

644

CreateTableChange devTable = new CreateTableChange();

645

devTable.setTableName("debug_log");

646

devTable.setSchemaName("public");

647

648

ColumnConfig logIdColumn = new ColumnConfig();

649

logIdColumn.setName("log_id");

650

logIdColumn.setType("BIGINT");

651

logIdColumn.setAutoIncrement(true);

652

ColumnConfig logIdConstraints = new ColumnConfig.ConstraintsConfig();

653

logIdConstraints.setPrimaryKey(true);

654

logIdColumn.setConstraints(logIdConstraints);

655

devTable.addColumn(logIdColumn);

656

657

ColumnConfig messageColumn = new ColumnConfig();

658

messageColumn.setName("message");

659

messageColumn.setType("TEXT");

660

devTable.addColumn(messageColumn);

661

662

filteredChangeSet.addChange(devTable);

663

changelog.addChangeSet(filteredChangeSet);

664

```

665

666

### Changeset with Custom SQL

667

668

```java { .api }

669

// Create changeset with custom SQL

670

ChangeSet sqlChangeSet = new ChangeSet(

671

"4", "dba", false, false,

672

"db/changelog/custom-sql.xml",

673

null, null, null, true, null, changelog

674

);

675

676

// Add custom SQL change

677

SQLChange customSQL = new SQLChange();

678

customSQL.setSql(

679

"CREATE OR REPLACE FUNCTION calculate_order_total(order_id BIGINT) " +

680

"RETURNS DECIMAL(10,2) AS $$ " +

681

"BEGIN " +

682

" RETURN (SELECT SUM(quantity * price) FROM order_items WHERE order_id = $1); " +

683

"END; " +

684

"$$ LANGUAGE plpgsql;"

685

);

686

customSQL.setEndDelimiter(";");

687

customSQL.setSplitStatements(false);

688

689

sqlChangeSet.addChange(customSQL);

690

691

// Add rollback SQL

692

SQLChange rollbackSQL = new SQLChange();

693

rollbackSQL.setSql("DROP FUNCTION IF EXISTS calculate_order_total(BIGINT);");

694

sqlChangeSet.addRollbackChange(rollbackSQL);

695

696

changelog.addChangeSet(sqlChangeSet);

697

```

698

699

### Validation Example

700

701

```java { .api }

702

import liquibase.database.Database;

703

import liquibase.Contexts;

704

import liquibase.LabelExpression;

705

import liquibase.exception.ValidationErrors;

706

707

// Validate changelog

708

try {

709

changelog.validate(database, new Contexts("production"), new LabelExpression());

710

System.out.println("Changelog validation passed");

711

} catch (LiquibaseException e) {

712

System.err.println("Changelog validation failed: " + e.getMessage());

713

}

714

715

// Detailed validation

716

ValidationErrors errors = changelog.validate(database);

717

if (errors.hasErrors()) {

718

System.out.println("Validation errors found:");

719

for (String error : errors.getErrorMessages()) {

720

System.out.println(" - " + error);

721

}

722

}

723

```