9 ms·
Meet Korma, a SQL DSL for Clojure
- timmorgan 15y agoMan this makes me want to use Clojure for something.
- untog 15y agoIf that's all it takes, check out LINQ-to-SQL in C#- it does similar stuff. I could take or leave much of C#, but I miss LINQ every time I don't have access to it.
- boyter 15y agoTotally agree. LINQ to SQL is the one feature from C# I wish I had in many other languages. The power you get from the chaining and lazy loading makes implementing many complex joins and the like very easy, testable and compile time checked.
- gtrak 15y agothe thing is, to implement something like linq in C# or any language requires compiler changes, with clojure or any lisp, this is library-level. You can't make korma or linq in something like java, it's too conservative. Macros!
- deleted 15y ago[deleted]
- tom_b 15y agoI am attracted to these types of DSLs but . . . I work with a number of legacy data sources that often have models that are not ORM-friendly. I fall into SQL code patterns that seem left behind by tools like this on a regular basis, particularly using SQL functions without default grouping because I'll select other stuff higher up. A simple example: select col1, col2, some_function() over (partition by col1,col2 order by col1,col2) as some_ck where <some conditions> This is often part of a larger query (e.g., this is embedded in bowels of a some longer "chain" of SQL where I will be using some_ck to decide on which tuples I want in the end). I get pretty significant mileage out of this - meaning I write much less other code around it to handle the data. I guess my complaint is that I often find the SQL DSLs lacking in expressiveness that I use regularly enough to miss. Of course, this could be because I've spent too much time hacking around in legacy data in "real soon now" mode rather than in "hmm . . . let's clean up this data model" mode.
- jwr 15y agoI think writing DSLs for SQL makes little sense. SQL is already a declarative query DSL, why not just use it? Putting another declarative layer on top buys you little (syntactic sugar for most libraries, this one additionally seems to deal with one-to-many relations, and I hope that support is read-write, not just read-only) — and isolates you from the database below. In every serious application I've worked on there was a need to use something which the DSL did not support. So why do it at all?
- groovy2shoes 15y agoIn this case, an embedded DSL brings all the goodies of Lisp's code-as-data to SQL.
- technomancy 15y agoRaw SQL is not very composable, while Korma emphasizes composability on the second paragraph of the page.
- hosh 15y agoAnd composability lets you create business DSLs and macros on top of that. I've used this to good effect with Rails' Arel, but since it is still Ruby, you can't go as far unless you're willing to parse the Ruby into something more legible, like S-expressions.
- its2010already 15y agoIt does make sense to be able to define business/application logic as reusable query components. For example, if your PERSON entity has TITLE, FIRST_NAME and LAST_NAME fields, that little bit of logic that concatenates them together in the right way to form a full name is something that is useful to define. Likewise, setting up a join of tables that is used many times in your application is something that Korma will let you do. Even though these components may be implementable on the database side (as user defined functions or views), it may not always be possible (or desirable) to do that way.
- 15y ago
- moomin 15y agoSee also ClojureQL http://clojureql.org/documentation.html http://clojureql.org/documentation.html Which doesn't have as nice a website but may have superior semantics.
- ibdknox 15y agoThe issue I had with ClojureQL is that it seems like the wrong abstraction to me. Myself and others I've talked to have found ourselves fighting with how it tries to model data and more specifically the kind of queries it generates. For example, it is very quick to use rather inefficient sub-selects.
- moomin 15y agoI'll be checking out korma. :)
- sirn 15y agoMy first impression with ClojureQL was pretty bad, because it didn't do parameterized SQL in the first public release (which fortunately have changed since they released 1.0.) I know it was only a beta, but first impression is strong. I'm now comfortable enough to use it in one of my production site, though. korma seems to done this right.
- sirn 15y agoDear author of Clojure library, please always put a Leiningen dependency string in your home page ([korma "0.2.0"] in this case). Apart from that, I like what I see, especially how it use c3p0 for connection pooling by default.
- ibdknox 15y agoSorry :) It's on the readme for the source. I'll add it to the website once things calm down a bit.
- alpb 15y agoPeople liked this may also like Rogue http://engineering.foursquare.com/2011/01/21/rogue-a-type-safe-scala-dsl-for-querying-mongodb/ http://engineering.foursquare.com/2011/01/21/rogue-a-type-sa... which is Scala DSL for MongoDB. It is not a SQL database but can be compared in terms of semantics.
- joeyespo 15y ago"takes the pain out of working with your favorite RDBMS" The way that's worded just sounds a little odd. Aside from that, this looks really cool.
- lukev 15y agoNot saying this isn't a great, useful library. But - what do people have against SQL? As far as I can see, it's a pretty good language for relational data manipulation. But lots of people act like actually writing SQL is dirty work. It's not. It's an elegant, expressive language, for what it does. Of course, use something like this if you have a documentable need for the flexibility/composability. If you're generating lots of custom queries, it may be justified. But in nine out of ten projects I've seen which use a RDBMS, the system could be made substantially simpler, more performant and more flexible by just writing raw SQL queries instead of screwing around with ORMs.
- ibdknox 15y agoKorma was actually designed to be used to do exactly that: write SQL. You don't have to use any of the ORM-y features and you're essentially just writing SQL in a lisp syntax. The advantage, as others have said, is simply composability, which leads to reusable SQL parts. It's up to you whether you use korma to "just write SQL" or you use the magic :)
- lukev 15y agoAbsolutely, and I completely grant you that there are projects where the composability is a huge win. The library looks great, by the way. I just think a lot of people will have a kneejerk reaction to use something like this because they have a distaste for raw SQL, rather than a considered analysis of the pros and cons. Because there are cons - every time you use something like this, however well designed, you introduce another layer of abstraction into your software, one that is bound to have some leaks. Maybe it's justified, maybe it isn't. Just do the analysis to see if this can benefit you, instead of avoiding SQL by default just because it's SQL.
- twp 15y agoSQL is fantastic, but the annoying bit is that you have to create strings to send to the database, and generating these strings correctly is hard. One of the key features of libraries like Korma and SQLAlchemy is that they provide a very eloquent way of robustly creating these strings. Yes, things like prepared statements help, but dealing with strings and prepared statements is not relevant to the problem that you want to solve. Korma et al. shave the yaks for you. Without something like Korma, your process looks something like: structural-description-of-query --(string operations)--> query-string-to-db --(careful unpacking of response)--> structured-results With Korma and its ilk, this process becomes: structural-description-of-query --(somebody else's problem)--> structured-results
- moizsyed 15y agoI love the name! Its a spicy south asian curry https://www.google.com/search?gcx=w&q=korma&um=1&ie=UTF-8&hl=en&tbm=isch&source=og&sa=N&tab=wi&biw=1472&bih=1319&sei=%20gK6xTr_DIePhiALpkMT4Dw https://www.google.com/search?gcx=w&q=korma&um=1&...
- r4vik 15y agoyou mean mild English curry?
- djKianoosh 15y agothe color scheme is awesome too
- moizsyed 15y agoI love the name! Its a spicy south asian curry https://www.google.com/search?gcx=w&q=korma&um=1&ie=UTF-8&hl=en&tbm=isch&source=og&sa=N&tab=wi&biw=1472&bih=1319&sei=%20gK6xTr_DIePhiALpkMT4Dw https://www.google.com/search?gcx=w&q=korma&um=1&...
- reflexer 15y agoNice page colors.
- scarface548 15y agoThere seems to something similar for Ruby in terms of C# linq https://github.com/suryagaddipati/linqr https://github.com/suryagaddipati/linqr
- thom 15y agoBack in the day, Ambition was pretty cool: http://defunkt.io/ambition/ http://defunkt.io/ambition/ It used ParseTree to parse idiomatic Ruby code against Enumerable APIs into SQL.
- dkubb 15y agoI wrote an Ambition-like API for DataMapper a couple of years ago and still keep it updated: https://github.com/dkubb/dm-ambition https://github.com/dkubb/dm-ambition It uses sourcify (which uses ParseTree on 1.8 and Ripper on 1.9). The semantics are identical to standard Enumerable API. In fact, it's not recommended, but you can turn off dm-ambition and the expressions will still work as-is -- only instead of generating a query from the block it iterates over the results and filter in-memory.
- thom 15y agoGreat stuff! I haven't really kept up with the Ruby world, and didn't realise there was a solution on 1.9.
- dkubb 15y agoWell, on 1.9 it's not quite as nice as 1.8. The ruby-core team decided to change ruby so that after parsing the source the AST would be thrown away as part of some kind of optimization. That means things like ParseTree don't work anymore, and you can't inspect the AST of a Proc at runtime. However, with sourcify you can sort of emulate the 1.8 behaviour, but it's not perfect. It uses ripper to parse the file where the Proc is defined, and then provides the same callbacks that ParseTree does. It mostly seems to work, but it does run into problems if two Procs are defined on the same line, eg: users.select { ... }.select { ... }. I'm actually a little disappointed that ruby-core decided to go in this direction. I think that decision will end up costing the community because it makes it harder for runtime introspection of code. It means less tools will be written on top of the runtime, and things like Ambition become harder if not impossible to do reliably. I'm glad to see Rubinius is going in the opposite direction though.
- spariev 15y agoNice looking DSL, but .. how could I do things like SELECT TOP 10 (MSSQL) or SELECT DISTINCT (just trying to use it for queries I need at work) ? Haven't found any clues on this in the docs (nice site BTW). Also, it would be nice to allow some raw SQL in where clause - so one won't have to wrestle with DSL just to occasionally use proprietary features or db-specific functions.
- vinothkr 15y agocheck this out https://github.com/duelinmarkers/clj-record https://github.com/duelinmarkers/clj-record