Should conditional logic be handled inside the database or on the server? I think it tends to not matter, but it feels like having them in the database gives much tighter constraints on what states are possible. e.g a user needs a certain role to update a table, that check happening on the server could mean their role is changed between when the server gets the information and when the request up update the tables is made. Basically having the check in the db makes the full request atomic.
There are two different things at play here, one is the implementation of the business logic, the other is handling transaction guarantees in a reasonable way. In Datomic you can write transactor functions, yes, but you can also write a "transaction data generator" on the server that converts everything to datomic primitives (including :db.fn/cas) and possibly some id generating functions as transaction functions. In SQL you can (probably) do the same thing - a "data update statement generator" that also somehow need to guarantee that the state we derived the transaction change from is still intact. This is not to be confused with implementing the business logic in the database statements/database functions. Database functions and the like could still be nescessary to be able to fulfil transaction guarantees.
@drewverlee If you're concerned about race conditions, you can either work with transactions or you can ensure your updates also check the condition, and then check result -- how many rows were updated -- to verify success. It depends on how time-critical such things need to be.
thansk @oscarlinusericsson and @seancorfield i'll chew on this.
I'm a big fan of trying to keep the database as purely a persistence mechanism, and therefore have no logic in the db.
The tables themselves wouldn't have logic (e.g triggers or constraints) but a db function could wrap the intent e.g only admins can delete users.
I guess i'm assuming the conditional logic in postgres actually makes a transaction...
IF ELSE branchs.
It seems like it is according to Gemini (with some slight modifications).
I've ended up on projects where the database is the integration mechanism. That turned into a lot of stored procedures and constraints. Not fun. I share @seancorfield's opinion.
@neumann
Sure, but there is difference between a constraint within a DB function/procedure (same thing right?) and one on your server.
If i write if user = admin on my server, based off a user session, and by the time they get around to issuing that query, their no longer an admin, because someone removed their privilege, the DB would be able to see that change, but the server would have stale data. Does that matter? Most of the time probable not, but it's different and i feel like the reason I don't consider the DB function route isn't because it's better for the use cases i have in mind, but because i'm less good at writing DB functions and understanding them then working with clojure.
One of potential upsides of Datomic was that you could write your DB functions in clojure... of course it's still tricky...
Since datomic's mechanisms were mentioned, might as well mention Rama, where microbatch topologies give you exclusive access to local data, thus guaranteeing ACID semantics. Maybe you're not going to use it, but hey that's another approach https://redplanetlabs.com/docs/~/acid.html#gsc.tab=0
thanks @pavel.filipenco