mentat/test/js/tests.js

120 lines
3.8 KiB
JavaScript
Raw Normal View History

// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
var datomish = require("../../target/release-node/datomish.js");
var schema = {
"name": "pages",
"attributes": [
{"name": "page/url",
"type": "string",
"cardinality": "one",
"unique": "identity",
"doc": "A page's URL."},
{"name": "page/title",
"type": "string",
"cardinality": "one",
2016-10-05 19:54:48 +00:00
"doc": "A page's title."}
]
};
async function testOpen() {
2016-10-05 19:54:48 +00:00
// Open a database.
let path = "/tmp/testing" + Date.now() + ".db";
console.log("Opening " + path);
let db = await datomish.open(path);
2016-10-05 19:54:48 +00:00
// Make sure we have our current schema.
await db.ensureSchema(schema);
2016-10-05 19:54:48 +00:00
// Add some data. Note that we use a temporary ID (the real ID
// will be assigned by Datomish).
let txResult = await db.transact([
{"db/id": datomish.tempid(),
"page/url": "https://mozilla.org/",
"page/title": "Mozilla"}
]);
console.log("Transaction returned " + JSON.stringify(txResult));
console.log("Transaction instant: " + txResult.txInstant);
2016-10-05 19:54:48 +00:00
// A simple query.
let results = await db.q("[:find [?url ...] :in $ :where [?e :page/url ?url]]");
console.log("Known URLs: " + JSON.stringify(results));
2016-10-05 19:54:48 +00:00
// Let's extend our schema. In the real world this would typically happen
// across releases.
schema.attributes.push({"name": "page/visitedAt",
"type": "instant",
"cardinality": "many",
"doc": "A visit to the page."});
await db.ensureSchema(schema);
// Now we can make assertions with the new vocabulary about existing
// entities.
// Note that we simply let Datomish find which page we're talking about by
// URL -- the URL is a unique property -- so we just use a tempid again.
await db.transact([
{"db/id": datomish.tempid(),
"page/url": "https://mozilla.org/",
"page/visitedAt": new Date()}
2016-10-05 19:54:48 +00:00
]);
// When did we most recently visit this page?
let date = (await db.q(
`[:find (max ?date) .
2016-10-05 19:54:48 +00:00
:in $ ?url
:where
[?page :page/url ?url]
[?page :page/visitedAt ?date]]`,
{"inputs": {"url": "https://mozilla.org/"}}));
2016-10-05 19:54:48 +00:00
console.log("Most recent visit: " + date);
// Add some more data about a couple of pages.
let start = Date.now();
let lr = datomish.tempid();
let reddit = datomish.tempid();
let res = await db.transact([
{"db/id": reddit,
"page/url": "http://reddit.com/",
"page/title": "Reddit",
"page/visitedAt": new Date(start)},
{"db/id": lr,
"page/url": "https://longreads.com/",
"page/title": "Longreads: The best longform stories on the web",
"page/visitedAt": (new Date(start + 100))},
// Two visits each.
{"db/id": lr,
"page/visitedAt": (new Date(start + 200))},
{"db/id": reddit,
"page/visitedAt": (new Date(start + 300))}
]);
// These are our new persistent IDs. We can use these directly in later
// queries or transactions
lr = res.tempid(lr);
reddit = res.tempid(reddit);
console.log("Persistent IDs are " + lr + ", " + reddit + ".");
// A query with a limit and order-by. Because we limit to 2, and order
// by most recent visit date first, we won't get mozilla.org in our results.
let recent = await db.q(
`[:find ?url (max ?date)
:in $
:where
[?page :page/url ?url]
[?page :page/visitedAt ?date]]`,
{"limit": 2, "order-by": [["_max_date", "desc"]]});
console.log("Recently visited: " + JSON.stringify(recent));
2016-10-05 19:54:48 +00:00
// Close: we're done!
await db.close();
}
testOpen()
.then((r) => console.log("Done."))
.catch((e) => console.log("Failure: " + e.stack));