I know this is kind of a snarky response, but seriously... why? This would take developer resources away from real feature work, introduce boatloads of complexity, add more points of failure, make testing and validation harder and make it harder to reason about the entire system end-to-end. Not that that isn't sometimes necessary, but you need a compelling reason, not just jumping into it because it sounds like a good idea.
Programmers have this strange compulsion to design swappable interfaces even when they're totally unnecessary and more often than not just break everything while– ironically– only one implementation is ever used.
YAGNI.
To allow others to impl the data store they want and to avoid having to write blog posts like these.
It's not that much real work to quickly pull out an iface on a stable system. Assuming it would be just mostly pass-through to your main impl anyways and this is a common approach in refactorization. You don't need some huge system, just drop it back a layer and abstract it.
Often, what you end up learning about your system when you do this minimal work (again, nothing big) is that you screwed up and buried SQL and string concatenation and a bunch of other hard-to-review pieces all throughout your app because you keep a stranglehold on terms like YAGNI when separation of concerns has real value. Sometimes you also end up learning that your tests don't cover what you thought they did. Nobody wants bloat, but this adds very little and helps devs clamoring for alternative stores.
But why?
For the longest time MySQL didn't support window function or CTEs. What do you do if you're using those? (I'm not sure of SQLite's window support, but I'm pretty sure it has CTEs.)
If you're using postgres, should you not use pg_trgm (trigram indexer to use an index for regex searches on text), postgis (GIS tools), pg-routing (routing tools), ossp_uuid (uuid support), better types (boolean, range, inet, geometric, &c), or features such as RETURNING just because someone doesn't like my choice of database? No, I'm going to do what makes my life easier and my application faster and more featureful.
That's not a good enough reason. Those others need to first justify what the specific benefits of switching would be. I have a strong feeling that a lot of these people don't actually know why this change should be made beyond "I heard that SQLite 'isn't a real DB' but I don't know what that means". The customer is not always right; sometimes people making feature requests need to be told "No".
> It's not that much real work to quickly pull out an iface on a stable system
Maybe we've worked on different things, but this has not been my experience. IME, replacing a DBMS is agony, and adding an abstraction layer so you can use multiple DBMS's is agony exponentially magnified. Some of that is due to bad choices you made in the original design, but a lot of it is just because these systems will never behave identically, no matter what promises they make about SQL standards. Don't forget, also, that when you target multiple DBMS's, you're locking yourself into hitting the lowest common denominator of the intersection between their feature sets. You might end up making performance worse because you can no longer use DBMS-specific optimizations!
But this is all immaterial: no matter how much or how little work it is, it's all unnecessary work. If there's no benefit to switching, why do any work at all, especially when it has all the downsides I mentioned above.
> Often, what you end up learning about your system when you do this minimal work (again, nothing big) is that you screwed up and buried SQL and string concatenation and a bunch of other hard-to-review pieces....
I agree! So go through the app and fix those and then see if you still need to swap out the storage layer (which is actually what the author is recommending). Don't just do it because it's faddish before you've even established that it would actually add value.
Let me show you why is insane.
Imagine you work on Java. Do you build a DSL/Transpiler to Java so you MAYBE could change later to C#?
A RDBMS is even more important that the glue code. Why hide it, why think is something "easy" to trow away?
Why think is nut to code most or all the code on it?
Why would I do such a thing? I rarely ever promote abstraction for abstraction's sake and will in almost all cases disagree with premature abstraction. There are levels and for simple CRUD things, a thin contract over your DB is a reasonable tradeoff.
> A RDBMS is even more important that the glue code. Why hide it, why think is something "easy" to trow away?
I don't think you even need glue code. You just need a well-specified contract. You don't want to throw away anything of course.
> Why think is nut to code most or all the code on it?
I don't think that. Often it can be prudent to use plsql/triggers for things. Doesn't mean the frontend of your web app needs to build the SQL in the JS though, right? Just a high level "DoThing" contract with a description of what it should do is fine.
(I think "glue code" in parent referred to "what is not the UI or DB" BTW, i.e. the "Java app".)
When the database is the most fundamental thing, then trying to abstract away the database can be a bit like trying to abstract away the programming language you are using.
I have code where I would much rather rewrite the "backend" in another language than swap out the database.
I think it was a very good analogy to say that abstracting over database is a bit like abstracting over what programming language you are using.
0 - https://github.com/cretz/yukup/blob/eecb3b24b33f40e6a1eefaa5... 1 - https://github.com/cretz/yukup/tree/eecb3b24b33f40e6a1eefaa5...
It has drawbacks but if accepting several db is an important goal, you don't want to handcraft this unless you can measure inaceptable perfs.
I am admittedly unfamiliar with this specific case, but even a cursory glance showed me some sqlite-specific code embedded in the main library portion [0].
0 - https://github.com/beetbox/beets/blob/4f7c1c9beda6c2a5b0705e...