<p dir="auto">seems like 90% of the time I'm interacting with a database most of my DB code doesn't care if i'm within a TX or not. often there are queries I'm executing in various places with different contexts, some of which require a transaction, some which don't. But I can't share the code without writing my own Queryer style interface. now granted its only a few lines, but it seems like this is something that should just be in the sql package itself.</p>
<p dir="auto">I'm happy to do the work, submit the PR etc. just curious if there is any object to adding it and why.</p>
<p dir="auto">Hi,</p>
<p dir="auto">I'm proposing a interface that implements all functions in <code class="notranslate">sql.DB</code> and <code class="notranslate">sql.Tx</code> that takes a <code class="notranslate">query string</code> as one of its arguments. This could be useful when implementing "dumb" functions that retrieves information but in itself dose not need to be prepared however might be used to verify whether to commit or rollback.</p>
<p dir="auto">The interface I'm proposing is: (The name can of course be changed)</p>
<div class="highlight highlight-source-go notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="type QueryAble interface {
    Exec(query string, args ...interface{}) (sql.Result, error)
    Prepare(query string) (*sql.Stmt, error)
    Query(query string, args ...interface{}) (*sql.Rows, error)
    QueryRow(query string, args ...interface{}) *sql.Row
}"><pre class="notranslate"><span class="pl-k">type</span> <span class="pl-smi">QueryAble</span> <span class="pl-k">interface</span> {
    <span class="pl-c1">Exec</span>(<span class="pl-s1">query</span> <span class="pl-smi">string</span>, <span class="pl-s1">args</span> <span class="pl-c1">...</span><span class="pl-k">interface</span>{}) (sql.<span class="pl-smi">Result</span>, <span class="pl-smi">error</span>)
    <span class="pl-c1">Prepare</span>(<span class="pl-s1">query</span> <span class="pl-smi">string</span>) (<span class="pl-c1">*</span>sql.<span class="pl-smi">Stmt</span>, <span class="pl-smi">error</span>)
    <span class="pl-c1">Query</span>(<span class="pl-s1">query</span> <span class="pl-smi">string</span>, <span class="pl-s1">args</span> <span class="pl-c1">...</span><span class="pl-k">interface</span>{}) (<span class="pl-c1">*</span>sql.<span class="pl-smi">Rows</span>, <span class="pl-smi">error</span>)
    <span class="pl-c1">QueryRow</span>(<span class="pl-s1">query</span> <span class="pl-smi">string</span>, <span class="pl-s1">args</span> <span class="pl-c1">...</span><span class="pl-k">interface</span>{}) <span class="pl-c1">*</span>sql.<span class="pl-smi">Row</span>
}</pre></div>
<p dir="auto">This is an example function <code class="notranslate">Get</code> that can be used with or without transactions.</p>
<div class="highlight highlight-source-go notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="func Get (q Queryable)(int){
    var test int
    res , _ := q.Query(&quot;SELECT COUNT(*) FROM table;&quot;)
    res.Next()
    res.Scan(&amp;test)
    res.Close()
    return test
}

func GetExample(db *sql.DB){

    //When you just want to retrieve the information, no need for a transaction
    fmt.Printf(&quot;Current len of Table %d\n&quot;, Get(db))

    //Make a change
    tx, _ :=db.Begin()
    // Add data to table
    if  Get(tx) &gt; 2 {
        fmt.Printf(&quot;Table to large: %d robacking to: %d \n&quot;, Get(tx) , Get(db))
        tx.Rollback()
    } else {
        fmt.Printf(&quot;Table update new len %d\n&quot;, Get(tx))
        tx.Commit()
    }
}"><pre class="notranslate"><span class="pl-k">func</span> <span class="pl-en">Get</span> (<span class="pl-s1">q</span> <span class="pl-smi">Queryable</span>)(<span class="pl-smi">int</span>){
    <span class="pl-k">var</span> <span class="pl-s1">test</span> <span class="pl-smi">int</span>
    <span class="pl-s1">res</span> , <span class="pl-s1">_</span> <span class="pl-c1">:=</span> <span class="pl-s1">q</span>.<span class="pl-en">Query</span>(<span class="pl-s">"SELECT COUNT(*) FROM table;"</span>)
    <span class="pl-s1">res</span>.<span class="pl-en">Next</span>()
    <span class="pl-s1">res</span>.<span class="pl-en">Scan</span>(<span class="pl-c1">&amp;</span><span class="pl-s1">test</span>)
    <span class="pl-s1">res</span>.<span class="pl-en">Close</span>()
    <span class="pl-k">return</span> <span class="pl-s1">test</span>
}

<span class="pl-k">func</span> <span class="pl-en">GetExample</span>(<span class="pl-s1">db</span> <span class="pl-c1">*</span>sql.<span class="pl-smi">DB</span>){

    <span class="pl-c">//When you just want to retrieve the information, no need for a transaction</span>
    <span class="pl-s1">fmt</span>.<span class="pl-en">Printf</span>(<span class="pl-s">"Current len of Table %d<span class="pl-cce">\n</span>"</span>, <span class="pl-en">Get</span>(<span class="pl-s1">db</span>))

    <span class="pl-c">//Make a change</span>
    <span class="pl-s1">tx</span>, <span class="pl-s1">_</span> <span class="pl-c1">:=</span><span class="pl-s1">db</span>.<span class="pl-en">Begin</span>()
    <span class="pl-c">// Add data to table</span>
    <span class="pl-k">if</span>  <span class="pl-en">Get</span>(<span class="pl-s1">tx</span>) <span class="pl-c1">&gt;</span> <span class="pl-c1">2</span> {
        <span class="pl-s1">fmt</span>.<span class="pl-en">Printf</span>(<span class="pl-s">"Table to large: %d robacking to: %d <span class="pl-cce">\n</span>"</span>, <span class="pl-en">Get</span>(<span class="pl-s1">tx</span>) , <span class="pl-en">Get</span>(<span class="pl-s1">db</span>))
        <span class="pl-s1">tx</span>.<span class="pl-en">Rollback</span>()
    } <span class="pl-k">else</span> {
        <span class="pl-s1">fmt</span>.<span class="pl-en">Printf</span>(<span class="pl-s">"Table update new len %d<span class="pl-cce">\n</span>"</span>, <span class="pl-en">Get</span>(<span class="pl-s1">tx</span>))
        <span class="pl-s1">tx</span>.<span class="pl-en">Commit</span>()
    }
}</pre></div>