This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
- # adventofcode (80)
- # beginners (94)
- # biff (19)
- # cider (74)
- # clj-kondo (11)
- # cljs-dev (7)
- # clojure (110)
- # clojure-austin (3)
- # clojure-australia (1)
- # clojure-belgium (1)
- # clojure-china (1)
- # clojure-europe (83)
- # clojure-filipino (1)
- # clojure-hk (1)
- # clojure-indonesia (1)
- # clojure-japan (1)
- # clojure-korea (1)
- # clojure-my (1)
- # clojure-nl (1)
- # clojure-norway (4)
- # clojure-sg (1)
- # clojure-taiwan (1)
- # clojure-uk (2)
- # cursive (3)
- # data-science (8)
- # datalevin (8)
- # emacs (18)
- # etaoin (5)
- # graalvm (1)
- # holy-lambda (3)
- # honeysql (1)
- # jackdaw (9)
- # java (10)
- # jobs (3)
- # luminus (9)
- # malli (106)
- # off-topic (88)
- # polylith (8)
- # portal (2)
- # re-frame (50)
- # reagent (11)
- # reitit (74)
- # remote-jobs (1)
- # shadow-cljs (46)
- # tools-deps (26)
- # xtdb (49)
Java time is hard to navigate; I am using https://cljdoc.org/d/tick/tick/0.5.0-RC5/doc/readme, how do I mutate the date? I am looking to update the date.
It looks like tick is based on java time. I think just about everything in java time is immutable, so you would produce a new value rather than mutate an existing date.
Java time becomes easier if you understand the relation between LocalDateTime <=> OffsetDateTime <=> ZonedDateTime and Instant
What is must-have DB (postgresql) library to use in any production commercial project?
What do you use in your real projects?
Is it just
org.clojure/java.jdbc or something with higher level of DSL?
https://github.com/seancorfield/next-jdbc provides database connections via a ranges of database drivers and functions for SQL queries to the database. Keys can also be automatically converted to/from kebab-case
https://github.com/seancorfield/honeysql provides a way to define database queries in Clojure rather than SQL and can be used with next.jdbc for database connection
The documentation for these projects are very detailed and worth reading. https://practical.li/clojure-web-services/relational-databases-and-sql/ also covers examples of practical application of next.jdbc which have been used in numerous commercial production projects
If you look at the options and waver, I'll just say that (resultset-seq) in clojure.core is a pretty good 85% solution, in one fell swoop lifting the most awful burdens of JDBC. If you must use SQL at all, that one function pays the price of admission to Clojure.
What do you mean? Just use
resultset-seq instead of
result-set/as-unqualified-lower-maps ? Or what? Sorry dont understand your message 🙂
Just pointing out that the JDBC situation in Clojure is quite different from Java. In Java, JDBC is so hard to use that Hibernate seemed reasonable and Spring on top of that and your question about a must-have library could easily be answered with "Hibernate and Spring and everything in the kitchen sink." But Clojure showed that the hardship was Java's fault, not JDBC's. In Clojure, you might not need any SQL library at all. JDBC is a breeze. Java interop to prepare and run statements, plus the resultset-seq function in clojure.core, might be sufficient. The libraries add various value and elevate the tone, but depending on what you need beyond your own automation of JDBC, it's your choice.
I don't use it in a real web project - nothing big. Not exactly sure what you mean by too low level though. Clojure is quite against ORMs and stuff so you'd have to explain. I just use it in tandem with honeysql in various tools.
@U04BRV8JQKE We use
next.jdbc heavily in production, powering 40 online dating sites with millions of users and a huge MySQL database. We also use HoneySQL to construct complex queries when we need to compose SQL fragments conditionally.
We still use
clojure.java.jdbc as well and the original 1.x of HoneySQL since our codebase in over a decade old in places (134,000 lines of code now).
@U04V70XH6 yeah, I see. I am already adding next.jdbs + honeysql to my pet project. They are very simple to understand, thank you! Specially honeysql DSL for complex queries
Is there a case when "symbol"
honeysql helpers are better than "keyword"? Or I can write any complex queries via "keyword" helpers like
It's personal preference, with a couple of very minor exceptions (that you hardly ever need to worry about).
If you look in the tests (and docs), you'll see examples of both, but most are keyword style.
If you don't need symbols evaluated in a query, a quoted symbol form is less typing 😁
Am I right I cant create database via
So I just need to use plain-text SQL via
@UC1DTFY1G nice example, thanks. What is about database creation? Then I need to create it not from clojure layer at all? So I need to create it from system layer (docker)
(jdbc/execute! ds ["create database if not exists foo"]) -- it's a pretty simple SQL command so you don't need HoneySQL for that really.
At work, we use plain
.sql files for all our DB migrations. We read them in and run them with
I just thinking what is better, to manage databases from docker-compose file (just add another section for additional database) or from clojure
.sql files for all our DB migrations
so there are database creation AND all tables creation code?
At this point we have about 950
.sql files representing the "migration" up from a completely empty Percona instance started with Docker to four full test databases.
We do automated SQL migrations to QA and production as well, the same way. We have a table in the DB containing the highest migration applied and then automatically apply any missing migrations as part of our automated deployment.
Libraries like Migratus help automate this. We built our own migration system many years ago.
We have 8 basic DB setup
.sql files, 3 initial creation
.sql files, and currently 924 individual migration files to modify the schemas etc.
The basic files create the four databases and populate our geolocation DB (one of the four). Those are only run on a "cold start" (in CI and occasionally in dev). The initial creation files 1) drop all the tables, 2) create the original set of tables we started the project with (our MVP schema), and set up the
dblevel table (to level
We chose a simple increasing number. And we also have the concept of dev-only migrations (which are applied in dev/CI but not QA or production) which are used for loading test data -- but are otherwise just part of the regular sequence of migrations... 00001_metadata.sql, 00002dev_initial_test_data.sql, 00004_cheater_create.sql, 00005_bannedIP_add_admin.sql etc up to 00923_bugfix_WS_14085_covalence_source_too_long.sql, and 00924_feature_WS_14075_admin_filter_skywriting_by_platform.sql -- during the (decade-plus) life of the project we switched to Jira and now use branch names for SQL migrations -- via a
next-migration task in our
build.clj file 🙂
I blogged about the first ten tickets we created, when we got started on this project back in 2009: https://corfield.org/blog/2014/06/03/getting-started/
I have a code below for future which executing its bosy again and again on calling the function, But the main definition of future is it catch the value, How to write it in function?
(def x 0) (defn increment-number  (let [future-var (future (loop [y x] (Thread/sleep 1000) (println "---y---" y) (if (> y 3) y (recur (inc y)))))] @future-var [x @future-var])) (increment-number)
(defn increment-number  (let [future-var (future (loop [y 0] (Thread/sleep 1000) (println "---y---" y) (if (> y 3) y (recur (inc y)))))] @future-var)) (increment-number)
So I assume you mean on each call of
(increment-number) you see the print statement right?
This is because you are creating a new future in each call inside the function. If you wanted to get the cached value, you can do something like this (simplified):
(defn increment-number  (future (loop [y 0] (Thread/sleep 1000) (println "---y---" y) (if (> y 3) y (recur (inc y)))))) (let [f (increment-number)] [@f @f @f])
If you run
(increment-number) again, it will print again because you are creating a new future.
@UC1DTFY1G Promise also catch the value right? How it will be helpful in real world scenario?
I haven't used
promise much so if I'm wrong someone can correct me...
future is a computation that starts immediately on a separate thread after the future is created. If you try to
deref the future before it's completed, it will block. so:
(def f (future (Thread/sleep 5000) 42)) @f ;Will return 42 after 5 secs
promiseis a promise that a value will be
delivered to the promise at some time. Difference from
futureis it does not specify how that will be done:
This will block indefinitely as no one delivers on the promise. However, we can deliver in the promise from somewhere else:
(def p (promise)) @p
So, I use future when you want to do something in a separate thread. I haven't used promises yet but I can imagine waiting for some event to happen and deliver on any promises available when that happens.
(def p (promise)) (future (Thread/sleep 10000) (deliver p 42)) @p ;Will block for 10 secs then return 42
No, not outside these toy examples. I think
deliver is only used in tandem with
Is there a way to dynamically name a variable? I have the following code
defbulkheadis a macro which creates a var in the current namespace with the name "symbol-name" (check docs here - https://github.com/ylgrgyq/resilience-for-clojure/blob/0.2.7/src/resilience/thread_pool_bulkhead.clj#L137) I need that
symbol-nameto be dynamic in nature. I have this for now,
but I'm wondering if there's a better way to do it.
(eval `(thread-pool-bulkhead/defbulkhead ~(symbol symbol-name)))
It's just my use-case. I am giving user the ability to create bulkheads dynamically and fetch the correct one when needed
I am currently learning about spec and why qualified keys are a good idea. How does one deal with keysets which you have no direct control over (e.g. a body of a ring request)? Is there an idiomatic way to wrap an existing map in a namespace so it can be validated by a spec?
another option could be to use
(s/keys :req-un […] for handling the unqualified keys directly (https://clojure.org/guides/spec#_entity_maps section of the Spec guide has examples)
I got bitten pretty bad by this (using unqualified keys) in my days of learning spec. I left some notes here https://github.com/clojure/clojure-site/issues/517 (which still haven't been reflected in the guide) - Since then I have adopted malli (https://github.com/metosin/malli) which solves this and many other design flaws of spec (the API is data+fns instead of macros being a huge one). I recommend taking a look at at it.
:req-un suffers from the flaw that your specs still need to be namespaced keywords, even though in the map they are not. This can lead to painful collisions of those fully qualified keywords later on, especially in a large codebase, due to spec using a global registry