npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

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

About

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

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

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

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

Open Software & Tools

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

© 2024 – Pkg Stats / Ryan Hefner

relvar.js

v0.1.6

Published

An amateur database inspired by CJ Date and Project M36.

Downloads

3

Readme

relvar.js

An amateur database inspired by CJ Date and Project M36.

Documentation will be sparse as I'm focused more on the development, but here's a demo that should give you the idea of what I'm gunning to do:

var {relvar, union, _sel, _un, selection
    , rvts, logrv, S, P, SP, _j, join, inv_selection, _but
    , where, _where, minus, _minus, rename, _ren, matching, _mat, not_matching, _nmat
    , db, save_db, assign_rv, update, _up, extend, _ext, count, _cnt, sum, _sum, assign_js_constraint} = require("../main.js");

const _arv = (...rvs) => (db) => assign_rv(db, ...rvs).db;

var GameDB = db(require("path").join(__dirname, "test.yaml"), {name: "GameDB"});
var {db: GameDB} = save_db(GameDB);

var C = relvar({
    attrs: {
        "C#": "number",
        "Cname": "string",
        "HP": "number"
    },
    tuples: [
        {"C#": 1, "Cname": "Reese of Wellington", "HP": 4}
        ,{"C#": 2, "Cname": "Sir Nic of the Weils", "HP": 18}
    ]
});

var I = relvar({
    attrs: {
        "I#": "number",
        "Iname": "string",
        "Durability": "number",
        "Damage": "number"
    },
    tuples: [
        {"I#": 1, "Iname": "Bronze Poniard", "Durability": 10, "Damage": 10}
        ,{"I#": 2, "Iname": "Glazed Donut", "Durability": 1, "Damage": 1}
        ,{"I#": 3, "Iname": "Venom-Soaked Blade", "Durability": 5, "Damage": 25}
        ,{"I#": 4, "Iname": "Ancient Spoon", "Durability": 1, "Damage": 80}
        ,{"I#": 5, "Iname": "Holy Hand Grenade of Antioch", "Durability": 1, "Damage": 999}
        ,{"I#": 6, "Iname": "Common Shortsword", "Durability": 30, "Damage": 15}
        ,{"I#": 7, "Iname": "Rot-Hilted Axe", "Durability": 8, "Damage": 15}
    ]
});

var CI = relvar({
    attrs: {
        "C#": "number",
        "I#": "number",
        "Slot": "number"
    },
    tuples: [
        {"C#": 1, "I#": 1, "Slot": 3},
        {"C#": 1, "I#": 3, "Slot": 4},
        {"C#": 2, "I#": 2, "Slot": 4},
        {"C#": 2, "I#": 4, "Slot": 3},
        {"C#": 2, "I#": 1, "Slot": 10},
    ]
});

var {db: GameDB} = GameDB.tap(_arv(["C", C], ["I", I], ["CI", CI])).tap(save_db);

var {run} = require("../db_lang.js");

console.log("C:")
logrv(C);

console.log("C join CI:")
join(C, CI).tap(logrv);

console.log("C{C#, Cname} join CI")
selection(C, "C#", "Cname").tap(_j(CI)).tap(logrv);

console.log("C join CI join I");
join(C, CI).tap(_j(I)).tap(logrv);

console.log("(C join CI join I){ALL BUT C#, HP, I#}");
join(C, CI).tap(_j(I)).tap(_but("C#", "HP", "I#")).tap(logrv);

console.log("Variant to test/display commutative properties of join:")
console.log("(C join I join CI){ALL BUT C#, HP, I#}");
join(C, I, CI).tap(_but("C#", "HP", "I#")).tap(logrv);

console.log("Give me all items that are owned by no character:")
console.log("I NOT MATCHING CI");
not_matching(I, CI).tap(logrv);

console.log("All characters with an item that deals more than 30 damage:")
console.log("C MATCHING (CI JOIN (I WHERE {Damage > 30}))")
matching(C, join(CI, where(I, i=>i.Damage > 30))).tap(logrv)

console.log("Just their names:")
console.log("(C MATCHING (CI JOIN (I WHERE {Damage > 30}))){Cname}")
matching(C, join(CI, where(I, i=>i.Damage > 30))).tap(_sel("Cname")).tap(logrv)

where(I, i=>i.Damage > 30)
.tap(_j(CI))
.tap(cii => matching(C, cii))
.tap(_sel("Cname"))
.tap(logrv);

console.log("Characters and the items they DON'T have: ")
console.log("((C{C#} JOIN I{I#}) MINUS (CI{C#, I#}) JOIN C{C#, Cname} JOIN I{I#, Iname}) {Cname, Iname} RENAME {Cname AS Character, Iname AS Missing Item}")
join(selection(C, "C#"), selection(I, "I#"))
.tap(_minus( selection(CI, "C#", "I#") ))
.tap(_j( selection(C, "C#", "Cname"),  selection(I, "I#", "Iname") ))
.tap(_sel("Cname", "Iname"))
.tap(_ren(["Cname", "Character"], ["Iname", "Missing Item"]))
.tap(logrv);

console.log("Fix overpowered items: ")
console.log("UPDATE I WHERE Damage > 30: {Damage := Damage / 2}")
update(I, i=>i.Damage > 30, ["Damage", i => Math.floor(i.Damage/2)])
.tap(logrv);

console.log("Show Damage Per Durability (DPD): ")
console.log("EXTEND I: {DPD := Damage / Durability}");
extend(I, ["DPD", "number", i=>Math.round(i.Damage/i.Durability)])
.tap(logrv);


console.log("Count of all character-item combos:\n\tCOUNT ( CI ) =", count(CI));
console.log("Count of all distinct slots in character-item combos:\n\tCOUNT ( CI { Slot } ) :", count(CI, "Slot"));
console.log("Sum of all item damage:\n\tSUM (I, Damage) =", sum(I, "Damage"));
console.log("Sum of all distinct item damage values:\n\tSUM (I, { Damage }) =", sum(I, ["Damage"]));
console.log("Sum of tripled item damage:\n\tSUM (I, 3 * Damage) = ", sum(I, "Damage", i=>i.Damage*3) )
console.log("Sum of all distinct tripled item damage:\n\tSUM( EXTEND I : { Damage := Damage * 3 }, {Damage}) = ", sum(extend(I, ["Damage", "number", i=>i.Damage*3]) , ["Damage"]))

console.log("My D implementation is behind on most features, but the plumbing exists: ");
console.log("(C join CI join I){ALL BUT C#, HP, I#}");
run(GameDB, "(C join I join CI){ALL BUT C#, HP, I#}").tap(logrv);

// With D, I hope to be able to allow constraints to be written in it
// as a simple solution rather than needing the prefab or custom JS.


// Add a uniqueness constraint to I.

const uniq_i = (rvs) => count(rvs.I) == count(rvs.I, "I#");
var {db: GameDB} = assign_js_constraint(GameDB, ["UNIQ_I", uniq_i]);

console.log("Attempt to violate the constraint:");
const new_i = union(I, {tuples: [{"I#": 7, "Iname": "Floppy Disk", "Durability": 40, "Damage": 3}] });
const attempt_assign = assign_rv(GameDB, ["I", new_i]);
console.dir(attempt_assign.c == "FAILED" ? attempt_assign.issue : "Oops. This shouldn't happen.");

console.log("Concede, follow the constraint:");
const new_i_2 = union(I, {tuples: [{"I#": 8, "Iname": "Floppy Disk", "Durability": 40, "Damage": 3}] });
const this_should_work = assign_rv(GameDB, ["I", new_i_2]);
logrv(this_should_work.db.data.relvars["I"]);

// Initialize an existing DB with supplied constraints: 

var my_constraints = {
    "UNIQ_I": uniq_i
};

var newGame = db(require("path").join(__dirname, "test2.yaml")
            , {name: "NewGame", supplied: {constraints_js: my_constraints}});

    // I don't recommend you do this normally.
    // This is just to ensure that the fresh file has the constraint and data.
    // Your usual DB will already have the constraint in its data.
    // if you've already built test2.yaml, you could comment these three lines out, and it'll still work.
    newGame.data.relvars = GameDB.data.relvars;
    newGame.data.constraints_js = ["UNIQ_I"];
    save_db(newGame);

console.log("Attempt to violate again on new DB:");
const attempt_assign_2 = assign_rv(newGame, ["I", new_i]);
console.dir(attempt_assign_2.c == "FAILED" ? attempt_assign_2.issue : "Oops. This shouldn't happen.");

Output:

C:
┌────────────┬──────────────────────┬────────────┐
│ C#::number │ Cname::string        │ HP::number │
├────────────┼──────────────────────┼────────────┤
│ 1          │ Reese of Wellington  │ 4          │
├────────────┼──────────────────────┼────────────┤
│ 2          │ Sir Nic of the Weils │ 18         │
└────────────┴──────────────────────┴────────────┘
C join CI:
┌────────────┬──────────────────────┬────────────┬────────────┬──────────────┐
│ C#::number │ Cname::string        │ HP::number │ I#::number │ Slot::number │
├────────────┼──────────────────────┼────────────┼────────────┼──────────────┤
│ 1          │ Reese of Wellington  │ 4          │ 1          │ 3            │
├────────────┼──────────────────────┼────────────┼────────────┼──────────────┤
│ 1          │ Reese of Wellington  │ 4          │ 3          │ 4            │
├────────────┼──────────────────────┼────────────┼────────────┼──────────────┤
│ 2          │ Sir Nic of the Weils │ 18         │ 2          │ 4            │
├────────────┼──────────────────────┼────────────┼────────────┼──────────────┤
│ 2          │ Sir Nic of the Weils │ 18         │ 4          │ 3            │
├────────────┼──────────────────────┼────────────┼────────────┼──────────────┤
│ 2          │ Sir Nic of the Weils │ 18         │ 1          │ 10           │
└────────────┴──────────────────────┴────────────┴────────────┴──────────────┘
C{C#, Cname} join CI
┌────────────┬──────────────────────┬────────────┬──────────────┐
│ C#::number │ Cname::string        │ I#::number │ Slot::number │
├────────────┼──────────────────────┼────────────┼──────────────┤
│ 1          │ Reese of Wellington  │ 1          │ 3            │
├────────────┼──────────────────────┼────────────┼──────────────┤
│ 1          │ Reese of Wellington  │ 3          │ 4            │
├────────────┼──────────────────────┼────────────┼──────────────┤
│ 2          │ Sir Nic of the Weils │ 2          │ 4            │
├────────────┼──────────────────────┼────────────┼──────────────┤
│ 2          │ Sir Nic of the Weils │ 4          │ 3            │
├────────────┼──────────────────────┼────────────┼──────────────┤
│ 2          │ Sir Nic of the Weils │ 1          │ 10           │
└────────────┴──────────────────────┴────────────┴──────────────┘
C join CI join I
┌────────────┬──────────────────────┬────────────┬────────────┬──────────────┬────────────────────┬────────────────────┬────────────────┐
│ C#::number │ Cname::string        │ HP::number │ I#::number │ Slot::number │ Iname::string      │ Durability::number │ Damage::number │
├────────────┼──────────────────────┼────────────┼────────────┼──────────────┼────────────────────┼────────────────────┼────────────────┤
│ 1          │ Reese of Wellington  │ 4          │ 1          │ 3            │ Bronze Poniard     │ 10                 │ 10             │
├────────────┼──────────────────────┼────────────┼────────────┼──────────────┼────────────────────┼────────────────────┼────────────────┤
│ 1          │ Reese of Wellington  │ 4          │ 3          │ 4            │ Venom-Soaked Blade │ 5                  │ 25             │
├────────────┼──────────────────────┼────────────┼────────────┼──────────────┼────────────────────┼────────────────────┼────────────────┤
│ 2          │ Sir Nic of the Weils │ 18         │ 2          │ 4            │ Glazed Donut       │ 1                  │ 1              │
├────────────┼──────────────────────┼────────────┼────────────┼──────────────┼────────────────────┼────────────────────┼────────────────┤
│ 2          │ Sir Nic of the Weils │ 18         │ 4          │ 3            │ Ancient Spoon      │ 1                  │ 80             │
├────────────┼──────────────────────┼────────────┼────────────┼──────────────┼────────────────────┼────────────────────┼────────────────┤
│ 2          │ Sir Nic of the Weils │ 18         │ 1          │ 10           │ Bronze Poniard     │ 10                 │ 10             │
└────────────┴──────────────────────┴────────────┴────────────┴──────────────┴────────────────────┴────────────────────┴────────────────┘
(C join CI join I){ALL BUT C#, HP, I#}
┌──────────────────────┬──────────────┬────────────────────┬────────────────────┬────────────────┐
│ Cname::string        │ Slot::number │ Iname::string      │ Durability::number │ Damage::number │
├──────────────────────┼──────────────┼────────────────────┼────────────────────┼────────────────┤
│ Reese of Wellington  │ 3            │ Bronze Poniard     │ 10                 │ 10             │
├──────────────────────┼──────────────┼────────────────────┼────────────────────┼────────────────┤
│ Reese of Wellington  │ 4            │ Venom-Soaked Blade │ 5                  │ 25             │
├──────────────────────┼──────────────┼────────────────────┼────────────────────┼────────────────┤
│ Sir Nic of the Weils │ 4            │ Glazed Donut       │ 1                  │ 1              │
├──────────────────────┼──────────────┼────────────────────┼────────────────────┼────────────────┤
│ Sir Nic of the Weils │ 3            │ Ancient Spoon      │ 1                  │ 80             │
├──────────────────────┼──────────────┼────────────────────┼────────────────────┼────────────────┤
│ Sir Nic of the Weils │ 10           │ Bronze Poniard     │ 10                 │ 10             │
└──────────────────────┴──────────────┴────────────────────┴────────────────────┴────────────────┘
Variant to test/display commutative properties of join:
(C join I join CI){ALL BUT C#, HP, I#}
┌──────────────────────┬────────────────────┬────────────────────┬────────────────┬──────────────┐
│ Cname::string        │ Iname::string      │ Durability::number │ Damage::number │ Slot::number │
├──────────────────────┼────────────────────┼────────────────────┼────────────────┼──────────────┤
│ Reese of Wellington  │ Bronze Poniard     │ 10                 │ 10             │ 3            │
├──────────────────────┼────────────────────┼────────────────────┼────────────────┼──────────────┤
│ Reese of Wellington  │ Venom-Soaked Blade │ 5                  │ 25             │ 4            │
├──────────────────────┼────────────────────┼────────────────────┼────────────────┼──────────────┤
│ Sir Nic of the Weils │ Bronze Poniard     │ 10                 │ 10             │ 10           │
├──────────────────────┼────────────────────┼────────────────────┼────────────────┼──────────────┤
│ Sir Nic of the Weils │ Glazed Donut       │ 1                  │ 1              │ 4            │
├──────────────────────┼────────────────────┼────────────────────┼────────────────┼──────────────┤
│ Sir Nic of the Weils │ Ancient Spoon      │ 1                  │ 80             │ 3            │
└──────────────────────┴────────────────────┴────────────────────┴────────────────┴──────────────┘
Give me all items that are owned by no character:
I NOT MATCHING CI
┌────────────┬──────────────────────────────┬────────────────────┬────────────────┐
│ I#::number │ Iname::string                │ Durability::number │ Damage::number │
├────────────┼──────────────────────────────┼────────────────────┼────────────────┤
│ 5          │ Holy Hand Grenade of Antioch │ 1                  │ 999            │
├────────────┼──────────────────────────────┼────────────────────┼────────────────┤
│ 6          │ Common Shortsword            │ 30                 │ 15             │
├────────────┼──────────────────────────────┼────────────────────┼────────────────┤
│ 7          │ Rot-Hilted Axe               │ 8                  │ 15             │
└────────────┴──────────────────────────────┴────────────────────┴────────────────┘
All characters with an item that deals more than 30 damage:
C MATCHING (CI JOIN (I WHERE {Damage > 30}))
┌────────────┬──────────────────────┬────────────┐
│ C#::number │ Cname::string        │ HP::number │
├────────────┼──────────────────────┼────────────┤
│ 2          │ Sir Nic of the Weils │ 18         │
└────────────┴──────────────────────┴────────────┘
Just their names:
(C MATCHING (CI JOIN (I WHERE {Damage > 30}))){Cname}
┌──────────────────────┐
│ Cname::string        │
├──────────────────────┤
│ Sir Nic of the Weils │
└──────────────────────┘
┌──────────────────────┐
│ Cname::string        │
├──────────────────────┤
│ Sir Nic of the Weils │
└──────────────────────┘
Characters and the items they DON'T have:
((C{C#} JOIN I{I#}) MINUS (CI{C#, I#}) JOIN C{C#, Cname} JOIN I{I#, Iname}) {Cname, Iname} RENAME {Cname AS Character, Iname AS Missing Item}
┌──────────────────────┬──────────────────────────────┐
│ Character::string    │ Missing Item::string         │
├──────────────────────┼──────────────────────────────┤
│ Reese of Wellington  │ Glazed Donut                 │
├──────────────────────┼──────────────────────────────┤
│ Reese of Wellington  │ Ancient Spoon                │
├──────────────────────┼──────────────────────────────┤
│ Reese of Wellington  │ Holy Hand Grenade of Antioch │
├──────────────────────┼──────────────────────────────┤
│ Reese of Wellington  │ Common Shortsword            │
├──────────────────────┼──────────────────────────────┤
│ Reese of Wellington  │ Rot-Hilted Axe               │
├──────────────────────┼──────────────────────────────┤
│ Sir Nic of the Weils │ Venom-Soaked Blade           │
├──────────────────────┼──────────────────────────────┤
│ Sir Nic of the Weils │ Holy Hand Grenade of Antioch │
├──────────────────────┼──────────────────────────────┤
│ Sir Nic of the Weils │ Common Shortsword            │
├──────────────────────┼──────────────────────────────┤
│ Sir Nic of the Weils │ Rot-Hilted Axe               │
└──────────────────────┴──────────────────────────────┘
Fix overpowered items:
UPDATE I WHERE Damage > 30: {Damage := Damage / 2}
┌────────────┬──────────────────────────────┬────────────────────┬────────────────┐
│ I#::number │ Iname::string                │ Durability::number │ Damage::number │
├────────────┼──────────────────────────────┼────────────────────┼────────────────┤
│ 1          │ Bronze Poniard               │ 10                 │ 10             │
├────────────┼──────────────────────────────┼────────────────────┼────────────────┤
│ 2          │ Glazed Donut                 │ 1                  │ 1              │
├────────────┼──────────────────────────────┼────────────────────┼────────────────┤
│ 3          │ Venom-Soaked Blade           │ 5                  │ 25             │
├────────────┼──────────────────────────────┼────────────────────┼────────────────┤
│ 4          │ Ancient Spoon                │ 1                  │ 40             │
├────────────┼──────────────────────────────┼────────────────────┼────────────────┤
│ 5          │ Holy Hand Grenade of Antioch │ 1                  │ 499            │
├────────────┼──────────────────────────────┼────────────────────┼────────────────┤
│ 6          │ Common Shortsword            │ 30                 │ 15             │
├────────────┼──────────────────────────────┼────────────────────┼────────────────┤
│ 7          │ Rot-Hilted Axe               │ 8                  │ 15             │
└────────────┴──────────────────────────────┴────────────────────┴────────────────┘
Show Damage Per Durability (DPD): 
EXTEND I: {DPD := Damage / Durability}
┌────────────┬──────────────────────────────┬────────────────────┬────────────────┬─────────────┐
│ I#::number │ Iname::string                │ Durability::number │ Damage::number │ DPD::number │
├────────────┼──────────────────────────────┼────────────────────┼────────────────┼─────────────┤
│ 1          │ Bronze Poniard               │ 10                 │ 10             │ 1           │
├────────────┼──────────────────────────────┼────────────────────┼────────────────┼─────────────┤
│ 2          │ Glazed Donut                 │ 1                  │ 1              │ 1           │
├────────────┼──────────────────────────────┼────────────────────┼────────────────┼─────────────┤
│ 3          │ Venom-Soaked Blade           │ 5                  │ 25             │ 5           │
├────────────┼──────────────────────────────┼────────────────────┼────────────────┼─────────────┤
│ 4          │ Ancient Spoon                │ 1                  │ 80             │ 80          │
├────────────┼──────────────────────────────┼────────────────────┼────────────────┼─────────────┤
│ 5          │ Holy Hand Grenade of Antioch │ 1                  │ 999            │ 999         │
├────────────┼──────────────────────────────┼────────────────────┼────────────────┼─────────────┤
│ 6          │ Common Shortsword            │ 30                 │ 15             │ 1           │
├────────────┼──────────────────────────────┼────────────────────┼────────────────┼─────────────┤
│ 7          │ Rot-Hilted Axe               │ 8                  │ 15             │ 2           │
└────────────┴──────────────────────────────┴────────────────────┴────────────────┴─────────────┘
Count of all character-item combos:
        COUNT ( CI ) = 5
Count of all distinct slots in character-item combos:
        COUNT ( CI { Slot } ) : 3
Sum of all item damage:
        SUM (I, Damage) = 1145
Sum of all distinct item damage values:
        SUM (I, { Damage }) = 1130
Sum of tripled item damage:
        SUM (I, 3 * Damage) =  3435
Sum of all distinct tripled item damage:
        SUM( EXTEND I : { Damage := Damage * 3 }, {Damage}) =  3390
My D implementation is behind on most features, but the plumbing exists:
(C join CI join I){ALL BUT C#, HP, I#}
┌──────────────────────┬────────────────────┬────────────────────┬────────────────┬──────────────┐
│ Cname::string        │ Iname::string      │ Durability::number │ Damage::number │ Slot::number │
├──────────────────────┼────────────────────┼────────────────────┼────────────────┼──────────────┤
│ Reese of Wellington  │ Bronze Poniard     │ 10                 │ 10             │ 3            │
├──────────────────────┼────────────────────┼────────────────────┼────────────────┼──────────────┤
│ Reese of Wellington  │ Venom-Soaked Blade │ 5                  │ 25             │ 4            │
├──────────────────────┼────────────────────┼────────────────────┼────────────────┼──────────────┤
│ Sir Nic of the Weils │ Bronze Poniard     │ 10                 │ 10             │ 10           │
├──────────────────────┼────────────────────┼────────────────────┼────────────────┼──────────────┤
│ Sir Nic of the Weils │ Glazed Donut       │ 1                  │ 1              │ 4            │
├──────────────────────┼────────────────────┼────────────────────┼────────────────┼──────────────┤
│ Sir Nic of the Weils │ Ancient Spoon      │ 1                  │ 80             │ 3            │
└──────────────────────┴────────────────────┴────────────────────┴────────────────┴──────────────┘
Attempt to violate the constraint:
{ c: 'CONSTRAINTS_FAILED', constraint_names: [ 'UNIQ_I' ] }
Concede, follow the constraint:
┌────────────┬──────────────────────────────┬────────────────────┬────────────────┐
│ I#::number │ Iname::string                │ Durability::number │ Damage::number │
├────────────┼──────────────────────────────┼────────────────────┼────────────────┤
│ 1          │ Bronze Poniard               │ 10                 │ 10             │
├────────────┼──────────────────────────────┼────────────────────┼────────────────┤
│ 2          │ Glazed Donut                 │ 1                  │ 1              │
├────────────┼──────────────────────────────┼────────────────────┼────────────────┤
│ 3          │ Venom-Soaked Blade           │ 5                  │ 25             │
├────────────┼──────────────────────────────┼────────────────────┼────────────────┤
│ 4          │ Ancient Spoon                │ 1                  │ 80             │
├────────────┼──────────────────────────────┼────────────────────┼────────────────┤
│ 5          │ Holy Hand Grenade of Antioch │ 1                  │ 999            │
├────────────┼──────────────────────────────┼────────────────────┼────────────────┤
│ 6          │ Common Shortsword            │ 30                 │ 15             │
├────────────┼──────────────────────────────┼────────────────────┼────────────────┤
│ 7          │ Rot-Hilted Axe               │ 8                  │ 15             │
├────────────┼──────────────────────────────┼────────────────────┼────────────────┤
│ 8          │ Floppy Disk                  │ 40                 │ 3              │
└────────────┴──────────────────────────────┴────────────────────┴────────────────┘
Attempt to violate again on new DB:
{ c: 'CONSTRAINTS_FAILED', constraint_names: [ 'UNIQ_I' ] }