Fork me on GitHub

map-indexed doesn't take more than one coll


(let [ks (conj (keys m) :nth)]
  (into [] (apply map #(zipmap ks %&) (range) (vals m))))
[{:nth 0, :x 1, :y 4, :z 7, :ab 10} {:nth 1, :x 2, :y 5, :z 8, :ab 11} {:nth 2, :x 3, :y 6, :z 9, :ab 12}]


nice! Trying to understand the 2 solutions now


the last one is exploiting the fact that apply is (apply f a b c rest), that the result of keys is a seq which things get conj'd to the front of, and that map stops as soon as any of the sequences passed to it are finished

Matthew Pettis03:03:32

Opinions please. What are the community recommended web app/routing frameworks? Is it ring/compojure, or reitit, or somethings else? And what are the best resources to get started with it?


There is also Clojure Liberator. I liked using it a lot.


I've been struggling to find a good "quickstart" for building a webapi in clojure. So far this is the best thing I've found -

👍 4

It keeps is relatively simple and got me started at least.


If you want a "fuller" example, I refer to this -

Matthew Pettis03:03:08

Thanks! I should add, I read this, which is a great very first start at understanding ring/compojure, so I need to find other things that expand on what was there, or see if there are other frameworks that are considered standard.


I know Pedestal has a series of tutorials that are helpful. It seemed a bit more complex than ring though.


The tutorials get you started and are pretty nice.

Matthew Pettis03:03:35

I did look at your medium link a bit back. The one part I needed expansion on was POST requests, which is mentioned in passing at the end. But it is a good read on GET and such...

Matthew Pettis03:03:43

I'll look at pedestal


I was using some middleware that would handle converting the body from JSON or various other formats to a clojure map.


It made it easy for what I was doing. I don't think POST is all that different from get, just the data comes in the :body


There's middleware that handles form posts if you're trying to post a form too.

👍 4

To be honest, where I get lost is trying to put the middleware together with compojure.


as I typically need different middleware for different routes.


If you do find a good resource, feel free to send it my way 🙂

Matthew Pettis03:03:58

🙂 will do, thanks for these resources.

👍 4

Hi all I have a doubt about destructuring and how can I do it with the result of a group-by where the “keys” are “true” or “false”, for example:

(def items [{:code "4" "type" "multi"}
             { :code "1" "type" "multi" "isDisabled" false}
             { :code "3" "type" "registration"}
             { :code "2" "type" "single" "isDisabled" true}
             { :code "5" "type" "single"}])
(group-by #(= true (get % "isDisabled")) items)


oh! I think I have it

(let [{foo true bar false} (group-by #(= true (get % "isDisabled")) items)])

Tzafrir Ben Ami11:03:03

FYI - instead of using = true you can use true? function

👍 4

I'm integrating my service with mongodb. The ones that I've seen getting most coverage are Monger and congomongo. I would have jumped on Monger but looking at their Github it hasn't been touched for a year. congomongo seems to currently be more active, but might be less mature. Anyone have any opinion on how to integrate with mongo?


We've been happily using Monger for a while now, without issues. You might want to look at the list of outstanding issues on the monger github repo and see if there's anything there that sounds likely to be a problem for you, but we've found it to be pretty stable and useful for our purposes.


@manutter51 Thanks for a good response. Provides me with more confidence going ahead with Monger

👍 4

#{1 2 3 4 5 6 7 8 9}
=> #{7 1 4 6 3 2 9 5 8}
What's going on here?


A set has no order.


If you need something ordered you would use a vector. A set is just a bunch of unique values, so it is not garanteed to get them out in any particular order. The same is true for hash-maps.


A vector is insertion ordered. A sorted set is ordered using a comparator. A (hash) set is neither.


@glfinn83 I maintained congomongo for years. At the time I preferred it over Monger because the latter used a single global dynamic var for the db connection, but Monger added that in a later release and was, otherwise, better maintained and better documented than congomongo. I stopped maintaining congomongo because we stopped using MongoDB at work and I'd been recommending people use Monger for a while by that point. Good to know someone has stepped up and is maintaining congomongo again now.

David Pham16:03:46

Does anyone would recommend Cordova over React Native for CLJS?

Michael Thurmond17:03:54

I have done a Reagent/CLJS Cordova app, We lost native look/feel but the company I was working for was paying people to use the app for data collection purposes

Michael Thurmond17:03:43

I'm not sure of other options out there. I have played around with re-natal a little bit


Another option would be to use Clojure instead, and cljfx

Michael Thurmond17:03:54

I have done a Reagent/CLJS Cordova app, We lost native look/feel but the company I was working for was paying people to use the app for data collection purposes

Mario C.19:03:22

App I am working on is using JDBC and raw sql. How do I structure the query call to prevent SQL injection? Ive read that I would need to use parameterized sql queries but not quite sure what that means exactly.

(as-> "ModelT; SELECT version from workbooks where name=Falcon" workbook
    (j/query postgre-db-spec [(str "SELECT user from " workbook-collection-name
                                   " WHERE name = ?; ") workbook]))


This code may or may not be vulnerable to SQL injection, depending on where workbook-collection-name comes from. In general, if any user has access to set or change the value of workbook-collection-name, and you build a SQL query using str, they can change it to a value that executes a SQL injection attack. The workbook parameter, though, is not vulnerable — you’ve included a ? placeholder for it in the query, and then passed workbook in as a parameter to j/query, which is what “parameterized SQL query” means.

Mario C.19:03:44

workbook-collection-name comes internally from a def at the top of the namespace. workbook gets passed in from the outside. This statement seems to run fine though. Shouldn't there be an exception thrown?

Mario C.19:03:05

My select version from workbooks where name=Falcon after the "ModelT" is my "injection"


That should be safe, actually. Because you’re using a parameterized query, the value of workbook is never concatenated with your original query string. Your query string is parsed first, and executed by the database engine, with the (unparsed) “injection” string as a raw value that it’s searching for in the name column.

👍 4

Beware, though: I don’t think SQL injection vulnerabilities will generally throw exceptions, otherwise they wouldn’t be as dangerous. They operate pretty much silently, which is why you need to be sure you don’t create them in the first place.

Mario C.20:03:22

Thank you, that explanation helps. Which is why the query was returning an empty list.


@mario.cordova.862 If it helps, each ? in the SQL string is a parameter for which the value is substituted as an object not as a string. You can't inject SQL fragments via ? so that's safe.


However, using str to build a raw SQL string can be vulnerable if you are building it from variables that come from user input. Does that clarify the difference?

Mario C.21:03:11

@seancorfield It does actually. Yea the whole file is building sql like that. But luckily for us this is an internal app but that begs the question is it worth it to rewrite everything as parameterized sql or the network security enough?


@mario.cordova.862 Well, I always use ? for the actual parameters, but I do build the rest of the SQL string with str most of the time -- but it's rare that "the rest of the SQL string" is built from any user input (it might be computed data but it doesn't directly contain user input).


Part of the reason for preferring ? aside from security is just type conversions: if your parameters are anything except simple numbers, just str'ing them into the SQL string won't work (string parameters would need ' around them -- but what about embedded quotes etc? booleans may or may not need to be turned into 0 and 1, etc).

👍 4
Mario C.22:03:10

Thats good to know, I didn't think of that