 
 ;; ## Protocol Implementation
 
+(defn- table-link
+  "Build a link to a clean table node."
+  [table-name table]
+  (link/create
+    (str "table:" table-name)
+    (::node/id table)
+    (::data/size table)))
+
+
 (defn- -list-tables
   [^Database db opts]
   (cond->> (map link-or-table->info (.tables db))

    (._meta db)))


(defn- -flush!
  [^Database db]
  (let [tables (reduce-kv
                 (fn [acc table-name value]
                   (assoc
                     acc table-name
                     (if (link/merkle-link? value)
                       value
                       (let [table (table/flush! value false)]
                         (link/create
                           (str "table:" table-name)
                           (::node/id table)
                           (::data/size table))))))
                 {} (.tables db))
        node (mdag/store-node!
               (.store db)
               nil
               (assoc (.root-data db)
                      :data/type data-type
                      ::tables tables))]
    (->Database
      (.store db)
      (assoc (.db-info db)
             ::node/id (::node/id node)
             ::data/size (node/reachable-size node))
      (dissoc (::node/data node) ::tables)
      tables
      (assoc (._meta db)
             ::node/links (::node/links node)))))


(extend-type Database

    (if (link/merkle-link? value)
      ; Resolve link to stored table root.
      (table/load-table (.store db) table-name value)
      ; Loaded table value.
      value)))


(defn- -set-table
  [^Database db table-name value]
  (let [table (if (table/dirty? value)
                (table/set-backing value (.store db) table-name)
                (table-link table-name value))]
    (->Database
      (.store db)
      (.db-info db)
