4.7 KiB
Create Vitruvio Patch
All messages shown to the user must be written in Portuguese.
You are creating a new Liquibase database migration patch inside a Vitruvio repository. Follow these steps in order.
Step 1 — Confirm you are inside a Vitruvio repo
ls vitruvio.json 2>/dev/null && echo "OK" || echo "NOT_A_VITRUVIO_REPO"
If NOT_A_VITRUVIO_REPO, stop and tell the user to cd into the correct repo.
Step 2 — Inspect existing patches to determine the next changeset ID
find patches/ -name "*.xml" | xargs grep -h 'id="[0-9]' 2>/dev/null | grep -oP 'id="\K[0-9]+' | sort -n | tail -1
The next ID = last found ID + 1. If no patches exist yet, start at 1.
Also check whether oracle and postgresql subdirectories already exist:
ls patches/
Step 3 — Collect migration details
Ask the user (in a single message, only ask what is missing):
- What this migration does — describe the change (e.g. "add column STATUS to table PEDIDO", "create table AUDIT_LOG", "insert config rows").
- Author — Vitruvio username (e.g.
joao.felix). Usegit config user.nameif unsure. - Module key — used in the filename (e.g.
GO,checklist,faturamento). Default: the repo'smetadata.keyfromvitruvio.json.
Step 4 — Create the patch files
Both oracle/ and postgresql/ files must always be created and kept in sync.
Filename convention: {YYYYMMDDHHmm}_{MODULE_KEY}.xml (e.g. 202506011430_checklist.xml). Use the current date and time.
mkdir -p patches/oracle patches/postgresql
Absolute rules
- Append-only. Never edit or delete existing
<changeSet>entries — modifying a checksum that Liquibase already recorded breaks deployment. - Unique numeric IDs. Each
<changeSet id="...">must have a unique ID within the repo. Increment from the last found. - Always use
<preConditions onFail="MARK_RAN">— every changeset must be idempotent and safe to re-run on any DB state. - Oracle ≠ PostgreSQL. Write each file for its target DB — data types, sequences, and quoting differ. Never copy-paste blindly.
- One logical change per changeset — don't batch unrelated changes into a single
<changeSet>.
File skeleton
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd
http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd">
<changeSet author="<author>" id="<next-id>" objectQuotingStrategy="LEGACY">
<preConditions onError="WARN" onFail="MARK_RAN" onSqlOutput="IGNORE">
<!-- guard appropriate for the operation — see examples below -->
</preConditions>
<sql endDelimiter=";" splitStatements="true" stripComments="false">
-- SQL for this DB dialect
</sql>
</changeSet>
</databaseChangeLog>
preConditions reference
| Operation | Guard to use |
|---|---|
| CREATE TABLE | <not><tableExists tableName="MY_TABLE"/></not> |
| ADD COLUMN | <not><columnExists tableName="MY_TABLE" columnName="MY_COL"/></not> |
| CREATE INDEX | <not><indexExists indexName="IDX_NAME"/></not> |
| ADD CONSTRAINT / FK | <not><foreignKeyConstraintExists foreignKeyName="FK_NAME"/></not> |
| INSERT row (by PK) | <sqlCheck expectedResult="0">SELECT COUNT(*) FROM MY_TABLE WHERE ID = 1</sqlCheck> |
| DROP TABLE | <tableExists tableName="MY_TABLE"/> |
| DROP COLUMN | <columnExists tableName="MY_TABLE" columnName="MY_COL"/> |
Oracle vs PostgreSQL differences to watch
| Oracle | PostgreSQL | |
|---|---|---|
| Auto-increment | Separate CREATE SEQUENCE + trigger or DEFAULT seq.NEXTVAL |
SERIAL or GENERATED ALWAYS AS IDENTITY |
| String type | VARCHAR2(n) |
VARCHAR(n) |
| Boolean | NUMBER(1) |
BOOLEAN |
| Date/time | DATE, TIMESTAMP |
DATE, TIMESTAMP |
| Current timestamp | SYSDATE |
CURRENT_TIMESTAMP |
| Quoting | LEGACY strategy (unquoted) |
Same |
Step 5 — Check vitruvio.json patches registration
The patches directory only needs to be registered once. Check if it is already there:
grep -A2 '"patches"' vitruvio.json
If not registered, add to vitruvio.json:
"patches": "patches/"
Step 6 — Report
Tell the user:
- Files created:
patches/oracle/<filename>.xmlandpatches/postgresql/<filename>.xml - Changeset IDs used
- Summary of what each changeset does
- Reminder: never edit existing changesets once committed — add new ones instead