<changeSet id="1" author="nvoxland">
<createTable tableName="company">
<column name="address" type="varchar(255)"/>
</createTable>
</changeSet>
For months, we’ve been suffering from mediocre performance of part of our website (codescene.io) due to inability to effectively cache expensive page loads. A large part of it was a problem with CloudFront I discovered in December 2023 after conversation with the AWS Support team. Here’s a story of solving this problem.
This is an experimental type of a blog post I call a "deep dive". It goes deeper than usual, it’s longer than my other posts, and it explores more aspects of the topic, trying to deepen your (and my) understanding of the subject (DNS resolution).
Talking to a relational database with Clojure is relatively easy. There’s a great library next.jdbc for that. In legacy applications, you may encounter an older library, clojure.java.jdbc.
Liquibase is a well-know tool for tracking, versioning, and deploying database schema changes.
It uses changelog files to list database changes in the form of changesets (SQL, XML, YAML, JSON), which consists of Change Types. Standard changsets use SQL or a DB-agnostic equivalent written in XML, YAML, or JSON.
Here’s an example of a very simple changset adding a new table with a single column:
<changeSet id="1" author="nvoxland">
<createTable tableName="company">
<column name="address" type="varchar(255)"/>
</createTable>
</changeSet>
Sometimes, there’s a more complicated migration that’s very difficult or impossible to express in SQL (or its Xml/YAML/JSON equivalent). That is, you need to write actual code to perform the migration. In that case, Liquibase offers customChange Change Type.
To implement a custom migration you need to:
Create a Java class that implements the liquibase.change.custom.CustomSqlChange
or liquibase.change.custom.CustomTaskChange
interface
(showing only a subset of methods here):
public class ExampleCustomTaskChange implements CustomTaskChange, CustomTaskRollback {
private String helloTo;
@SuppressWarnings({"UnusedDeclaration", "FieldCanBeLocal"})
private ResourceAccessor resourceAccessor;
@Override
public void execute(Database database) throws CustomChangeException {
Scope.getCurrentScope().getLog(getClass()).info("Hello "+getHelloTo());
}
@Override
public void rollback(Database database) throws CustomChangeException, RollbackImpossibleException {
Scope.getCurrentScope().getLog(getClass()).info("Goodbye "+getHelloTo());
}
...
}
Compile the created class
, package it into a JAR file, and then add it to a Liquibase classpath.
Reference the class in your changelog:
...
<changeSet id="21" author="nvoxland">
<customChange class="liquibase.change.custom.ExampleCustomTaskChange">
<param name="helloTo" value="world"/>
</customChange>
</changeSet>
...
Persuading your ssh client to use one and only one SSH key may be tricky. In any case, it may help to understand what keys/identities are actually used when you connect to the remote host.