Re: Using a dynamic var for my database connection for implicit connections+transactions

2015-08-06 Thread Eric Normand
Hi Pablo I think the reason you've got so many responses is because most people share the same problem. I do think this is a fruitful area of discussion. There are multiple ways to go about it. Based on your original post, I'll share my two cents: In my experience, mixing an atom and

Re: Using a dynamic var for my database connection for implicit connections+transactions

2015-08-06 Thread J . Pablo Fernández
On 5 August 2015 at 19:33, James Reeves ja...@booleanknot.com wrote: So when you're testing, presumably you use a dynamic binding to override the global connection to the test database? The wrap transaction always overrides the dynamic binding, whether it's in tests or not. -- J. Pablo

Re: Using a dynamic var for my database connection for implicit connections+transactions

2015-08-05 Thread James Gatannah
On Monday, August 3, 2015 at 5:19:34 AM UTC-5, Colin Yates wrote: I have heard this approach before, but I have never seen how it works in real life. Interesting. I don't think I've ever worked anywhere that didn't take this kind of approach. Even if we weren't doing it formally. For

Re: Using a dynamic var for my database connection for implicit connections+transactions

2015-08-05 Thread James Gatannah
On Monday, August 3, 2015 at 10:21:09 PM UTC-5, Dmitri wrote: My understanding is that the problem is actually caused by the stateless nature of the functions. You're talking about database interactions. By definition, those are not stateless. The trick is to isolate this statefulness as

Re: Using a dynamic var for my database connection for implicit connections+transactions

2015-08-05 Thread Colin Yates
I think we are talking at cross purposes - I thought you were talking about delaying the mutation until the 'main' logic has finished, whereby the main logic would push the mutation into a queue which were then executed later. Something like queueing up a bunch of commands to be executed later.

Re: Using a dynamic var for my database connection for implicit connections+transactions

2015-08-05 Thread Dmitri
What I'm talking about is whether it's a better pattern to leave a repetitive and error prone task to the user or encapsulate it in a single place. The whole discussion boils down to following options. The first option is that we keep functions pure and the connection is passed as a parameter

Re: Using a dynamic var for my database connection for implicit connections+transactions

2015-08-05 Thread James Reeves
On 5 August 2015 at 14:03, Dmitri dmitri.sotni...@gmail.com wrote: What I'm talking about is whether it's a better pattern to leave a repetitive and error prone task to the user or encapsulate it in a single place. The whole discussion boils down to following options. The first option is

Re: Using a dynamic var for my database connection for implicit connections+transactions

2015-08-05 Thread Dmitri
I agree that wrapping the functions is a sensible approach. Using wrap-transaction is precisely how I ended up doing it with the conman yesql wrapper https://github.com/luminus-framework/conman The approach I took there is to have the generated functions use the connection atom, and have

Re: Using a dynamic var for my database connection for implicit connections+transactions

2015-08-05 Thread Colin Yates
This. I would repeat with as strong an emphasis as possible the sanity of using a dedicated test database - how else can you test schema creation for example... Dmitri writes: I agree that wrapping the functions is a sensible approach. Using wrap-transaction is precisely how I ended up doing

Re: Using a dynamic var for my database connection for implicit connections+transactions

2015-08-05 Thread James Reeves
On 5 August 2015 at 18:04, Dmitri dmitri.sotni...@gmail.com wrote: I agree that wrapping the functions is a sensible approach. Using wrap-transaction is precisely how I ended up doing it with the conman yesql wrapper https://github.com/luminus-framework/conman The approach I took there is to

Re: Using a dynamic var for my database connection for implicit connections+transactions

2015-08-05 Thread Dmitri
There are a number of options here depending on your workflow. You could override the dynamic var, create a separate connection for tests and pass it around explicitly in test code, or get the connection from the environment. The last option is what I tend to do, the profiles.clj will contain

Re: Using a dynamic var for my database connection for implicit connections+transactions

2015-08-04 Thread J . Pablo Fernández
On 3 August 2015 at 23:47, Rob Lally rob.la...@gmail.com wrote: I’m also a little confused by your suggestion that it would be impossible to enclose each test in a transaction. The article you point to shows one way. It shows how to pass data to the test by using a dynamic var, which is what

Re: Using a dynamic var for my database connection for implicit connections+transactions

2015-08-03 Thread Rob Lally
Everything you say is true. And programming is always about picking the right trade-offs at the right time, making this sort of conversation one that can never come to a *right* answer. But… in this case Pablo was experiencing concrete problems: those problems stemmed from how easy it was to

Re: Using a dynamic var for my database connection for implicit connections+transactions

2015-08-03 Thread Rob Lally
Hey Pablo, Sorry, you are completely correct: I accidentally typed transaction when I meant connection. My bad. I don’t understand what you mean by connections having to be global when dealing with an RDBMS. It is true that you normally want to pool them to conserve resources, and that

Re: Using a dynamic var for my database connection for implicit connections+transactions

2015-08-03 Thread Dmitri
While I generally agree that purity is something to strive for, I think it's also important to consider the problem that's being solved in each particular scenario. While creating stateless database query functions and passing the connection round explicitly achieves purity, it's not entirely

Re: Using a dynamic var for my database connection for implicit connections+transactions

2015-08-03 Thread Dmitri
My understanding is that the problem is actually caused by the stateless nature of the functions. Since the function accepts the connection as a parameter it's up to the user of the function to ensure that it's passed the correct connection. Every functional solution presented in this thread

Re: Using a dynamic var for my database connection for implicit connections+transactions

2015-08-03 Thread Colin Yates
I have heard this approach before, but I have never seen how it works in real life. For example, what about 'selects' - where do they happen? What about if my updates are not independent (e.g. if the first update works then do the second update otherwise do this completely different thing?). For

Re: Using a dynamic var for my database connection for implicit connections+transactions

2015-08-03 Thread J . Pablo Fernández
Other than the fact that this approach doesn't reach the level of functional purity that some people want, after playing with it for a while, we found it very productive and leads to clean/readable code and tests, so we decided to turn it into a library: https://clojars.org/conman

Re: Using a dynamic var for my database connection for implicit connections+transactions

2015-08-03 Thread J . Pablo Fernández
Rob, The transactions are not global, the transactions are local. Connections are global and there's no way around it with the constraints of a traditional RDBMs. Your idea of making the global connection unavailable for code that's in the context of a transaction would prevent the errors I'm

Re: Using a dynamic var for my database connection for implicit connections+transactions

2015-08-03 Thread J . Pablo Fernández
James, I'm not new to functional programming and I understand the principles and why they are good. I worked in Haskell, Erlang and other Lisps before. Even if only a tiny portion of my codebase deals with the database, I still need a pattern for that part of the codebase. It is very easy to say

Re: Using a dynamic var for my database connection for implicit connections+transactions

2015-08-02 Thread James Gatannah
On Thursday, July 30, 2015 at 7:44:31 PM UTC-5, J. Pablo Fernández wrote: Hello Clojurians, I found passing around the database connection to each function that uses it very error prone when you are using transactions as passing the wrong one could mean a query runs outside the

Re: Using a dynamic var for my database connection for implicit connections+transactions

2015-08-01 Thread Jo Geraerts
Hello, I think you are coming to a point where you might want to consider Stuart Sierra's component library. https://github.com/stuartsierra/component A dynamic var is kind of thread-bounded global state, which is to be avoided. There is a nice talk to go with it

Re: Using a dynamic var for my database connection for implicit connections+transactions

2015-08-01 Thread Rob Lally
Hey Pablo, I could be wrong, but it seems that the key problem here is the existence of the global transaction. If the global transaction didn’t exist then any time you failed to pass in a transaction the code would fail: immediately and loudly. I appreciate what you’re trying to do but it

Re: Using a dynamic var for my database connection for implicit connections+transactions

2015-08-01 Thread James Reeves
On 1 August 2015 at 01:38, jongwon.choi oz.jongwon.c...@gmail.com wrote: That's how I normally use dynamic vars. Some people afraid of using it, but it is like a knife - If you know how to use it, it is useful to remove unnecessary complexity. Well, it's more that dynamic vars trade

Re: Using a dynamic var for my database connection for implicit connections+transactions

2015-08-01 Thread Colin Yates
That is indeed a useful library for wiring things up at init-time, but it doesn't help at all for run-time wiring, like transactions. On 1 Aug 2015 07:33, Jo Geraerts j...@umask.net wrote: Hello, I think you are coming to a point where you might want to consider Stuart Sierra's component

Re: Using a dynamic var for my database connection for implicit connections+transactions

2015-07-31 Thread jongwon.choi
Cut paste from my own code base: (def ^:dynamic *db-conn*) (defmacro with-db-connection [ body] `(jdbc/with-db-connection [con# (get-db-conn)] (binding [*db-conn* con#] ~@body))) A few points. Do not give any value to the dynamic var, make it unbound and make it fail early for

Re: Using a dynamic var for my database connection for implicit connections+transactions

2015-07-31 Thread J . Pablo Fernández
On Friday, 31 July 2015 11:48:54 UTC+1, Colin Yates wrote: I am away from the code at the moment, but is there any reason why the dynamic connection can’t be private? This goes some way to providing safety. No, I don't think there's a problem with it being private, I just didn't think of

Re: Using a dynamic var for my database connection for implicit connections+transactions

2015-07-31 Thread James Reeves
On 31 July 2015 at 09:54, J. Pablo Fernández pup...@pupeno.com wrote: For me, the thing is, I have a traditional relational database here, this is already far from pure. For example, calling (db/create-user pup...@pupeno.com) twice will not only not return the same thing the second time,

Re: Using a dynamic var for my database connection for implicit connections+transactions

2015-07-31 Thread J . Pablo Fernández
Hello James, Thanks for your answer. I do understand your point. Pure functions are easier to reason about and my use of dynamic here breaks that purity. I'm not doing it lightly. It already happened to me, that one of those functions that was running inside the transaction, was not passed the

Re: Using a dynamic var for my database connection for implicit connections+transactions

2015-07-31 Thread Colin Yates
This is always tricky - the other dimension is that the transaction can span multiple components which should all be ignorant of each other, so a collecting fn (like James’ ‘do-things*’) isn’t feasible. For me, I have the service create a tx and then either I pass in the tx instead of the db

Using a dynamic var for my database connection for implicit connections+transactions

2015-07-30 Thread J . Pablo Fernández
Hello Clojurians, I found passing around the database connection to each function that uses it very error prone when you are using transactions as passing the wrong one could mean a query runs outside the transaction when in the source code it is inside the with-db-transaction function. So I

Re: Using a dynamic var for my database connection for implicit connections+transactions

2015-07-30 Thread James Reeves
On 31 July 2015 at 01:44, J. Pablo Fernández pup...@pupeno.com wrote: I found passing around the database connection to each function that uses it very error prone when you are using transactions as passing the wrong one could mean a query runs outside the transaction when in the source code