<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>enriquekesslerm.com</title>
    <link href="https://enriquekesslerm.com/atom.xml" rel="self" type="application/atom+xml"/>
    <link href="https://enriquekesslerm.com"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2023-12-16T00:00:00+00:00</updated>
    <id>https://enriquekesslerm.com/atom.xml</id>
    <entry xml:lang="en">
        <title>Publish your cargo docs</title>
        <published>2023-12-16T00:00:00+00:00</published>
        <updated>2023-12-16T00:00:00+00:00</updated>
        <author>
          <name>Quique Kessler Martínez</name>
        </author>
        <link rel="alternate" href="https://enriquekesslerm.com/blog/publish-cargo-docs/" type="text/html"/>
        <id>https://enriquekesslerm.com/blog/publish-cargo-docs/</id>
        
        <content type="html">&lt;p&gt;As discussed on &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;CeleritasCelery&#x2F;rune&#x2F;issues&#x2F;48&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;CeleritasCelery&#x2F;rune&#x2F;issues&#x2F;48&lt;&#x2F;a&gt;, we see valuable to publish the documentation to somewhere consumable, for future contributors to see the documentation without actually having the barrier of running &lt;code&gt;cargo doc --workspace&lt;&#x2F;code&gt; on their machines.&lt;&#x2F;p&gt;
&lt;p&gt;Was testing the way to publish the cargo doc output, and saw that the tracing crate is doing something very similar with netlify. Since I like netlify (have this web on there) thought that we can do an MVP with something similar to &lt;code&gt;tracing&lt;&#x2F;code&gt;: https:&#x2F;&#x2F;tracing-rs.netlify.app&#x2F;tracing&#x2F;&lt;&#x2F;p&gt;
&lt;p&gt;First, we move the core changes I have on &lt;code&gt;master&lt;&#x2F;code&gt; to &lt;code&gt;core&lt;&#x2F;code&gt; again. We want to be clean for the &lt;code&gt;docs publishing&lt;&#x2F;code&gt; PR. We need dependencies included as part of the builds on netlify, because we seem to need gdk and pango, as with the CI. Talking about CI, we need to only publish these changes upon push to mainline, which is kinda what netlify does by default, so we should be good there, no need to update the CI.&lt;&#x2F;p&gt;
&lt;p&gt;There are some issues with the dependencies, so I&#x27;m really interested in knowing why we have them on the rune repo either way. Do we require specific dependencies for anything? Can we gate those dependencies with features (cfg or something) to avoid this?&lt;&#x2F;p&gt;
&lt;p&gt;Since we have that limitation, it sounds like we could build a CI step to happen on push to master where we would install rustup with the dependencies, run the command ourselves and deploy the target&#x2F;doc, similar to what netlify is doing. I wonder whether netlify can just deploy a directory. Let&#x27;s see with the netlify github action.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;yaml&quot; style=&quot;background-color:#282828;color:#fdf4c1aa;&quot; class=&quot;language-yaml &quot;&gt;&lt;code class=&quot;language-yaml&quot; data-lang=&quot;yaml&quot;&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# .github&#x2F;workflows&#x2F;netlify.yml
&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#8ec07c;&quot;&gt;name&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;Build and Deploy to Netlify
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d3869b;&quot;&gt;on&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#8ec07c;&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#8ec07c;&quot;&gt;pull_request&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#8ec07c;&quot;&gt;jobs&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#8ec07c;&quot;&gt;build&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#8ec07c;&quot;&gt;runs-on&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;ubuntu-22.04
&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#8ec07c;&quot;&gt;steps&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;- &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#8ec07c;&quot;&gt;uses&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;actions&#x2F;checkout@v3
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# ( Build to .&#x2F;dist or other directory... )
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;      - &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#8ec07c;&quot;&gt;name&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;Deploy to Netlify
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#8ec07c;&quot;&gt;uses&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;nwtgck&#x2F;actions-netlify@v2.0
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#8ec07c;&quot;&gt;with&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;          &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#8ec07c;&quot;&gt;publish-dir&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;#39;.&#x2F;dist&amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;          &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#8ec07c;&quot;&gt;production-branch&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;master
&lt;&#x2F;span&gt;&lt;span&gt;          &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#8ec07c;&quot;&gt;github-token&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;${{ secrets.GITHUB_TOKEN }}
&lt;&#x2F;span&gt;&lt;span&gt;          &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#8ec07c;&quot;&gt;deploy-message&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;Deploy from GitHub Actions&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;          &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#8ec07c;&quot;&gt;enable-pull-request-comment&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d3869b;&quot;&gt;false
&lt;&#x2F;span&gt;&lt;span&gt;          &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#8ec07c;&quot;&gt;enable-commit-comment&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d3869b;&quot;&gt;true
&lt;&#x2F;span&gt;&lt;span&gt;          &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#8ec07c;&quot;&gt;overwrites-pull-request-comment&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d3869b;&quot;&gt;true
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#8ec07c;&quot;&gt;env&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;          &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#8ec07c;&quot;&gt;NETLIFY_AUTH_TOKEN&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;${{ secrets.NETLIFY_AUTH_TOKEN }}
&lt;&#x2F;span&gt;&lt;span&gt;          &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#8ec07c;&quot;&gt;NETLIFY_SITE_ID&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;${{ secrets.NETLIFY_SITE_ID }}
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#8ec07c;&quot;&gt;timeout-minutes&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d3869b;&quot;&gt;1
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Added both the NETLIFY_AUTH_TOKEN and the NETLIFY_SITE_ID to the secrets of my fork of rune. Let&#x27;s test the github action by pushing to docs.&lt;&#x2F;p&gt;
&lt;p&gt;It did publish, but since the target&#x2F;doc directory has all the crates, including the `rune` one, we should set up a redirect from &lt;code&gt;&#x2F;&lt;&#x2F;code&gt; to &lt;code&gt;&#x2F;rune&lt;&#x2F;code&gt;. All the internal links should work.&lt;&#x2F;p&gt;
&lt;p&gt;As part of the same PR, I fixed all the warnings on cargo doc, making sure that the documentation is correctly published. The trick to deploy cargo doc is to deploy &lt;code&gt;target&#x2F;doc&lt;&#x2F;code&gt; and then pair that with a redirect of the main page (configured rune-rs.netlify.app on my own account) to &lt;code&gt;&#x2F;rune&lt;&#x2F;code&gt; which (as the main crate) has the info about the subcrates as well.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;IMPORTANT&lt;&#x2F;strong&gt;&lt;&#x2F;strong&gt;: For this to work, you need to do the following steps. I would do the steps myself, but I imagined you would like to have control of the app itself, as the author of the project:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Create a Netlify account if you don&#x27;t have any.&lt;&#x2F;li&gt;
&lt;li&gt;Create a new site with the Rune project on Github.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;strong&gt;Note down&lt;&#x2F;strong&gt;&lt;&#x2F;strong&gt; the site id.&lt;&#x2F;li&gt;
&lt;li&gt;Change the site name to something like rune-rs, for &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;rune-rs.netlify.app&quot;&gt;https:&#x2F;&#x2F;rune-rs.netlify.app&lt;&#x2F;a&gt; to work. I&#x27;ll remove my site with the same name to avoid conflicts.&lt;&#x2F;li&gt;
&lt;li&gt;Go to your profile, User Settings, Applications and Generate a No Expiry (or to be expired, although that will need changing the secrets whenever it expires again) Personal Access Token and &lt;strong&gt;&lt;strong&gt;note it down&lt;&#x2F;strong&gt;&lt;&#x2F;strong&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Go to the SECRETS configuration of this repo.&lt;&#x2F;li&gt;
&lt;li&gt;With the site id you noted down, add the NETLIFY_SITE_ID secret.&lt;&#x2F;li&gt;
&lt;li&gt;With the personal access token you noted down, add the NETLIFY_AUTH_TOKEN secret.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The site will be published on any push to &lt;code&gt;master&lt;&#x2F;code&gt;, no need to publish on PRs!&lt;&#x2F;p&gt;
&lt;p&gt;With that, we have a successfully published cargo docs on &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;rune-rs.netlify.app&quot;&gt;https:&#x2F;&#x2F;rune-rs.netlify.app&lt;&#x2F;a&gt; so that other contributors can see the documentation without the barrier of running &lt;code&gt;cargo doc --workspace&lt;&#x2F;code&gt; manually. Here&#x27;s the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;CeleritasCelery&#x2F;rune&#x2F;pull&#x2F;50&quot;&gt;PR&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Setting up the Rune project for success</title>
        <published>2023-12-02T00:00:00+00:00</published>
        <updated>2023-12-02T00:00:00+00:00</updated>
        <author>
          <name>Quique Kessler Martínez</name>
        </author>
        <link rel="alternate" href="https://enriquekesslerm.com/blog/rune-ci-pipeline/" type="text/html"/>
        <id>https://enriquekesslerm.com/blog/rune-ci-pipeline/</id>
        
        <content type="html">&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;&#x2F;h2&gt;
&lt;p&gt;After very recently syncing with Troy, the owner of the Rune project (you can check my first contribution blog post &lt;a href=&quot;https:&#x2F;&#x2F;enriquekesslerm.com&#x2F;blog&#x2F;bye-lazy-static-welcome-once-cell&#x2F;&quot;&gt;here&lt;&#x2F;a&gt;), we were discussing about the next (immediate) steps for the project, and overall my next contribution. Here&#x27;s my proposal:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Step by step, we need CI for pull requests and then we can potentially work on simplifying and completing the backlog of issues we have. With a prioritized backlog, we can call for contributions on both Emacs and Rust’s subreddits. What do you think?&lt;&#x2F;p&gt;
&lt;p&gt;After the CI, I can build something with async rust (probably file io can benefit from it), and make sure to measure it with benchmarks (criterion or cargo benchmark). Those benchmarks could potentially be added to CI once we are happy with them, and make sure we don’t regress performance with pull requests or commits.&lt;&#x2F;p&gt;
&lt;p&gt;Looking forward to next steps,
Best,
Quique.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;With that, here&#x27;s the first step: CI for the Rune project, buckle up!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;stepping-stones&quot;&gt;Stepping stones&lt;&#x2F;h2&gt;
&lt;p&gt;I was aware that Jon Gjenset (@jonhoo) did a super nice video explaining his recommendation for CI that should run on lib&#x2F;bin crates (&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=xUH-4y92jPg&amp;amp;t=491s&quot;&gt;ref&lt;&#x2F;a&gt;). That video goes through an overview of some files of the project &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jonhoo&#x2F;rust-ci-conf&#x2F;&quot;&gt;rust-ci-conf&lt;&#x2F;a&gt;, which is a set of Github Actions workflows to cover the bare minimum for crates: stepping stones to a great CI pipeline for our Rune project.&lt;&#x2F;p&gt;
&lt;p&gt;With that, I used the project as a blueprint of what CI could look like and started modifying the workflows with the specific requirements of the &lt;code&gt;rune&lt;&#x2F;code&gt; crate. From the top of my head:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Rune is a binary, not a library, so we can&#x27;t run doctests on it.&lt;&#x2F;li&gt;
&lt;li&gt;Rune has the rust-toolchain set to &lt;code&gt;beta&lt;&#x2F;code&gt; and that broke CI and is not common in other popular crates.&lt;&#x2F;li&gt;
&lt;li&gt;Rune does not have any feature gates so &lt;code&gt;cargo-hack&lt;&#x2F;code&gt; wouldn&#x27;t do us any good.&lt;&#x2F;li&gt;
&lt;li&gt;Rune does not run correctly on Windows (yet), so it wouldn&#x27;t make sense to run CI on something we don&#x27;t support yet.&lt;&#x2F;li&gt;
&lt;li&gt;Rune uses &lt;code&gt;unsafe&lt;&#x2F;code&gt; code, which means we need to care about safety and ensure any change is sanitized and avoids any Undefined Behaviour.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Staring from those requirements, I modified the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Qkessler&#x2F;rune&#x2F;blob&#x2F;master&#x2F;.github&#x2F;DOCS.md?plain=1#L1&quot;&gt;DOCS.md file of the .github folder&lt;&#x2F;a&gt; with the intention of documenting possible improvement points I see on CI, with the intention of future contributors iterating on the current CI pipeline.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;potential-improvements&quot;&gt;Potential improvements&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;cargo-hack&quot;&gt;cargo-hack&lt;&#x2F;h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;cargo-hack&lt;&#x2F;code&gt; checks combinations of feature flags to ensure that features are all additive which is required for feature unification.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jonhoo&#x2F;rust-ci-conf&#x2F;blob&#x2F;main&#x2F;.github&#x2F;workflows&#x2F;check.yml#L77&quot;&gt;source&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As we don&#x27;t currently have any meaningful feature gates.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;scheduled&quot;&gt;scheduled&lt;&#x2F;h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Run scheduled (rolling) jobs on a nightly basis, as your crate may break independently of any given PR. E.g., updates to rust nightly and updates to this crates dependencies. See check.yml for information about how the concurrency cancelation and workflow triggering works&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jonhoo&#x2F;rust-ci-conf&#x2F;blob&#x2F;main&#x2F;.github&#x2F;workflows&#x2F;scheduled.yml#L1&quot;&gt;source&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As we don&#x27;t run on nightly, we don&#x27;t really need to check whether nightly breaks our builds. A potential argument for adding this could be that we are running nightly for the CI, and we could break the CI from nightly builds. I propose revisiting adding the &lt;code&gt;scheduled.yml&lt;&#x2F;code&gt; linked above if that&#x27;s the case.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;loom&quot;&gt;loom&lt;&#x2F;h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Loom is a testing tool for concurrent Rust code. It runs a test many times, permuting the possible concurrent executions of that test under the C11 memory model. It uses state reduction techniques to avoid combinatorial explosion.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;loom&quot;&gt;source&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Loom is great and it&#x27;s backed by Tokio, but it would mean a bigger investment in making the threads we use be loom specific. Definitely something to iterate on, as we get onto Async Emacs.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;codecov-io&quot;&gt;codecov.io&lt;&#x2F;h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Enhance Your Testing the Codecov Way: Codecov is the all-in-one code coverage reporting solution for any test suite — giving developers actionable insights to deploy reliable code with confidence.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;about.codecov.io&quot;&gt;source&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;codecov&#x2F;codecov-action&quot;&gt;repo of Github Action&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If we want to add a badge or have nice reports on coverage, we could investigate CodeCov. It requires a token that should be added to the secrets of the repository: &lt;code&gt;CODECOV_TOKEN&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;windows-tests&quot;&gt;Windows tests&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;yaml&quot; style=&quot;background-color:#282828;color:#fdf4c1aa;&quot; class=&quot;language-yaml &quot;&gt;&lt;code class=&quot;language-yaml&quot; data-lang=&quot;yaml&quot;&gt;&lt;span style=&quot;font-weight:bold;color:#8ec07c;&quot;&gt;matrix&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#8ec07c;&quot;&gt;os&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;macos-latest&lt;&#x2F;span&gt;&lt;span&gt;] &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# REVIEW: We could add windows-latest here.
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;As of today, we don&#x27;t support Windows, or at least the tests are failing. We can iterate on this and if we feel Windows should be supported in the near feature, we can add &lt;code&gt;windows-latest&lt;&#x2F;code&gt; to run CI on it.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;doctests-on-binary-crates&quot;&gt;Doctests on binary crates&lt;&#x2F;h3&gt;
&lt;p&gt;As suggested by &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust&#x2F;issues&#x2F;50784&quot;&gt;issue&lt;&#x2F;a&gt;, doctests won&#x27;t currently run on Binary creates. I don&#x27;t see anything particularly wrong with running doctests on binary crates. Some of the argumenst include that &amp;quot;Why would a binary be documented?&amp;quot;. Documentation is not only useful for consumers of the library, but rather also internal developers that are maintaining it, looking for better understanding of the binary crate. It&#x27;s key that developers onboarding into the project have the material to have a swift ramp-up process, to move the project forward. &lt;&#x2F;p&gt;
&lt;p&gt;Once the issue above is stabilized, we can add the following to the test.yml fire:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;yaml&quot; style=&quot;background-color:#282828;color:#fdf4c1aa;&quot; class=&quot;language-yaml &quot;&gt;&lt;code class=&quot;language-yaml&quot; data-lang=&quot;yaml&quot;&gt;&lt;span&gt;-   &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#8ec07c;&quot;&gt;name&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;cargo test --doc
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#8ec07c;&quot;&gt;run&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;cargo test --locked --all-features --doc
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;iterative-process&quot;&gt;Iterative process&lt;&#x2F;h2&gt;
&lt;p&gt;The overarching theme with this contribution is: &lt;strong&gt;I see CI as an iterative process, and I&#x27;m sure we&#x27;ll be changing it in the future&lt;&#x2F;strong&gt;. This acts as a good start, and opens the project to possible issues it may have, that CI now catches (say, dependency issue, as we see running &lt;code&gt;cargo test&lt;&#x2F;code&gt; with &lt;code&gt;-Zminimal-versions&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;I see this first PR as not fixing all the issues with the repository, but rather creating the stepping stones to fix them in the next commits. Every commit that includes this PR has been tested with the CI changes, iterating on the process. I&#x27;m open to rebasing the commits if needed, but it&#x27;s useful to see the iteration process to arrive to a CI that fits the project&#x27;s needs.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;I was able to get a successfully configured CI pipeline for the Rune project, and propose additional improvements that we can discuss on the PR for it. I see CI as an iterative process, and I bet it&#x27;s something we modify sooner than we think. As suggested by the step by step game plan above, next steps include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Run the runtime directly on Emacs, and add it to the CI.&lt;&#x2F;li&gt;
&lt;li&gt;Create a benchmark suite to avoid any regressions on performance, and add it to the CI.&lt;&#x2F;li&gt;
&lt;li&gt;Start playing with async code, where &lt;code&gt;loom&lt;&#x2F;code&gt; could potentially fit (and add it to the CI).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Lots of work left, really excited about the future!&lt;&#x2F;p&gt;
&lt;p&gt;P.S: Here&#x27;s the PR link: &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;CeleritasCelery&#x2F;rune&#x2F;pull&#x2F;35&quot;&gt;#35&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Bye lazy_static, Welcome once_cell!</title>
        <published>2023-11-26T00:00:00+00:00</published>
        <updated>2023-11-26T00:00:00+00:00</updated>
        <author>
          <name>Quique Kessler Martínez</name>
        </author>
        <link rel="alternate" href="https://enriquekesslerm.com/blog/bye-lazy-static-welcome-once-cell/" type="text/html"/>
        <id>https://enriquekesslerm.com/blog/bye-lazy-static-welcome-once-cell/</id>
        
        <content type="html">&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;&#x2F;h2&gt;
&lt;p&gt;Very recently I have become really interested in a project called &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;CeleritasCelery&#x2F;rune&quot;&gt;rune&lt;&#x2F;a&gt; (&lt;strong&gt;R&lt;&#x2F;strong&gt;ust &lt;strong&gt;Un&lt;&#x2F;strong&gt;der &lt;strong&gt;E&lt;&#x2F;strong&gt;macs, love the name), which in nature creates a Rust Virtual Machine to run Emacs on. The author of the project has written in detail about pros and cons of using Rust &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;coredumped.dev&#x2F;2023&#x2F;01&#x2F;17&#x2F;design-of-emacs-in-rust&#x2F;&quot;&gt;here&lt;&#x2F;a&gt;, for avid readers!&lt;&#x2F;p&gt;
&lt;p&gt;In this post, I plan to contribute to the project by migrating all the usages of the late &lt;code&gt;lazy_static&lt;&#x2F;code&gt; to the newer alternative &lt;code&gt;once_cell&lt;&#x2F;code&gt;. &lt;code&gt;once_cell&lt;&#x2F;code&gt; has the benefit of being macro-less and being included in the standard library, as of 1.70 (there&#x27;s nice documentation in the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;std&#x2F;cell&#x2F;index.html&quot;&gt;module&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;Since it&#x27;s included in the standard library, I thought we could just use that, but then I thought back to the project initiative: do we need to support a minimal Rust version, say running on old devices? Quite possible &lt;strong&gt;not&lt;&#x2F;strong&gt;, as the project is not yet in production (0.1.0 version, though I don&#x27;t think we are following &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;semver.org&#x2F;&quot;&gt;semver&lt;&#x2F;a&gt;) and it won&#x27;t be for a while. I don&#x27;t find locking ourselves into a &lt;code&gt;once_cell&lt;&#x2F;code&gt; dependency is the right play, but rather, use the std version.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;minimal-stable-rust-version&quot;&gt;Minimal Stable Rust Version&lt;&#x2F;h2&gt;
&lt;p&gt;Nevertheless, for the sake of completion, I wanted to verify the minimal Rust version we support in the rune repo. For that, we can use the command provided by the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;foresterre.github.io&#x2F;cargo-msrv&#x2F;&quot;&gt;cargo-msrv crate&lt;&#x2F;a&gt;: &lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#282828;color:#fdf4c1aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;  cargo &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;msrv
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;│     Checking fluent-syntax v0.11.0                                                     │
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;│     Checking fluent-bundle v0.15.2                                                     │
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;│    Compiling quote-use-macros v0.7.2                                                   │
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;│     Checking tracing v0.1.40                                                           │
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;│     Checking druid v0.8.3                                                              │
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;│    Compiling quote-use v0.7.2                                                          │
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;│    Compiling attribute-derive-macro v0.6.1                                             │
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;│    Compiling attribute-derive v0.6.1                                                   │
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;│ Compiling get-size-derive v0.1.3                                                       │
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;│ (https:&#x2F;&#x2F;github.com&#x2F;CeleritasCelery&#x2F;get-size.git&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;branch=boxed_slice_fix#e0e9377d&lt;&#x2F;span&gt;&lt;span&gt;)      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;│
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;│ Checking get-size v0.1.4                                                               │
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;│ (https:&#x2F;&#x2F;github.com&#x2F;CeleritasCelery&#x2F;get-size.git&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;branch=boxed_slice_fix#e0e9377d&lt;&#x2F;span&gt;&lt;span&gt;)      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;│
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;│     Checking text-buffer v0.1.0 (&#x2F;Users&#x2F;enrikes&#x2F;Documents&#x2F;rune&#x2F;crates&#x2F;text-buffer&lt;&#x2F;span&gt;&lt;span&gt;)     &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;│
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;│ error&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;E0658&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;: use of unstable library feature &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;#39;is_some_and&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;                            │
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;│    --&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt; src&#x2F;buffer.rs:130:29                                                            │
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;│     &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;|                                                                                  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;│
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;│ 130 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;|         |&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;name: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;ignore.is_some_and(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;|&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;x == name&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;||                        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;│
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;│ !buffer_list.contains_key(name&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;;                                                       &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;│
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;│     &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;|                             &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;^^^^^^^^^^^                                          │ │     &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;|                                                                                  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;│
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;│ = note: see issue &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;#93050 &amp;lt;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust&#x2F;issues&#x2F;93050&amp;gt; for more     │
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;│ information                                                                            │
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;│                                                                                        │
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;│ For more information about this error, try `rustc --explain E0658`.                    │
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;│ error: could not compile `rune` due to previous error                                  │
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;└────────────────────────────────────────────────────────────────────────────────────────┘
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;Finished The MSRV is: 1.70.0   ███████████████████████████████████████████████ 00:15:22
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Good to see, the Minimum Stable Rust Version is the 1.70.0, &lt;strong&gt;which includes std::sync::OnceLock&lt;&#x2F;strong&gt; (If you are curious about the error above, the API &lt;code&gt;is_some_and&lt;&#x2F;code&gt; has been stabilized in &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;stable&#x2F;std&#x2F;option&#x2F;enum.Option.html#method.is_some_and&quot;&gt;1.70.0&lt;&#x2F;a&gt; as well).&lt;&#x2F;p&gt;
&lt;h1 id=&quot;investigation&quot;&gt;Investigation&lt;&#x2F;h1&gt;
&lt;p&gt;With that, we&#x27;ll move forward with OnceLock (Sync version of OnceCell), but pretty much the same properties apply:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;OnceCell&lt;T&gt; is somewhat of a hybrid of Cell and RefCell that works for values that typically only need to be set once. This means that a reference &amp;amp;T can be obtained without moving or copying the inner value (unlike Cell) but also without runtime checks (unlike RefCell). However, its value can also not be updated once set unless you have a mutable reference to the OnceCell.&lt;&#x2F;p&gt;
&lt;p&gt;OnceCell provides the following methods:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;get: obtain a reference to the inner value&lt;&#x2F;li&gt;
&lt;li&gt;set: set the inner value if it is unset (returns a Result)&lt;&#x2F;li&gt;
&lt;li&gt;get_or_init: return the inner value, initializing it if needed&lt;&#x2F;li&gt;
&lt;li&gt;get_mut: provide a mutable reference to the inner value, only available if you have a mutable reference to the cell itself.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The corresponding Sync version of OnceCell&lt;T&gt; is OnceLock&lt;T&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;stable&#x2F;std&#x2F;cell&#x2F;index.html&quot;&gt;source&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The first change I plan to make to the code base is the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;CeleritasCelery&#x2F;rune&#x2F;blob&#x2F;master&#x2F;src&#x2F;buffer.rs#L1&quot;&gt;buffer.rs&lt;&#x2F;a&gt;, not part of core. &lt;strong&gt;REVIEW&lt;&#x2F;strong&gt;: I wonder whether as a follow-up we can consider moving the code around to avoid having similar files without their own modules.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#282828;color:#fdf4c1aa;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#fabd2f;&quot;&gt;lazy_static! &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;static ref &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;BUFFERS&lt;&#x2F;span&gt;&lt;span&gt;: Mutex&amp;lt;HashMap&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fabd2f;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;&amp;#39;static&lt;&#x2F;span&gt;&lt;span&gt; LispBuffer&amp;gt;&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;=
&lt;&#x2F;span&gt;&lt;span&gt;        Mutex::new(HashMap::default());
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;&#x2F;&#x2F; versus the OnceLock version.
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;static &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;BUFFERS&lt;&#x2F;span&gt;&lt;span&gt;: OnceLock&amp;lt;Mutex&amp;lt;HashMap&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fabd2f;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;&amp;#39;static&lt;&#x2F;span&gt;&lt;span&gt; LispBuffer&amp;gt;&amp;gt;&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;OnceLock::new();
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;As you&#x27;ll see, we are not initializing the value here, and there isn&#x27;t really an API to do so in the std, while there was on once_cell. If we wanted to hold the value across the different modules, we could potentially initialize it on main.rs and then access its value across the different functions. Don&#x27;t know whether context here is that, or rather the context of the function, say all the variables at the time of execution (global set with &lt;code&gt;setq&lt;&#x2F;code&gt;, and locals created with &lt;code&gt;let*&lt;&#x2F;code&gt; for example).&lt;&#x2F;p&gt;
&lt;p&gt;Interesting, checking the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;CeleritasCelery&#x2F;rune&#x2F;blob&#x2F;master&#x2F;src&#x2F;core&#x2F;gc&#x2F;context.rs#L28&quot;&gt;Context struct&lt;&#x2F;a&gt;, we are using std::cell to hold the vector of &lt;code&gt;OwnedObject&lt;&#x2F;code&gt;, which makes me think whether the &lt;code&gt;lazy_static!&lt;&#x2F;code&gt; usage is just due to old code that wasn&#x27;t ported to the new APIs. Right, that&#x27;s not the case, the &lt;code&gt;git blame&lt;&#x2F;code&gt; command shows that the &lt;code&gt;lazy_static!&lt;&#x2F;code&gt; macro was used in 2023. Since we don&#x27;t have the LazyLock API stabilized yet (&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust&#x2F;issues&#x2F;109736&quot;&gt;issue tracker&lt;&#x2F;a&gt;), we&#x27;ll have to think of an ergonomic way to initialize the BUFFERS static:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;We could initialize it in main.rs and then consume it, although we would kinda using the BUFFERS static as a global variable, and that means that all the modules would be aware of it, which is probably not the right solution.&lt;&#x2F;li&gt;
&lt;li&gt;We could initialize it on each of the &lt;code&gt;lock()&lt;&#x2F;code&gt; usages, which is kinda repeating the initialization part.&lt;&#x2F;li&gt;
&lt;li&gt;We could have a helper function on buffer.rs that gets or inits the BUFFERS static.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Opting for three, created this helper function:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#282828;color:#fdf4c1aa;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;&#x2F;&#x2F;&#x2F; Helper function to avoid calling `get_or_init` on each of the calls to `lock()` on the Mutex.
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;&#x2F;&#x2F;&#x2F;
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;&#x2F;&#x2F;&#x2F; TODO: Once [`LazyLock`] is stabilized, this can be changed to initializing on the LazyLock::new() method.
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;&#x2F;&#x2F;&#x2F; Stabilization tracker: https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust&#x2F;issues&#x2F;109736
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8ec07c;&quot;&gt;buffers&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;&amp;#39;static &lt;&#x2F;span&gt;&lt;span&gt;Mutex&amp;lt;HashMap&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fabd2f;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;&amp;#39;static&lt;&#x2F;span&gt;&lt;span&gt; LispBuffer&amp;gt;&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;BUFFERS&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fabd2f;&quot;&gt;get_or_init&lt;&#x2F;span&gt;&lt;span&gt;(|| Mutex::new(HashMap::default()))
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Did something very similar for &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;CeleritasCelery&#x2F;rune&#x2F;blob&#x2F;master&#x2F;src&#x2F;data.rs#L20&quot;&gt;data.rs&lt;&#x2F;a&gt;. With that, we are only missing the complex changes for the &lt;code&gt;INTERNED_SYMBOLS&lt;&#x2F;code&gt; (&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;CeleritasCelery&#x2F;rune&#x2F;blob&#x2F;master&#x2F;build.rs#L231&quot;&gt;ref&lt;&#x2F;a&gt;). This is great, because it&#x27;s making me dive deeper into why we are using x or y in different files. In this case, let&#x27;s dive deep into the build.rs &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;CeleritasCelery&#x2F;rune&#x2F;blob&#x2F;master&#x2F;build.rs#L231&quot;&gt;file&lt;&#x2F;a&gt;. We seem to be working with nightly a lot. Let&#x27;s message the owner and see what he thinks. If he&#x27;s good with it, we could just use &lt;code&gt;LazyLock&lt;&#x2F;code&gt; instead of helper methods on buffer.rs and data.rs.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;build-rs&quot;&gt;build.rs&lt;&#x2F;h1&gt;
&lt;p&gt;I was trying to understand why we include everything we generate with the build.rs file using the &lt;code&gt;include!&lt;&#x2F;code&gt; macro, and I was pointed to &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;cargo&#x2F;reference&#x2F;build-scripts.html#outputs-of-the-build-script&quot;&gt;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;cargo&#x2F;reference&#x2F;build-scripts.html#outputs-of-the-build-script&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I don&#x27;t see that we are actually running the &lt;code&gt;println!&lt;&#x2F;code&gt; macros that I&#x27;m adding inside the build.rs file when running &lt;code&gt;cargo run -- --load --repl&lt;&#x2F;code&gt;. I wonder when is that build.rs file running. Searching around, I see that because of &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;cargo&#x2F;issues&#x2F;985&quot;&gt;this issue&lt;&#x2F;a&gt;, &lt;code&gt;println!&lt;&#x2F;code&gt; won&#x27;t run anything as it&#x27;s used to communicate with cargo to run specific cargo commands on it (&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;cargo&#x2F;issues&#x2F;985#issuecomment-1071667472&quot;&gt;ref&lt;&#x2F;a&gt;). A workaround of this is to use &lt;code&gt;println!(&amp;quot;cargo:warning={}&amp;quot;, ...)&lt;&#x2F;code&gt; we&#x27;ll see the output. From that debugging output, I understand that:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;The build.rs script is used on rune to pull all the functions created for FFI using the #[defun] macro. From that macro, we take the lisp name and the contents and define the outputs for emacs to consume.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Here&#x27;s the output of my prints:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#282828;color:#fdf4c1aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;warning: rune@0.1.0: Reading &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;src&#x2F;emacs.rs&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;warning: rune@0.1.0: name between predicates &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;kill_emacs&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;warning: rune@0.1.0: lisp_name: kill-emacs
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;warning: rune@0.1.0: Reading &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;src&#x2F;reader.rs&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;warning: rune@0.1.0: Reading &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;src&#x2F;interpreter.rs&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;warning: rune@0.1.0: name between predicates &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;eval&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;warning: rune@0.1.0: lisp_name: eval
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;warning: rune@0.1.0: Reading &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;src&#x2F;threads.rs&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;warning: rune@0.1.0: name between predicates &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;go&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;warning: rune@0.1.0: lisp_name: go
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Basically, we read through the files and build all the defuns, but also the &lt;code&gt;defsym&lt;&#x2F;code&gt; and the &lt;code&gt;defvar&lt;&#x2F;code&gt; (ref: &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;CeleritasCelery&#x2F;rune&#x2F;blob&#x2F;master&#x2F;build.rs#L103-L110&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;CeleritasCelery&#x2F;rune&#x2F;blob&#x2F;master&#x2F;build.rs#L103-L110&lt;&#x2F;a&gt;). For the defsym, wanted to understand what they are a bit further. Added the print for &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;CeleritasCelery&#x2F;rune&#x2F;blob&#x2F;master&#x2F;build.rs#L143&quot;&gt;all_defsym&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#282828;color:#fdf4c1aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;warning: rune@0.1.0: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;KW_TEST&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;, None), (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;KW_DOCUMENTATION&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;, None), (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;MD5&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;, None), (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;SHA1&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;, None), (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;SHA224&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;, None), (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;SHA256&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;, None), (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;SHA384&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;, None), (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;SHA512&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;, None), (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;MANY&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;, None), (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;INTEGER&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;, None), (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;SYMBOL&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;, None), (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;COMPILED_FUNCTION&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;, None), (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;HASH_TABLE&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;, None), (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;BUFFER&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;, None), (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;SUBR&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;, None), (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;FUNCTION&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;, None), (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;QUOTE&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;, None), (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;MACRO&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;, None), (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;UNQUOTE&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;, Some(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;\&amp;quot;,\&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;)), (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;SPLICE&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;, Some(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;\&amp;quot;,@\&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;)), (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;BACKQUOTE&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;, Some(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;\&amp;quot;`\&amp;quot;&amp;quot;)), (&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;AND_OPTIONAL&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;, Some(&amp;quot;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;optional&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;\&amp;quot;&amp;quot;)), (&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;AND_REST&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;, Some(&amp;quot;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;rest&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;\&amp;quot;&amp;quot;)), (&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;LAMBDA&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;, None), (&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;CLOSURE&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;, None), (&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;CONDITION_CASE&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;, None), (&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;UNWIND_PROTECT&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;, None), (&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;SAVE_EXCURSION&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;, None), (&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;SAVE_CURRENT_BUFFER&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;, None), (&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;WHILE&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;, None), (&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;INLINE&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;, None), (&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;PROGN&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;, None), (&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;PROG1&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;, None), (&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;PROG2&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;, None), (&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;SETQ&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;, None), (&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;DEFCONST&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;, None), (&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;COND&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;, None), (&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;LET&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;, None), (&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;LET_STAR&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;, Some(&amp;quot;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;let*&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;\&amp;quot;&amp;quot;)), (&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;IF&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;, None), (&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;AND&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;, None), (&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;OR&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;, None), (&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;INTERACTIVE&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;, None), (&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;CATCH&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;, None), (&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;THROW&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;, None), (&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;ERROR&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;, None), (&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;DEBUG&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;, None), (&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;VOID_VARIABLE&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;, None)]
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We seem to be defining them on different files, here&#x27;s eval.rs:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#282828;color:#fdf4c1aa;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#fabd2f;&quot;&gt;defsym!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;FUNCTION&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fabd2f;&quot;&gt;defsym!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;QUOTE&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fabd2f;&quot;&gt;defsym!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;MACRO&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fabd2f;&quot;&gt;defsym!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;UNQUOTE&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;,&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fabd2f;&quot;&gt;defsym!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;SPLICE&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;,@&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;They seem to be symbols, probably for use on the different functions that we create. Don&#x27;t think I should dive deeper there, won&#x27;t work on it for now.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s start with the build.rs changes for once_cell, now that we know how that file will be created on the &lt;code&gt;OUT_DIR&lt;&#x2F;code&gt;, after reading its code and the rust documentation. I&#x27;m kinda split between using the unstable features or not. I would love the confirmation from the core maintainer.&lt;&#x2F;p&gt;
&lt;p&gt;If we were to use the unstable &lt;code&gt;lazy_cell&lt;&#x2F;code&gt;, we can just use the initialization, which is more ergonomic, removing helper methods, which could prove tricky for the statics on the build.rs file: &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;CeleritasCelery&#x2F;rune&#x2F;blob&#x2F;master&#x2F;build.rs#L232&quot;&gt;INTERNED_SYMBOLS&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#282828;color:#fdf4c1aa;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#fabd2f;&quot;&gt;writeln!&lt;&#x2F;span&gt;&lt;span&gt;(
&lt;&#x2F;span&gt;&lt;span&gt;    f,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;use std::sync::LazyLock;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;pub(crate) static INTERNED_SYMBOLS: LazyLock&amp;lt;Mutex&amp;lt;ObjectMap&amp;gt;&amp;gt; = LazyLock::new(|| Mutex::new({{
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;    let size: usize = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;{symbol_len}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;    let mut map = SymbolMap::with_capacity(size);
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;    sym::init_symbols(&amp;amp;mut map);
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;    ObjectMap {{
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;        map,
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;        block: Block::new_global(),
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;    }}
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;}}));
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;With &lt;code&gt;LazyLock&lt;&#x2F;code&gt;, the callers wouldn&#x27;t have to call &lt;code&gt;get&lt;&#x2F;code&gt; on the OnceLock, and instead use the methods of the content directly, since by nature, &lt;strong&gt;they can assume it has been initialized&lt;&#x2F;strong&gt;. &lt;&#x2F;p&gt;
&lt;p&gt;I was pretty happy with the simplification, since it removes the forced initialization + comment on the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;CeleritasCelery&#x2F;rune&#x2F;blob&#x2F;master&#x2F;src&#x2F;main.rs#L47&quot;&gt;main.rs file&lt;&#x2F;a&gt; and &lt;strong&gt;removes the lazy_static dependency from the code base&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;diff&quot; style=&quot;background-color:#282828;color:#fdf4c1aa;&quot; class=&quot;language-diff &quot;&gt;&lt;code class=&quot;language-diff&quot; data-lang=&quot;diff&quot;&gt;&lt;span&gt; float-cmp = &amp;quot;0.9.0&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt; fn_macros = { version = &amp;quot;0.1.0&amp;quot;, path = &amp;quot;fn_macros&amp;quot; }
&lt;&#x2F;span&gt;&lt;span&gt; hostname = &amp;quot;0.3.1&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;-lazy_static = &amp;quot;1.4.0&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt; memoffset = &amp;quot;0.8.0&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt; num_enum = &amp;quot;0.5.11&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt; paste = &amp;quot;1.0.12&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Open or Raise Emacs</title>
        <published>2022-04-17T00:00:00+00:00</published>
        <updated>2022-04-17T00:00:00+00:00</updated>
        <author>
          <name>Quique Kessler Martínez</name>
        </author>
        <link rel="alternate" href="https://enriquekesslerm.com/blog/open-or-raise-emacs/" type="text/html"/>
        <id>https://enriquekesslerm.com/blog/open-or-raise-emacs/</id>
        
        <content type="html">&lt;p&gt;I use &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.keyboardmaestro.com&#x2F;main&#x2F;&quot;&gt;Keyboard maestro&lt;&#x2F;a&gt; to Activate the applications I use the most, with the intention of reducing hand movement I endure every day. In my normal developing workflow, I would start working with Emacs to do my first Inbox Review, I would then open up the browser to search for anything while developing and I would then want to go back to Emacs to keep developing. Everything works with a keypress and following &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.merriam-webster.com&#x2F;dictionary&#x2F;mnemonics&quot;&gt;mnemonics&lt;&#x2F;a&gt; to make the keys easier to remember.&lt;&#x2F;p&gt;
&lt;p&gt;The latter is the part that I have been interested in improving. I use the Emacs client-server approach to have a fast running Emacs instance at all times. If I would want to close Emacs, I would be back to an open instance instantly.&lt;&#x2F;p&gt;
&lt;p&gt;The problem with Emacs is that having the server running, we can&#x27;t use the application condition with Keyboard maestro, since we already have an open application, even if it&#x27;s running in the background.&lt;&#x2F;p&gt;
&lt;p&gt;The idea is then run an Apple script as the condition to check whether the Emacs process is running (and not the Emacs window) to launch the Emacs client, or only activate the window that is already there. To do so, I would want to use an Apple Script to grep for the background process.&lt;&#x2F;p&gt;
&lt;p&gt;Here is the script that I use as condition:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;applescript&quot; style=&quot;background-color:#282828;color:#fdf4c1aa;&quot; class=&quot;language-applescript &quot;&gt;&lt;code class=&quot;language-applescript&quot; data-lang=&quot;applescript&quot;&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;tell &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8ec07c;&quot;&gt;application &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;System Events&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;set &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;emacsWindowsCount &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;to &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fabd2f;&quot;&gt;count &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;of&lt;&#x2F;span&gt;&lt;span&gt; window &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d3869b;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;of &lt;&#x2F;span&gt;&lt;span&gt;(processes &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;whose &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fabd2f;&quot;&gt;name &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;is &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;Emacs&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; emacsWindowsCount &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;is &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d3869b;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;then
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;error number &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d3869b;&quot;&gt;-1
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;end if
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;end tell
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And here is the Keyboard maestro macro I ended up with. The LauchEmacsClient is an application that I created with Automator to just call the &lt;code&gt;emacsclient&lt;&#x2F;code&gt; binary with the buffer I want to start with.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;enriquekesslerm.com&#x2F;blog&#x2F;open-or-raise-emacs&#x2F;images&#x2F;activate-emacs-macro.png&quot; alt=&quot;img&quot; title=&quot;Activate Emacs keyboard maestro macro.&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If anyone is interested in the &lt;code&gt;.kmmacros&lt;&#x2F;code&gt; file, ping me on &lt;a href=&quot;mailto:enrique.kesslerm@gmail.com&quot;&gt;email&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Diving deep into Sequelize</title>
        <published>2021-05-25T00:00:00+00:00</published>
        <updated>2021-05-25T00:00:00+00:00</updated>
        <author>
          <name>Quique Kessler Martínez</name>
        </author>
        <link rel="alternate" href="https://enriquekesslerm.com/blog/sequelize/" type="text/html"/>
        <id>https://enriquekesslerm.com/blog/sequelize/</id>
        
        <content type="html">&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;&#x2F;h2&gt;
&lt;p&gt;In this post we will go deep into the SQL ORM world, highlighting some of the strong points for Sequelize. I find that everyone could find this post interesting, specially if you have heard of the &amp;quot;new&amp;quot; ES6 features. Sequelize is a great option for SQL database management. Let&#x27;s get started!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-is-sequelize&quot;&gt;What is Sequelize?&lt;&#x2F;h2&gt;
&lt;p&gt;Per the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;sequelize.org&#x2F;&quot;&gt;Sequelize website&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Sequelize is a promise-based Node.js ORM for Postgres, MySQL, MariaDB, SQLite and Microsoft SQL Server. It features solid transaction support, relations, eager and lazy loading, read replication and more.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;But what does it really mean? What does the average Joe (The software engineer Joe, nevertheless) has to know about Sequelize?&lt;&#x2F;p&gt;
&lt;p&gt;In my book, Sequelize is one of the most popular &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;nodejs.org&#x2F;es&#x2F;&quot;&gt;Node.js&lt;&#x2F;a&gt; &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Object%E2%80%93relational_mapping&quot;&gt;ORMs (Object Relational Mapper)&lt;&#x2F;a&gt;, which provides extensive functionality to connect and work with relational databases, namely PostgreSQL, MySQL, MariaDB and more. One of the strong points of Sequelize is that the whole implementation hovers around &lt;a href=&quot;https:&#x2F;&#x2F;enriquekesslerm.com&#x2F;blog&#x2F;sequelize&#x2F;#promises&quot;&gt;Promises&lt;&#x2F;a&gt; which —as you know, we&#x27;re all ES6 developers, aren&#x27;t we?— provide asynchronous support. In this case, to database transitions, which is really interesting.&lt;&#x2F;p&gt;
&lt;p&gt;Even though I will be talking about Promises more in depth in the following paragraphs, let&#x27;s see a practical example: Image you are working on a web for your company, and you are tasked to connect to a database and perform some long and heavy transactions, all when the user presses a button. One option would be to keep the user waiting for the database to finish its transactions (this is not the way I would go about it) and the better option is to do all the database work asynchronously, using Promises!&lt;&#x2F;p&gt;
&lt;p&gt;You can find about setting up Sequelize with your database —the right way— in the Set up Sequelize in a Node.js project section.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;promises&quot;&gt;Promises&lt;&#x2F;h2&gt;
&lt;p&gt;Most of the methods provided by Sequelize are asynchronous and therefore return Promises. But what are Promises anyway?&lt;&#x2F;p&gt;
&lt;p&gt;According to the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;developer.mozilla.org&#x2F;en-US&#x2F;docs&#x2F;Web&#x2F;JavaScript&#x2F;Reference&#x2F;Global_Objects&#x2F;Promise&quot;&gt;JavaScript documentation&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;A Promise is a proxy for a value not necessarily known when the promise is created. It allows you to associate handlers with an asynchronous action&#x27;s eventual success value or failure reason. This lets asynchronous methods return values like synchronous methods: instead of immediately returning the final value, the asynchronous method returns a promise to supply the value at some point in the future.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The practical definition is that we are able to control when and in what situation wait for the result of asynchronous operations, and act accordingly to them. As I mentioned in the example &lt;a href=&quot;https:&#x2F;&#x2F;enriquekesslerm.com&#x2F;blog&#x2F;sequelize&#x2F;#what-is-sequelize&quot;&gt;before&lt;&#x2F;a&gt;, our developer friend would most likely want to wait for the database to finish if the next redirect is to the page where the information is updated. But let&#x27;s imagine the case that the user is redirected to another page that doesn&#x27;t really need to have the information updated. In that case we would benefit from doing work asynchronously, avoiding the wait; Pretty cool, huh?&lt;&#x2F;p&gt;
&lt;p&gt;There are several operations that we can apply to Promises, in order to control the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;developer.mozilla.org&#x2F;en-US&#x2F;docs&#x2F;Web&#x2F;JavaScript&#x2F;Reference&#x2F;Global_Objects&#x2F;Promise#description&quot;&gt;state&lt;&#x2F;a&gt; of the information they are processing. A Promise will initially be &lt;code&gt;pending&lt;&#x2F;code&gt;, but then it can either go to &lt;code&gt;fulfilled&lt;&#x2F;code&gt; —if the operation hasn&#x27;t ended in error— or to &lt;code&gt;rejected&lt;&#x2F;code&gt;, meaning the operation has failed.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s assume we define the following Promise from the &lt;code&gt;getAllProducts&lt;&#x2F;code&gt; operation, which applies a series of filters to the list of products of the user:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;javascript&quot; style=&quot;background-color:#282828;color:#fdf4c1aa;&quot; class=&quot;language-javascript &quot;&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;&#x2F;&#x2F; We can also create Promises with the constructor: new Promise(function)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;productList &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8ec07c;&quot;&gt;getAllProducts&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;idUser&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;filters&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If we were to print the &lt;code&gt;productList&lt;&#x2F;code&gt; variable out (via &lt;code&gt;console.log&lt;&#x2F;code&gt;), we would likely get &amp;quot;Promise{ &lt;Pending&gt; }&amp;quot;, representing that the Promise is in the &lt;code&gt;pending&lt;&#x2F;code&gt; state —it hasn&#x27;t finished the operation.&lt;&#x2F;p&gt;
&lt;p&gt;The three common Promise operations —which we will use more extensively in Sequelize— are:&lt;&#x2F;p&gt;
&lt;h2 id=&quot;then&quot;&gt;&lt;code&gt;then()&lt;&#x2F;code&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;code&gt;then()&lt;&#x2F;code&gt; function is used when we want to run some function when the Promise has resolved. In this case, if we wanted to print the list of products, we would write:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;javascript&quot; style=&quot;background-color:#282828;color:#fdf4c1aa;&quot; class=&quot;language-javascript &quot;&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;&#x2F;&#x2F; We could also omit the function body, as it&amp;#39;s only one line.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;productList.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fabd2f;&quot;&gt;then&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;promiseResult &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8ec07c;&quot;&gt;console&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fabd2f;&quot;&gt;log&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;promiseResult&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;})
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;As we see in the snippet, we get the result of the operation as a parameter to the inside function, which we can then use in the body of the function.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;catch&quot;&gt;&lt;code&gt;catch()&lt;&#x2F;code&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;code&gt;catch()&lt;&#x2F;code&gt; function is used to literally &amp;quot;Catch&amp;quot; a possible error in the operation. Let&#x27;s assume we are throwing an error in the &lt;code&gt;getAllProducts&lt;&#x2F;code&gt; function if the user (symbolized with &lt;code&gt;idUser&lt;&#x2F;code&gt;) doesn&#x27;t exist. We can then catch the error in the result of the Promise:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;javascript&quot; style=&quot;background-color:#282828;color:#fdf4c1aa;&quot; class=&quot;language-javascript &quot;&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;productList.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fabd2f;&quot;&gt;catch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;error &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8ec07c;&quot;&gt;console&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fabd2f;&quot;&gt;log&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;error&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;&#x2F;&#x2F; This could be: ERROR&amp;gt; The user doesn&amp;#39;t exist! 
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;finally&quot;&gt;&lt;code&gt;finally()&lt;&#x2F;code&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;code&gt;finally()&lt;&#x2F;code&gt; function is used to run a certain code whether the Promise resulted in a success or an error. It might remind you of the try-catch-finally structure, and it has been inspired in that. Let&#x27;s redirect the user —with a populated or empty list— to the search page.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;javascript&quot; style=&quot;background-color:#282828;color:#fdf4c1aa;&quot; class=&quot;language-javascript &quot;&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;&#x2F;&#x2F; Let&amp;#39;s assume we have the response variable (&amp;#39;res&amp;#39;) declared before.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;productList.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fabd2f;&quot;&gt;then&lt;&#x2F;span&gt;&lt;span&gt;(
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;promiseResult &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8ec07c;&quot;&gt;console&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fabd2f;&quot;&gt;log&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;promiseResult&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;promiseResult
&lt;&#x2F;span&gt;&lt;span&gt;  })&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fabd2f;&quot;&gt;catch&lt;&#x2F;span&gt;&lt;span&gt;(
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;err &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8ec07c;&quot;&gt;console&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fabd2f;&quot;&gt;log&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;err&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fabd2f;&quot;&gt;finally&lt;&#x2F;span&gt;&lt;span&gt;(
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;productList &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;res.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8ec07c;&quot;&gt;redirect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;#39;search&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;, { productList: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;productList&lt;&#x2F;span&gt;&lt;span&gt;}))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This has also been an excellent example of Promise chaining, which is the passing of the callback outputs from one function to the next. The &lt;code&gt;catch&lt;&#x2F;code&gt; function catches all errors until that point, so it&#x27;s common to use several &lt;code&gt;then&lt;&#x2F;code&gt; functions that then a &lt;code&gt;catch&lt;&#x2F;code&gt; one.&lt;&#x2F;p&gt;
&lt;p&gt;⚠️ NOTE: We are returning the &lt;code&gt;promiseResult&lt;&#x2F;code&gt; in the &lt;code&gt;then&lt;&#x2F;code&gt; function to get the argument for the &lt;code&gt;finally&lt;&#x2F;code&gt; call. If we didn&#x27;t do that, JavaScript wouldn&#x27;t complain, but the &lt;code&gt;productList&lt;&#x2F;code&gt; variable would be &#x27;undefined&#x27;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;instances-vs-models&quot;&gt;Instances vs Models&lt;&#x2F;h2&gt;
&lt;p&gt;When you are starting to get in the Sequelize mood, it is crucial to differentiate &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;sequelize.org&#x2F;master&#x2F;manual&#x2F;model-instances.html&quot;&gt;Instances&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;sequelize.org&#x2F;master&#x2F;manual&#x2F;model-basics.html&quot;&gt;Models&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;model&quot;&gt;Model&lt;&#x2F;h3&gt;
&lt;p&gt;For cohesion, let&#x27;s start with Models. &lt;code&gt;Models&lt;&#x2F;code&gt; are exactly what you would expect in relational databases. They represent an abstraction of an entity in your application&#x27;s &lt;code&gt;domain&lt;&#x2F;code&gt;, from which you need to store information. It is also commonly known as &lt;code&gt;Table&lt;&#x2F;code&gt; —Sequelize handles all the Table creation for you when the model is &lt;code&gt;defined&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Models can be defined in &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;sequelize.org&#x2F;master&#x2F;manual&#x2F;model-basics.html#model-definition&quot;&gt;two equivalent ways&lt;&#x2F;a&gt; in Sequelize, from which I will only discuss the one that I find more convenient, no need to get into Sintax Hell when we have ready-to-go shortcut functions. I find that the easier is to use the &lt;code&gt;define&lt;&#x2F;code&gt; function, which is defined as:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;javascript&quot; style=&quot;background-color:#282828;color:#fdf4c1aa;&quot; class=&quot;language-javascript &quot;&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;sequelize.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8ec07c;&quot;&gt;define&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;modelName&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;attributes&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;options&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;&#x2F;&#x2F; This sequelize object is an instance of the Sequelize class.
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Going back to the product example, let&#x27;s define the Product Model.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;javascript&quot; style=&quot;background-color:#282828;color:#fdf4c1aa;&quot; class=&quot;language-javascript &quot;&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;Product &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;sequelize.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8ec07c;&quot;&gt;define&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;#39;Product&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;, {
&lt;&#x2F;span&gt;&lt;span&gt;  idProduct: {
&lt;&#x2F;span&gt;&lt;span&gt;    type: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;DataTypes&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;INTEGER&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    allowNull: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d3869b;&quot;&gt;false&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    primaryKey: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d3869b;&quot;&gt;true&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    autoIncrement: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d3869b;&quot;&gt;true&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;  },
&lt;&#x2F;span&gt;&lt;span&gt;  name: {
&lt;&#x2F;span&gt;&lt;span&gt;    type: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;DataTypes&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;STRING&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    allowNull: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d3869b;&quot;&gt;false&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;  },
&lt;&#x2F;span&gt;&lt;span&gt;  price: {
&lt;&#x2F;span&gt;&lt;span&gt;    type: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;DataTypes&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;DOUBLE&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    allowNull: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d3869b;&quot;&gt;false&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;  },
&lt;&#x2F;span&gt;&lt;span&gt;  idUser: {
&lt;&#x2F;span&gt;&lt;span&gt;    type: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;DataTypes&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;INTEGER&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    references: {
&lt;&#x2F;span&gt;&lt;span&gt;      model: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;User&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;      key: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;#39;idUser&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;  }
&lt;&#x2F;span&gt;&lt;span&gt;})
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It could be more complex than the previous snippet, but I find that the Product model we defined has all the information I need for the explanation. As we know, every Table should have its &lt;code&gt;primaryKey&lt;&#x2F;code&gt;, which then will be used to identify a particular row in the Table.&lt;&#x2F;p&gt;
&lt;p&gt;⚠️ We set the &lt;code&gt;autoIncrement&lt;&#x2F;code&gt; property to &lt;code&gt;true&lt;&#x2F;code&gt;, in order to have ids automatically created for us.&lt;&#x2F;p&gt;
&lt;p&gt;The other Product property that I wanted to mention is the idUser. You might be thinking, why are Users mixed up in all of this. Let me introduce you to the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.w3schools.com&#x2F;sql&#x2F;sql_foreignkey.asp&quot;&gt;Foreign Key&lt;&#x2F;a&gt;, my friend. The idUser property has the references property, creating a &amp;quot;link&amp;quot; to the &lt;code&gt;idUser&lt;&#x2F;code&gt; key —represented with the &lt;code&gt;key&lt;&#x2F;code&gt; property— of the &lt;code&gt;User&lt;&#x2F;code&gt; model.&lt;&#x2F;p&gt;
&lt;p&gt;If you want to dig more into the possible attributes for Model definition Sequelize offers, see:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;sequelize.org&#x2F;master&#x2F;class&#x2F;lib&#x2F;model.js~Model.html#static-method-init&quot;&gt;https:&#x2F;&#x2F;sequelize.org&#x2F;master&#x2F;class&#x2F;lib&#x2F;model.js~Model.html#static-method-init&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;sequelize.org&#x2F;master&#x2F;class&#x2F;lib&#x2F;model.js~Model.html&quot;&gt;https:&#x2F;&#x2F;sequelize.org&#x2F;master&#x2F;class&#x2F;lib&#x2F;model.js~Model.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;sequelize.org&#x2F;master&#x2F;class&#x2F;lib&#x2F;sequelize.js~Sequelize.html#instance-method-define&quot;&gt;https:&#x2F;&#x2F;sequelize.org&#x2F;master&#x2F;class&#x2F;lib&#x2F;sequelize.js~Sequelize.html#instance-method-define&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;instance&quot;&gt;Instance&lt;&#x2F;h2&gt;
&lt;p&gt;Citing the Sequelize documentation:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;As you already know, a model is an ES6 class. An instance of the class represents one object from that model (which maps to one row of the table in the database). This way, model instances are DAOs.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Although a Model is a class, you cannot create instances using the default constructor —via &lt;code&gt;new&lt;&#x2F;code&gt; — but using special creation and building functions. In this case, even though we have a shortcut to the creation of Instances, I find interesting showing the &amp;quot;long&amp;quot; way of creating them.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;javascript&quot; style=&quot;background-color:#282828;color:#fdf4c1aa;&quot; class=&quot;language-javascript &quot;&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8ec07c;&quot;&gt;createProduct &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;async &lt;&#x2F;span&gt;&lt;span&gt;() &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;product &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;Product.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8ec07c;&quot;&gt;build&lt;&#x2F;span&gt;&lt;span&gt;({ name: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;Headphones&amp;quot; &lt;&#x2F;span&gt;&lt;span&gt;})
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8ec07c;&quot;&gt;console&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fabd2f;&quot;&gt;log&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;product&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fabd2f;&quot;&gt;name&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;&#x2F;&#x2F; &amp;quot;Headphones&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;await &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;product.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8ec07c;&quot;&gt;save&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;From the snippet we can get gold information out of the build method. You might be thinking to yourself: we are assigning a &lt;code&gt;Promise&lt;&#x2F;code&gt; to a constant, and then accessing its attribute. Enrique, your code is wrong.&lt;&#x2F;p&gt;
&lt;p&gt;Mysteriously, the build function is one of the few methods in Sequelize that are not asynchronous, hence we are not assigning a Promise, but a &lt;code&gt;Product&lt;&#x2F;code&gt; Instance. Note the save function on the instance —asynchronous. The build function does not insert the new &amp;quot;row&amp;quot; into the Product(s) Table. We need to explicitly save the instance using the &lt;code&gt;save&lt;&#x2F;code&gt; function.&lt;&#x2F;p&gt;
&lt;p&gt;Pretty cool, huh? Sequelize provides a shortcut for the combined operations: &lt;code&gt;create&lt;&#x2F;code&gt;. The &lt;code&gt;create&lt;&#x2F;code&gt; is an asynchronous function, which uses the same parameters as the &lt;code&gt;build&lt;&#x2F;code&gt; method, but saving the instance in the database in the process. See:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;javascript&quot; style=&quot;background-color:#282828;color:#fdf4c1aa;&quot; class=&quot;language-javascript &quot;&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;product &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;await &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;Product.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8ec07c;&quot;&gt;create&lt;&#x2F;span&gt;&lt;span&gt;(
&lt;&#x2F;span&gt;&lt;span&gt;  {
&lt;&#x2F;span&gt;&lt;span&gt;    name: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;Headphones&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    price: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d3869b;&quot;&gt;120&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;  }
&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fabd2f;&quot;&gt;catch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;err &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8ec07c;&quot;&gt;console&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fabd2f;&quot;&gt;log&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;err&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8ec07c;&quot;&gt;console&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fabd2f;&quot;&gt;log&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;product&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fabd2f;&quot;&gt;name&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;&#x2F;&#x2F; &amp;quot;Headphones&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note the catch function applied to the Promise to output any possible creation or insertion errors, as discussed in the &lt;a href=&quot;https:&#x2F;&#x2F;enriquekesslerm.com&#x2F;blog&#x2F;sequelize&#x2F;#promises&quot;&gt;Promises&lt;&#x2F;a&gt; section. After the create operation, the &lt;code&gt;product&lt;&#x2F;code&gt; instance is inserted in the database.&lt;&#x2F;p&gt;
&lt;p&gt;⚠️ If you want to log the product instance, use the &lt;code&gt;toJSON()&lt;&#x2F;code&gt; function, as the default &lt;code&gt;toString&lt;&#x2F;code&gt; is pretty terrifying, printing all the internals.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;query-the-database&quot;&gt;Query the database&lt;&#x2F;h2&gt;
&lt;p&gt;Why would we want to store information in a database if not to use it later on? Querying in sequelize couldn&#x27;t be easier, both through raw queries —not here to judge— or Finder methods.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;raw-queries&quot;&gt;Raw queries&lt;&#x2F;h3&gt;
&lt;p&gt;Just for you hermits out there, let&#x27;s start with Raw queries. We are working
with SQL databases anyway, right?  You can raw query the database through the
sequelize.query method. From the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;sequelize.org&#x2F;master&#x2F;manual&#x2F;raw-queries.html&quot;&gt;Sequelize documentation&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;By default the function will return two arguments - a results array, and an object containing metadata (such as amount of affected rows, etc). Note that since this is a raw query, the metadata are dialect specific. Some dialects return the metadata &amp;quot;within&amp;quot; the results object (as properties on an array). &lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;⚠️ If you are using MSSQL or MySQL, the two return variables will be the same object.&lt;&#x2F;p&gt;
&lt;p&gt;Here is an update for our Product example.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;javascript&quot; style=&quot;background-color:#282828;color:#fdf4c1aa;&quot; class=&quot;language-javascript &quot;&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;results&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;metadata&lt;&#x2F;span&gt;&lt;span&gt;] &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;await &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;sequelize.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8ec07c;&quot;&gt;query&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;UPDATE Product SET price = 42 WHERE idProduct = 1&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;&#x2F;&#x2F; Results will be an empty array and metadata will contain the number of affected rows.
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note that the even if we inserted the Product —singular— Model in the database, Sequelize creates both tables: Product and Products. Query away with your preference.&lt;&#x2F;p&gt;
&lt;p&gt;There are special cases where you don&#x27;t need change access to the database, just the data, i.e. through a SELECT query. You can then import the QueryType metadata.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;javascript&quot; style=&quot;background-color:#282828;color:#fdf4c1aa;&quot; class=&quot;language-javascript &quot;&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span&gt;{ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;QueryTypes &lt;&#x2F;span&gt;&lt;span&gt;} &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fabd2f;&quot;&gt;require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;#39;sequelize&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;products &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;await &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;sequelize.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8ec07c;&quot;&gt;query&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;SELECT * FROM `Products`&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, { type: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;QueryTypes&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;SELECT &lt;&#x2F;span&gt;&lt;span&gt;});
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Passing the QueryType Metadata, the function no longer needs to return two return variables, but the SELECT query&#x27;s affected rows. If you wouldn&#x27;t mind, let&#x27;s go back to abstraction, where I fill a bit more comfortable. Sequelize defines shortcut functions to query the database(s).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;finder-methods&quot;&gt;Finder methods&lt;&#x2F;h2&gt;
&lt;p&gt;By default, the finder methods return Instances. We can then use those instances to get information, as if we were accessing an ES6 class. Here are the finder functions:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;findAll()&lt;&#x2F;code&gt;: returns an array of Instances for the Model that has been queried:&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;javascript&quot; style=&quot;background-color:#282828;color:#fdf4c1aa;&quot; class=&quot;language-javascript &quot;&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;productList &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;await &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;Product.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8ec07c;&quot;&gt;findAll&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;findByPk()&lt;&#x2F;code&gt;: returns an instance by passing the Primary Key as argument. In our case, the &lt;code&gt;idProduct&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;javascript&quot; style=&quot;background-color:#282828;color:#fdf4c1aa;&quot; class=&quot;language-javascript &quot;&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;idProduct &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d3869b;&quot;&gt;1
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;product &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;await &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;Product.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8ec07c;&quot;&gt;findByPk&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;idProduct&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8ec07c;&quot;&gt;console&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fabd2f;&quot;&gt;log&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;product&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;price&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;&#x2F;&#x2F; 42, after the UPDATE.
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;findOne()&lt;&#x2F;code&gt;: the method returns the first instance matching the options passed. As with all Sequelize methods —I really value the consistency— the format of the options is through objects.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;javascript&quot; style=&quot;background-color:#282828;color:#fdf4c1aa;&quot; class=&quot;language-javascript &quot;&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;product &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;await &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;Product.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8ec07c;&quot;&gt;findOne&lt;&#x2F;span&gt;&lt;span&gt;({ where: { price: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d3869b;&quot;&gt;42 &lt;&#x2F;span&gt;&lt;span&gt;} });
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;&#x2F;&#x2F; This product constant is the same for the findByPk method.
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Although there are others, I find that the ones mentioned are the most important. If you still have the curiosity, see:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;sequelize.org&#x2F;master&#x2F;manual&#x2F;model-querying-finders.html&quot;&gt;https:&#x2F;&#x2F;sequelize.org&#x2F;master&#x2F;manual&#x2F;model-querying-finders.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;sequelize.org&#x2F;master&#x2F;manual&#x2F;model-querying-basics.html&quot;&gt;https:&#x2F;&#x2F;sequelize.org&#x2F;master&#x2F;manual&#x2F;model-querying-basics.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;sequelize.org&#x2F;master&#x2F;manual&#x2F;getters-setters-virtuals.html&quot;&gt;https:&#x2F;&#x2F;sequelize.org&#x2F;master&#x2F;manual&#x2F;getters-setters-virtuals.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;⚠️ For querying Operators are specially interesting, you can access all the operators you expect: &lt;code&gt;and&lt;&#x2F;code&gt;, &lt;code&gt;or&lt;&#x2F;code&gt;, &lt;code&gt;eq&lt;&#x2F;code&gt;, &lt;code&gt;between&lt;&#x2F;code&gt;, &lt;code&gt;like&lt;&#x2F;code&gt; and more. Check: &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;sequelize.org&#x2F;master&#x2F;manual&#x2F;model-querying-basics.html#operators&quot;&gt;Operators&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;minimize-transactions&quot;&gt;Minimize transactions&lt;&#x2F;h2&gt;
&lt;p&gt;When working with databases and specially with a ton of requests to it, it is key to have the mindset of reducing as much database transactions as possible. What do I mean by that?&lt;&#x2F;p&gt;
&lt;p&gt;Instead of having multiple database requests to get and update some information, try to think of an &lt;a href=&quot;https:&#x2F;&#x2F;enriquekesslerm.com&#x2F;blog&#x2F;sequelize&#x2F;#query-the-database&quot;&gt;SQL query&lt;&#x2F;a&gt; (remember that you can use both raw and Sequelize methods) to do the job in a single transaction if possible. A nice example of this is the Update functionality by Sequelize.&lt;&#x2F;p&gt;
&lt;p&gt;Sequelize provides several ways of updating instances. The first one —bear with me here— is getting a certain instance, modify the properties you want to update and then save the instance back to the database. For our Product example, let&#x27;s make it cheaper. With the sequelize methods discussed before, we would achieve that using:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;javascript&quot; style=&quot;background-color:#282828;color:#fdf4c1aa;&quot; class=&quot;language-javascript &quot;&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;idProduct &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d3869b;&quot;&gt;1
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;productInstance &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;Product.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8ec07c;&quot;&gt;getByPk&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;idProduct&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;productInstance&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;price &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d3869b;&quot;&gt;12 &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;&#x2F;&#x2F; It was 42 before.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;await &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;product.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8ec07c;&quot;&gt;save&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The previous sequence of operations creates two SQL requests, the first SELECT to get the product by id, and then a second one to update the value —when the instance is saved through the &lt;code&gt;save()&lt;&#x2F;code&gt; method). That is the essence of what I mean, instead of being happy with the previous snippet, let&#x27;s think further.&lt;&#x2F;p&gt;
&lt;p&gt;We know that Sequelize provides an &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;sequelize.org&#x2F;master&#x2F;class&#x2F;lib&#x2F;model.js~Model.html#static-method-update&quot;&gt;Update method&lt;&#x2F;a&gt; to update multiple instances that match the &lt;code&gt;were&lt;&#x2F;code&gt; options. Here would be the snippet for the second option.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;javascript&quot; style=&quot;background-color:#282828;color:#fdf4c1aa;&quot; class=&quot;language-javascript &quot;&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;idProduct &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d3869b;&quot;&gt;1
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;numAffectedRows&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;product&lt;&#x2F;span&gt;&lt;span&gt;] &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;Product.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8ec07c;&quot;&gt;update&lt;&#x2F;span&gt;&lt;span&gt;({
&lt;&#x2F;span&gt;&lt;span&gt;  where: {
&lt;&#x2F;span&gt;&lt;span&gt;    idProduct: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d3869b;&quot;&gt;1
&lt;&#x2F;span&gt;&lt;span&gt; }})
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That snippet only produces an UPDATE query, using the WHERE clause to limit the target rows. As you see, you get the number of affected rows as the first deconstructing argument, and the actual affected rows in the second. No need to save the database afterwards, pretty cool, huh?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;set-up-sequelize-in-a-node-js-project&quot;&gt;Set up Sequelize in a Node.js project&lt;&#x2F;h2&gt;
&lt;p&gt;On this section I intend to give you a working Sequelize configuration, done the efficient way. There are multiple ways to use Sequelize in your Node.js project, but I&#x27;m sure you will agree with me that there is no need to redefine the Sequelize connection every time you want to access the database.&lt;&#x2F;p&gt;
&lt;p&gt;Instead, we should strive towards having a reusable and maintainable configuration, benefiting from having code that would work well with several DBs —let&#x27;s image you intend to change from MySQL to PostgreSQL.&lt;&#x2F;p&gt;
&lt;p&gt;I need to give credit where credit is due: I got this information for one of my projects from &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bezkoder.com&#x2F;node-js-express-sequelize-mysql&#x2F;&quot;&gt;bezkoder&#x27;s&lt;&#x2F;a&gt; blog post, which I highly recommend for a more profound dive on the setup part of Sequelize. Let&#x27;s get started.&lt;&#x2F;p&gt;
&lt;p&gt;First, Sequelize requires a series of arguments to set up the connection to the database. I recommend defining a &lt;code&gt;db.config.js&lt;&#x2F;code&gt; file, where you will insert the constants required for the connection.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;javascript&quot; style=&quot;background-color:#282828;color:#fdf4c1aa;&quot; class=&quot;language-javascript &quot;&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span style=&quot;color:#fabd2f;&quot;&gt;module&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fabd2f;&quot;&gt;exports &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;  HOST: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;#39;localhost&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;  DB: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;#39;bualatok&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;  USER: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;#39;root&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;  PASSWORD: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fabd2f;&quot;&gt;process&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fabd2f;&quot;&gt;env&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;DB_PASSWORD&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;  dialect: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;#39;mysql&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;  pool: {
&lt;&#x2F;span&gt;&lt;span&gt;    max: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d3869b;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    min: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d3869b;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    acquire: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d3869b;&quot;&gt;30000&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    idle: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d3869b;&quot;&gt;10000
&lt;&#x2F;span&gt;&lt;span&gt;  },
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;As you can see in the snippet below, you need to setup the IP of the server
you are connecting to —through the &lt;code&gt;HOST&lt;&#x2F;code&gt; property. The interesting part is
that you could either have your own server (i.e MySQL server) or connect to
one elsewhere. The &lt;code&gt;DB&lt;&#x2F;code&gt; property is the name of the database you will be
connecting to. The &lt;code&gt;USER&lt;&#x2F;code&gt; and &lt;code&gt;PASSWORD&lt;&#x2F;code&gt; are pretty self-explanatory, but note
the use of the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;motdotla&#x2F;dotenv&quot;&gt;dotenv package&lt;&#x2F;a&gt;, which provides easy to use environment variables, that you will then .gitignore. The &lt;code&gt;dialect&lt;&#x2F;code&gt; property is picked from a set list, you can find it &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;sequelize.org&#x2F;v5&#x2F;manual&#x2F;dialects.html&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;pool&lt;&#x2F;code&gt; property is interesting enough to comment on it alone: Sequelize —and databases in general— uses the word &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;es.wikipedia.org&#x2F;wiki&#x2F;Connection_pool&quot;&gt;&amp;quot;pool&amp;quot;&lt;&#x2F;a&gt;, as a &amp;quot;set&amp;quot; of connections to the database, which can then be used in parallel. We set up a pool of connections to limit the access to the db but still consider the possibility of having multiple &amp;quot;users&amp;quot; creating transactions at the same time.&lt;&#x2F;p&gt;
&lt;p&gt;After having the db.config setup, we need to create the file which will be then imported throughout the application to access the database efficiently. We can even reduce the exports to our liking, or need. Here is the &lt;code&gt;index.js&lt;&#x2F;code&gt; file in the &lt;code&gt;&#x2F;models&lt;&#x2F;code&gt; directory:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;javascript&quot; style=&quot;background-color:#282828;color:#fdf4c1aa;&quot; class=&quot;language-javascript &quot;&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;dbConfig &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fabd2f;&quot;&gt;require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;..&#x2F;config&#x2F;db.config.js&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span&gt;{ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;Sequelize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;Op&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;DataTypes &lt;&#x2F;span&gt;&lt;span&gt;} &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fabd2f;&quot;&gt;require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;sequelize&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;sequelize &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;new &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8ec07c;&quot;&gt;Sequelize&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;dbConfig&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;DB&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;dbConfig&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;USER&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;dbConfig&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;PASSWORD&lt;&#x2F;span&gt;&lt;span&gt;, {
&lt;&#x2F;span&gt;&lt;span&gt;  host: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;dbConfig&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;HOST&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;  dialect: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;dbConfig&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;dialect&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;  operatorsAliases: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d3869b;&quot;&gt;false&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;  pool: {
&lt;&#x2F;span&gt;&lt;span&gt;    max: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;dbConfig&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;pool&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;max&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    min: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;dbConfig&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;pool&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;min&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    acquire: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;dbConfig&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;pool&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;acquire&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    idle: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;dbConfig&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;pool&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;idle
&lt;&#x2F;span&gt;&lt;span&gt;  }
&lt;&#x2F;span&gt;&lt;span&gt;})
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa5c4b;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;db &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;{}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;db&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;DataTypes &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;DataTypes
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;db&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;Sequelize &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;Sequelize
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;db&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;sequelize &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;sequelize
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;db&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;Op &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;Op
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;db&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;User &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fabd2f;&quot;&gt;require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;.&#x2F;user.model.js&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;sequelize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;DataTypes&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;db&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;Product &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fabd2f;&quot;&gt;require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b8bb26;&quot;&gt;&amp;quot;.&#x2F;product.model.js&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;sequelize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;DataTypes&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;db&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;User&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fabd2f;&quot;&gt;module&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fabd2f;&quot;&gt;exports &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fe8019;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fdf4c1;&quot;&gt;db
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Using the previous file, we are able to only require the needed aspects from &amp;quot;sequelize&amp;quot; and configure the database connection pool using the &lt;code&gt;new Sequelize(...)&lt;&#x2F;code&gt; constructor —note that it uses the dbConfig object defined in the previous snippet. We are able to concentrate everything related to the database, even the &lt;code&gt;User&lt;&#x2F;code&gt; and &lt;code&gt;Product&lt;&#x2F;code&gt; models and import from that single file.&lt;&#x2F;p&gt;
&lt;p&gt;I find this process the more efficient way to set up Sequelize in a Node.js project, and I would recommend starting with those configuration files.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;should-you-use-sequelize&quot;&gt;Should you use Sequelize?&lt;&#x2F;h2&gt;
&lt;p&gt;After all the Sequelize talk, I figure you are thinking whether Sequelize is for you, your project, your team or your own use. This section tries to answer the previous question using pros and cons, and leaves you to the final answer.&lt;&#x2F;p&gt;
&lt;p&gt;PROS:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Sequelize provides a layer of abstraction, reducing the possible errors that developers can include in Raw SQL queries.&lt;&#x2F;li&gt;
&lt;li&gt;Sequelize is multi-dialect, providing support for the use-case of having multiple databases with different providers at the same time —weird but OK.&lt;&#x2F;li&gt;
&lt;li&gt;Using an ORM —Sequelize in this case— speeds up the development process for simple, repetitive queries.&lt;&#x2F;li&gt;
&lt;li&gt;If you are concerned about security, ORMs will shield your application from injection attacks, since the framework will filter the requests for you.&lt;&#x2F;li&gt;
&lt;li&gt;Sequelize &amp;quot;forces&amp;quot; you to create a maintainable database, that is independent of the database provider you use in that moment, making the switching process seemless.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;CONS:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;If you are trying to pick an ORM to avoid learning SQL, you will be rendered out alone when the ORM goes out of the window. Understand the SQL sintax underneath the ORM&#x27;s calls.&lt;&#x2F;li&gt;
&lt;li&gt;Complex calls in ORMs are usually inefficient. If your queries are not simple or repetitive, you are better off using Raw Queries.&lt;&#x2F;li&gt;
&lt;li&gt;Sequelize doens&#x27;t have a perfect documentation, finding the information you need might be trivial or not.&lt;&#x2F;li&gt;
&lt;li&gt;Learning a new ORM might tie you to a different and new sintax.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The Pros and Cons list that everyone was waiting for. If after the list you find that you are getting more and more curious about using Sequelize, go on! As you might know:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;By experimenting with voluntary discomfort, we  learn to appreciate far more of our life, and can be content with a much simpler and more wholesome one.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;I intend to keep myself learning every day, and learning additional technologies is always exciting!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;final-conclusions&quot;&gt;Final conclusions&lt;&#x2F;h2&gt;
&lt;p&gt;And there you have it folks, this brief Sequelize introduction is over. I really hope this post has inspired you in some way, to either try Sequelize or keep in mind it exists. I find Sequelize —and ORMs in general— to be the next generation of database transaction processing. If you have any questions or wanna chat with me, hit me up by &lt;a href=&quot;mailto:enrique.kesslerm@gmail.com&quot;&gt;email&lt;&#x2F;a&gt; or on &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;quique_kessler&quot;&gt;twitter&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;advanced-topics&quot;&gt;Advanced topics&lt;&#x2F;h2&gt;
&lt;p&gt;Now that you have been given the seed of curiosity with Sequelize, I find that learning more is just about finding the right information. Below I provide a list of advanced topics that you might enjoy reading about if you are really taking serious using Sequelize for your project.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;sequelize.org&#x2F;master&#x2F;manual&#x2F;dialect-specific-things.html&quot;&gt;Dialect specific configuration&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;sequelize.org&#x2F;master&#x2F;manual&#x2F;hooks.html&quot;&gt;Hooks&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;sequelize.org&#x2F;master&#x2F;manual&#x2F;constraints-and-circularities.html&quot;&gt;Constraints&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;sequelize.org&#x2F;master&#x2F;manual&#x2F;legacy.html&quot;&gt;Using legacy tables&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;sequelize.org&#x2F;master&#x2F;manual&#x2F;migrations.html&quot;&gt;Migrate your current project&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;sequelize.org&#x2F;master&#x2F;manual&#x2F;typescript.html&quot;&gt;Using Typescript with Sequelize&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;DanielHreben&#x2F;sequelize-transparent-cache&quot;&gt;Caching information with Sequelize&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;bonaval&#x2F;sequelize-temporal&quot;&gt;Sequelize temporal records&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;jasonwatmore.com&#x2F;post&#x2F;2020&#x2F;08&#x2F;18&#x2F;nodejs-mysql-simple-api-for-authentication-registration-and-user-management&quot;&gt;Role, Permission based Auth with Sequelize&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.datensen.com&#x2F;&quot;&gt;Visual definition of Sequelize models&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
</feed>
