npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

clunky-migration-tool

v1.0.0

Published

A version migration tool, written in Bash.

Downloads

4

Readme

Clunky migration tool

A version migration tool, written in Bash - fast and well tested. May be used for database schema and data migrations.

Upgrade a PostgreSQL database to the most recent schema, with:

CMT_TARGET_PSQL_URI=postgres://user:pwd@localhost:5432/app
clunky-migration-tool -m filetree:psql

An example SQL file tree that defines the upgrade process is given below:

.clunky-migration-tool-source-filetree
 v0001
     from-scratch
         000-schema.sql
         010-data.sql
 v0002
     from-previous
         000-patch-schema.sql
         010-update-data.sql
     from-scratch
         000-schema.sql
         010-data.sql

To display the files involved in a migration from version v3 to version v5 (a "dry run"), use:

CMT_TARGET_DEBUG_VERSION=v3
clunky-migration-tool -m filetree:debug v5

Command line

clunky-migration-tool
  -v|--verbose              enable verbose mode
  -m|--mode source:target   upgrades taken from source type and applied to target type
  -D name=value             defines a variable 'name' set to 'value'
  -C directory              run in the specified directory
  <to-version>              "last" or empty (equivalent), or a given version (e.g. "v5")

Overview

"Clunky migration tool" uses a "source" to update a "target". If a target is at version 3, but a source contains upgrades up to version 5, an upgrade from version 3 to version 4 may be first applied, followed by an upgrade from version 4 to version 5. A fresh target may be directly populated to the desired version, without going through incremental upgrades.

In common scenarios, a target may be a database, and a source may be a file tree containing SQL files, organized by version.

However, this project does not prescribe what a target or a source may be. Instead, it defines the interfaces that sources and targets must implement.

Sources and targets

A source must define the following interface:

source_initialize
source_get_version ${VERSION_NAME}
source_get_changes ${VERSION_START} ${VERSION_END}

The function source_initialize is optional, and may perform initialization tasks.

The function source_get_version returns the actual identifier that corresponds to a given version name. An actual version identifier must be returned for the special version names first and last - for example v1 and v5, respectively. If the given ${VERSION_NAME} cannot be resolved, the function must exit with an error code. If ${VERSION_NAME} is scratch, then scratch must be returned. The names first, last, and scratch have a special meaning and cannot be used as actual application versions.

The function source_get_changes returns a set of handles to patches that need to be applied in order to migrate from ${VERSION_START} to ${VERSION_END} (both parameters are passed through source_get_version). If ${VERSION_START} is "scratch", the function may return the changes needed to directly create the target at ${VERSION_END}. If downgrades are not supported, namely when ${VERSION_END} is before ${VERSION_START}, the function must return an empty string.

A target must define the following interface:

target_initialize
target_get_current_version
target_accept_changes ${VERSION}

The function target_initialize is optional, but it is likely needed to perform initialization tasks.

The function target_get_current_version returns the current version of the target, or scratch if the target has not been populated with any version.

The function target_accept_changes transactionally applies changes to the target, and sets the current version to its parameter ${VERSION}. It must allow the output of source_get_changes to be piped into it. Moreover, it must not change the version if the set of changes provided by the source is empty.

For example, the following code template is expected to work.

source_initialize
target_initialize
BEGIN=$(target_get_current_version)
END=$(source_get_version "last") # or other version to upgrade to
source_get_changes ${BEGIN} ${END} | target_accept_changes ${END}

Custom sources and targets

The type of the source and the type of the target are specified in the mode parameter, -m, and are separated by a column. In the example below, the source is of type filetree, and the target of type psql.

clunky-migration-tool -m filetree:psql v5

These two types are standard, and their interfaces are defined within the library, respectively, at:

${LIBRARY_ROOT}/source/filetree/main.sh
${LIBRARY_ROOT}/target/psql/main.sh

User-specified types can be used and implemented as follows:

ls -l ./clunky-migration-tool/target/sqlite/main.sh
clunky-migration-tool -m filetree:sqlite v5

The library first searches for user-defined source and target types, thus unintentional name clashes with library-defined types are avoided.

Postgres migration example

This library was initially written to populate and upgrade Postgresql databases from SQL files grouped by version into directories. In this scenario, the source is of type "filetree", and the target is of type "psql". The corresponding implementations and tests are available in the ${LIBRARY_ROOT}/source/filetree and ${LIBRARY_ROOT}/target/psql directories, respectively.

A source of type filetree may contain directories and files as follows:

v0001-0.0.0
    from-scratch
        000-schema.sql
        010-data.sql
v0002-0.0.1
    from-previous
        000-patch-schema.sql
        010-update-data.sql
    from-scratch
        000-schema.sql
        010-data.sql

A target of type psql stores the current version into a specially created table, executes the SQL code contained in the SQL files whose names are supplied by the source, and updates the current version only if everything goes well during the upgrade.