<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Library on Clément Joly – Open-Source, Rust &amp; SQLite</title><link>https://cj.rs/tags/library/</link><description>Recent content in Library on Clément Joly – Open-Source, Rust &amp; SQLite</description><image><title>Clément Joly – Open-Source, Rust &amp; SQLite</title><url>https://cj.rs/images/open-graph-pages.jpg</url><link>https://cj.rs/images/open-graph-pages.jpg</link></image><generator>Hugo</generator><language>en</language><copyright>Clément Joly</copyright><lastBuildDate>Thu, 28 May 2026 23:48:29 +0000</lastBuildDate><atom:link href="https://cj.rs/tags/library/index.xml" rel="self" type="application/rss+xml"/><item><title>Rusqlite Snapshot Testing</title><link>https://cj.rs/rusqlite-snapshot-testing/</link><pubDate>Sat, 29 Mar 2025 17:32:05 +0000</pubDate><guid>https://cj.rs/rusqlite-snapshot-testing/</guid><description>Snapshot testing tool for rusqlite</description><content:encoded><![CDATA[
<p style="display: flex; justify-content: space-between">
  <a href="https://github.com/cljoly/rusqlite-snapshot-testing" data-goatcounter-click="ext-github-rusqlite-snapshot-testing" data-goatcounter-title="cljoly/rusqlite-snapshot-testing">
    <span class="svgicon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
    stroke-linecap="round" stroke-linejoin="round">
    <path
        d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22">
    </path>
</svg></span>&nbsp;cljoly/rusqlite-snapshot-testing
  </a>
  <a class="badges" href="https://github.com/cljoly/rusqlite-snapshot-testing" data-goatcounter-click="ext-stargithub-rusqlite-snapshot-testing" data-goatcounter-title="stars cljoly/rusqlite-snapshot-testing">
    <img src="https://img.shields.io/github/stars/cljoly/rusqlite-snapshot-testing?style=social" alt="Github stars for rusqlite-snapshot-testing">
  </a>
</p>


<div class="badges">

<p><a href="https://docs.rs/rusqlite-snapshot-testing">
<img alt="docs.rs" loading="lazy" src="https://img.shields.io/docsrs/rusqlite-snapshot-testing"></a>
<a href="https://crates.io/crates/rusqlite-snapshot-testing">
<img alt="Crates.io" loading="lazy" src="https://img.shields.io/crates/v/rusqlite-snapshot-testing"></a>

</div>
</p>
<p>Tool to perform snapshot testing on an SQLite database, using <a href="https://crates.io/crates/rusqlite">rusqlite</a>.</p>
<p>The goal is to expose both data and the schema in the snapshots. It is also compatible with <a href="https://insta.rs">Insta Snapshots</a></p>
<p><strong>This is experimental software, expect breaking changes between 0.x versions, consistent with the semver rules for Rust.</strong></p>
<h2 id="background-reading-on-snapshot-testing">Background reading on snapshot testing.</h2>
<ul>
<li><a href="https://ianthehenry.com/posts/my-kind-of-repl/">https://ianthehenry.com/posts/my-kind-of-repl/</a></li>
<li><a href="https://tigerbeetle.com/blog/2024-05-14-snapshot-testing-for-the-masses/">https://tigerbeetle.com/blog/2024-05-14-snapshot-testing-for-the-masses/</a></li>
<li><a href="https://blog.janestreet.com/the-joy-of-expect-tests/">https://blog.janestreet.com/the-joy-of-expect-tests/</a></li>
</ul>
]]></content:encoded></item><item><title>Rusqlite Changelog</title><link>https://cj.rs/rusqlite_migration_docs/changelog/</link><pubDate>Mon, 24 Mar 2025 20:32:05 +0000</pubDate><guid>https://cj.rs/rusqlite_migration_docs/changelog/</guid><description>&lt;p&gt;Release notes for the &lt;a href="https://cj.rs/rusqlite_migration"&gt;rusqlite_migration library&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="version-260"&gt;Version 2.6.0&lt;/h2&gt;
&lt;h3 id="dependencies"&gt;Dependencies&lt;/h3&gt;
&lt;p&gt;Rusqlite was updated from 0.39.0 to 0.40.0.
Please see &lt;a href="https://github.com/rusqlite/rusqlite/releases/tag/v0.40.0"&gt;the release notes for 0.40.0&lt;/a&gt;.
There are in paricular quite a few breaking changes around VTab APIs.&lt;/p&gt;
&lt;p&gt;Update other dev dependencies, see git history for details.
Also factored out the rusqlite package dependency details into the workspace-level Cargo.toml.&lt;/p&gt;
&lt;h2 id="version-250"&gt;Version 2.5.0&lt;/h2&gt;
&lt;h3 id="dependencies-1"&gt;Dependencies&lt;/h3&gt;
&lt;p&gt;Rusqlite was updated from 0.38.0 to 0.39.0.
Please see &lt;a href="https://github.com/rusqlite/rusqlite/releases/tag/v0.39.0"&gt;the release notes for 0.39.0&lt;/a&gt;.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Release notes for the <a href="https://cj.rs/rusqlite_migration">rusqlite_migration library</a>.</p>
<h2 id="version-260">Version 2.6.0</h2>
<h3 id="dependencies">Dependencies</h3>
<p>Rusqlite was updated from 0.39.0 to 0.40.0.
Please see <a href="https://github.com/rusqlite/rusqlite/releases/tag/v0.40.0">the release notes for 0.40.0</a>.
There are in paricular quite a few breaking changes around VTab APIs.</p>
<p>Update other dev dependencies, see git history for details.
Also factored out the rusqlite package dependency details into the workspace-level Cargo.toml.</p>
<h2 id="version-250">Version 2.5.0</h2>
<h3 id="dependencies-1">Dependencies</h3>
<p>Rusqlite was updated from 0.38.0 to 0.39.0.
Please see <a href="https://github.com/rusqlite/rusqlite/releases/tag/v0.39.0">the release notes for 0.39.0</a>.</p>
<p>Update other dev dependencies, see git history for details.</p>
<h2 id="version-241">Version 2.4.1</h2>
<h3 id="documentation">Documentation</h3>
<p>Attempt to fix the docs.rs build which started failing in 2.4.0.</p>
<h3 id="dependencies-2">Dependencies</h3>
<p>Update some dev dependencies, see git history for details.</p>
<h2 id="version-240">Version 2.4.0</h2>
<h3 id="dependencies-3">Dependencies</h3>
<p>Rusqlite was updated from 0.37.0 to 0.38.0.
Please see <a href="https://github.com/rusqlite/rusqlite/releases/tag/v0.38.0">the release notes for 0.38.0</a>, there are a few breaking changes in this one.</p>
<p>Update other dev dependencies, see git history for details.</p>
<h3 id="features">Features</h3>
<p>Rusqlite 0.38 makes the cache statement optional. This feature was used for <a href="https://docs.rs/rusqlite_migration/2.3.0/rusqlite_migration/struct.M.html#method.foreign_key_check">foreign key checks</a>. The <code>rusqlite_migration</code> library does not enable any features from rusqlite, not even the default one. This way, downstream users can freely chose which feature to enable based on their needs. As a result, <code>rusqlite_migration</code> now handles statement caching for foreign key checks internally now. As side benefit, this also makes caching more efficient: the prepared statement is kept for the minimum time where it is needed and freed immediately, without taking space in the global cache used by rusqlite.</p>
<h3 id="other">Other</h3>
<ul>
<li>Use scoped GitHub tokens in actions, with as little privileges as possible.</li>
<li>Improve test build time by removing some unused optional deps.</li>
<li>Update most dependencies after a cooldown (this does not apply to security updates).</li>
<li>Errors don’t use debug output anymore, they should be more friendly to humans. This is not considered a breaking change because <code>Dislay</code> of errors is meant for human consuption and not for flow control in the program.</li>
</ul>
<h2 id="version-230">Version 2.3.0</h2>
<h3 id="dependencies-4">Dependencies</h3>
<p>Rusqlite was updated from 0.36.0 to 0.37.0.
Please see <a href="https://github.com/rusqlite/rusqlite/releases/tag/v0.37.0">the release notes for 0.37.0</a>.</p>
<h3 id="other-1">Other</h3>
<ul>
<li>Misc. clippy fixes</li>
<li>Minor improvements to the example in the Readme</li>
</ul>
<h2 id="version-220">Version 2.2.0</h2>




  
  
  
  

  <div class="alert alert-note">
    <p class="alert-heading">
      ℹ️
      
        Note
      
    </p>
    <p>The code of this version is identical to <a href="#version-220-beta-1">Version 2.2.0 Beta 1</a></p>
  </div>



<h3 id="features-1">Features</h3>
<ul>
<li>Implement the <code>Display</code> trait for <code>M</code>. This makes it easier to print errors pertaining to a particular migration (this feature is planned for the future, in the context of more extensive migration checks)</li>
</ul>
<h3 id="dependencies-5">Dependencies</h3>
<p>Rusqlite was updated from 0.35.0 to 0.36.0.
Please see <a href="https://github.com/rusqlite/rusqlite/releases/tag/v0.36.0">the release notes for 0.36.0</a>.</p>
<h3 id="other-2">Other</h3>
<ul>
<li>Update development dependencies</li>
<li>Improve tests to cover more cases, in particular around downward migrations</li>
<li>Add docs.rs link to Cargo metadata</li>
<li>Fix clippy warning in rust 1.87.0</li>
</ul>
<h2 id="version-220-beta-1">Version 2.2.0 Beta 1</h2>
<h3 id="features-2">Features</h3>
<ul>
<li>Implement the <code>Display</code> trait for <code>M</code>. This makes it easier to print errors pertaining to a particular migration (this feature is planned for the future, in the context of more extensive migration checks)</li>
</ul>
<h3 id="dependencies-6">Dependencies</h3>
<p>Rusqlite was updated from 0.35.0 to 0.36.0.
Please see <a href="https://github.com/rusqlite/rusqlite/releases/tag/v0.36.0">the release notes for 0.36.0</a>.</p>
<h3 id="other-3">Other</h3>
<ul>
<li>Update development dependencies</li>
<li>Improve tests to cover more cases, in particular around downward migrations</li>
<li>Add docs.rs link to Cargo metadata</li>
<li>Fix clippy warning in rust 1.87.0</li>
</ul>
<h2 id="version-210">Version 2.1.0</h2>
<h3 id="dependencies-7">Dependencies</h3>
<p>Rusqlite was updated from 0.34.0 to 0.34.0.
Please see <a href="https://github.com/rusqlite/rusqlite/releases/tag/v0.35.0">the release notes for 0.35.0</a>.</p>
<h2 id="version-200">Version 2.0.0</h2>
<h3 id="breaking-changes">Breaking changes</h3>
<h4 id="remove-the-alpha-async-tokio-rusqlite-feature">Remove the <code>alpha-async-tokio-rusqlite</code> Feature</h4>
<p>As the name of the feature suggest, we have had experimental support for async using tokio for a while now. Supporting that feature has been quite a big burden, introducing some duplicated code in the <code>AsyncMigrations</code> struct in particular, as well as a whole set of very similar tests. Plus the benefit of async is limited here, because everything gets executed in a blocking fashion in sqlite anyway.</p>
<p>It turns out that we don’t need the async support in rusqlite_migration for folks to use async libraries. For instance, with tokio-rusqlite, you can define migrations like in the sync context and run:</p>
<div class="highlight"><pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span>    <span style="color:#e06c75">async_conn</span>
</span></span><span style="display:flex;"><span>        .<span style="color:#e06c75">call_unwrap</span>(<span style="color:#56b6c2">|</span><span style="color:#e06c75">conn</span><span style="color:#56b6c2">|</span> <span style="color:#e06c75">MIGRATIONS</span>.<span style="color:#e06c75">to_latest</span>(<span style="color:#e06c75">conn</span>))
</span></span><span style="display:flex;"><span>        .<span style="color:#c678dd">await</span><span style="color:#56b6c2">?</span>;
</span></span></code></pre></div><p>See <a href="https://github.com/cljoly/rusqlite_migration/blob/master/examples/async/src/main.rs">the updated async example</a> for details, in particular why it’s fine to call <a href="https://docs.rs/tokio-rusqlite/0.6.0/tokio_rusqlite/struct.Connection.html#method.call_unwrap">a method</a> with unwrap in its name.</p>
<h4 id="make-the-builder-finalizer-method-not-generic">Make the Builder <code>Finalizer</code> Method Not Generic</h4>
<p>On a related note, now that we have removed the <code>AsyncMigrations</code> (see the section right above) struct, we only have <code>Migrations</code> so there is no need for the <code>MigrationsBuilder.finalize</code> method to be generic. Thus we removed the generic argument. To update your code, you can just do this:</p>
<div class="highlight"><pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-diff" data-lang="diff"><span style="display:flex;"><span><span style="color:#e06c75">-        .finalize::&lt;Migrations&gt;());
</span></span></span><span style="display:flex;"><span><span style="color:#98c379;font-weight:bold">+        .finalize());
</span></span></span></code></pre></div><h4 id="remove-migrationsnew_iter">Remove <code>Migrations::new_iter</code></h4>
<p>This function has been deprecated for a while now, remove it as a part of the major version bump. You can use the standard <code>FromIter</code> trait implementation instead.</p>
<h3 id="behavior-change">Behavior Change</h3>
<ul>
<li>When the <a href="https://www.sqlite.org/fileformat.html#user_version_number">user version field</a> is altered by other code in your application, we are now returning an explicit error (<code>Error::InvalidUserVersion</code>) when this can be detected. Previously, the library would silently misbehave.</li>
</ul>
<h3 id="features-3">Features</h3>
<ul>
<li>Add the new <a href="https://docs.rs/rusqlite_migration/2.0.0-beta.1/rusqlite_migration/struct.Migrations.html#method.from_slice"><code>Migrations::from_slice</code></a> constructor, which is <code>const</code> and takes a slice, so that it can be constructed in global constant, without using <code>LazyLock</code> or similar. Internally, this is possible because we now use a <a href="https://doc.rust-lang.org/std/borrow/enum.Cow.html"><code>Cow</code></a> structure to hold migrations.</li>
<li>Add <a href="https://docs.rs/rusqlite_migration/2.0.0-beta.1/rusqlite_migration/struct.Migrations.html#method.pending_migrations"><code>Migrations::pending_migrations</code></a> which returns the number of migrations that would be applied. This is mostly useful to take a backup of the database prior to applying migrations (and do nothing if no migrations will be applied).</li>
</ul>
<h3 id="dependencies-8">Dependencies</h3>
<p>Rusqlite was updated from 0.32.1 to 0.34.0.
Please see <a href="https://github.com/rusqlite/rusqlite/releases/tag/v0.34.0">the release notes for 0.34.0</a> and
<a href="https://github.com/rusqlite/rusqlite/releases/tag/v0.33.0">the release notes for 0.33.0</a>.
Tokio Rusqlite was removed as a dependency.</p>
<h3 id="minimum-rust-version">Minimum Rust Version</h3>
<p>Rust 1.84.</p>
<p>Moving forward, we expect to keep this aligned with rusqlite itself, now that it has a <a href="https://github.com/rusqlite/rusqlite?tab=readme-ov-file#minimum-supported-rust-version-msrv">policy</a> (introduced in <a href="https://github.com/rusqlite/rusqlite/pull/1576">october 2024</a>).</p>
<h2 id="version-200-beta-1">Version 2.0.0 Beta 1</h2>
<h3 id="features-4">Features</h3>
<ul>
<li>Add the new <a href="https://docs.rs/rusqlite_migration/2.0.0-beta.1/rusqlite_migration/struct.Migrations.html#method.from_slice"><code>Migrations::from_slice</code></a> constructor, which is <code>const</code> and takes a slice, so that it can be constructed in global constant, without using <code>LazyLock</code> or similar. Internally, this is possible because we now use a <a href="https://doc.rust-lang.org/std/borrow/enum.Cow.html"><code>Cow</code></a> structure to hold migrations.</li>
<li>Add <a href="https://docs.rs/rusqlite_migration/2.0.0-beta.1/rusqlite_migration/struct.Migrations.html#method.pending_migrations"><code>Migrations::pending_migrations</code></a> which returns the number of migrations that would be applied. This is mostly useful to take a backup of the database prior to applying migrations (and do nothing if no migrations will be applied).</li>
</ul>
<h2 id="version-200-alpha-1">Version 2.0.0 Alpha 1</h2>
<h3 id="breaking-changes-1">Breaking changes</h3>
<h4 id="remove-the-alpha-async-tokio-rusqlite-feature-1">Remove the <code>alpha-async-tokio-rusqlite</code> Feature</h4>
<p>As the name of the feature suggest, we have had experimental support for async using tokio for a while now. Supporting that feature has been quite a big burden, introducing some duplicated code in the <code>AsyncMigrations</code> struct in particular, as well as a whole set of very similar tests. Plus the benefit of async is limited here, because everything gets executed in a blocking fashion in sqlite anyway.</p>
<p>It turns out that we don’t need the async support in rusqlite_migration for folks to use async libraries. For instance, with tokio-rusqlite, you can define migrations like in the sync context and run:</p>
<div class="highlight"><pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span>    <span style="color:#e06c75">async_conn</span>
</span></span><span style="display:flex;"><span>        .<span style="color:#e06c75">call_unwrap</span>(<span style="color:#56b6c2">|</span><span style="color:#e06c75">conn</span><span style="color:#56b6c2">|</span> <span style="color:#e06c75">MIGRATIONS</span>.<span style="color:#e06c75">to_latest</span>(<span style="color:#e06c75">conn</span>))
</span></span><span style="display:flex;"><span>        .<span style="color:#c678dd">await</span><span style="color:#56b6c2">?</span>;
</span></span></code></pre></div><p>See <a href="https://github.com/cljoly/rusqlite_migration/blob/master/examples/async/src/main.rs">the updated async example</a> for details, in particular why it’s fine to call <a href="https://docs.rs/tokio-rusqlite/0.6.0/tokio_rusqlite/struct.Connection.html#method.call_unwrap">a method</a> with unwrap in its name.</p>
<h4 id="make-the-builder-finalizer-method-not-generic-1">Make the Builder <code>Finalizer</code> Method Not Generic</h4>
<p>On a related note, now that we have removed the <code>AsyncMigrations</code> (see the section right above) struct, we only have <code>Migrations</code> so there is no need for the <code>MigrationsBuilder.finalize</code> method to be generic. Thus we removed the generic argument. To update your code, you can just do this:</p>
<div class="highlight"><pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-diff" data-lang="diff"><span style="display:flex;"><span><span style="color:#e06c75">-        .finalize::&lt;Migrations&gt;());
</span></span></span><span style="display:flex;"><span><span style="color:#98c379;font-weight:bold">+        .finalize());
</span></span></span></code></pre></div><h4 id="remove-migrationsnew_iter-1">Remove <code>Migrations::new_iter</code></h4>
<p>This function has been deprecated for a while now, remove it as a part of the major version bump. You can use the standard <code>FromIter</code> trait implementation instead.</p>
<h3 id="behavior-change-1">Behavior Change</h3>
<ul>
<li>When the <a href="https://www.sqlite.org/fileformat.html#user_version_number">user version field</a> is altered by other code in your application, we are now returning an explicit error (<code>Error::InvalidUserVersion</code>) when this can be detected. Previously, the library would silently misbehave.</li>
</ul>
<h3 id="dependencies-9">Dependencies</h3>
<p>Rusqlite was updated from 0.32.1 to 0.34.0.
Please see <a href="https://github.com/rusqlite/rusqlite/releases/tag/v0.34.0">the release notes for 0.34.0</a> and
<a href="https://github.com/rusqlite/rusqlite/releases/tag/v0.33.0">the release notes for 0.33.0</a>.
Tokio Rusqlite was removed as a dependency.</p>
<h3 id="features-5">Features</h3>
<ul>
<li><code>Migrations::new</code> is now <code>const</code></li>
</ul>
<h3 id="minimum-rust-version-1">Minimum Rust Version</h3>
<p>Rust 1.84.</p>
<p>Moving forward, we expect to keep this aligned with rusqlite itself, now that it has a <a href="https://github.com/rusqlite/rusqlite?tab=readme-ov-file#minimum-supported-rust-version-msrv">policy</a> (introduced in <a href="https://github.com/rusqlite/rusqlite/pull/1576">october 2024</a>).</p>
<h2 id="version-131">Version 1.3.1</h2>
<p>The only change is a fix to the deps.rs badge in the documentation.</p>
<h2 id="version-130">Version 1.3.0</h2>




  
  
  
  

  <div class="alert alert-note">
    <p class="alert-heading">
      ℹ️
      
        Note
      
    </p>
    <p>The code of this version is identical to <a href="#version-130-beta-1">Version 1.3.0 Beta 1</a></p>
  </div>



<p>Rusqlite was updated from 0.31.0 to 0.32.1.
Please see <a href="https://github.com/rusqlite/rusqlite/releases/tag/v0.32.0">the release notes for 0.32.0</a> and
<a href="https://github.com/rusqlite/rusqlite/releases/tag/v0.32.1">for 0.32.1</a>.
Tokio Rusqlite was updated from 0.5.1 to 0.6.0.
Please see the <a href="https://github.com/programatik29/tokio-rusqlite/releases/tag/v0.6.0">release notes</a>.</p>
<h3 id="minimum-rust-version-2">Minimum Rust Version</h3>
<p>Rust 1.77</p>
<h3 id="documentation-1">Documentation</h3>
<p>Various documentation improvements and clarification. In particular, call out that if a rusqlite error is encountered during a migration, the next migrations in the list are not applied.</p>
<h3 id="other-4">Other</h3>
<ul>
<li>Apply minor or patch updates to the dependencies</li>
<li>Update development dependencies</li>
<li>Make CI testing more reproducible by forcing the use of Cargo.lock</li>
</ul>
<h2 id="version-130-beta-1">Version 1.3.0 Beta 1</h2>
<p>This reintroduces the async features temporarily removed from <a href="#version-130-alpha-without-tokio-1">Version 1.3.0 Alpha-Without-Tokio 1</a></p>
<p>Rusqlite was updated from 0.31.0 to 0.32.1.
Please see <a href="https://github.com/rusqlite/rusqlite/releases/tag/v0.32.0">the release notes for 0.32.0</a> and
<a href="https://github.com/rusqlite/rusqlite/releases/tag/v0.32.1">for 0.32.1</a>.
Tokio Rusqlite was updated from 0.5.1 to 0.6.0.
Please see the <a href="https://github.com/programatik29/tokio-rusqlite/releases/tag/v0.6.0">release notes</a>.</p>
<h3 id="minimum-rust-version-3">Minimum Rust Version</h3>
<p>Rust 1.77</p>
<h3 id="documentation-2">Documentation</h3>
<p>Various documentation improvements and clarification. In particular, call out that if a rusqlite error is encountered during a migration, the next migrations in the list are not applied.</p>
<h3 id="other-5">Other</h3>
<ul>
<li>Apply minor or patch updates to the dependencies</li>
<li>Update development dependencies</li>
<li>Make CI testing more reproducible by forcing the use of Cargo.lock</li>
</ul>
<h2 id="version-130-alpha-without-tokio-1">Version 1.3.0 Alpha-Without-Tokio 1</h2>
<h3 id="major-changes">Major Changes</h3>
<p>This is an alpha version to start integrating rusqlite 0.32.1. Unfortunately, at this time, tokio-rusqlite is did not update to rusqlite 0.32.1. So we are temporarily removing the async features, while we figure out a way to bring them back. <strong>To be clear, we intend to support the async features going forward, this is a temporary change in a specifically tagged version</strong>.</p>
<p>Rusqlite was updated from 0.31.0 to 0.32.1. Please see <a href="https://github.com/rusqlite/rusqlite/releases/tag/v0.32.0">the release notes for 0.32.0</a> and
<a href="https://github.com/rusqlite/rusqlite/releases/tag/v0.32.1">for 0.32.1</a></p>
<h3 id="minimum-rust-version-4">Minimum Rust Version</h3>
<p>Rust 1.77</p>
<h3 id="documentation-3">Documentation</h3>
<p>Various documentation improvements and clarification. In particular, call out that if a rusqlite error is encountered during a migration, the next migrations in the list are not applied.</p>
<h3 id="other-6">Other</h3>
<ul>
<li>Apply minor or patch updates to the dependencies</li>
<li>Update development dependencies</li>
<li>Make CI testing more reproducible by forcing the use of Cargo.lock</li>
</ul>
<h2 id="version-120">Version 1.2.0</h2>
<p><em>Same code as version 1.2.0-beta.1</em></p>
<h3 id="documentation-4">Documentation</h3>
<ul>
<li>Improved the badges a little bit</li>
</ul>
<h2 id="version-120-beta-1">Version 1.2.0 Beta 1</h2>
<p>Small release, mainly to update dependencies.</p>
<h3 id="minimum-rust-version-5">Minimum Rust Version</h3>
<p>Now using edition 2021, but the minimum rust version is still 1.70</p>
<h3 id="new-features">New Features</h3>
<p>No new features.</p>
<h3 id="other-7">Other</h3>
<ul>
<li>Update rusqlite to 0.31</li>
<li>Update various development dependencies</li>
<li>Improve CI build time</li>
<li>Impove documentation</li>
<li>Fix some broken examples</li>
</ul>
<h3 id="see-also">See also</h3>
<p>Rusqlite was updated from 0.30 to 0.31. Please see <a href="https://github.com/rusqlite/rusqlite/releases/tag/v0.31.0">its release notes</a></p>
<h2 id="version-110">Version 1.1.0</h2>
<p><em>Same code as version 1.1.0-beta.1</em></p>
<h3 id="minimum-rust-version-6">Minimum Rust Version</h3>
<p>Rust 1.70</p>
<h3 id="new-features-1">New Features</h3>
<ul>
<li>Support for tokio-rusqlite behind the feature named <code>alpha-async-tokio-rusqlite</code>thanks to <a href="https://github.com/czocher">@czocher</a>. See <a href="https://github.com/cljoly/rusqlite_migration/tree/c54951d22691432fbfd511cc68f1c5b8a2306737/examples/async">the example</a>. This feature is alpha, meaning that compatibility in future minor versions is not guaranteed.</li>
<li>Create migrations from directories holding SQL files thanks to <a href="https://github.com/czocher">@czocher</a>. See <a href="https://github.com/cljoly/rusqlite_migration/tree/af4da527ff75e3b8c089d2300cab7fbe66096411/examples/from-directory">the example</a>.</li>
<li>Add up/down hooks to run custom Rust code during migrations (<a href="https://github.com/cljoly/rusqlite_migration/pull/28">PR</a> thanks to <a href="https://github.com/matze">@matze</a>)</li>
<li>Add foreign_key_check method to migrations (<a href="https://github.com/cljoly/rusqlite_migration/pull/20">PR</a> thanks to <a href="https://github.com/Jokler">@Jokler</a>)</li>
<li>Make <code>Migration</code> functions const (<a href="https://github.com/cljoly/rusqlite_migration/pull/19">PR</a> thanks to <a href="https://github.com/fkaa">@fkaa</a>)</li>
<li>Make <code>Migrations</code> serializable (using the Debug serializer) with <a href="https://insta.rs">insta</a>.</li>
</ul>
<h3 id="depreciation">Depreciation</h3>
<ul>
<li>Mark <code>Migrations::from_iter</code> as deprecated</li>
</ul>
<h3 id="other-8">Other</h3>
<ul>
<li>Documentation improvements
<ul>
<li>Repository metadata improvements</li>
</ul>
</li>
<li>Code quality improvements
<ul>
<li>Introduce cargo mutants &amp; fix bugs found</li>
<li>Clippy warning fixes and other linter improvements</li>
<li>Report on test coverage &amp; improve test coverage</li>
<li>Add benchmarks</li>
</ul>
</li>
<li>Made errors returned more precise</li>
<li>Updated dependencies</li>
</ul>
<h3 id="see-also-1">See also</h3>
<p>Rusqlite was updated from 0.29.0 to 0.30.0. Please see <a href="https://github.com/rusqlite/rusqlite/releases/tag/v0.30.0">its release notes</a></p>
<h2 id="version-110-beta-1">Version 1.1.0 Beta 1</h2>
<p><strong>⚠️ The APIs exposed in this version may be unstable.</strong></p>
<p>Summing up all the changes from the previous Alpha versions.</p>
<h3 id="minimum-rust-version-7">Minimum Rust Version</h3>
<p>Rust 1.70</p>
<h3 id="new-features-2">New Features</h3>
<ul>
<li>Support for tokio-rusqlite behind the feature named <code>alpha-async-tokio-rusqlite</code>thanks to <a href="https://github.com/czocher">@czocher</a>. See <a href="https://github.com/cljoly/rusqlite_migration/tree/c54951d22691432fbfd511cc68f1c5b8a2306737/examples/async">the example</a>. This feature is alpha, meaning that compatibility in future minor versions is not guaranteed.</li>
<li>Create migrations from directories holding SQL files thanks to <a href="https://github.com/czocher">@czocher</a>. See <a href="https://github.com/cljoly/rusqlite_migration/tree/af4da527ff75e3b8c089d2300cab7fbe66096411/examples/from-directory">the example</a>.</li>
<li>Add up/down hooks to run custom Rust code during migrations (<a href="https://github.com/cljoly/rusqlite_migration/pull/28">PR</a> thanks to <a href="https://github.com/matze">@matze</a>)</li>
<li>Add foreign_key_check method to migrations (<a href="https://github.com/cljoly/rusqlite_migration/pull/20">PR</a> thanks to <a href="https://github.com/Jokler">@Jokler</a>)</li>
<li>Make <code>Migration</code> functions const (<a href="https://github.com/cljoly/rusqlite_migration/pull/19">PR</a> thanks to <a href="https://github.com/fkaa">@fkaa</a>)</li>
<li>Make <code>Migrations</code> serializable (using the Debug serializer) with <a href="https://insta.rs">insta</a>.</li>
</ul>
<h3 id="depreciation-1">Depreciation</h3>
<ul>
<li>Mark <code>Migrations::from_iter</code> as deprecated</li>
</ul>
<h3 id="other-9">Other</h3>
<ul>
<li>Documentation improvements
<ul>
<li>Repository metadata improvements</li>
</ul>
</li>
<li>Code quality improvements
<ul>
<li>Introduce cargo mutants &amp; fix bugs found</li>
<li>Clippy warning fixes and other linter improvements</li>
<li>Report on test coverage &amp; improve test coverage</li>
<li>Add benchmarks</li>
</ul>
</li>
<li>Made errors returned more precise</li>
<li>Updated dependencies</li>
</ul>
<h3 id="see-also-2">See also</h3>
<p>Rusqlite was updated from 0.29.0 to 0.30.0. Please see <a href="https://github.com/rusqlite/rusqlite/releases/tag/v0.30.0">its release notes</a></p>
<h2 id="version-110-alpha-2">Version 1.1.0 Alpha 2</h2>
<p><strong>⚠️ The APIs exposed in this version may be unstable.</strong></p>
<h3 id="minimum-rust-version-8">Minimum Rust Version</h3>
<p>Rust 1.64</p>
<h3 id="new-features-3">New Features</h3>
<ul>
<li>Create migrations from directories holding SQL files. See <a href="https://github.com/cljoly/rusqlite_migration/tree/af4da527ff75e3b8c089d2300cab7fbe66096411/examples/from-directory">the example</a>.</li>
</ul>
<h3 id="depreciation-2">Depreciation</h3>
<ul>
<li>Mark <code>Migrations::from_iter</code> as deprecated</li>
</ul>
<h3 id="other-10">Other</h3>
<ul>
<li>Documentation improvements</li>
<li>Code quality improvements
<ul>
<li>Introduce cargo mutants &amp; fix bugs found</li>
<li>Clippy warning fixes</li>
<li>Report on test coverage &amp; improve test coverage</li>
<li>Add benchmarks</li>
</ul>
</li>
<li>Made errors returned more precise</li>
<li>Update dependencies</li>
</ul>
<h2 id="version-110-alpha-1">Version 1.1.0 Alpha 1</h2>
<p><strong>⚠️ The APIs exposed in this version may be unstable.</strong></p>
<h3 id="minimum-rust-version-9">Minimum Rust Version</h3>
<p>Rust 1.61</p>
<h3 id="new-features-4">New Features</h3>
<ul>
<li>Add up/down hooks to run custom Rust code during migrations (<a href="https://github.com/cljoly/rusqlite_migration/pull/28">PR</a> thanks to <a href="https://github.com/matze">@matze</a>)
<ul>
<li>The purpose of this release is to get feedback on the new API. Please feel free to comment on <a href="https://github.com/cljoly/rusqlite_migration/discussions/36">this discussion</a>!</li>
</ul>
</li>
<li>Add foreign_key_check method to migrations (<a href="https://github.com/cljoly/rusqlite_migration/pull/20">PR</a> thanks to <a href="https://github.com/Jokler">@Jokler</a>)
<ul>
<li>Please beware of the <a href="https://github.com/cljoly/rusqlite_migration/issues/4#issuecomment-1166363260">follow up work needed on this</a></li>
</ul>
</li>
<li>Make <code>Migration</code> functions const (<a href="https://github.com/cljoly/rusqlite_migration/pull/19">PR</a> thanks to <a href="https://github.com/fkaa">@fkaa</a>)</li>
</ul>
<h3 id="other-11">Other</h3>
<ul>
<li>CI improvements</li>
<li>Linter improvements</li>
<li>Repository metadata improvements</li>
<li>Documentation improvements</li>
<li>Dev dependencies update (not dependencies of the library when used in another crate)</li>
</ul>
<h2 id="version-102">Version 1.0.2</h2>
<h3 id="bug-fix">Bug fix</h3>
<ul>
<li>fix: adapt to rusqlite 0.29 and tighten dependency requirements for rusqlite (see <a href="https://github.com/cljoly/rusqlite_migration/issues/68#issuecomment-1485795284">this discussion</a>)</li>
</ul>
<h2 id="version-101">Version 1.0.1</h2>
<h3 id="bug-fix-1">Bug Fix</h3>
<ul>
<li>fix: error instead of panicking on higher migration level (see commit ad57d92d1677420eb81c4e25635be1884f9b7ce7)</li>
</ul>
<h3 id="other-12">Other</h3>
<ul>
<li>Documentation improvements</li>
</ul>
<h2 id="version-100">Version 1.0.0</h2>
<h3 id="breaking-changes-2">Breaking changes</h3>
<ul>
<li>Remove deprecated symbols (<code>Migrations.latest</code>, <code>SchemaVersionError::MigrateToLowerNotSupported</code>)</li>
</ul>
<h3 id="other-13">Other</h3>
<ul>
<li>Documentation improvements</li>
</ul>
<h2 id="version-051">Version 0.5.1</h2>
<h3 id="potentially-breaking-changes">Potentially Breaking Changes</h3>
<ul>
<li>Update the <code>rusqlite</code> crate (to protect agaisnt <a href="https://rustsec.org/advisories/RUSTSEC-2020-0014.html">RUSTSEC-2020-0014</a>)</li>
</ul>
<h3 id="other-14">Other</h3>
<ul>
<li>Improve the documentation</li>
</ul>
<h2 id="version-050">Version 0.5.0</h2>
<ul>
<li>Update the <code>env_logger</code> dependency</li>
<li>Improve the documentation</li>
</ul>
<h2 id="version-041--042">Version 0.4.1 / 0.4.2</h2>
<ul>
<li>Update documentation</li>
</ul>
<h2 id="version-040">Version 0.4.0</h2>
<h3 id="new-features-5">New features</h3>
<ul>
<li>Add downward migrations, i.e. migrations to go to past schema version of the database. Thanks @MightyPork!</li>
<li>Unsafe code is now forbidden.</li>
</ul>
<h3 id="breaking-changes-3">Breaking changes</h3>
<ul>
<li>Rename <code>latest</code> to <code>to_latest</code>. The old symbol is deprecated and will be removed eventually.</li>
<li>An error is now returned when a migration is attempted while no migrations exist.</li>
</ul>
<h3 id="other-15">Other</h3>
<ul>
<li>Improve general rust API documentation.</li>
<li>Generate parts of the readme based on rust comments, for increased consistency with the docs.rs content.</li>
<li>Various refactoring and clean-ups.</li>
</ul>
<h2 id="version-031">Version 0.3.1</h2>
<p>Fix in readme, for crates.io</p>
<h2 id="version-03">Version 0.3</h2>
<h3 id="new-features-6">New features</h3>
<ul>
<li>Multi line sql statements like:
<pre tabindex="0"><code>M::up(r#&#34;
CREATE TABLE t1(a, b);
CREATE TABLE t2(a, b);
&#34;#)
</code></pre>are now fully supported</li>
</ul>
<h3 id="other-16">Other</h3>
<ul>
<li>Various doc &amp; CI improvements</li>
<li>Fix a case of failure with silent errors.</li>
</ul>
]]></content:encoded></item><item><title>Rusqlite Migration</title><link>https://cj.rs/rusqlite_migration/</link><pubDate>Sat, 21 Aug 2021 15:32:05 +0100</pubDate><guid>https://cj.rs/rusqlite_migration/</guid><description>↕️ Simple database schema migration library for rusqlite, written with performance in mind.</description><content:encoded><![CDATA[
<p style="display: flex; justify-content: space-between">
  <a href="https://github.com/cljoly/rusqlite_migration" data-goatcounter-click="ext-github-rusqlite_migration" data-goatcounter-title="cljoly/rusqlite_migration">
    <span class="svgicon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
    stroke-linecap="round" stroke-linejoin="round">
    <path
        d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22">
    </path>
</svg></span>&nbsp;cljoly/rusqlite_migration
  </a>
  <a class="badges" href="https://github.com/cljoly/rusqlite_migration" data-goatcounter-click="ext-stargithub-rusqlite_migration" data-goatcounter-title="stars cljoly/rusqlite_migration">
    <img src="https://img.shields.io/github/stars/cljoly/rusqlite_migration?style=social" alt="Github stars for rusqlite_migration">
  </a>
</p>


<div class="badges">

<p><a href="https://docs.rs/rusqlite_migration">
<img alt="docs.rs" loading="lazy" src="https://img.shields.io/docsrs/rusqlite_migration"></a>
<a href="https://crates.io/crates/rusqlite_migration">
<img alt="Crates.io" loading="lazy" src="https://img.shields.io/crates/v/rusqlite_migration"></a>
<a href="https://cj.rs/rusqlite_migration/changelog">

  <img alt="Changelog" loading="lazy" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2OSIgaGVpZ2h0PSIyMCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJDaGFuZ2Vsb2ciPjx0aXRsZT5DaGFuZ2Vsb2c8L3RpdGxlPjxmaWx0ZXIgaWQ9ImJsdXIiPjxmZUdhdXNzaWFuQmx1ciBpbj0iU291cmNlR3JhcGhpYyIgc3RkRGV2aWF0aW9uPSIxNiIvPjwvZmlsdGVyPjxsaW5lYXJHcmFkaWVudCBpZD0icyIgeDI9IjAiIHkyPSIxMDAlIj48c3RvcCBvZmZzZXQ9IjAiIHN0b3AtY29sb3I9IiNiYmIiIHN0b3Atb3BhY2l0eT0iLjEiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3Atb3BhY2l0eT0iLjEiLz48L2xpbmVhckdyYWRpZW50PjxjbGlwUGF0aCBpZD0iciI+PHJlY3Qgd2lkdGg9IjY5IiBoZWlnaHQ9IjIwIiByeD0iMyIgZmlsbD0iI2ZmZiIvPjwvY2xpcFBhdGg+PGcgY2xpcC1wYXRoPSJ1cmwoI3IpIj48cmVjdCB3aWR0aD0iMCIgaGVpZ2h0PSIyMCIgZmlsbD0icHVycGxlIi8+PHJlY3QgeD0iMCIgd2lkdGg9IjY5IiBoZWlnaHQ9IjIwIiBmaWxsPSJwdXJwbGUiLz48cmVjdCB3aWR0aD0iNjkiIGhlaWdodD0iMjAiIGZpbGw9InVybCgjcykiLz48L2c+PGcgZmlsbD0iI2ZmZiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1mYW1pbHk9IlZlcmRhbmEsR2VuZXZhLERlamFWdSBTYW5zLHNhbnMtc2VyaWYiIHRleHQtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIGZvbnQtc2l6ZT0iMTEwIj48dGV4dCBhcmlhLWhpZGRlbj0idHJ1ZSIgeD0iMzQ1IiB5PSIxNTAiIGZpbGw9IiMwMTAxMDEiIGZpbGwtb3BhY2l0eT0iLjgwIiBmaWx0ZXI9InVybCgjYmx1cikiIHRyYW5zZm9ybT0ic2NhbGUoLjEpIiB0ZXh0TGVuZ3RoPSI1OTAiPkNoYW5nZWxvZzwvdGV4dD48dGV4dCBhcmlhLWhpZGRlbj0idHJ1ZSIgeD0iMzQ1IiB5PSIxNTAiIGZpbGw9IiMwMTAxMDEiIGZpbGwtb3BhY2l0eT0iLjMiIHRyYW5zZm9ybT0ic2NhbGUoLjEpIiB0ZXh0TGVuZ3RoPSI1OTAiPkNoYW5nZWxvZzwvdGV4dD48dGV4dCB4PSIzNDUiIHk9IjE0MCIgdHJhbnNmb3JtPSJzY2FsZSguMSkiIGZpbGw9IiNmZmYiIHRleHRMZW5ndGg9IjU5MCI+Q2hhbmdlbG9nPC90ZXh0PjwvZz48L3N2Zz4="></a>
<a href="https://github.com/rust-secure-code/safety-dance/">

  <img alt="unsafe forbidden" loading="lazy" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTAiIGhlaWdodD0iMjAiIHJvbGU9ImltZyIgYXJpYS1sYWJlbD0idW5zYWZlOiBmb3JiaWRkZW4iPjx0aXRsZT51bnNhZmU6IGZvcmJpZGRlbjwvdGl0bGU+PGZpbHRlciBpZD0iYmx1ciI+PGZlR2F1c3NpYW5CbHVyIGluPSJTb3VyY2VHcmFwaGljIiBzdGREZXZpYXRpb249IjE2Ii8+PC9maWx0ZXI+PGxpbmVhckdyYWRpZW50IGlkPSJzIiB4Mj0iMCIgeTI9IjEwMCUiPjxzdG9wIG9mZnNldD0iMCIgc3RvcC1jb2xvcj0iI2JiYiIgc3RvcC1vcGFjaXR5PSIuMSIvPjxzdG9wIG9mZnNldD0iMSIgc3RvcC1vcGFjaXR5PSIuMSIvPjwvbGluZWFyR3JhZGllbnQ+PGNsaXBQYXRoIGlkPSJyIj48cmVjdCB3aWR0aD0iMTEwIiBoZWlnaHQ9IjIwIiByeD0iMyIgZmlsbD0iI2ZmZiIvPjwvY2xpcFBhdGg+PGcgY2xpcC1wYXRoPSJ1cmwoI3IpIj48cmVjdCB3aWR0aD0iNDciIGhlaWdodD0iMjAiIGZpbGw9IiM1NTUiLz48cmVjdCB4PSI0NyIgd2lkdGg9IjYzIiBoZWlnaHQ9IjIwIiBmaWxsPSIjNGIwIi8+PHJlY3Qgd2lkdGg9IjExMCIgaGVpZ2h0PSIyMCIgZmlsbD0idXJsKCNzKSIvPjwvZz48ZyBmaWxsPSIjZmZmIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LWZhbWlseT0iVmVyZGFuYSxHZW5ldmEsRGVqYVZ1IFNhbnMsc2Fucy1zZXJpZiIgdGV4dC1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgZm9udC1zaXplPSIxMTAiPjx0ZXh0IGFyaWEtaGlkZGVuPSJ0cnVlIiB4PSIyNDUiIHk9IjE1MCIgZmlsbD0iIzAxMDEwMSIgZmlsbC1vcGFjaXR5PSIuODAiIGZpbHRlcj0idXJsKCNibHVyKSIgdHJhbnNmb3JtPSJzY2FsZSguMSkiIHRleHRMZW5ndGg9IjM3MCI+dW5zYWZlPC90ZXh0Pjx0ZXh0IGFyaWEtaGlkZGVuPSJ0cnVlIiB4PSIyNDUiIHk9IjE1MCIgZmlsbD0iIzAxMDEwMSIgZmlsbC1vcGFjaXR5PSIuMyIgdHJhbnNmb3JtPSJzY2FsZSguMSkiIHRleHRMZW5ndGg9IjM3MCI+dW5zYWZlPC90ZXh0Pjx0ZXh0IHg9IjI0NSIgeT0iMTQwIiB0cmFuc2Zvcm09InNjYWxlKC4xKSIgZmlsbD0iI2ZmZiIgdGV4dExlbmd0aD0iMzcwIj51bnNhZmU8L3RleHQ+PHRleHQgYXJpYS1oaWRkZW49InRydWUiIHg9Ijc3NSIgeT0iMTUwIiBmaWxsPSIjMDEwMTAxIiBmaWxsLW9wYWNpdHk9Ii44MCIgZmlsdGVyPSJ1cmwoI2JsdXIpIiB0cmFuc2Zvcm09InNjYWxlKC4xKSIgdGV4dExlbmd0aD0iNTMwIj5mb3JiaWRkZW48L3RleHQ+PHRleHQgYXJpYS1oaWRkZW49InRydWUiIHg9Ijc3NSIgeT0iMTUwIiBmaWxsPSIjMDEwMTAxIiBmaWxsLW9wYWNpdHk9Ii4zIiB0cmFuc2Zvcm09InNjYWxlKC4xKSIgdGV4dExlbmd0aD0iNTMwIj5mb3JiaWRkZW48L3RleHQ+PHRleHQgeD0iNzc1IiB5PSIxNDAiIHRyYW5zZm9ybT0ic2NhbGUoLjEpIiBmaWxsPSIjZmZmIiB0ZXh0TGVuZ3RoPSI1MzAiPmZvcmJpZGRlbjwvdGV4dD48L2c+PC9zdmc+"></a>
<a href="https://coveralls.io/github/cljoly/rusqlite_migration">
<img alt="Coveralls" loading="lazy" src="https://img.shields.io/coverallsCoverage/github/cljoly/rusqlite_migration"></a></p>

</div>

<p>Rusqlite Migration is a performant and simple schema migration library for <a href="https://crates.io/crates/rusqlite">rusqlite</a>.</p>
<ul>
<li><strong>Performance</strong>:
<ul>
<li><em>Fast database opening</em>: to keep track of the current migration state, most tools create one or more tables in the database. These tables require parsing by SQLite and are queried with SQL statements. This library uses the <a href="https://sqlite.org/pragma.html#pragma_user_version"><code>user_version</code></a> value instead. It’s much lighter as it is just an integer at a <a href="https://www.sqlite.org/fileformat.html#user_version_number">fixed offset</a> in the SQLite file.</li>
<li><em>Fast compilation</em>: this crate is very small and does not use macros to define the migrations.</li>
</ul>
</li>
<li><strong>Simplicity</strong>: this crate strives for simplicity. Just define a set of SQL statements as strings in your Rust code. Add more SQL statements over time as needed. No external CLI required. Additionally, rusqlite_migration works especially well with other small libraries complementing rusqlite, like <a href="https://crates.io/crates/serde_rusqlite">serde_rusqlite</a>.</li>
</ul>
<h2 id="example">Example</h2>
<p>Here, we define SQL statements to run with <a href="https://docs.rs/rusqlite_migration/latest/rusqlite_migration/struct.Migrations.html#method.new"><code>Migrations::new()</code></a> and run these (if necessary) with <a href="https://docs.rs/rusqlite_migration/latest/rusqlite_migration/struct.Migrations.html#method.to_latest"><code>Migrations::to_latest()</code></a>.</p>
<div class="highlight"><pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#c678dd">use</span> <span style="color:#e06c75">rusqlite</span>::{<span style="color:#e06c75">params</span>, <span style="color:#e06c75">Connection</span>};
</span></span><span style="display:flex;"><span><span style="color:#c678dd">use</span> <span style="color:#e06c75">rusqlite_migration</span>::{<span style="color:#e06c75">Migrations</span>, <span style="color:#e06c75">M</span>};
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#7f848e">// 1️⃣ Define migrations
</span></span></span><span style="display:flex;"><span><span style="color:#c678dd">const</span> <span style="color:#e06c75">MIGRATIONS_SLICE</span>: <span style="color:#c678dd">&amp;</span>[<span style="color:#e06c75">M</span><span style="color:#56b6c2">&lt;</span><span style="color:#e5c07b">&#39;_</span><span style="color:#56b6c2">&gt;</span>] <span style="color:#56b6c2">=</span> <span style="color:#56b6c2">&amp;</span>[
</span></span><span style="display:flex;"><span>    <span style="color:#e06c75">M</span>::<span style="color:#e06c75">up</span>(<span style="color:#98c379">&#34;CREATE TABLE friend(name TEXT NOT NULL);&#34;</span>),
</span></span><span style="display:flex;"><span>    <span style="color:#7f848e">// In the future, add more migrations here:
</span></span></span><span style="display:flex;"><span>    <span style="color:#7f848e">//M::up(&#34;ALTER TABLE friend ADD COLUMN email TEXT;&#34;),
</span></span></span><span style="display:flex;"><span>];
</span></span><span style="display:flex;"><span><span style="color:#c678dd">const</span> <span style="color:#e06c75">MIGRATIONS</span>: <span style="color:#e5c07b">Migrations</span><span style="color:#56b6c2">&lt;</span><span style="color:#e5c07b">&#39;_</span><span style="color:#56b6c2">&gt;</span> <span style="color:#56b6c2">=</span> <span style="color:#e06c75">Migrations</span>::<span style="color:#e06c75">from_slice</span>(<span style="color:#e06c75">MIGRATIONS_SLICE</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#c678dd">fn</span> <span style="color:#61afef;font-weight:bold">main</span>() {
</span></span><span style="display:flex;"><span>    <span style="color:#c678dd">let</span> <span style="color:#c678dd">mut</span> <span style="color:#e06c75">conn</span> <span style="color:#56b6c2">=</span> <span style="color:#e06c75">Connection</span>::<span style="color:#e06c75">open_in_memory</span>().<span style="color:#e06c75">unwrap</span>();
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#7f848e">// Apply some PRAGMA, often better to do it outside of migrations
</span></span></span><span style="display:flex;"><span>    <span style="color:#e06c75">conn</span>.<span style="color:#e06c75">pragma_update_and_check</span>(<span style="color:#e5c07b">None</span>, <span style="color:#98c379">&#34;journal_mode&#34;</span>, <span style="color:#56b6c2">&amp;</span><span style="color:#98c379">&#34;WAL&#34;</span>, <span style="color:#56b6c2">|</span><span style="color:#e06c75">_</span><span style="color:#56b6c2">|</span> <span style="color:#e5c07b">Ok</span>(()))
</span></span><span style="display:flex;"><span>        .<span style="color:#e06c75">unwrap</span>();
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#7f848e">// 2️⃣ Update the database schema, atomically
</span></span></span><span style="display:flex;"><span>    <span style="color:#e06c75">MIGRATIONS</span>.<span style="color:#e06c75">to_latest</span>(<span style="color:#56b6c2">&amp;</span><span style="color:#c678dd">mut</span> <span style="color:#e06c75">conn</span>).<span style="color:#e06c75">unwrap</span>();
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#7f848e">// 3️⃣ Use the database 🥳
</span></span></span><span style="display:flex;"><span>    <span style="color:#e06c75">conn</span>.<span style="color:#e06c75">execute</span>(<span style="color:#98c379">&#34;INSERT INTO friend (name) VALUES (?1)&#34;</span>, <span style="color:#56b6c2;font-weight:bold">params!</span>[<span style="color:#98c379">&#34;John&#34;</span>])
</span></span><span style="display:flex;"><span>        .<span style="color:#e06c75">unwrap</span>();
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>Please see the <a href="https://github.com/cljoly/rusqlite_migrate/tree/master/examples">examples</a> folder for more, in particular:</p>
<ul>
<li>migrations with multiple SQL statements (using for instance <code>r#&quot;…&quot;</code> or <code>include_str!(…)</code>)</li>
<li>migrations defined <a href="https://github.com/cljoly/rusqlite_migration/tree/master/examples/from-directory">from a directory</a> with SQL files</li>
<li>migrations to <a href="https://github.com/cljoly/rusqlite_migration/blob/master/examples/simple/src/main.rs">previous versions (downward migrations)</a></li>
<li>migrations <a href="https://github.com/cljoly/rusqlite_migration/blob/master/examples/async/src/main.rs">when using <code>async</code></a></li>
</ul>
<p>I’ve also made a <a href="https://cj.rs/blog/sqlite-pragma-cheatsheet-for-performance-and-consistency/">cheatsheet of SQLite pragma for improved performance and consistency</a>.</p>
<h3 id="built-in-tests">Built-in tests</h3>
<p>To test that the migrations are working, you can add this in your test module:</p>
<div class="highlight"><pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#7f848e">#[test]</span>
</span></span><span style="display:flex;"><span><span style="color:#c678dd">fn</span> <span style="color:#61afef;font-weight:bold">migrations_test</span>() {
</span></span><span style="display:flex;"><span>    <span style="color:#56b6c2;font-weight:bold">assert!</span>(<span style="color:#e06c75">MIGRATIONS</span>.<span style="color:#e06c75">validate</span>().<span style="color:#e06c75">is_ok</span>());
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>The migrations object is also suitable for serialisation with <a href="https://insta.rs/">insta</a>, using the <code>Debug</code> serialisation. You can store a snapshot of your migrations like this:</p>
<div class="highlight"><pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#7f848e">#[test]</span>
</span></span><span style="display:flex;"><span><span style="color:#c678dd">fn</span> <span style="color:#61afef;font-weight:bold">migrations_insta_snapshot</span>() {
</span></span><span style="display:flex;"><span>    <span style="color:#c678dd">let</span> <span style="color:#e06c75">migrations</span> <span style="color:#56b6c2">=</span> <span style="color:#e06c75">Migrations</span>::<span style="color:#e06c75">new</span>(<span style="color:#56b6c2;font-weight:bold">vec!</span>[
</span></span><span style="display:flex;"><span>        <span style="color:#7f848e">// ...
</span></span></span><span style="display:flex;"><span>    ]);
</span></span><span style="display:flex;"><span>    <span style="color:#e06c75">insta</span>::<span style="color:#56b6c2;font-weight:bold">assert_debug_snapshot!</span>(<span style="color:#e06c75">migrations</span>);
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><h2 id="optional-features">Optional Features</h2>
<p>Rusqlite migration provides several <a href="https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section">Cargo features</a>. They are:</p>
<ul>
<li><code>from-directory</code>: enable loading migrations from *.sql files in a given directory</li>
</ul>
<h2 id="active-users">Active Users</h2>

<div class="badges">

<p><a href="https://crates.io/crates/rusqlite_migration">
<img alt="Crates.io Downloads" loading="lazy" src="https://img.shields.io/crates/d/rusqlite_migration?style=social"></a> <a href="https://crates.io/crates/rusqlite_migration">
<img alt="Crates.io Downloads (recent)" loading="lazy" src="https://img.shields.io/crates/dr/rusqlite_migration?style=social"></a></p>

</div>

<p>This crate is actively used in a number of projects. You can find up-to-date list of those on:</p>
<ul>
<li><a href="https://crates.io/crates/rusqlite_migration/reverse_dependencies">crates.io</a> / <a href="https://lib.rs/crates/rusqlite_migration/rev">lib.rs</a></li>
<li><a href="https://github.com/cljoly/rusqlite_migration/network/dependents?dependent_type=REPOSITORY">GitHub’s list of dependent repositories</a></li>
</ul>
<p>A number of contributors are also reporting issues as they arise, another indicator of active use.</p>
<h2 id="minimum-supported-rust-version-msrv">Minimum Supported Rust Version (MSRV)</h2>
<p>This crate extends rusqlite and as such is tightly integrated with it. Thus, it supports the <a href="https://github.com/rusqlite/rusqlite?tab=readme-ov-file#minimum-supported-rust-version-msrv">same MSRV</a> as rusqlite. At the time of writing, this means:</p>




  <figure>
    <blockquote >
      <p>Latest stable Rust version at the time of release. It might compile with older versions.</p>

    </blockquote>
    
  </figure>



<h2 id="limits">Limits</h2>
<ol>
<li>
<p>Since this crate uses the <a href="https://www.sqlite.org/fileformat.html#user_version_number"><code>user_version</code></a> field, if your program or any other library changes it, this library will behave in an unspecified way: it may return an error, apply the wrong set of migrations, do nothing at all&hellip;</p>
</li>
<li>
<p>The <a href="https://www.sqlite.org/fileformat.html#user_version_number"><code>user_version</code></a> field is effectively a i32, so there is a theoretical limit (about two billion) on the number of migrations that can be applied by this library. You are likely to hit memory limits well before that though, so in practice, you can think of the number of migrations as limitless. And you would need to create 10 000 new migrations, every day, for over 5 centuries, before getting close to the limit.</p>
</li>
</ol>
<h2 id="contributing">Contributing</h2>
<p>Contributions (documentation or code improvements in particular) are welcome, see <a href="https://cj.rs/docs/contribute/">contributing</a>!</p>
<p>We use various tools for testing that you may find helpful to install locally (e.g. to fix failing CI checks):</p>
<ul>
<li><a href="https://crates.io/crates/cargo-insta">cargo-insta</a></li>
<li><a href="https://mutants.rs/installation.html">cargo-mutants</a></li>
</ul>
<h2 id="acknowledgments">Acknowledgments</h2>
<p>I would like to thank all the contributors, as well as the authors of the dependencies this crate uses.</p>
<p>Thanks to <a href="https://www.migadu.com/">Migadu</a> for offering a discounted service to support this project. It is not an endorsement by Migadu though.</p>
]]></content:encoded></item></channel></rss>