Fork me on GitHub
#clojure
<
2016-01-24
>
nha13:01:39

@niwinz: how does catacumba compare to yada ?

jethroksy13:01:17

its more like aleph than yada

nha13:01:18

well yada is built on aleph, and catacumba seems to aim higher (meaning it's not low-level)

jethroksy13:01:39

yada is built on manifold

jethroksy13:01:59

catacumba and aleph are both async toolkits of sorts

nha13:01:17

yes - hence why I'd be interested in knowing the differences

nha13:01:05

well there is a lot of docs for catacumba so I may just have a look - although I am pretty much commited to yada by now

niwinz13:01:41

@nha the big difference between catacumba and yada, is that yada is very opinionated in terms on how the things should be done and catacumba is much les opinionated.

niwinz13:01:17

catacumba is much like aleph but a little bit more high level and web development focused

niwinz13:01:32

with some concepts taken from pedestal such as interceptors

niwinz13:01:41

the both solves similar things but using different approach

niwinz13:01:01

in fact manifold is first citized in catacumba in same way as in yada

nha13:01:03

Ok I see. I was looking through the docs assoc-routes! seemed opinionated to me when first reading it

nha13:01:17

Yes manifold is really nice with sse/ws

niwinz13:01:42

assoc-routes is part of the "component" integration, but it does not uses any strange magic, you can do it yourself

niwinz13:01:21

and it is not mandatory to use that, it is named toolkit because it offers different things but them almost all are optional

nha13:01:31

right. makes sense

niwinz13:01:48

and you can use just that you want or just reimplement them, catacumba is entirelly open to extensibility

nha13:01:17

built on protocols, right ?

niwinz13:01:35

and multimethods in some cases

nha13:01:19

maybe a crazy question - would it be possible to mix them in a project (meaning on the same server component) ?

niwinz13:01:49

I don't know

nha13:01:01

I know yada produces ring handlers, that I pass to the aleph server

nha13:01:24

well at least that's what I understand so far

niwinz13:01:03

Yes, this is the difference, catacumba has a ring handler adapter (you can put a ring handlers under some route)

niwinz13:01:18

but in the ground it works a little bit different and it is not constrained to ring spec

niwinz13:01:04

ring is designed for synchronous operations, and catacumba approach with route pipeline of handlers is designed from the ground up for async

nha13:01:54

Right I saw that somewhere already. With the pedestal guys I think. So catacumba is more integrated as well (meaning has the routing part built-in).

niwinz13:01:58

With ring is designed for synchrnous apps I mean that all middleware stuf build on ring does not works well in async environments

niwinz13:01:40

catacumba has rouing builtin but is not mandatory to use.

niwinz13:01:12

Obviously it is much more integrated that any other posible solution.

nha13:01:13

Of course simple_smile I'll keep catacumba in mind for the next wep app simple_smile

niwinz13:01:36

in fact is not a routing, is just a pipeline of handlers that can take decisions on the flow

niwinz13:01:44

and the request lifecicle 😉

niwinz13:01:00

nice! let me know if you have any feedback or suggestion

nha13:01:07

Oh ok. a la pedestal then.

niwinz13:01:14

catacumba is already used in productions in some places and works pretty well

nha13:01:22

Sure I will simple_smile I must say I love how you document your projects

niwinz13:01:01

This is something essential I think. The documentation is very important

darwin15:01:40

boring Sunday? looking for a project? write a library to print Clojure data structures into Chrome DevTools Console: https://github.com/binaryage/cljs-devtools/issues/11

bcoop71318:01:18

can anyone give me a quick rundown on testing frameworks in clojure? Is there a defacto leader?

bcoop71318:01:23

looks like there is clojure.test, Speclj and something called Midje. Do most people just use clojure.test?

seancorfield18:01:58

We use Expectations very heavily.

seancorfield18:01:49

I suspect clojure.test is popular because it's built in but it's pretty basic assert-style stuff.

seancorfield18:01:26

There's test.check in contrib for generative testing (which can be really useful in many cases).

seancorfield18:01:17

We found Midje had too much "magic" for our tastes and requires learning a whole new DSL that didn't feel very Clojure-y (to us). We liked the minimal style of Expectations and we like the way it has evolved over the years.

seancorfield18:01:39

We use test.check a little too (with Expectations).

intey19:01:27

I'm use speclj. BDD style, looks nice. Try midje, but don't found how to execute action before each test (resetting DB) and return to speclj. It's old, seems that not maintained. but works.

seancorfield19:01:29

We use clojure.test with clj-webdriver because it suits the procedural "assertive" nature of WebDriver.

bcoop71319:01:17

excellent, ill give Expectations a go. Thanks.

seancorfield19:01:49

@intey: interesting... I looked at Speclj but the lack of maintenance put us off.

seancorfield19:01:33

If you use Boot, there's a task for Expectations now (as well as one for clojure.test).

intey19:01:18

Yeah, it's looks abandoned. But tests looks pretty with it. Maybe in biggrer projects it isn't so.

amacdougall19:01:21

So this is a little bit off-topic, but maybe someone knows—I was using YeSQL, which reads SQL-format files into JDBC parameterized queries. It's been fine! But evidently, you can't parameterize ORDER BY or sort direction (`ASC` / DESC) in a JDBC PreparedStatement, at least with Postgres. This seems like a really common need. If anyone has run into it, and has a better idea than "just build all your queries from strings, losing all the benefits of parameterized queries in the first place", I'm all ears. ...although the more I read about it, the more I realize that ORDER BY and sort direction are simply outside the purpose of prepared statements... weird that LIMIT and OFFSET work, though.

rm19:01:33

why not? ORDER BY meow IF(:asc == true, ASC, DESC) woudn't that work?

amacdougall19:01:40

Postgres has a CASE statement that could do what you're talking about; I think you could inject a true. I'll try that! I don't think you can parameterize the field to order by, though: it's a raw table identifier in SQL, not a field value.

rm19:01:09

you're right

rm19:01:47

btw, how does case work?

amacdougall19:01:35

Even if the sort direction can be parameterized using your suggestion, that would be really nice. But I'd still need user/get-users-ordered-by-foo {:page 2, :per-page 100, :sort :asc} instead of user/get-users {:page 2, :per-page 100, :order-by :foo, :sort :asc}.

amacdougall19:01:58

I really don't want to get into the business of building queries from strings in my own code, though. That's way too 2001 PHP for my taste.

amacdougall19:01:45

CASE WHEN <condition> THEN <result> [WHEN <condition> THEN <result> ...] ELSE <fallback>

amacdougall19:01:32

So, ORDER BY foo CASE WHEN :asc THEN ASC ELSE DESC... maybe? I haven't used it, but I saw a co-worker use it recently, and it was like that. Kind of an unexpected detour in the SQL syntax, but I get it.

juhoteperi19:01:42

@amacdougall: HoneySQL works well for building queries dynamically

rm19:01:24

amacdougall: just tried in mysql, case statement for asc/desc doesn't work.

amacdougall19:01:57

Ah, thanks for the recommendation! I'll look at it. I'm considering all possibilities right now. It's a real shame, though—I really like YeSQL's core concept, and it obviously makes it really easy to write whatever SQL you feel like. But of course, it's not like it's difficult to test some SQL in the db console and then throw it in a string once it's cooked... see every SQL heredoc ever written.

rm19:01:50

there should be a way :) If sort direction is the only limitation maybe create two views that differs only by sort direction?

rm19:01:29

or order by if(:asc, id, -id) asc -- that does not work either

amacdougall19:01:25

Well, in theory I'd want my admin page to have a sort direction toggle for every field—that's pretty standard. But that means I'd have to have an easy way to specify every combination of order-by and sort direction. YeSQL wants to generate a Clojure function for each SQL query, which makes sense as long as... huh. I guess I could write some monster query which has an internal CASE statement which turns on a string passed into it...

SELECT * FROM USERS
  CASE order_by
    WHEN "email" THEN ORDER BY email
    WHEN "username" THEN ORDER BY username
  CASE sort_direction
    WHEN "asc" THEN ASC
    ELSE DESC;

amacdougall19:01:57

But that would require setting the values of order_by and sort_direction based on query parameters, and man, I just don't want to get into it.

amacdougall19:01:29

Not to mention that I'd need a WHEN .. THEN clause for every field I want to be able to sort on.

amacdougall19:01:12

I'll try HoneySQL first. I'll just have to unravel some of the Luminus defaults.

amacdougall20:01:27

Actually, the hell with it; I'll just make a distinct and awkwardly-named query/function for each combination of stuff, by copy-pasting shamelessly, and then I'll wallpaper over it in my user/get-users function.

(defn get-users [params]
  (let [f (case (:order-by params)
            :username db/get-users-ordered-by-username
            :email db/get-users-ordered-by-email)]
    (f params)))
It's going to be gross, but it will let me forge ahead without any further analysis paralysis.