Fork me on GitHub
Steven Deobald12:09:40

I realize this isn't crux-specific but I searched the channels for "web" and got a dozen different frameworks back as a result. If the Pariyatti app has very little sexy front-end things to it (no websockets, crazy JS, or any of that nonesense) would you folks have any recommendations for a small set of libraries (or a framework) to lean on so that we can focus on the database? To put things in perspective: The web app is likely to have 2 - 4 users to start with and unlikely to have more than a dozen in the coming decade or two. It's not an admin console... but it's close.


I reckon if you ask 5 Clojure devs you'd get 5 different answers to that one 🙂


for me - Integrant, Ring/Ring Jetty, Reitit (and surrounding libraries) will probably get you 90% of the way there, but I'm probably more towards the wiring-things-up-myself end, not to mention maybe a little out-of-date with the absolute latest and greatest 🙂


we're due to revamp it though

Steven Deobald14:09:18

@U050V1N74 I'm pretty comfortable with slow, stable libraries... it's a 100% volunteer project so choosing a bleeding edge database is probably all the "latest and greatest" I need in the codebase, to be honest. 😉

Steven Deobald12:09:58

(Pointers to other channels appreciated as well.)


If you do end up using JUXT libs, Q&A can happen in #juxt

Steven Deobald14:09:44

@jonpither I'd be pretty happy to have a single corporation in a compatible timezone to send my complaints and patches. 😉 Can a person get a web app off the ground these days entirely on juxt libs?


hmm. let's just say it's possible 😉

Laszlo Szolnoki21:09:24

Hi, I'm new to Clojure and totally new to Crux. Could you please advise what am I doing wrong here:


(defproject crux-test "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url ""
  :license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"
            :url ""}
  :dependencies [[org.clojure/clojure "1.10.1"]
                 [juxt/crux-core "RELEASE"]
                 [juxt/crux-jdbc "RELEASE"]
                 [seancorfield/next.jdbc "1.1.582"]
                 [org.clojure/ "1.0.86"]
                 [com.zaxxer/HikariCP "3.4.5"]
                 [com.taoensso/nippy "2.15.1"]
                 [org.postgresql/postgresql "42.2.16.jre7"]
                 [com.h2database/h2 "1.4.200" :scope "provided"]
  :main ^:skip-aot crux-test.core
  :target-path "target/%s"
  :profiles {:uberjar {:aot :all
                       :jvm-opts [""]}}) 
(ns crux-test.core
  (:require [crux.api :as crux]
            [next.jdbc :as jdbc]
            [next.jdbc.result-set :as jdbcr]
            [ :as log]

(def db-spec { :classname   "org.h2.Driver"
               :subprotocol "h2:file"
               :subname     (str (System/getProperty "user.dir") "/" "crux-test")
               :user        "lszolnok"
               :password    "******"})

(def module-tree { :crux.node/topology 'crux.jdbc/topology
                   :crux.jdbc/connection-pool {:dialect {:crux/module 'crux.jdbc.h2/->dialect}
                            ;; :pool-opts { ... }
                                                        :db-spec db-spec}
                             :crux/tx-log {:crux/module 'crux.jdbc/->tx-log
                                           :connection-pool :crux.jdbc/connection-pool}
                             :crux/document-store {:crux/module 'crux.jdbc/->document-store
                                                   :connection-pool :crux.jdbc/connection-pool}})

(crux/start-node module-tree)
Error msg:
2. Unhandled clojure.lang.Compiler$CompilerException
   Error compiling crux/jdbc.clj at (1:1)
   #:clojure.error{:phase :compile-syntax-check,
                   :line 1,
                   :column 1,
                   :source "crux/jdbc.clj"}
    7648  clojure.lang.Compiler/load
           381  clojure.lang.RT/loadResourceScript
           372  clojure.lang.RT/loadResourceScript
           459  clojure.lang.RT/load
           424  clojure.lang.RT/load
                  core.clj: 6126  clojure.core/load/fn
                  core.clj: 6125  clojure.core/load
                  core.clj: 6109  clojure.core/load
       408  clojure.lang.RestFn/invoke
                  core.clj: 5908  clojure.core/load-one
                  core.clj: 5903  clojure.core/load-one
                  core.clj: 5948  clojure.core/load-lib/fn
                  core.clj: 5947  clojure.core/load-lib
                  core.clj: 5928  clojure.core/load-lib
       142  clojure.lang.RestFn/applyTo
                  core.clj:  667  clojure.core/apply
                  core.clj: 5985  clojure.core/load-libs
                  core.clj: 5969  clojure.core/load-libs
       137  clojure.lang.RestFn/applyTo
                  core.clj:  667  clojure.core/apply
                  core.clj: 6007  clojure.core/require
                  core.clj: 6007  clojure.core/require
       137  clojure.lang.RestFn/applyTo
                  core.clj:  665  clojure.core/apply
                  core.clj: 6079  clojure.core/serialized-require
                  core.clj: 6088  clojure.core/requiring-resolve
                  core.clj: 6082  clojure.core/requiring-resolve
              topology.clj:   15  crux.topology/resolve-id
              topology.clj:   13  crux.topology/resolve-id
              topology.clj:   39  crux.topology/fn
              topology.clj:   38  crux.topology/fn
                 alpha.clj:  923  clojure.spec.alpha/spec-impl/reify
                 alpha.clj: 1157  clojure.spec.alpha/and-spec-impl/fn
                 alpha.clj: 1183  clojure.spec.alpha/and-spec-impl/reify
                 alpha.clj:  164  clojure.spec.alpha/conform
                 alpha.clj:  160  clojure.spec.alpha/conform
              topology.clj:   49  crux.topology/options->topology/fn
                  core.clj: 2753  clojure.core/map/fn
       42  clojure.lang.LazySeq/sval
       51  clojure.lang.LazySeq/seq
           535  clojure.lang.RT/seq
                  core.clj:  137  clojure.core/seq
                  core.clj:  660  clojure.core/apply
                  core.clj:  660  clojure.core/apply
              topology.clj:   50  crux.topology/options->topology
              topology.clj:   43  crux.topology/options->topology
              topology.clj:   99  crux.topology/start-topology
              topology.clj:   97  crux.topology/start-topology
                  node.clj:  313  crux.node/start
                  node.clj:  312  crux.node/start
          384  clojure.lang.Var/invoke
          42  crux.api.Crux/startNode
                   api.clj:  370  crux.api/start-node
                   api.clj:  353  crux.api/start-node
                  core.clj:   24  crux-test.core/eval20448
                  core.clj:   24  crux-test.core/eval20448
    7177  clojure.lang.Compiler/eval
    7636  clojure.lang.Compiler/load
                      REPL:    1  crux-test.core/eval20436
                      REPL:    1  crux-test.core/eval20436
    7177  clojure.lang.Compiler/eval
    7132  clojure.lang.Compiler/eval
                  core.clj: 3214  clojure.core/eval
                  core.clj: 3210  clojure.core/eval
    interruptible_eval.clj:   91  nrepl.middleware.interruptible-eval/evaluate/fn
                  main.clj:  437  clojure.main/repl/read-eval-print/fn
                  main.clj:  437  clojure.main/repl/read-eval-print
                  main.clj:  458  clojure.main/repl/fn
                  main.clj:  458  clojure.main/repl
                  main.clj:  368  clojure.main/repl
      1523  clojure.lang.RestFn/invoke
    interruptible_eval.clj:   84  nrepl.middleware.interruptible-eval/evaluate
    interruptible_eval.clj:   56  nrepl.middleware.interruptible-eval/evaluate
    interruptible_eval.clj:  155  nrepl.middleware.interruptible-eval/interruptible-eval/fn/fn
           22  clojure.lang.AFn/run
               session.clj:  190  nrepl.middleware.session/session-exec/main-loop/fn
               session.clj:  189  nrepl.middleware.session/session-exec/main-loop
           22  clojure.lang.AFn/run
                       nil:   -1  java.lang.Thread/run

1. Caused by
   Could not locate crux/system__init.class, crux/system.clj or
   crux/system.cljc on classpath.


Hi 🙂 thanks for sharing all the details! I see you're using RELEASE here - just to rule out any possibility for confusion there, please can you set it to 20.09-1.12.0-beta (for both crux-core and crux-jdbc) and check you still see this error? We just pushed this release today. I can't see anything obviously wrong. Feel free to share a GitHub gist link or repo etc. if it's any easier


@laszlo.szolnoki it looks like you need to specify the crux version where it says RELEASE in project.clj

Laszlo Szolnoki22:09:00

@kevin842 Thanks for the prompt response. I tried with :dependencies [juxt/crux-core "20.09-1.12.0-beta"] and [juxt/crux-jdbc "20.09-1.12.0-beta"] and it says Error locating module {:module crux.jdbc/topology}


you should reply to @refset because he actually works for juxt :) but I believe all that :crux.node/topology stuff disappeared in 1.12.0, so I think you can remove that line and the config should just be as described here


you can also compare the 1.11 and 1.12 references using the dropdown on the left to see how the config style changed.. the new docs are nice!


Ah yes, good point, the "topology" stuff is no longer applicable as of today, and the docs have been updated. That's probably the culprit. (We will write up the full 1.12 announcement tomorrow)

Laszlo Szolnoki22:09:28

Thanks a lot, I'll re-check if the dependencies and the module-tree are correct acc. to the new docs tomorrow. BTW it seems to work fine with postgres...I mean without 'topology'. H2 is still an issue for me. I get a nullpointer exception like the H2 mv.db file didn't exist.

Laszlo Szolnoki08:09:19

Thanks @kevin842 and @U899JBRPF To summarize the solution to my problem: 1. :crux.node/topology was not needed 2. The db-spec for H2 that worked with java.jdbc did not work with next.jdbc For next.jdbc it works like this:`(def h2-file {:dbtype "h2" :dbname (str (System/getProperty "user.dir") "\\" <dbname_>) :user <username_> :password <password_> })`

🙏 3
🙂 3

is there a simple way to get the :crux.tx/tx-time in a query?


We don't offer a convenient means of accessing the tx time or valid time of an entity from Datalog, and consequently you're not able to join against it with 4-tuple clauses. However you can use an entity-history lookup as a custom predicate if you really want to retrieve the information (it requires referencing db inside the Datalog) There are a few reasons for this current limitation - primarily due to unresolved semantic debates and a lack of native index support. Can you describe your use-case a little? Are you building an audit view?


I ended up just storing time as an attribute - usually for the best anyway

👍 3

Yeah that's definitely the safest bet 🙂


is it like [e a v tx] like datomic and I need to join against tx?