├── .gitattributes ├── 1-getting-started.nextjournal.md ├── 2-put-transactions.nextjournal.md ├── 3-datalog-queries.nextjournal.md ├── 4-bitemporality.nextjournal.md ├── 5-match.nextjournal.md ├── 6-delete.nextjournal.md ├── 7-evict.nextjournal.md ├── 8-await-transactions.nextjournal.md ├── LICENSE ├── README.md ├── deps.edn ├── images-src ├── 1a-start-earth-title.png ├── 1a-start-earth-title.svg ├── 2a-put-tx-pluto-title.png ├── 2a-put-tx-pluto-title.svg ├── 3a-datalog-queries-mercury-title.png ├── 3a-datalog-queries-mercury-title.svg ├── 4a-bitemporality-neptune-title.png ├── 4a-bitemporality-neptune-title.svg ├── 5a-match-saturn-title.png ├── 5a-match-saturn-title.svg ├── 6a-delete-jupiter-title.png ├── 6a-delete-jupiter-title.svg ├── 7a-evict-meteor-title.png ├── 7a-evict-meteor-title.svg ├── 8a-await-kepra5-title.png ├── 8a-await-kepra5-title.svg ├── Earth_Eastern_Hemisphere.jpg ├── space-background-square.png ├── space-background.jpg ├── xtdb-cube-raster.png ├── xtdb-logo-raster.png ├── xtdb-text-raster-inverted.png ├── xtdb-text-raster-inverted.xcf └── xtdb-text-raster.png └── images ├── 1a-start-earth-title-OLD.png ├── 1a-start-earth-title.png ├── 1b-put-tx-pluto.png ├── 2a-put-tx-pluto-title-OLD.png ├── 2a-put-tx-pluto-title.png ├── 2b-datalog-mercury.png ├── 3a-datalog-queries-mercury-title.png ├── 3b-bitemporality-neptune.png ├── 4a-bitemporality-neptune-title.png ├── 4b-match-saturn.png ├── 5a-match-saturn-title.png ├── 5b-delete-jupiter.png ├── 6a-delete-jupiter-title.png ├── 6b-evict-meteor.png ├── 7a-evict-meteor-title.png ├── 7b-await-kepra5.png ├── 7b-evict-ice.jpg ├── 7c-evict-meteor.jpg └── 8a-await-kepra5-title.png /.gitattributes: -------------------------------------------------------------------------------- 1 | *.png filter=lfs diff=lfs merge=lfs -text 2 | *.jpg filter=lfs diff=lfs merge=lfs -text 3 | *.xcf filter=lfs diff=lfs merge=lfs -text 4 | *.svg filter=lfs diff=lfs merge=lfs -text 5 | -------------------------------------------------------------------------------- /1-getting-started.nextjournal.md: -------------------------------------------------------------------------------- 1 | # 1: Getting Started with XTDB – A Tale of Time and Space 2 | 3 | ![XTDB Tutorial: Start](https://github.com/xtdb/xtdb-tutorial/raw/main/images/1a-start-earth-title.png) 4 | 5 | # Introduction 6 | 7 | Welcome to the official XTDB tutorial, which complements the official [documentation](https://docs.xtdb.com/administration/installing/). 8 | 9 | If you’re new to XTDB and want to get a practical hands-on guide, you’re in the right place. 10 | 11 | ## The Story 12 | 13 | It’s the year 2115. 14 | You have been hired by an inter-planetary bank, Helios Banking Inc. 15 | Your task is to travel around the solar system completing assignments using XTDB. 16 | 17 | You have been given a company spaceship so transport won’t be a problem. 18 | Space Customs require all astronauts to complete a flight manifest for every journey. 19 | You also have a handy XTDB manual with you so you can read up on some background information before you get stuck into each assignment. 20 | 21 | Let’s begin. 22 | 23 | ## Setup 24 | 25 | You need to get XTDB running before you can use it. 26 | 27 | 28 | ```edn no-exec 29 | {:deps 30 | {org.clojure/clojure {:mvn/version "1.11.1"} 31 | org.clojure/tools.deps.alpha {:mvn/version "0.14.1212"} 32 | com.xtdb/xtdb-core {:mvn/version "dev-SNAPSHOT"}} ;; "RELEASE" 33 | 34 | :mvn/repos 35 | {"snapshots" {:url "https://s01.oss.sonatype.org/content/repositories/snapshots"}}} 36 | ``` 37 | 38 | ```clojure 39 | (require '[xtdb.api :as xt]) 40 | ``` 41 | 42 | You are now ready for your first assignment, so you head over to the spaceport. 43 | 44 | # Spaceport 45 | 46 | On entering your spaceship, you notice a flashing blue light on the left of your communications panel. 47 | You submit an iris scan to unlock your first message. 48 | 49 | 50 | > A warm welcome from the Helios family. 51 | > 52 | > For your first assignment we would like you to go to Pluto and help Tombaugh Resources Ltd. set up their stock reporting system. 53 | > There will be a ticket with more information waiting for you upon your arrival. 54 | > Find Reginald if you have any questions. 55 | > 56 | >Safe journeys, and don’t forget to fill in your flight manifest. They won’t let you land without one. 57 | > 58 | > — Helios Banking Inc. 59 | 60 | ## Power up 61 | 62 | Before you leave you must fill in your flight manifest. 63 | To do this, you must first set up a XTDB node. 64 | You want to get started as quickly as possible so you decide to use XTDB's inbuilt standalone node. 65 | 66 | You read the XTDB manual entry for the standalone node to make sure this is OK. 67 | 68 | > If you want to get up and running with XTDB fast, consider using the standalone node. 69 | > There is a XTDB inbuilt standalone node which is the most simple way to start playing with XTDB. 70 | > Bear in mind that this does not store any information beyond your session. 71 | > 72 | > For persistent storage consider using RocksDB and for scale you should consider using Kafka. 73 | > 74 | > — XTDB manual *[Read More](https://docs.xtdb.com/administration/installing/)* 75 | 76 | You decide this is fine for now, and so define your XTDB node. 77 | 78 | ```clojure 79 | (def node (xt/start-node {})) 80 | ``` 81 | 82 | ## Flight Manifest 83 | 84 | You take a look around your ship and check the critical levels. 85 | 86 | You read the manual entry for putting data into XTDB. 87 | 88 | > XTDB takes information in document form. 89 | > Each document must be in Extensible Data Notation (edn) and each document must contain a unique `:xt/id` value. 90 | > However, beyond those two requirements you have the flexibility to add whatever you like to your documents because XTDB is schemaless. 91 | > 92 | > — XTDB manual *[Read More](https://xtdb.com/reference/transactions.html#put)* 93 | 94 | Just as you’re about to write your manifest, one of the porters passes you a secret note and asks you to deliver it to a martian named Kaarlang. 95 | They are certain you will meet Kaarlang on your travels and so you see no harm in delivering the note for them. 96 | 97 | ```clojure 98 | (def manifest 99 | {:xt/id :manifest 100 | :pilot-name "Johanna" 101 | :id/rocket "SB002-sol" 102 | :id/employee "22910x2" 103 | :badges "SETUP" 104 | :cargo ["stereo" "gold fish" "slippers" "secret note"]}) 105 | ``` 106 | 107 | You put the manifest into XTDB. 108 | 109 | ```clojure 110 | (xt/submit-tx node [[::xt/put manifest]]) 111 | ``` 112 | 113 | This is `put`, one of XTDB's four transaction operations. 114 | 115 | Make sure this transaction has taken effect using `sync` which ensures that the node's indexes are caught up with the latest transaction. 116 | 117 | ```clojure 118 | (xt/sync node) 119 | ``` 120 | 121 | Check that this was successful by asking XTDB to show the whole entity. 122 | 123 | ```clojure 124 | (xt/entity (xt/db node) :manifest) 125 | ``` 126 | 127 | You enter the countdown for lift off to Pluto. [See you soon](https://nextjournal.com/xtdb-tutorial/put). 128 | 129 | ![Pluto: tx/put](https://github.com/xtdb/xtdb-tutorial/raw/main/images/1b-put-tx-pluto.png) 130 | -------------------------------------------------------------------------------- /2-put-transactions.nextjournal.md: -------------------------------------------------------------------------------- 1 | # 2: Put Transactions with XTDB – Pluto Assignment 2 | 3 | ![XTDB Tutorial: tx/put](https://github.com/xtdb/xtdb-tutorial/raw/main/images/2a-put-tx-pluto-title.png) 4 | 5 | # Introduction 6 | 7 | This is the second part of the XTDB tutorial. 8 | The Earth instalment looked at setting up a simple XTDB standalone node and a very simple `put` transaction. 9 | 10 | ## Setup 11 | 12 | You need to get XTDB running before you can use it. 13 | 14 | 15 | ```edn no-exec 16 | {:deps 17 | {org.clojure/clojure {:mvn/version "1.11.1"} 18 | org.clojure/tools.deps.alpha {:mvn/version "0.14.1212"} 19 | com.xtdb/xtdb-core {:mvn/version "dev-SNAPSHOT"}} ;; "RELEASE" 20 | 21 | :mvn/repos 22 | {"snapshots" {:url "https://s01.oss.sonatype.org/content/repositories/snapshots"}}} 23 | ``` 24 | 25 | ```clojure 26 | (require '[xtdb.api :as xt]) 27 | ``` 28 | 29 | # Arrival on Pluto 30 | 31 | As you enter the Plutonian atmosphere, a message pops up on your communication panel: 32 | 33 | > Welcome to the dwarf planet Pluto. 34 | > You are entering privately governed space. 35 | > If you do not have the correct papers, entry will be denied. 36 | > We hope you enjoy your stay. 37 | > 38 | > Have a nice day. 39 | > 40 | > \- Anarchic Directorate of Pluto 41 | 42 | The government of Pluto is asking to see your flight manifest. 43 | 44 | ## Choose your path: 45 | 46 | - **You have your manifest**: 47 | - *You have permission to land, continue to the spaceport.* 48 | 49 | - **You do not have your manifest**: 50 | - *You do not have permission to land. You can either return to [Earth](https://nextjournal.com/xtdb-tutorial/start), or continue at your own risk.* 51 | 52 | # Spaceport 53 | 54 | As you circle the dwarf planet to land, you have a quick read of your XTDB manual. 55 | You know you will be using the `put` operation a lot for this assignment and although you used the operation to add your manifest before you left, you think it is a good idea to brush up on your knowledge. 56 | 57 | > Currently there are only four transaction operations in XTDB: put, delete, match and evict. 58 | > 59 | >> **Transaction** **(Description)** 60 | >> 61 | >> put (Writes a version of a document) 62 | >> 63 | >> delete (Deletes a version of a document) 64 | >> 65 | >> match (Stops a transaction if the precondition is not met.) 66 | >> 67 | >> evict (Removes a document entirely) 68 | > 69 | > ## Put: 70 | > 71 | > The `put` transaction is used to write versions of a document (doc). 72 | > 73 | > Each document must be in Extensible Data Notation (edn) and must contain a unique :xt/id value. 74 | > However, beyond those two requirements you have the flexibility to add whatever you like to your documents because XTDB is schemaless. 75 | > 76 | > Along with the document (doc), put has two optional additional arguments: 77 | >> start `valid-time` *(The time at which the entry will be valid from.)* 78 | >> 79 | >> end `valid-time` *(The time at which the entry will be valid until.)* 80 | > 81 | > This means that you can query back through the database, you can use valid-time arguments to see the state of the database at a different time. 82 | > 83 | > 84 | > Time in XTDB is denoted `#inst "yyyy-MM-ddThh:mm:ss"`. 85 | > For example, 9:30 pm on January 2nd 1999 would be written: 86 | > 87 | >> `#inst "1999-01-02T21:30:00".` 88 | > 89 | > 90 | > A complete put transaction has the form: 91 | >> `[::xt/put doc valid-time-start valid-time-end]` 92 | > 93 | > \- XTDB manual *[Read More](https://xtdb.com/reference/transactions.html)* 94 | 95 | 96 | You are happy with what you have read, and in anticipation of your first assignment you define the standalone node. 97 | 98 | ```clojure 99 | (def node (xt/start-node {})) 100 | ``` 101 | 102 | # Assignment 103 | 104 | You land on the surface of the dwarf planet. 105 | As you do, the job ticket for this assignment is unlocked. 106 | 107 | ## Ticket 108 | 109 | > ### Task 110 | > *Commodity Logging* 111 | > 112 | > ### Company 113 | > *Tombaugh Resources Ltd.* 114 | > 115 | > ### Contact 116 | > *R. Glogofloon* 117 | > 118 | > ### Submitted 119 | > *2115-02-20T13:38:20* 120 | > 121 | > ### Additional information: 122 | > *We need help setting up a new recording system for our mine. 123 | > I have enclosed a list of the commodities we deal with. 124 | > Please send someone soon because we already have a week’s worth of unrecorded stocktakes.* 125 | 126 | You make your way over to the mines on the next shuttle. 127 | On your way you decide to get a head start and put the commodities into XTDB. 128 | 129 | ```clojure 130 | (xt/submit-tx 131 | node 132 | [[::xt/put 133 | {:xt/id :commodity/Pu 134 | :common-name "Plutonium" 135 | :type :element/metal 136 | :density 19.816 137 | :radioactive true}] 138 | 139 | [::xt/put 140 | {:xt/id :commodity/N 141 | :common-name "Nitrogen" 142 | :type :element/gas 143 | :density 1.2506 144 | :radioactive false}] 145 | 146 | [::xt/put 147 | {:xt/id :commodity/CH4 148 | :common-name "Methane" 149 | :type :molecule/gas 150 | :density 0.717 151 | :radioactive false}]]) 152 | 153 | (xt/sync node) 154 | ``` 155 | 156 | Since it takes six hours for each transaction to reach your XTDB node on Earth from here, it is a good idea to batch up all the commodities in a single transaction. 157 | 158 | ## Stock Take 159 | 160 | You arrive at the mine and are met by the CEO, Reginald Glogofloon, a 150 year old Plutonian. 161 | 162 | > Hello, I’m glad you’re here. 163 | > 164 | > I would like you to fill in our last weeks worth of data on our commodities. 165 | > We need to be able to look back at a given day and see what our stocks were for auditing purposes. 166 | > 167 | > The stock for each day must be submitted at 6pm Earth time (UTC) for your banks records. 168 | > 169 | > Are you able to do that for me? 170 | > 171 | > \- R. Glogofloon 172 | 173 | ## Choose your path: 174 | 175 | - **"Yes I'll give it a go"**: 176 | - *Continue to complete the assignment.* 177 | 178 | - **"I'm not sure how to even begin"**: 179 | - *Go back and read the manual entry.* 180 | 181 | You remember that with XTDB you have the option of adding a `valid-time`. 182 | This comes in useful now as you enter the weeks worth of stock takes for Plutonium. 183 | 184 | ```clojure 185 | (xt/submit-tx 186 | node 187 | [[::xt/put 188 | {:xt/id :stock/Pu 189 | :commod :commodity/Pu 190 | :weight-ton 21 } 191 | #inst "2115-02-13T18"] 192 | 193 | [::xt/put 194 | {:xt/id :stock/Pu 195 | :commod :commodity/Pu 196 | :weight-ton 23 } 197 | #inst "2115-02-14T18"] 198 | 199 | [::xt/put 200 | {:xt/id :stock/Pu 201 | :commod :commodity/Pu 202 | :weight-ton 22.2 } 203 | #inst "2115-02-15T18"] 204 | 205 | [::xt/put 206 | {:xt/id :stock/Pu 207 | :commod :commodity/Pu 208 | :weight-ton 24 } 209 | #inst "2115-02-18T18"] 210 | 211 | [::xt/put 212 | {:xt/id :stock/Pu 213 | :commod :commodity/Pu 214 | :weight-ton 24.9 } 215 | #inst "2115-02-19T18"]]) 216 | 217 | (xt/sync node) 218 | ``` 219 | 220 | You notice that the amount of Nitrogen and Methane has not changed which saves you some time: 221 | 222 | ```clojure 223 | (xt/submit-tx 224 | node 225 | [[::xt/put 226 | {:xt/id :stock/N 227 | :commod :commodity/N 228 | :weight-ton 3 } 229 | #inst "2115-02-13T18" 230 | #inst "2115-02-19T18"] 231 | 232 | [::xt/put 233 | {:xt/id :stock/CH4 234 | :commod :commodity/CH4 235 | :weight-ton 92 } 236 | #inst "2115-02-15T18" 237 | #inst "2115-02-19T18"]]) 238 | ``` 239 | 240 | The CEO is impressed with your speed, but a little skeptical that you have done it properly. 241 | 242 | You gain their confidence by showing them the entries for Plutonium on two different days: 243 | 244 | ```clojure 245 | (xt/entity (xt/db node #inst "2115-02-14") :stock/Pu) 246 | ``` 247 | 248 | ```clojure 249 | (xt/entity (xt/db node #inst "2115-02-18") :stock/Pu) 250 | ``` 251 | 252 | ## Easy Ingest 253 | 254 | As a parting gift to them you create an easy ingest function so that if they needed to add more commodities to their stock list they could do it fast. 255 | 256 | ```clojure 257 | (defn easy-ingest 258 | "Uses XTDB put transaction to add a vector of documents to a specified 259 | node" 260 | [node docs] 261 | (xt/submit-tx node 262 | (vec (for [doc docs] 263 | [::xt/put doc]))) 264 | (xt/sync node)) 265 | ``` 266 | 267 | Tombaugh Resources Ltd. are happy that this will be simple enough to use. 268 | They thank you for the extra help and you head back to your ship. 269 | 270 | # Spaceport 271 | 272 | You are back at your ship and check your communications panel. 273 | There is a new assignment waiting for you: 274 | 275 | > Congratulations on completing your first assignment. 276 | > 277 | > We would like you to go to Mercury, the hub of the trade world. 278 | > Their main trade center has a new IT department and want you to show them how to query XTDB" 279 | > 280 | > \- Helios Banking Inc. 281 | 282 | It’s a long flight so you refuel, and update your manifest. 283 | You have been awarded a new badge, so you add this to your manifest. 284 | 285 | ```clojure 286 | (xt/submit-tx 287 | node 288 | [[::xt/put 289 | {:xt/id :manifest 290 | :pilot-name "Johanna" 291 | :id/rocket "SB002-sol" 292 | :id/employee "22910x2" 293 | :badges ["SETUP" "PUT"] 294 | :cargo ["stereo" "gold fish" "slippers" "secret note"]}]]) 295 | ``` 296 | 297 | You enter the countdown for lift off to Mercury. [See you soon.](https://nextjournal.com/xtdb-tutorial/datalog) 298 | 299 | ![Mercury: Datalog](https://github.com/xtdb/xtdb-tutorial/raw/main/images/2b-datalog-mercury.png) 300 | -------------------------------------------------------------------------------- /3-datalog-queries.nextjournal.md: -------------------------------------------------------------------------------- 1 | # 3: Datalog Queries with XTDB – Mercury Assignment 2 | 3 | ![Mercury: Datalog Queries](https://github.com/xtdb/xtdb-tutorial/raw/main/images/3a-datalog-queries-mercury-title.png) 4 | 5 | # Introduction 6 | 7 | This is the third instalment of the XTDB tutorial, focusing on Datalog queries. 8 | 9 | ## Setup 10 | 11 | You need to get XTDB running before you can use it. 12 | 13 | 14 | ```edn no-exec 15 | {:deps 16 | {org.clojure/clojure {:mvn/version "1.11.1"} 17 | org.clojure/tools.deps.alpha {:mvn/version "0.14.1212"} 18 | com.xtdb/xtdb-core {:mvn/version "dev-SNAPSHOT"}} ;; "RELEASE" 19 | 20 | :mvn/repos 21 | {"snapshots" {:url "https://s01.oss.sonatype.org/content/repositories/snapshots"}}} 22 | ``` 23 | 24 | ```clojure 25 | (require '[xtdb.api :as xt]) 26 | ``` 27 | 28 | # Arrival on Mercury 29 | 30 | You come into range of the satellites orbiting Mercury. 31 | Your communications panel lights up and you read: 32 | 33 | > Greetings. 34 | > 35 | > You have reached Mercury, home to the greatest stock market in the Solar System. 36 | > Your ship has been flagged as a transport vessel for business-related activities. 37 | > 38 | > Please have your flight manifest ready and prepare to land. 39 | > 40 | > \- Mercury Commonwealth 41 | 42 | The government is asking to see your flight manifest. 43 | 44 | ## Choose your path: 45 | 46 | - **You have your manifest**: 47 | - *You have permission to land, continue to the spaceport.* 48 | 49 | - **You do not have your manifest**: 50 | - *You do not have permission to land. You can either return to [Pluto](https://nextjournal.com/xtdb-tutorial/put) or continue at your own risk.* 51 | 52 | # Spaceport 53 | 54 | You read your XTDB manual as you wait for an available landing pad. 55 | 56 | > A Datalog query consists of a set of variables and a set of clauses. 57 | > The result of running a query is a result set (or lazy sequence) of the possible combinations of values that satisfy all of the clauses at the same time. 58 | > These combinations of values are referred to as "tuples". 59 | > 60 | > The possible values within the result tuples are derived from your database of documents. 61 | > The documents themselves are represented in the database indexes as "entity–attribute–value" (EAV) facts. 62 | > For example, a single document `{:xt/id :myid, :color "blue", :age 12}` is transformed into two facts `[[:myid :color "blue"][:myid :age 12]]`. 63 | > 64 | > In the most basic case, a Datalog query works by searching for "subgraphs" in the database that match the pattern defined by the clauses. 65 | > The values within these subgraphs are then returned according to the list of return variables requested in the `:find` vector within the query." 66 | > 67 | > \- XTDB manual *[Read More](https://xtdb.com/reference/queries.html)* 68 | 69 | You are happy with what you have read, and in anticipation of the assignment, you define the standalone node. 70 | 71 | ```clojure 72 | (def node (xt/start-node {})) 73 | ``` 74 | 75 | # Assignment 76 | 77 | You land on the surface of the tidally locked planet. 78 | As you do, the job ticket for this assignment is issued. 79 | 80 | ## Ticket 81 | 82 | > ### Task 83 | > *Find information on products for stock buyers* 84 | > 85 | > ### Company 86 | > *Interplanetary Buyers & Sellers (IPBS)* 87 | > 88 | > ### Contact 89 | > *Cosmina Sinnett* 90 | > 91 | > ### Submitted 92 | > *2115-06-20T10:54:27* 93 | > 94 | > ### Additional information: 95 | > *We have some new starters in the sales team. 96 | > They need to be trained on how to query XTDB using Datalog to quickly find the information they need on a product. 97 | > Traders must have access to up-to-date information when talking to their clients. 98 | > We would also like you to create a function that can be used for the things we have to look up a lot. 99 | > I will include example data so they can learn using relevant commodities.* 100 | 101 | On your way over to the IPBS office, you input the data in the attachment using the easy ingest function you created on Pluto. 102 | 103 | ```clojure 104 | (defn easy-ingest 105 | "Uses XTDB put transaction to add a vector of 106 | documents to a specified system" 107 | [node docs] 108 | (xt/submit-tx node 109 | (vec (for [doc docs] 110 | [::xt/put doc]))) 111 | (xt/sync node)) 112 | 113 | (def data 114 | [{:xt/id :commodity/Pu 115 | :common-name "Plutonium" 116 | :type :element/metal 117 | :density 19.816 118 | :radioactive true} 119 | 120 | {:xt/id :commodity/N 121 | :common-name "Nitrogen" 122 | :type :element/gas 123 | :density 1.2506 124 | :radioactive false} 125 | 126 | {:xt/id :commodity/CH4 127 | :common-name "Methane" 128 | :type :molecule/gas 129 | :density 0.717 130 | :radioactive false} 131 | 132 | {:xt/id :commodity/Au 133 | :common-name "Gold" 134 | :type :element/metal 135 | :density 19.300 136 | :radioactive false} 137 | 138 | {:xt/id :commodity/C 139 | :common-name "Carbon" 140 | :type :element/non-metal 141 | :density 2.267 142 | :radioactive false} 143 | 144 | {:xt/id :commodity/borax 145 | :common-name "Borax" 146 | :IUPAC-name "Sodium tetraborate decahydrate" 147 | :other-names ["Borax decahydrate" "sodium borate" "sodium tetraborate" "disodium tetraborate"] 148 | :type :mineral/solid 149 | :appearance "white solid" 150 | :density 1.73 151 | :radioactive false}]) 152 | 153 | (easy-ingest node data) 154 | ``` 155 | 156 | This means you are ready to give them a tutorial when you get there. 157 | 158 | > Oh good, you’re here. 159 | > 160 | > I have a room reserved and we have five new starters ready and waiting to learn how to query XTDB. 161 | > 162 | > We are in the middle of our double sunrise. 163 | > The workers take this time to rest, but in half an Earth hour the sun will rise again and the workers will start back. 164 | > 165 | > You can take this time to prepare any training material if you wish. 166 | > 167 | > \- Cosmina Sinnett 168 | 169 | You have the opportunity to prepare examples for the lesson ahead. 170 | 171 | ## Choose your path: 172 | 173 | - **"You use the time wisely and plan some examples"**: 174 | - *Continue to complete the assignment.* 175 | 176 | - **"You decide to wing it and see how the tutorial goes"**: 177 | - *You go and teach the new starters. They are not impressed with your lack of preparation. They learn next to nothing and you realize you made a mistake.* 178 | 179 | # Datalog Tutorial 180 | 181 | You put together examples and make notes so you can be confident in your lesson. 182 | 183 | ## Lesson Plan 184 | 185 | ### 1. Basic Query 186 | 187 | ```clojure 188 | (xt/q (xt/db node) 189 | '{:find [element] 190 | :where [[element :type :element/metal]]}) 191 | ``` 192 | 193 | *This basic query is returning all the elements that are defined as `:element/metal`. 194 | The `:find` clause tells XTDB the variables you want to return.* 195 | 196 | *In this case, we are returning the `:xt/id` due to our placement of `element`.* 197 | 198 | ### 2. Quoting 199 | 200 | ```clojure 201 | (= 202 | (xt/q (xt/db node) 203 | '{:find [element] 204 | :where [[element :type :element/metal]]}) 205 | 206 | (xt/q (xt/db node) 207 | {:find '[element] 208 | :where '[[element :type :element/metal]]}) 209 | 210 | (xt/q (xt/db node) 211 | (quote 212 | {:find [element] 213 | :where [[element :type :element/metal]]}))) 214 | ``` 215 | 216 | *The vectors given to the clauses should be quoted. 217 | How you do it at this stage is arbitrary.* 218 | 219 | ### 3. Return the name of metal elements. 220 | 221 | ```clojure 222 | (xt/q (xt/db node) 223 | '{:find [name] 224 | :where [[e :type :element/metal] 225 | [e :common-name name]]}) 226 | ``` 227 | 228 | *To find all the names of the commodities that have a certain property, such as `:type`, you need to use a combination of clauses. 229 | Here we have bound the results of type `:element/metal` to `e`. 230 | Next, we can use the results bound to `e` and bind the `:common-name` of them to `name`. 231 | `name` is what has been specified to be returned and so our result is the common names of all the elements that are metals.* 232 | 233 | *One way to think of this is that you are filtering to only get the results that satisfy all the clauses.* 234 | 235 | ### 4. More information. 236 | 237 | ```clojure 238 | (xt/q (xt/db node) 239 | '{:find [name rho] 240 | :where [[e :density rho] 241 | [e :common-name name]]}) 242 | ``` 243 | 244 | *You can pull out as much data as you want into your result tuples by adding additional variables to the `:find` clause.* 245 | 246 | *The example above returns the `:density` and the `:common-name` values for all entities in XTDB that have values of some kind for both `:density` and `:common-name` attributes.* 247 | 248 | ### 5. Arguments 249 | 250 | ```clojure 251 | (xt/q (xt/db node) 252 | '{:find [name] 253 | :where [[e :type type] 254 | [e :common-name name]] 255 | :in [type]} 256 | :element/metal) 257 | ``` 258 | 259 | *`:in` can be used to further filter the results. Lets break down what is going down here.* 260 | 261 | *First, we are assigning all `:xt/id`s that have a `:type` to `e`:* 262 | 263 | `e` ← `#{[:commodity/Pu] [:commodity/borax] [:commodity/CH4] [:commodity/Au] [:commodity/C] [:commodity/N]}` 264 | 265 | *At the same time, we are assigning all the `:types` to `type`:* 266 | 267 | `type` ← `#{[:element/gas] [:element/metal] [:element/non-metal] [:mineral/solid] [:molecule/gas]}` 268 | 269 | *Then we assign all the names within `e` that have a `:common-name` to `name`:* 270 | 271 | `name` ← `#{["Methane"] ["Carbon"] ["Gold"] ["Plutonium"] ["Nitrogen"] ["Borax"]}` 272 | 273 | *We have specified that we want to get the names out, but not before looking at `:in`* 274 | 275 | *For `:in` we have further filtered the results to only show us the names of that have `:type` `:element/metal`.* 276 | 277 | *We could have done that before inside the `:where` clause, but using `:in` removes the need for hard-coding inside the query clauses.* 278 | 279 | *We pass the value(s) to be used as the third argument to `xt/q`.* 280 | 281 | *** 282 | 283 | You give your lesson to the new starters when they return. 284 | They are a good audience and follow it well. 285 | 286 | To check their understanding you set them a task to create a function to aid their daily queries. 287 | You are impressed with their efforts. 288 | 289 | ```clojure 290 | (defn filter-type 291 | [type] 292 | (xt/q (xt/db node) 293 | '{:find [name] 294 | :where [[e :common-name name] 295 | [e :type type]] 296 | :in [type]} 297 | type)) 298 | 299 | (defn filter-appearance 300 | [description] 301 | (xt/q (xt/db node) 302 | '{:find [name IUPAC] 303 | :where [[e :common-name name] 304 | [e :IUPAC-name IUPAC] 305 | [e :appearance appearance]] 306 | :in [appearance]} 307 | description)) 308 | ``` 309 | 310 | ```clojure 311 | (filter-type :element/metal) 312 | ``` 313 | 314 | ```clojure 315 | (filter-appearance "white solid") 316 | ``` 317 | 318 | When you are finished, Cosmina thanks you and you head back to the spaceport. 319 | 320 | # Spaceport 321 | 322 | You are back at your spaceship. 323 | Seeing another light on your communications panel, you realize there is another assignment ready for you. 324 | 325 | > Congratulations on completing your assignment. 326 | > You are getting the hang of things now, and we are impressed with your progress. 327 | > 328 | > We would like you to go to Neptune. 329 | > They have recently lost a lot of data in a flood so they have decided to digitize their entire system and archives. 330 | > We told them you could do it in such a way that the data is still time ordered as it was with their previous filing system. 331 | > 332 | > Good luck, and don’t forget to update your manifest." 333 | > 334 | > \- Helios Banking Inc. 335 | 336 | You update your manifest with the latest badge. 337 | 338 | ```clojure 339 | (xt/submit-tx 340 | node 341 | [[::xt/put 342 | {:xt/id :manifest 343 | :pilot-name "Johanna" 344 | :id/rocket "SB002-sol" 345 | :id/employee "22910x2" 346 | :badges ["SETUP" "PUT" "DATALOG-QUERIES"] 347 | :cargo ["stereo" "gold fish" "slippers" "secret note"]}]]) 348 | 349 | (xt/sync node) 350 | ``` 351 | 352 | You enter the countdown for liftoff to Neptune. [ See you soon.](https://nextjournal.com/xtdb-tutorial/bitemporality) 353 | 354 | ![Neptune: Bitemporality](https://github.com/xtdb/xtdb-tutorial/raw/main/images/3b-bitemporality-neptune.png) 355 | -------------------------------------------------------------------------------- /4-bitemporality.nextjournal.md: -------------------------------------------------------------------------------- 1 | # 4: Bitemporality with XTDB – Neptune Assignment 2 | 3 | ![Neptune: Bitemporality](https://github.com/xtdb/xtdb-tutorial/raw/main/images/4a-bitemporality-neptune-title.png) 4 | 5 | # Introduction 6 | 7 | This is the bitemporal instalment of the XTDB "choose your own adventure" tutorial series. 8 | 9 | ## Setup 10 | 11 | You need to get XTDB running before you can use it. 12 | 13 | 14 | ```edn no-exec 15 | {:deps 16 | {org.clojure/clojure {:mvn/version "1.11.1"} 17 | org.clojure/tools.deps.alpha {:mvn/version "0.14.1212"} 18 | com.xtdb/xtdb-core {:mvn/version "dev-SNAPSHOT"}} ;; "RELEASE" 19 | 20 | :mvn/repos 21 | {"snapshots" {:url "https://s01.oss.sonatype.org/content/repositories/snapshots"}}} 22 | ``` 23 | 24 | ```clojure 25 | (require '[xtdb.api :as xt]) 26 | ``` 27 | 28 | # Arrival on Neptune 29 | 30 | You enter the Neptunian atmosphere and your communications panel lights up. 31 | 32 | > It is our honour to welcome you to the planet, Neptune. 33 | > 34 | > If you are visiting for business reasons, please present your manifest. 35 | > 36 | > Otherwise, have your visa ready for inspection. 37 | > 38 | > \- Poseidon Republic of Wealth 39 | 40 | 41 | The government is asking to see your flight manifest. 42 | 43 | ## Choose your path: 44 | 45 | - **You have your manifest**: 46 | - *You have permission to land, continue to the spaceport.* 47 | 48 | - **You do not have your manifest**: 49 | - *You do not have permission to land. You can either return to [Mercury](https://nextjournal.com/xtdb-tutorial/datalog) or continue at your own risk.* 50 | 51 | # Spaceport 52 | 53 | On your way down to the landing site, you take the time to read the XTDB manual. 54 | 55 | > One or more documents can be inserted into XTDB via a put transaction at a specific valid-time. 56 | > The valid-time can be any time (past, future or present). 57 | > 58 | > If no valid-time is provided, XTDB will default to the transaction time, i.e. 59 | > the present. 60 | > Each document survives until it is deleted or a new version of it is added. 61 | > 62 | > \- XTDB manual *[Read More](https://xtdb.com/articles/bitemporality.html)* 63 | 64 | You are happy with what you have read, and in anticipation of the assignment, you define the standalone node. 65 | 66 | ```clojure 67 | (def node (xt/start-node {})) 68 | ``` 69 | 70 | # Assignment 71 | 72 | Upon landing on the ice giant, your communications panel lights up indicating that the job ticket is available. 73 | 74 | ## Ticket 75 | 76 | 77 | > ### Task 78 | > *Back fill insurance documents* 79 | > 80 | > ### Company 81 | > *Coast Insurance* 82 | > 83 | > ### Contact 84 | > *Lyndon Mercia-York* 85 | > 86 | > ### Submitted 87 | > *2115-02-22T13:38:20* 88 | > 89 | > ### Additional information: 90 | > *We have lost a lot of our records in a flood. 91 | > I think it is prudent to start storing our data digitally. 92 | > It is important to track policy holders' level of cover at the time of the incident. 93 | > We have read a lot about the conveniences of XTDB's bitemporality in this situation. 94 | > We need you to help us get up and running. 95 | > Please send someone quickly though - the waters are rising.* 96 | 97 | Outside your ship, you are met by a panicked looking Lyndon. 98 | 99 | > Thank goodness you’re here. 100 | > 101 | > We need you to show us how to put our customers' information into XTDB in order of time. 102 | > Working with insurance claims, we should be able to easily look back in time at what type of coverage the customer had at the time of the incident. 103 | > 104 | > Are you able to help us? 105 | > 106 | > \- Lyndon Mercia-York 107 | 108 | 109 | ## Choose your path: 110 | 111 | * **"Yes, I'll give it a go."**: 112 | * *Continue to complete the assignment.* 113 | 114 | * **"I'm not even sure how to begin"**: 115 | * *Take some time to read through the XTDB manual again. If you're still unsure then you can follow along anyway and see if things become clear.* 116 | 117 | ## Assignment 118 | 119 | Lyndon gives you some data for a client that you can use as an example. 120 | Coast Insurance need to know what kind of cover each customer has and if it was valid at a given time. 121 | 122 | You show them how to ingest a document using a `valid-time` so that the information is backdated to when the customer took the cover out. 123 | 124 | ```clojure 125 | (xt/submit-tx 126 | node 127 | [[::xt/put 128 | {:xt/id :consumer/RJ29sUU 129 | :consumer-id :RJ29sUU 130 | :first-name "Jay" 131 | :last-name "Rose" 132 | :cover? true 133 | :cover-type :Full} 134 | #inst "2114-12-03"]]) 135 | 136 | (xt/sync node) 137 | ``` 138 | 139 | The company needs to know the history of insurance for each cover. 140 | You show them how to use the bitemporality of XTDB to do this. 141 | 142 | ```clojure 143 | (xt/submit-tx 144 | node 145 | [[::xt/put ;; (1) 146 | {:xt/id :consumer/RJ29sUU 147 | :consumer-id :RJ29sUU 148 | :first-name "Jay" 149 | :last-name "Rose" 150 | :cover? true 151 | :cover-type :Full} 152 | #inst "2113-12-03" ;; Valid time start 153 | #inst "2114-12-03"] ;; Valid time end 154 | 155 | [::xt/put ;; (2) 156 | {:xt/id :consumer/RJ29sUU 157 | :consumer-id :RJ29sUU 158 | :first-name "Jay" 159 | :last-name "Rose" 160 | :cover? true 161 | :cover-type :Full} 162 | #inst "2112-12-03" 163 | #inst "2113-12-03"] 164 | 165 | [::xt/put ;; (3) 166 | {:xt/id :consumer/RJ29sUU 167 | :consumer-id :RJ29sUU 168 | :first-name "Jay" 169 | :last-name "Rose" 170 | :cover? false} 171 | #inst "2112-06-03" 172 | #inst "2112-12-02"] 173 | 174 | [::xt/put ;; (4) 175 | {:xt/id :consumer/RJ29sUU 176 | :consumer-id :RJ29sUU 177 | :first-name "Jay" 178 | :last-name "Rose" 179 | :cover? true 180 | :cover-type :Promotional} 181 | #inst "2111-06-03" 182 | #inst "2112-06-03"]]) 183 | 184 | (xt/sync node) 185 | ``` 186 | 187 | 1. This is the insurance that the customer had last year. Along with the start `valid-time` you use an end `valid-time` so as not to affect the most recent version of the document. 188 | 2. This is the previous insurance plan. Again, you use a start and end `valid-time`. 189 | 3. There was a period when the customer was not covered, 190 | 4. and before that the customer was on a promotional plan. 191 | 192 | ## Queries through time 193 | 194 | You now show them a few queries. 195 | You know that you can query XTDB as of a given `valid-time`. 196 | This shows the state of XTDB at that time. 197 | 198 | First you chose a date that the customer had full cover: 199 | 200 | ```clojure 201 | (xt/q (xt/db node #inst "2114-01-01") 202 | '{:find [cover type] 203 | :where [[e :consumer-id :RJ29sUU] 204 | [e :cover? cover] 205 | [e :cover-type type]]}) 206 | ``` 207 | 208 | Next you show them a query for a the customer in a time when they had a different type of cover: 209 | 210 | ```clojure 211 | (xt/q (xt/db node #inst "2111-07-03") 212 | '{:find [cover type] 213 | :where [[e :consumer-id :RJ29sUU] 214 | [e :cover? cover] 215 | [e :cover-type type]]}) 216 | ``` 217 | 218 | And finally you show them a time when the customer had no cover at all. 219 | 220 | ```clojure 221 | (xt/q (xt/db node #inst "2112-07-03") 222 | '{:find [cover type] 223 | :where [[e :consumer-id :RJ29sUU] 224 | [e :cover? cover] 225 | [e :cover-type type]]}) 226 | ``` 227 | 228 | Confident in their ability to put the remainder of their records into XTDB, Lyndon thanks you. 229 | 230 | > I can’t believe we’ve not digitized sooner. 231 | > There was a huge push to start using more paper as the Neptune tree population was getting out of control from the accelerated terraforming, but since all these floods I’m not sure paper was the right choice." 232 | > 233 | > \- Lyndon Mercia-York 234 | 235 | You say goodbye to Lyndon and head back to the spaceport. 236 | 237 | # Spaceport 238 | 239 | Back at your spaceship, you check your communications panel. 240 | There is a new assignment waiting for you. 241 | 242 | > We have assigned you a quick task on Saturn helping a small company who are having some problems keeping their records in order. 243 | > 244 | > This shouldn’t take long, but don’t forget they will still need to see your manifest. 245 | > 246 | > — Helios Banking Inc. 247 | 248 | You add the new badge to your manifest 249 | 250 | ```clojure 251 | (xt/submit-tx 252 | node 253 | [[::xt/put 254 | {:xt/id :manifest 255 | :pilot-name "Johanna" 256 | :id/rocket "SB002-sol" 257 | :id/employee "22910x2" 258 | :badges ["SETUP" "PUT" "DATALOG-QUERIES" "BITEMP"] 259 | :cargo ["stereo" "gold fish" "slippers" "secret note"]}]]) 260 | 261 | (xt/sync node) 262 | ``` 263 | 264 | Countdown to liftoff to the ringed planet. [See you soon.](https://nextjournal.com/xtdb-tutorial/match) 265 | 266 | ![Saturn: Match](https://github.com/xtdb/xtdb-tutorial/raw/main/images/4b-match-saturn.png) 267 | -------------------------------------------------------------------------------- /5-match.nextjournal.md: -------------------------------------------------------------------------------- 1 | # 5: Match with XTDB – Saturn Assignment 2 | 3 | ![Saturn: Match Transactions](https://github.com/xtdb/xtdb-tutorial/raw/main/images/5a-match-saturn-title.png) 4 | 5 | # Introduction 6 | 7 | This is the `match` instalment of the XTDB tutorial. 8 | 9 | ## Setup 10 | 11 | You need to get XTDB running before you can use it. 12 | 13 | 14 | ```edn no-exec 15 | {:deps 16 | {org.clojure/clojure {:mvn/version "1.11.1"} 17 | org.clojure/tools.deps.alpha {:mvn/version "0.14.1212"} 18 | com.xtdb/xtdb-core {:mvn/version "dev-SNAPSHOT"}} ;; "RELEASE" 19 | 20 | :mvn/repos 21 | {"snapshots" {:url "https://s01.oss.sonatype.org/content/repositories/snapshots"}}} 22 | ``` 23 | 24 | ```clojure 25 | (require '[xtdb.api :as xt]) 26 | ``` 27 | 28 | # Arrival on Saturn 29 | 30 | As you pass through the innermost ring of Saturn, A warning light appears on your communications panel. 31 | You open the message. 32 | It’s from Space Customs and reads: 33 | 34 | > We extend you the warmest welcome. 35 | > 36 | > We must check papers before we can give you permission to land. 37 | > 38 | > \- Cronus Peaceful Nations 39 | 40 | 41 | They are asking to see your flight manifest. 42 | 43 | ## Choose your path: 44 | 45 | 46 | * **You have your manifest**: 47 | * *You have permission to land, continue to the spaceport.* 48 | 49 | 50 | * **You do not have your manifest**: 51 | * *You do not have permission to land. You can either return to [Neptune](https://nextjournal.com/xtdb-tutorial/bitemporality) or continue at your own risk.* 52 | 53 | # Spaceport 54 | 55 | As you prepare to land you open your XTDB manual to the page on `match` 56 | 57 | > Currently there are only four primitve transaction operations in XTDB: put, delete, match and evict. 58 | > 59 | >> **Transaction** **(Description)** 60 | >> 61 | >> put (Writes a version of a document) 62 | >> 63 | >> delete (Deletes a version of a document) 64 | >> 65 | >> match (Stops a transaction if the precondition is not met.) 66 | >> 67 | >> evict (Removes a document entirely) 68 | > 69 | > ## match: 70 | > 71 | > match checks the current state of an entity - if the entity doesn’t match the provided doc, the transaction will not continue. 72 | > You can also pass nil to check that the entity doesn’t exist prior to your transaction. 73 | > 74 | > A match transaction takes the entity id, along with an expected document. 75 | > Optionally you can provide a valid time. 76 | > 77 | > Time in XTDB is denoted #inst 'yyyy-MM-ddThh:mm:ss'. 78 | > For example, 9:30 pm on January 2nd 1999 would be written: `#inst "1999-01-02T21:30:00"`. 79 | > 80 | > A complete match transaction has the form: 81 | > 82 | > `[::xt/match entity-id expected-doc valid-time]` 83 | > 84 | > Note that if there is no old-doc in the system, you can provide `nil` in its place." 85 | > 86 | > \- XTDB manual *[Read More](https://xtdb.com/reference/transactions.html#match)* 87 | 88 | You are happy with what you have read, and in anticipation of the assignment, you define the standalone node. 89 | 90 | ```clojure 91 | (def node (xt/start-node {})) 92 | ``` 93 | 94 | # Assignment 95 | 96 | As you land on the surface of Saturn the job ticket for this assignment is unlocked. 97 | 98 | ## Ticket 99 | 100 | > ### Task 101 | > *Secure trading system* 102 | > 103 | > ### Company 104 | > *Cronus Market Technologies* 105 | > 106 | > ### Contact 107 | > *Ubuku Eppimami* 108 | > 109 | > ### Submitted 110 | > *2115-02-23T13:38:20* 111 | > 112 | > ### Additional information: 113 | > *We need to be shown how to ensure no trades are done without the buyer and seller having the expected funds or stock respectively* 114 | 115 | The next shuttle to the CMT office leaves in 5 Earth minutes. 116 | While you wait you use the easy ingest function you created on Pluto to put the example data into your system. 117 | 118 | ```clojure 119 | (defn easy-ingest 120 | "Uses XTDB put transaction to add a vector of 121 | documents to a specified node" 122 | [node docs] 123 | (xt/submit-tx node 124 | (vec (for [doc docs] 125 | [::xt/put doc]))) 126 | (xt/sync node)) 127 | 128 | (def data 129 | [{:xt/id :gold-harmony 130 | :company-name "Gold Harmony" 131 | :seller? true 132 | :buyer? false 133 | :units/Au 10211 134 | :credits 51} 135 | 136 | {:xt/id :tombaugh-resources 137 | :company-name "Tombaugh Resources Ltd." 138 | :seller? true 139 | :buyer? false 140 | :units/Pu 50 141 | :units/N 3 142 | :units/CH4 92 143 | :credits 51} 144 | 145 | {:xt/id :encompass-trade 146 | :company-name "Encompass Trade" 147 | :seller? true 148 | :buyer? true 149 | :units/Au 10 150 | :units/Pu 5 151 | :units/CH4 211 152 | :credits 1002} 153 | 154 | {:xt/id :blue-energy 155 | :seller? false 156 | :buyer? true 157 | :company-name "Blue Energy" 158 | :credits 1000}]) 159 | 160 | (easy-ingest node data) 161 | ``` 162 | 163 | You also decide to make some Clojure functions so you can easily show Ubuku the stock and fund levels after the trades. 164 | 165 | ```clojure 166 | (defn stock-check 167 | [company-id item] 168 | {:result (xt/q (xt/db node) 169 | {:find '[name funds stock] 170 | :where ['[e :company-name name] 171 | '[e :credits funds] 172 | ['e item 'stock]] 173 | :in '[e]} 174 | company-id) 175 | :item item}) 176 | 177 | (defn format-stock-check 178 | [{:keys [result item] :as stock-check}] 179 | (for [[name funds commod] result] 180 | (str "Name: " name ", Funds: " funds ", " item " " commod))) 181 | ``` 182 | 183 | Just as you are finishing off your shuttle arrives. 184 | 185 | After a short journey through the icy lower clouds of Saturn, you are met by a friendly-faced Ubuku. 186 | 187 | > Hello, friend. 188 | > 189 | > We have been using XTDB for a short time now and think it is great. 190 | > The problem is a human one. 191 | > Occasionally we process trades without first confirming the state of the funds in the buyer's account. This means that any trades happening at approximately the same time will not observe each other's effects on the current balance, and therefore the final state of the account will not reflect all the trades correctly. 192 | > 193 | > I know there is a way that we can stop this happening in XTDB. 194 | > 195 | > I sent you some example data in the job ticket for you to use, I trust you found it. 196 | > 197 | > Do you think you can help us? 198 | > 199 | > \- Ubuku Eppimami 200 | 201 | 202 | ## Choose your path: 203 | 204 | 205 | * **"Yes, I'll give it a go."**: 206 | * *Continue to complete the assignment.* 207 | 208 | 209 | * **"I'm not even sure how to begin"**: 210 | * *Take some time to read through the XTDB manual again. If you're still unsure then you can follow along anyway and see if things become clear.* 211 | 212 | ## Assignment 213 | 214 | You explain to Ubuku that all they need to do to solve their problem is to use the `match` operation instead of `put` when they are processing their trades. 215 | 216 | You show Ubuku the `match` operation for a valid transaction. 217 | You move 10 units of Methane (`:units/CH4`) each at the cost of 100 credits to Blue Energy: 218 | 219 | ```clojure 220 | (xt/submit-tx 221 | node 222 | [[::xt/match 223 | :blue-energy 224 | {:xt/id :blue-energy 225 | :seller? false 226 | :buyer? true 227 | :company-name "Blue Energy" 228 | :credits 1000}] 229 | [::xt/put 230 | {:xt/id :blue-energy 231 | :seller? false 232 | :buyer? true 233 | :company-name "Blue Energy" 234 | :credits 900 235 | :units/CH4 10}] 236 | 237 | [::xt/match 238 | :tombaugh-resources 239 | {:xt/id :tombaugh-resources 240 | :company-name "Tombaugh Resources Ltd." 241 | :seller? true 242 | :buyer? false 243 | :units/Pu 50 244 | :units/N 3 245 | :units/CH4 92 246 | :credits 51}] 247 | [::xt/put 248 | {:xt/id :tombaugh-resources 249 | :company-name "Tombaugh Resources Ltd." 250 | :seller? true 251 | :buyer? false 252 | :units/Pu 50 253 | :units/N 3 254 | :units/CH4 82 255 | :credits 151}]]) 256 | 257 | (xt/sync node) 258 | ``` 259 | 260 | You explain that because the old doc is as expected for both the buyer and the seller that the transaction goes through. 261 | 262 | You show Ubuku the result of the trade using the function you created earlier: 263 | 264 | ```clojure 265 | (format-stock-check (stock-check :tombaugh-resources :units/CH4)) 266 | ``` 267 | 268 | ```clojure 269 | (format-stock-check (stock-check :blue-energy :units/CH4)) 270 | ``` 271 | 272 | They are happy that this works as he sees the 100 credits move from Blue energy to Tombaugh Resources Ltd. 273 | and 10 units of Methane the other way. 274 | 275 | Ubuku asks if you can show them what would happen if the state of funds in the account of a buyer did not match expectations. 276 | You show him a trade where the old doc is not as expected for Encompass trade, to buy 10,000 units of Gold from Gold Harmony. 277 | 278 | ```clojure 279 | (xt/submit-tx 280 | node 281 | [[::xt/match 282 | :gold-harmony 283 | {:xt/id :gold-harmony 284 | :company-name "Gold Harmony" 285 | :seller? true 286 | :buyer? false 287 | :units/Au 10211 288 | :credits 51}] 289 | [::xt/put 290 | {:xt/id :gold-harmony 291 | :company-name "Gold Harmony" 292 | :seller? true 293 | :buyer? false 294 | :units/Au 211 295 | :credits 51}] 296 | 297 | [::xt/match 298 | :encompass-trade 299 | {:xt/id :encompass-trade 300 | :company-name "Encompass Trade" 301 | :seller? true 302 | :buyer? true 303 | :units/Au 10 304 | :units/Pu 5 305 | :units/CH4 211 306 | :credits 100002}] 307 | [::xt/put 308 | {:xt/id :encompass-trade 309 | :company-name "Encompass Trade" 310 | :seller? true 311 | :buyer? true 312 | :units/Au 10010 313 | :units/Pu 5 314 | :units/CH4 211 315 | :credits 1002}]]) 316 | 317 | (xt/sync node) 318 | ``` 319 | 320 | ```clojure 321 | (format-stock-check (stock-check :gold-harmony :units/Au)) 322 | ``` 323 | 324 | ```clojure 325 | (format-stock-check (stock-check :encompass-trade :units/Au)) 326 | ``` 327 | 328 | You explain to Ubuku that this time because you have both `match` operations in the same transaction, the trade does not go through. 329 | The accounts remain the same, even though the failing `match` was the second operation. 330 | 331 | Ubuku thanks you. 332 | This is just what they are looking for. 333 | You head back to the space station to see if there is another assignment waiting for you. 334 | 335 | # Spaceport 336 | 337 | Back at the spaceship, there is a light waiting for you on your communications panel. 338 | 339 | > Well done, you’ve had a productive week. 340 | > We have one final task for you to do before you finish for the week 341 | > 342 | > You need to go to Jupiter and meet Kaarlang, it’s his last day working for us and he needs to delete his trade clients from his personal XTDB node for data protection. 343 | > 344 | > \- Helios Banking Inc. 345 | 346 | 347 | You update your manifest with your most recent badge. 348 | 349 | ```clojure 350 | (xt/submit-tx 351 | node 352 | [[::xt/put 353 | {:xt/id :manifest 354 | :pilot-name "Johanna" 355 | :id/rocket "SB002-sol" 356 | :id/employee "22910x2" 357 | :badges ["SETUP" "PUT" "DATALOG-QUERIES" "BITEMP" "MATCH"] 358 | :cargo ["stereo" "gold fish" "slippers" "secret note"]}]]) 359 | 360 | (xt/sync node) 361 | ``` 362 | 363 | As you do so, you check to see if you still have the note that the porter gave you for Kaarlang back on Earth. 364 | 365 | ```clojure 366 | (xt/q (xt/db node) 367 | '{:find [belongings] 368 | :where [[e :cargo belongings]] 369 | :in [belongings]} 370 | "secret note") 371 | ``` 372 | 373 | Feeling a bit apprehensive, you enter countdown for liftoff to Jupiter. 374 | [See you soon.](https://nextjournal.com/xtdb-tutorial/delete) 375 | 376 | ![Jupiter: Delete](https://github.com/xtdb/xtdb-tutorial/raw/main/images/5b-delete-jupiter.png) 377 | -------------------------------------------------------------------------------- /6-delete.nextjournal.md: -------------------------------------------------------------------------------- 1 | # 6: Delete with XTDB – Jupiter Assignment 2 | 3 | ![Jupiter: Delete](https://github.com/xtdb/xtdb-tutorial/raw/main/images/6a-delete-jupiter-title.png) 4 | 5 | # Introduction 6 | 7 | This is the `delete` instalment of the XTDB tutorial. 8 | 9 | ## Setup 10 | 11 | You need to get XTDB running before you can use it. 12 | 13 | 14 | ```edn no-exec 15 | {:deps 16 | {org.clojure/clojure {:mvn/version "1.11.1"} 17 | org.clojure/tools.deps.alpha {:mvn/version "0.14.1212"} 18 | com.xtdb/xtdb-core {:mvn/version "dev-SNAPSHOT"}} ;; "RELEASE" 19 | 20 | :mvn/repos 21 | {"snapshots" {:url "https://s01.oss.sonatype.org/content/repositories/snapshots"}}} 22 | ``` 23 | 24 | ```clojure 25 | (require '[xtdb.api :as xt]) 26 | ``` 27 | 28 | # Arrival on Jupiter 29 | 30 | You approach Jupiter and marvel at its bands. 31 | You wish you could have seen it this close before the Great Red Spot dissipated. 32 | 33 | As you enter the Jovian atmosphere your communications panel lights up with the now expected, but a rather terse message from boundary control. 34 | 35 | > Jupiter’s boundary is controlled. 36 | > If you wish to enter, present your papers now. 37 | > 38 | > \- Zeus Confederacy 39 | 40 | The government is asking to see your flight manifest. 41 | 42 | ## Choose your path: 43 | 44 | 45 | * **You have your manifest**: 46 | * *You have permission to land, continue to the spaceport.* 47 | 48 | 49 | * **You do not have your manifest**: 50 | * *You do not have permission to land. You can either return to [Saturn](https://nextjournal.com/xtdb-tutorial/match) or continue at your own risk.* 51 | 52 | # Spaceport 53 | 54 | It’s a turbulent ride down to the spaceport. 55 | To take your mind off the colossal storm outside, you check the XTDB manual for the `delete` operation. 56 | 57 | > Currently there are only four primitive transaction operations in XTDB: put, delete, match and evict. 58 | > 59 | >> **Transaction** **(Description)** 60 | >> 61 | >> put (Writes a version of a document) 62 | >> 63 | >> delete (Deletes a version of a document) 64 | >> 65 | >> match (Stops a transaction if the precondition is not met.) 66 | >> 67 | >> evict (Removes a document entirely) 68 | > 69 | > ## delete 70 | > Deletes a document at a given valid time. 71 | > Historical version of the document will still be available. 72 | > 73 | > The delete operation takes a valid eid with the option to include a start and end valid-time. 74 | > 75 | > The document will be deleted as of the transaction time, or beteen the start and end valid-times if provided. 76 | > Historical versions of the document that fall outside of the valid-time window will be preserved. 77 | > 78 | > A complete delete transaction has the form: 79 | > [::xt/delete eid valid-time-start valid-time-end] 80 | > 81 | > \- XTDB manual *[Read More](https://xtdb.com/reference/transactions.html#delete)* 82 | 83 | You are happy with what you have read, and in anticipation of the assignment, you define the standalone node. 84 | 85 | ```clojure 86 | (def node (xt/start-node {})) 87 | ``` 88 | 89 | # Assignment 90 | 91 | You land on the raised platform and open your job ticket 92 | 93 | ## Ticket 94 | 95 | > ### Task 96 | > *Remove assigned clients* 97 | > 98 | > ### Company 99 | > *Helios Banking Inc.* 100 | > 101 | > ### Contact 102 | > *Kaarlang* 103 | > 104 | > ### Submitted 105 | > *2115-02-10T13:38:20* 106 | > 107 | > ### Additional information: 108 | > *Help Kaarlang delete client history from his XTDB node in accordance with Earth data protection laws.* 109 | 110 | As you leave your ship, you are met by the martian Kaarlang: 111 | 112 | > Hi there, I believe you’re here to help me. 113 | > 114 | > I’ve been told I need to delete my client history with today being my last day. 115 | > 116 | > Is this something you can help me with?" 117 | > 118 | > \- Kaarlang 119 | 120 | 121 | ## Choose your path: 122 | 123 | 124 | * **"Yes, we'll work together to do this."** : 125 | * *Continue to complete the assignment.* 126 | 127 | 128 | * **"I'm not even sure how to begin"** : 129 | * *Take some time to read through the XTDB manual again. If you're still unsure then you can follow along anyway and see if things become clear.* 130 | 131 | ## Assignment 132 | 133 | Kaarlang gives you his client history so you can sync up your XTDB node. 134 | 135 | ```clojure 136 | (xt/submit-tx node 137 | [[::xt/put {:xt/id :kaarlang/clients 138 | :clients [:encompass-trade]} 139 | #inst "2110-01-01T09" 140 | #inst "2111-01-01T09"] 141 | 142 | [::xt/put {:xt/id :kaarlang/clients 143 | :clients [:encompass-trade :blue-energy]} 144 | #inst "2111-01-01T09" 145 | #inst "2113-01-01T09"] 146 | 147 | [::xt/put {:xt/id :kaarlang/clients 148 | :clients [:blue-energy]} 149 | #inst "2113-01-01T09" 150 | #inst "2114-01-01T09"] 151 | 152 | [::xt/put {:xt/id :kaarlang/clients 153 | :clients [:blue-energy :gold-harmony :tombaugh-resources]} 154 | #inst "2114-01-01T09" 155 | #inst "2115-01-01T09"]]) 156 | 157 | (xt/sync node) 158 | ``` 159 | 160 | To get a good visual aid, you show Kaarlang how to view his client history. 161 | This way you both can see when the clients are deleted. 162 | 163 | ```clojure 164 | (xt/entity-history 165 | (xt/db node #inst "2116-01-01T09") 166 | :kaarlang/clients 167 | :desc 168 | {:with-docs? true}) 169 | ``` 170 | You explain that you are using a snapshot of XTDB with a future `valid-time` to see the full history. 171 | 172 | The result shows the names of the clients that have been assigned to Kaarlang since he started at the company in 2110. 173 | 174 | Next, you delete the whole history of clients by choosing a start and end `valid-time` that spans thier entire employment time. 175 | 176 | ```clojure 177 | (xt/submit-tx 178 | node 179 | [[::xt/delete :kaarlang/clients #inst "2110-01-01" #inst "2116-01-01"]]) 180 | 181 | (xt/sync node) 182 | ``` 183 | 184 | Using the same method as before you show Kaarlang the effect that this operation has had. 185 | 186 | ```clojure 187 | (xt/entity-history 188 | (xt/db node #inst "2115-01-01T08") 189 | :kaarlang/clients 190 | :desc 191 | {:with-docs? true}) 192 | ``` 193 | 194 | You point out that there are no longer any documents attached to the transactions. 195 | 196 | However, should you ever need to retrieve the deleted documents again you can always do so, since these valid time deletions are 'soft'. 197 | 198 | ```clojure 199 | (xt/entity-history 200 | (xt/db node #inst "2115-01-01T08") 201 | :kaarlang/clients 202 | :desc 203 | {:with-docs? true 204 | :with-corrections? true}) 205 | ``` 206 | 207 | Kaarlang is impressed it is all that easy. 208 | 209 | > I am grateful that you took the time to show me this. 210 | > 211 | > Today is a sad day for me as I have very much enjoyed my time here. 212 | > 213 | > Although, I was expecting to hear from a friend before I left. 214 | > There is a very important message that I am waiting for." 215 | > 216 | > \- Kaarlang 217 | 218 | 219 | You remember the secret note in your pocket and pass it to Kaarlang. 220 | 221 | # The Secret Note. 222 | 223 | Kaarlang reads the note. 224 | 225 | He looks at you with a peculiar facial expression. 226 | 227 | > This is the note I was waiting for. 228 | > 229 | > It has information about the a top secret stellar transport shuttle. 230 | > 231 | > If you are interested in a great adventure, the shuttle comes once every hundred years or so to take a select few to a nearby star system. 232 | > The system is home to a mysterious hyper-intelligent form of life. 233 | > 234 | > I’m sure there would be a place for you if you were willing to help out. 235 | > The passengers on the shuttle have the right to be forgotten. 236 | > We need someone that can remove the passengers data from the solar system. 237 | > 238 | > What do you think?" 239 | > 240 | > \- Kaarlang 241 | 242 | 243 | ## Choose your path 244 | 245 | 246 | * **"That sounds like a great opportunity, I'm in"** 247 | * *You head off to the [secret location](https://nextjournal.com/xtdb-tutorial/evict) of the shuttle.* 248 | 249 | 250 | * **"No thanks, not for me."** 251 | * *You choose not to go with Kaarlang. You continue working for Helios Banking Inc. for the rest of your days.* 252 | 253 | ![Oumuamua: Evict](https://github.com/xtdb/xtdb-tutorial/raw/main/images/7c-evict-meteor.jpg) 254 | -------------------------------------------------------------------------------- /7-evict.nextjournal.md: -------------------------------------------------------------------------------- 1 | # 7: Evict with XTDB – The secret mission 2 | 3 | ![Oumuamua: Evict](https://github.com/xtdb/xtdb-tutorial/raw/main/images/7a-evict-meteor-title.png) 4 | 5 | # Introduction 6 | 7 | This is the `evict` instalment of the XTDB tutorial. 8 | 9 | ## Setup 10 | 11 | You need to get XTDB running before you can use it. 12 | 13 | 14 | ```edn no-exec 15 | {:deps 16 | {org.clojure/clojure {:mvn/version "1.11.1"} 17 | org.clojure/tools.deps.alpha {:mvn/version "0.14.1212"} 18 | com.xtdb/xtdb-core {:mvn/version "dev-SNAPSHOT"}} ;; "RELEASE" 19 | 20 | :mvn/repos 21 | {"snapshots" {:url "https://s01.oss.sonatype.org/content/repositories/snapshots"}}} 22 | ``` 23 | 24 | ```clojure 25 | (require '[xtdb.api :as xt]) 26 | ``` 27 | 28 | # Arrival 29 | 30 | You arrive at the comet 'Oumuamua and pull alongside, asking for permission to land. 31 | A voice comes over the communications system 32 | 33 | 34 | > How did you find us? Who sent you?? 35 | > 36 | > \- Mysterious person 37 | 38 | 39 | ## Choose your path: 40 | 41 | 42 | * **"Kaarlang sent me"** : 43 | * *You have permission to land, continue to the spaceport.* 44 | 45 | 46 | * **"I'm not sure how I got here, I found you by mistake"**: 47 | * *You are sent away. You must return to [Jupiter](https://nextjournal.com/xtdb-tutorial/delete) and find Kaarlang.* 48 | 49 | # Spaceport 50 | 51 | You land on the spaceport and are ushered inside. 52 | The ship's captain, Ilex, greets you. 53 | 54 | > Hello, it’s good to have you with us. 55 | > 56 | > We are set to leave the solar system right away and as part of our service we offer people the right to be forgotten. 57 | > Some are not worried that their information is kept here, however others want there to be no personal data left behind. 58 | > 59 | > You may not have been told this yet, but this comet is actually a transportation vessel. 60 | > It will take us to the star system Gilese 667C which is home to intelligent life far superior to our own. 61 | > We all are hoping to find opportunities beyond our wildest dreams. 62 | > All records of this transportation vessel and any life outside of the solar system are heavily monitored and wiped in the interest of preserving the normal technological advancement of the Human race. 63 | > This means we know little of the beings we are going to meet. 64 | > 65 | > Our task for you is to remove the records of the people who have chosen to be forgotten here. 66 | > 67 | > \- Ilex 68 | 69 | You are excited by the prospect and agree to help. 70 | First, you read the manual entry for `evict` as this will be the perfect tool. 71 | 72 | > Currently there are only four primitive transaction operations in XTDB: put, delete, match and evict. 73 | > 74 | >> **Transaction** **(Description)** 75 | >> 76 | >> put (Writes a version of a document) 77 | >> 78 | >> delete (Deletes a version of a document) 79 | >> 80 | >> match (Stops a transaction if the precondition is not met.) 81 | >> 82 | >> evict (Removes a document entirely) 83 | > 84 | > ## Evict 85 | > XTDB supports eviction of active and historical data to assist with technical compliance for information privacy regulations. 86 | > 87 | > The main transaction log contains only hashes and is immutable. 88 | > All document content is stored in a dedicated document log (or Key-Value store) that can be evicted by compaction. 89 | > 90 | > evict removes a document from XTDB. 91 | > The transaction history will be available, but all versions at or within the provided valid time window are evicted. 92 | > 93 | > A complete evict transaction has the form: 94 | > `[::xt/evict eid]` 95 | > 96 | > \- XTDB manual *[Read More.](https://xtdb.com/reference/transactions.html#evict)* 97 | 98 | You are happy with what you have read, and in anticipation of the assignment, you define the standalone system. 99 | 100 | ```clojure 101 | (def node (xt/start-node {})) 102 | ``` 103 | 104 | # Data Removal 105 | 106 | You are given the data for the people on the ship and sync up your XTDB node. 107 | You decide that you are going to embark on this adventure along with them so you add your name to the list. 108 | 109 | ```clojure 110 | (xt/submit-tx node 111 | [[::xt/put 112 | {:xt/id :person/kaarlang 113 | :full-name "Kaarlang" 114 | :origin-planet "Mars" 115 | :identity-tag :KA01299242093 116 | :DOB #inst "2040-11-23"}] 117 | 118 | [::xt/put 119 | {:xt/id :person/ilex 120 | :full-name "Ilex Jefferson" 121 | :origin-planet "Venus" 122 | :identity-tag :IJ01222212454 123 | :DOB #inst "2061-02-17"}] 124 | 125 | [::xt/put 126 | {:xt/id :person/thadd 127 | :full-name "Thad Christover" 128 | :origin-moon "Titan" 129 | :identity-tag :IJ01222212454 130 | :DOB #inst "2101-01-01"}] 131 | 132 | [::xt/put 133 | {:xt/id :person/johanna 134 | :full-name "Johanna" 135 | :origin-planet "Earth" 136 | :identity-tag :JA012992129120 137 | :DOB #inst "2090-12-07"}]]) 138 | 139 | (xt/sync node) 140 | ``` 141 | 142 | Before you start the eviction process you make a query function so you can see the full results of anything stored in XTDB: 143 | 144 | ```clojure 145 | (defn full-query 146 | [node] 147 | (xt/q 148 | (xt/db node) 149 | '{:find [(pull e [*])] 150 | :where [[e :xt/id id]]})) 151 | ``` 152 | 153 | You show the others the result: 154 | 155 | ```clojure 156 | (full-query node) 157 | ``` 158 | 159 | The XTDB manual said that the `evict` operation will remove a document entirely. 160 | Ilex tells you the only person who wishes to exercise their right to be forgotten is Kaarlang. 161 | 162 | ```clojure 163 | (xt/submit-tx node [[::xt/evict :person/kaarlang]]) 164 | 165 | (xt/sync node) 166 | ``` 167 | 168 | You use your function and see that the transaction was a success. 169 | 170 | ```clojure 171 | (full-query node) 172 | ``` 173 | 174 | All the data associated with the specified `:xt/id` has been removed from the XTDB along with the eid itself. 175 | 176 | The transaction history is immutable. 177 | This means the transactions will never be removed. 178 | You assure Ilex that the documents are completely removed from XTDB, you can show this by looking at the `entity-history` information for each person. 179 | 180 | ```clojure 181 | (xt/entity-history (xt/db node) 182 | :person/kaarlang 183 | :desc 184 | {:with-docs? true}) 185 | ``` 186 | 187 | You show the results to Kaarlang who is happy that there his details are no longer a part of the ships logs. 188 | 189 | # Departure 190 | 191 | The ship starts to shake as the engines are fired up. 192 | 193 | Ilex thanks you and takes you to the Cryogenics department. 194 | You must be put into stasis as the journey will take around 25 years, even at the near-light speeds of the ship. 195 | 196 | You are astonished by the amount that you have done in one short week. 197 | How did little old you end up with an opportunity as big as this? 198 | 199 | Your eyes get heavy as the cryogenicist initiates the hibernation process. 200 | As they do, you wonder if you’ll ever come back to the solar system. 201 | 202 | ![ice.jpg](https://github.com/xtdb/xtdb-tutorial/raw/main/images/7b-evict-ice.jpg) 203 | 204 | # This is not The End 205 | 206 | I hope you enjoyed learning about the basics of XTDB. 207 | Although this is the final instalment for the main tutorial series it is not the end of the XTDB tutorial. 208 | There is one last bonus mission to complete: learning to `await` transactions on [Kepra-5](https://nextjournal.com/xtdb-tutorial/await). 209 | 210 | ![Kepra 5: Await](https://github.com/xtdb/xtdb-tutorial/raw/main/images/7b-await-kepra5.png) 211 | -------------------------------------------------------------------------------- /8-await-transactions.nextjournal.md: -------------------------------------------------------------------------------- 1 | # 8: Await with XTDB - Kepra-5 Assignment 2 | 3 | ![Kepra-5: Await](https://github.com/xtdb/xtdb-tutorial/raw/main/images/8a-await-kepra5-title.png) 4 | 5 | # Introduction 6 | 7 | This is the `await-tx` instalment of the XTDB tutorial. 8 | 9 | ## Setup 10 | 11 | You need to get XTDB running before you can use it. 12 | 13 | 14 | ```edn no-exec 15 | {:deps 16 | {org.clojure/clojure {:mvn/version "1.11.1"} 17 | org.clojure/tools.deps.alpha {:mvn/version "0.14.1212"} 18 | com.xtdb/xtdb-core {:mvn/version "dev-SNAPSHOT"}} ;; "RELEASE" 19 | 20 | :mvn/repos 21 | {"snapshots" {:url "https://s01.oss.sonatype.org/content/repositories/snapshots"}}} 22 | ``` 23 | 24 | ```clojure 25 | (require '[xtdb.api :as xt]) 26 | ``` 27 | 28 | # Recap 29 | 30 | Last time you opted to leave the solar system on the secret spaceship 'Oumuamua on an exciting new adventure. 31 | You have been travelling for 25 years at near light speed to reach the star system Gilese 667C. 32 | This star system is home to intelligent life far superior to our own. 33 | With you on the ship is the captain, Ilex, and your new friend Kaarlang. 34 | You were put into cryostasis so you could safely withstand the long journey. 35 | 36 | **We begin again in the year 2140.** 37 | 38 | # Awakening 39 | 40 | You open your eyes after what feels like only a moment, your 25-year slumber broken by a loud hiss from the opening of the cryogenic pod door. 41 | You take a minute to acknowledge the cold surroundings. You realize the ship engines have fallen still and assume that you are now in geostationary orbit. 42 | 43 | Captain Ilex's voice comes over the intercom. 44 | 45 | > Good morning passengers. 46 | > And hello new world. 47 | > We've reached the planet Kepra-5 of the Gilese 667C star system. 48 | > 49 | > If you could make your way to the [space elevator](https://en.wikipedia.org/wiki/Space_elevator) which is waiting to take you to the planet surface, where you will need to go through customs and get a new passport. 50 | > 51 | > We would like to wish you all the best in your future travels." 52 | > 53 | > \- Ilex 54 | 55 | Finding your way to the space elevator dock, you notice that you feel a lot heavier than usual. 56 | You wonder if this is your body being weaker than usual from being in cryostasis for so long, or if this new planet has stronger gravity. 57 | 58 | ## Choose your path: 59 | 60 | 61 | * **You want to test this, and are interested to know how the gravity of the planet below compares to planets back in your home solar system:** 62 | * *You see it as a good opportunity to refresh yourself with ingestion and queries.* 63 | 64 | 65 | * **You think about testing this, but you're in a rush and want to get your passport as fast as possible:** 66 | * *Head over to passport control.* 67 | 68 | # Gravity comparison 69 | 70 | You spin up a new XTDB node and ingest the known data from the solar system. 71 | 72 | ```clojure 73 | (def node (xt/start-node {})) 74 | ``` 75 | 76 | ```clojure 77 | (def stats 78 | [{:body "Sun" 79 | :type "Star" 80 | :units {:radius "Earth Radius" 81 | :volume "Earth Volume" 82 | :mass "Earth Mass" 83 | :gravity "Standard gravity (g)"} 84 | :radius 109.3 85 | :volume 1305700 86 | :mass 33000 87 | :gravity 27.9 88 | :xt/id :Sun} 89 | {:body "Jupiter" 90 | :type "Gas Giant" 91 | :units {:radius "Earth Radius" 92 | :volume "Earth Volume" 93 | :mass "Earth Mass" 94 | :gravity "Standard gravity (g)"} 95 | :radius 10.97 96 | :volume 1321 97 | :mass 317.83 98 | :gravity 2.52 99 | :xt/id :Jupiter} 100 | {:body "Saturn" 101 | :type "Gas Giant" 102 | :units {:radius "Earth Radius" 103 | :volume "Earth Volume" 104 | :mass "Earth Mass" 105 | :gravity "Standard gravity (g)"} 106 | :radius :volume 107 | :mass :gravity 108 | :xt/id :Saturn} 109 | {:body "Saturn" 110 | :units {:radius "Earth Radius" 111 | :volume "Earth Volume" 112 | :mass "Earth Mass" 113 | :gravity "Standard gravity (g)"} 114 | :radius 9.14 115 | :volume 764 116 | :mass 95.162 117 | :gravity 1.065 118 | :type "planet" 119 | :xt/id :Saturn} 120 | {:body "Uranus" 121 | :units {:radius "Earth Radius" 122 | :volume "Earth Volume" 123 | :mass "Earth Mass" 124 | :gravity "Standard gravity (g)"} 125 | :radius 3.981 126 | :volume 63.1 127 | :mass 14.536 128 | :gravity 0.886 129 | :type "planet" 130 | :xt/id :Uranus} 131 | {:body "Neptune" 132 | :units {:radius "Earth Radius" 133 | :volume "Earth Volume" 134 | :mass "Earth Mass" 135 | :gravity "Standard gravity (g)"} 136 | :radius 3.865 137 | :volume 57.7 138 | :mass 17.147 139 | :gravity 1.137 140 | :type "planet" 141 | :xt/id :Neptune} 142 | {:body "Earth" 143 | :units {:radius "Earth Radius" 144 | :volume "Earth Volume" 145 | :mass "Earth Mass" 146 | :gravity "Standard gravity (g)"} 147 | :radius 1 148 | :volume 1 149 | :mass 1 150 | :gravity 1 151 | :type "planet" 152 | :xt/id :Earth} 153 | {:body "Venus" 154 | :units {:radius "Earth Radius" 155 | :volume "Earth Volume" 156 | :mass "Earth Mass" 157 | :gravity "Standard gravity (g)"} 158 | :radius 0.9499 159 | :volume 0.857 160 | :mass 0.815 161 | :gravity 0.905 162 | :type "planet" 163 | :xt/id :Venus} 164 | {:body "Mars" 165 | :units {:radius "Earth Radius" 166 | :volume "Earth Volume" 167 | :mass "Earth Mass" 168 | :gravity "Standard gravity (g)"} 169 | :radius 0.532 170 | :volume 0.151 171 | :mass 0.107 172 | :gravity 0.379 173 | :type "planet" 174 | :xt/id :Mars} 175 | {:body "Ganymede" 176 | :units {:radius "Earth Radius" 177 | :volume "Earth Volume" 178 | :mass "Earth Mass" 179 | :gravity "Standard gravity (g)"} 180 | :radius 0.4135 181 | :volume 0.0704 182 | :mass 0.0248 183 | :gravity 0.146 184 | :type "moon" 185 | :xt/id :Ganymede} 186 | {:body "Titan" 187 | :units {:radius "Earth Radius" 188 | :volume "Earth Volume" 189 | :mass "Earth Mass" 190 | :gravity "Standard gravity (g)"} 191 | :radius 0.4037 192 | :volume 0.0658 193 | :mass 0.0225 194 | :gravity 0.138 195 | :type "moon" 196 | :xt/id :Titan} 197 | {:body "Mercury" 198 | :units {:radius "Earth Radius" 199 | :volume "Earth Volume" 200 | :mass "Earth Mass" 201 | :gravity "Standard gravity (g)"} 202 | :radius 0.3829 203 | :volume 0.0562 204 | :mass 0.0553 205 | :gravity 0.377 206 | :type "planet" 207 | :xt/id :Mercury}]) 208 | 209 | (xt/submit-tx node (mapv (fn [stat] [::xt/put stat]) stats)) 210 | 211 | (xt/sync node) 212 | ``` 213 | 214 | The elevator arrives and you drag yourself aboard. 215 | As you are carried to the surface, you note the relief as the force of gravity on your body is cancelled by the movement of the lift. 216 | 217 | As soon as you reach the surface, you waste no time in taking the gravity reading from your iPhone CM. 218 | The reading is 1.4g - no wonder you feel sluggish. 219 | 220 | You want to check against the data of the other planets on your node, to see how the gravity from this planet compares, so you write a function to add the new planetary data and query it against the other planets: 221 | 222 | ```clojure 223 | (xt/submit-tx 224 | node 225 | [[::xt/put 226 | {:body "Kepra-5" 227 | :units {:radius "Earth Radius" 228 | :volume "Earth Volume" 229 | :mass "Earth Mass" 230 | :gravity "Standard gravity (g)"} 231 | :radius 0.6729 232 | :volume 0.4562 233 | :mass 0.5653 234 | :gravity 1.4 235 | :type "planet" 236 | :xt/id :Kepra-5}]]) 237 | 238 | (xt/sync node) 239 | 240 | (sort 241 | (xt/q 242 | (xt/db node) 243 | '{:find [g planet] 244 | :where [[planet :gravity g]]})) 245 | ``` 246 | 247 | Nice, you see that Kepra-5 has gravitational forces stronger than Neptune but weaker than Jupiter. 248 | 249 | Now you’ve satisfied your curiosity, you head over to passport control. 250 | 251 | # Passport Control 252 | 253 | You find yourself at passport control where you are told your XTDB experience is needed. 254 | 255 | Kaarlang has arrived there first and has been chatting to the manager here. 256 | As an advanced civilization, they are quite happily using XTDB with no issues but still have a problem with human error. 257 | Some employees have been handing out passports before putting the traveller's information into XTDB. 258 | When it gets particularly busy, it’s not uncommon for the employees to forget to go back and put the data in, resulting in unregistered travellers. 259 | 260 | Kaarlang has told the manager that you have a background in solving problems using XTDB, so has offered them your skills. 261 | 262 | Your task is to make a function that ensures no passport is given before the traveller's data is successfully ingested into XTDB. 263 | 264 | ```clojure 265 | (defn ingest-and-query 266 | [traveller-doc] 267 | (xt/submit-tx node [[::xt/put traveller-doc]]) 268 | (xt/q 269 | (xt/db node) 270 | '{:find [n] 271 | :where [[id :passport-number n]] 272 | :in [id]} 273 | (:xt/id traveller-doc))) 274 | ``` 275 | 276 | You test out your function. 277 | 278 | ```clojure 279 | (ingest-and-query 280 | {:xt/id :origin-planet/test-traveller 281 | :chosen-name "Test" 282 | :given-name "Test Traveller" 283 | :passport-number (java.util.UUID/randomUUID) 284 | :stamps [] 285 | :penalties []}) 286 | ``` 287 | 288 | This strikes you as peculiar - you received no errors from your XTDB node upon submitting, but the ingested traveller doc has not returned a passport number. 289 | 290 | You are sure your query and ingest syntax is correct, but to check you try running the query again. 291 | This time you get the expected result: 292 | 293 | ```clojure 294 | (ingest-and-query 295 | {:xt/id :origin-planet/test-traveller 296 | :chosen-name "Test" 297 | :given-name "Test Traveller" 298 | :passport-number (java.util.UUID/randomUUID) 299 | :stamps [] 300 | :penalties []}) 301 | ``` 302 | 303 | **The plot thickens.** 304 | 305 | Confused, you open your trusty XTDB manual, skimming through until you hit the page on `await-tx`: 306 | 307 | > Blocks until the node has indexed a transaction that is at or past the supplied tx. 308 | > Will throw on timeout. 309 | > Returns the most recent tx indexed by the node. 310 | > 311 | > \- XTDB manual *[Read More](https://xtdb.com/reference/transactions.html#await)* 312 | 313 | Of course. 314 | Submit operations in XTDB are **asynchronous** - your query did not return the new data as it had not yet been indexed into XTDB. 315 | You decide to rewrite your function using `await-tx`: 316 | 317 | ```clojure 318 | (defn ingest-and-query 319 | "Ingests the given traveller's document into XTDB, returns the passport 320 | number once the transaction is complete." 321 | [traveller-doc] 322 | (xt/await-tx node 323 | (xt/submit-tx node [[::xt/put traveller-doc]])) 324 | (xt/q 325 | (xt/db node) 326 | '{:find [n] 327 | :where [[id :passport-number n]] 328 | :in [id]} 329 | (:xt/id traveller-doc))) 330 | ``` 331 | 332 | You run the function again, Changing the traveller-doc so you can see if it’s worked. 333 | This time you receive the following: 334 | 335 | ```clojure 336 | (ingest-and-query 337 | {:xt/id :origin-planet/new-test-traveller 338 | :chosen-name "Testy" 339 | :given-name "Test Traveller" 340 | :passport-number (java.util.UUID/randomUUID) 341 | :stamps [] 342 | :penalties []}) 343 | ``` 344 | 345 | > ## Caution 346 | > 347 | > *XTDB is fundamentally asynchronous: you submit a transaction to the central transaction log - then, later, each individual XTDB node reads the transaction from the log and indexes it. 348 | > If you submit a transaction and then run a query without explicitly waiting for the node to have indexed the transaction - either via `sync` or `await-tx` - you’re not guaranteed that your query will reflect your recent transaction. 349 | > On a small use-case, you might get lucky - but, if you want to reliably read your writes, use `await-tx`. 350 | > If you’re ingesting a large batch of data though, calling `await-tx` after every transaction will slow the process significantly - you only need to await the final transaction to know that all of the preceding transactions are available.* 351 | 352 | You show this to the manager at the passport control office. 353 | They are happy that this will work. 354 | 355 | > Thank you, this will save us so much time in dealing with missing traveller information. 356 | > As a token of our gratitude, we would like to grant you with free entry to the planet. 357 | 358 | You graciously accept. 359 | For the passport, you must provide your origin planet, name and also a chosen name. 360 | Many people come to Kepra-5 to start fresh, so your chosen name can be anything you wish. 361 | 362 | Once chosen you can not easily change it, so you think carefully. 363 | 364 | ```clojure 365 | (ingest-and-query 366 | {:xt/id :earth/ioelena 367 | :chosen-name "Ioelena" 368 | :given-name "Johanna" 369 | :passport-number (java.util.UUID/randomUUID) 370 | :stamps [] 371 | :penalties []}) 372 | ``` 373 | 374 | New name, new you. 375 | 376 | Now that you are in the Gilese 667C you must keep your passport up to date wherever you travel. 377 | You take a note of your passport number and put it somewhere safe. 378 | 379 | Through customs, you are now free to explore the exciting new planet. 380 | Taking in your surroundings, you see a hostel nearby. 381 | You head over. 382 | Although you’ve been in cryostasis for such a long time, the new gravity has made you very tired. 383 | 384 | # THE END. 385 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 JUXT 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # XTDB Tutorial 2 | 3 | Official XTDB "Space Adventure" tutorial 4 | 5 | ## Quickstart 6 | 7 | * Read the tutorial: https://nextjournal.com/xtdb-tutorial/ 8 | * Try online: 9 | 1. https://nextjournal.com/try/xtdb-tutorial/start 10 | 2. https://nextjournal.com/try/xtdb-tutorial/put 11 | 3. https://nextjournal.com/try/xtdb-tutorial/datalog 12 | 4. https://nextjournal.com/try/xtdb-tutorial/bitemporality 13 | 5. https://nextjournal.com/try/xtdb-tutorial/match 14 | 6. https://nextjournal.com/try/xtdb-tutorial/delete 15 | 7. https://nextjournal.com/try/xtdb-tutorial/evict 16 | 8. https://nextjournal.com/try/xtdb-tutorial/await 17 | 18 | ## Install Tutorial on Nextjournal 19 | 20 | The Quickstart is the easiest way to run the tutorial and you can use the Nextjournal 21 | "Remix" feature to bring the tutorial into your own Nextjournal Clojure notebooks if you 22 | like. However, you can import the Markdown files in this repository directly, if you would 23 | prefer. 24 | 25 | 1. Create a new account on [Nextjournal](https://nextjournal.com). 26 | 1. Click "+ NEW" to create a new notebook on the [Nextjournal Dashboard](https://nextjournal.com/dashboard). 27 | 1. At the bottom of the page, choose "Import from a URL (e.g. GitHub)" and paste in the link to the file in GitHub (e.g. `https://github.com/xtdb/xtdb-tutorial/blob/main/1-getting-started.nextjournal.md`) 28 | 1. You do not need to name the `deps.edn` block -- the metadata names it for you. 29 | 30 | You can now run the tutorial notebook. 31 | 32 | ## Reinstallation (for maintainers) 33 | 34 | To reinstall the tutorial: Treat this GitHub repository as the golden store. Make edits to the Markdown file in 35 | GitHub, then reimport the notebooks using the following instructions. 36 | 37 | 1. Log in as the `xtdb-tutorial` Nextjournal user (ask @deobald or @refset for creds, stored via `pass` `juxt.xtdb.ops/password-store` on Keybase) 38 | 2. Go to the [Nextjournal Dashboard](https://nextjournal.com/dashboard) and open notebook you want to edit. 39 | 3. Click anywhere in the document, select all (ctrl+a) and delete the contents. 40 | 4. At the bottom of the page, choose "Import from a URL (e.g. GitHub)" and paste in the link to the file in GitHub (e.g. `https://github.com/xtdb/xtdb-tutorial/blob/main/1-getting-started.nextjournal.md`) 41 | 5. Scroll to the bottom of the page and expand the Appendix. Pull from the repo to ensure the changes are brought in 42 | 6. Click "Run All" under the Play icon to evaluate all snippets 43 | 7. Select "Publish Changes" in the share dialog 44 | 8. Check to make sure the public URLs in the `"Quickstart"` work correctly. 45 | 9. If the lessons seem out-of-order, it is because they are listed reverse-chronologically. Whatever lesson you edited, publish lessons _backward_ from that point. For example, if you edited Lesson 4, you must publish #3, #2, and finally #1 (Note if you haven't edited a lesson, you only need to re-publish the old notebook without following the import steps). 46 | 47 | TIPS: Publish last (e.g. Tutorial #8) to first so that the notebook listing is always in the correct order, i.e. import/edit backwards from the last notebook. If necessary add a non-obvious space to the end of a paragraph so that you can re-publish an otherwise unchanged notebook. Open tutorials in multiple tabs so that you can process them more efficiently in a pipelined fashion while waiting for "Run All" commands. 48 | 49 | ## Copyright & License 50 | 51 | The MIT License (MIT) 52 | 53 | Copyright © 2019-2021 JUXT LTD. 54 | 55 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 56 | 57 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 58 | 59 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 60 | -------------------------------------------------------------------------------- /deps.edn: -------------------------------------------------------------------------------- 1 | {:deps 2 | {org.clojure/clojure {:mvn/version "1.11.1"} 3 | org.clojure/tools.deps.alpha {:mvn/version "0.14.1212"} 4 | com.xtdb/xtdb-core {:mvn/version "dev-SNAPSHOT"}} ;; "RELEASE" 5 | 6 | :mvn/repos 7 | {"snapshots" {:url "https://s01.oss.sonatype.org/content/repositories/snapshots"}}} 8 | -------------------------------------------------------------------------------- /images-src/1a-start-earth-title.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:dafc44a13412fed84be2baf03ee8a34728107241102b3d7ca08709296db99427 3 | size 1083812 4 | -------------------------------------------------------------------------------- /images-src/1a-start-earth-title.svg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:fd41c6bd19f86f08371021cad40970c0204a28a7aa7286f72578701ae2cb6c88 3 | size 6378706 4 | -------------------------------------------------------------------------------- /images-src/2a-put-tx-pluto-title.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:38c701d353f0fceff7cf4ead20dfddd2ea591309e9a1b62b816b0fac5b5926a4 3 | size 805541 4 | -------------------------------------------------------------------------------- /images-src/2a-put-tx-pluto-title.svg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:1acc3bf0a0b14a474826ad76502ff6c9d4b5c8e7f716842ecd63cb6af3a9255c 3 | size 1694010 4 | -------------------------------------------------------------------------------- /images-src/3a-datalog-queries-mercury-title.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:965cf3811e23637e7c60284f4d5777489541fc9f363362e9b7f3defee8d61078 3 | size 913049 4 | -------------------------------------------------------------------------------- /images-src/3a-datalog-queries-mercury-title.svg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:d5a0b36b11ab256f505cef93eb9d7b5537dd0e5b22af54fe3b9b472d7a511817 3 | size 1436106 4 | -------------------------------------------------------------------------------- /images-src/4a-bitemporality-neptune-title.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:4f2eb895ae47857f4e20a23faef6d426fb08dd948657d7d5391b83ff1d9f048d 3 | size 724890 4 | -------------------------------------------------------------------------------- /images-src/4a-bitemporality-neptune-title.svg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:dcf271114ec926e454ec84c1b3e1e9268384a7136859bf382feba760f4272cb1 3 | size 931509 4 | -------------------------------------------------------------------------------- /images-src/5a-match-saturn-title.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:aa997ecef9cc7c03a034519f7c48708e98a1b459fe6689ea6af65b11282de80f 3 | size 794137 4 | -------------------------------------------------------------------------------- /images-src/5a-match-saturn-title.svg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:5b5a198179eae7428c3d4c5604acfcac5cd8407a50e6ea1c13cda64ad44232e2 3 | size 986776 4 | -------------------------------------------------------------------------------- /images-src/6a-delete-jupiter-title.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:3ea7dda985387dda57a908721e39e3486d13c7ce0e7460becacd1348fcced529 3 | size 923382 4 | -------------------------------------------------------------------------------- /images-src/6a-delete-jupiter-title.svg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:dd1f63c3f59d9cbbb3e809c6eb478192bbc2454e209533f09ebdc7c5d4e4d910 3 | size 1503561 4 | -------------------------------------------------------------------------------- /images-src/7a-evict-meteor-title.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:69f0bdbbcc3b9f480ca81e6f4b83e32e6ef36b9691121ba8fce259370d02378a 3 | size 765353 4 | -------------------------------------------------------------------------------- /images-src/7a-evict-meteor-title.svg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:a9c23c7ff19f4c9ca69f27d99d9926c183482ddec42df17ee920d343eb1f8767 3 | size 1277022 4 | -------------------------------------------------------------------------------- /images-src/8a-await-kepra5-title.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:9a8e17fa2c920f03c9ee9fb0c9dc6baa563435fb544b6a598d51122a62c91ce6 3 | size 933791 4 | -------------------------------------------------------------------------------- /images-src/8a-await-kepra5-title.svg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:97cc22d1b53af7b05cd9a9f5d6dfcb5cc114c63a6fd5a67c9dbf85b0971fc661 3 | size 1711482 4 | -------------------------------------------------------------------------------- /images-src/Earth_Eastern_Hemisphere.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:3b47b77b49ccd18ecf0aa58610a2047cc68a2e06a1de2e224295a1346aa2dc95 3 | size 536295 4 | -------------------------------------------------------------------------------- /images-src/space-background-square.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:b58aee354ac4b994180b6e3167cb7d8841e00feb3c2652a42e4bb696adeff003 3 | size 558991 4 | -------------------------------------------------------------------------------- /images-src/space-background.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:ec5190ae459c0ed3ca211f474ea1a20b639cb82b29213b7b9a3fdd0f9985a86e 3 | size 128947 4 | -------------------------------------------------------------------------------- /images-src/xtdb-cube-raster.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:9a17a56c878c4d6fb656ba33acf355b0c77130b8517bc44d90867958bc4c15e5 3 | size 223581 4 | -------------------------------------------------------------------------------- /images-src/xtdb-logo-raster.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:c2513f17994ac0daa8ef2f63eb7ecf00c29f6cbb8d616065eac711c1879b3cfe 3 | size 269653 4 | -------------------------------------------------------------------------------- /images-src/xtdb-text-raster-inverted.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:cf48476d3eb4fb156ca62c5a00905c5ee7f4ee6f92adc8c2ab995fd865e707c5 3 | size 25572 4 | -------------------------------------------------------------------------------- /images-src/xtdb-text-raster-inverted.xcf: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:6bdf457392f7473148a1478b65af239f2dbdae9d82a64496f81882d3c9794cef 3 | size 42053 4 | -------------------------------------------------------------------------------- /images-src/xtdb-text-raster.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:e5ed06622fa895e9e822e87eafc387f49416532920aa13fd465b9cba4a5f94d8 3 | size 27999 4 | -------------------------------------------------------------------------------- /images/1a-start-earth-title-OLD.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:1f3cc74d05c125b0253b7935837a36c6aacfe6943a95a1736c9bae07878ad25c 3 | size 565912 4 | -------------------------------------------------------------------------------- /images/1a-start-earth-title.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:dafc44a13412fed84be2baf03ee8a34728107241102b3d7ca08709296db99427 3 | size 1083812 4 | -------------------------------------------------------------------------------- /images/1b-put-tx-pluto.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:01ac60d26ecdb5ee03a800526ed49e200b294a6fb1a66820e99210814137a4e0 3 | size 632798 4 | -------------------------------------------------------------------------------- /images/2a-put-tx-pluto-title-OLD.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:2ff52860d36826cc38a308e14c4d00c0510212554729c6b71fbbd31b0dde4c4f 3 | size 444807 4 | -------------------------------------------------------------------------------- /images/2a-put-tx-pluto-title.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:38c701d353f0fceff7cf4ead20dfddd2ea591309e9a1b62b816b0fac5b5926a4 3 | size 805541 4 | -------------------------------------------------------------------------------- /images/2b-datalog-mercury.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:69667bd3ddb9af69136823fc2c8835c2941b4d5fb088b059f707e5e6ea6de2f0 3 | size 367481 4 | -------------------------------------------------------------------------------- /images/3a-datalog-queries-mercury-title.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:965cf3811e23637e7c60284f4d5777489541fc9f363362e9b7f3defee8d61078 3 | size 913049 4 | -------------------------------------------------------------------------------- /images/3b-bitemporality-neptune.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:ba4a8394dd2645c70f14a270c4d7b38904475605f4ec24a123defffe1ee72b6b 3 | size 72784 4 | -------------------------------------------------------------------------------- /images/4a-bitemporality-neptune-title.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:4f2eb895ae47857f4e20a23faef6d426fb08dd948657d7d5391b83ff1d9f048d 3 | size 724890 4 | -------------------------------------------------------------------------------- /images/4b-match-saturn.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:0e1be0c20387b0639a8a13fc2994e60db6c346be01ae6060fb4f6e4def0bb4c4 3 | size 128713 4 | -------------------------------------------------------------------------------- /images/5a-match-saturn-title.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:aa997ecef9cc7c03a034519f7c48708e98a1b459fe6689ea6af65b11282de80f 3 | size 794137 4 | -------------------------------------------------------------------------------- /images/5b-delete-jupiter.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:2802b30fe40d88d6c7503fc3a1533509ba1fcce10c68ea971add7e66335600be 3 | size 554914 4 | -------------------------------------------------------------------------------- /images/6a-delete-jupiter-title.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:3ea7dda985387dda57a908721e39e3486d13c7ce0e7460becacd1348fcced529 3 | size 923382 4 | -------------------------------------------------------------------------------- /images/6b-evict-meteor.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:3dcb0c7652f3d8c82ebb1f5c988cdd8ab81461e8ed58401a161e3270e17d39f6 3 | size 366233 4 | -------------------------------------------------------------------------------- /images/7a-evict-meteor-title.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:69f0bdbbcc3b9f480ca81e6f4b83e32e6ef36b9691121ba8fce259370d02378a 3 | size 765353 4 | -------------------------------------------------------------------------------- /images/7b-await-kepra5.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:e1329c53906b1c96da2278fdb0764e202e95b9e5d119a1d41c9279e58d72c8d2 3 | size 740119 4 | -------------------------------------------------------------------------------- /images/7b-evict-ice.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:c8f1ae7b05127d8a7766f50373ff897afd6bcfcacdfa49fab2697ed8801ba1e0 3 | size 972958 4 | -------------------------------------------------------------------------------- /images/7c-evict-meteor.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:8c51707a49180ad7498ac54b041ef056d673ab1e958b3122a1ee166aa44a15dd 3 | size 434560 4 | -------------------------------------------------------------------------------- /images/8a-await-kepra5-title.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:9a8e17fa2c920f03c9ee9fb0c9dc6baa563435fb544b6a598d51122a62c91ce6 3 | size 933791 4 | --------------------------------------------------------------------------------