Wow, I find this quite interesting, however, there are probably some real downsides to this? Maybe someone else can highlight some of those.
An issue I can think of is for instance: consider a system where each time a new request comes in a new transaction is started. That situation would result in having a new `DBImpl struct` for each request. It seems that that last "but you probably only have one of these DB objects" doesn't hold. How would you tackle that issue?
Sure, if you want to compose the various methods into a single transaction, then each business-logic-implementing function needs to take a transaction object as a parameter. In that case, you don't even need something like DBImpl.
Looking at database code I have written, I never do the object thing (but was replying to an author who does). I typically have a package with functions that take transactions as an argument, like this:
(If you poke around the package, methods that don't make more than one database call take a sqlx.ExtContext instead of a *sqlx.Tx. Functions that need to start their own transactions take the connection instead, though I'm not sure I'd recommend that approach because it hurts composability.)
To test it, I just run against an actual Postgres instance which is pretty easy to find. (I am not sure I would steal my database setup / teardown utilities from that project. The tests end up indented too far. A more idiomatic Go way is "app := testapp.New(); defer app.Cleanup(); tests go here"; in that codebase I picked the "testapp.Test(t, func(t testing.TB) { tests go here })" pattern. Definitely something I look for and avoid these days, but didn't in 2020 ;)
Thanks for your reply, very interesting, I didn't know about the `sqlx.ExtContext` interface yet! I will do a deeper dive into your project later, I'm hoping to find more inspiration.
An issue I can think of is for instance: consider a system where each time a new request comes in a new transaction is started. That situation would result in having a new `DBImpl struct` for each request. It seems that that last "but you probably only have one of these DB objects" doesn't hold. How would you tackle that issue?