Indeed. The strength of Go's interfaces is precisely that a library provider does not need to create interfaces, unless they are critical to the implementation of the library. You should create these types of interfaces when you need them.
There's a subtle versioning problem here. If Go adds a method that applies to both the DB and Tx objects, the proposed interface could not add the method in question without breaking the compatibility promise. So that would mean an interface with a similar purpose but a new name, in order to maintain compatibility. There are differences in meaning between performing operations on the DB object vs. performing them on the Tx. Only in your code own do you know if it is safe to hide these distinctions behind an interface. In a transaction, it isn't necessary to close a statement after it is used, because it will be closed when the transaction ends <https://golang.org/pkg/database/sql/#Tx.Prepare>, whereas with the DB connection, explicit close is necessary <https://golang.org/pkg/database/sql/#DB.Prepare>. The sql package has really good reasons for forcing the clients to think about what they really need, rather than providing the proposed interface. Eric. On Thursday, January 16, 2020 at 9:36:50 AM UTC-8, Marcin Romaszewicz wrote: > > I have that exact interface in all of my DB code, and I never use sql.Tx > or sql.DB directly. You don't need Go's libraries to adopt this at all, > just use your own. > > On Wed, Jan 15, 2020 at 11:20 PM Mhd Shulhan <m.sh...@gmail.com > <javascript:>> wrote: > >> ## Problem >> >> At some point we have a function that receive an instance of database >> connection to query rows in specific table. >> >> Let's say that function F() accept DB that query table T. >> >> If function F() called with DB instance, it will query only rows that has >> been committed into database. >> >> IF function F() called with Tx instance, it will query all rows including >> the one that has not been committed yet into database. >> >> Since DB and Tx are different types, we will have two functions that >> almost have identical code, >> >> func F(db *sql.DB) (output int) { >> q := `SELECT … FROM T WHERE …` >> err := db.QueryRow(q).Scan(&output) >> … >> return output >> } >> >> func FWithTx(tx *sql.Tx)(output int) { >> q := `SELECT … FROM T WHERE …` >> err := tx.QueryRow(q).Scan(&output) >> … >> return output >> } >> >> >> ## Proposed solution >> >> Add an interface Session (the name is not fixed yet) to package sql with >> the following signature, >> >> type Session interface { >> func Exec(query string, args ...interface{}) (Result, error) >> func ExecContext(ctx context.Context, query string, args >> ...interface{}) (Result, error) >> func Prepare(query string) (*Stmt, error) >> func PrepareContext(ctx context.Context, query string) (*Stmt, error) >> func Query(query string, args ...interface{}) (*Rows, error) >> func QueryContext(ctx context.Context, query string, args >> ...interface{}) (*Rows, error) >> func QueryRow(query string, args ...interface{}) *Row >> func QueryRowContext(ctx context.Context, query string, args >> ...interface{}) *Row >> } >> >> Session interface is combination of DB and Tx that contains all identical >> methods. >> >> >> ## Rationale >> >> Without Session, user will have two functions that have the same code, >> >> By using Session, we can minimise duplicate code in the user level. for >> example using the previous problems definition the function F() become one, >> >> func F(session sql.Session)(output int) { >> q := `SELECT … FROM T WHERE …` >> err := session.QueryRow().Scan(&output) >> … >> return output >> } >> >> >> ## Discussion >> >> Any thought about this proposal? >> >> -- >> You received this message because you are subscribed to the Google Groups >> "golang-nuts" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to golan...@googlegroups.com <javascript:>. >> To view this discussion on the web visit >> https://groups.google.com/d/msgid/golang-nuts/C8AB29FF-7A85-445A-B09E-A0E7CB322A4C%40gmail.com >> . >> > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/9f4cab90-67e0-4f85-83d9-8e4f4e8c0ff7%40googlegroups.com.