1

少し「賢く」なり、ボイラープレートSQLコードの一部を抽象化しようと思いました(sqlxを使用 - https://github.com/jmoiron/sqlx)。アイデアは、結果を処理するための関数ポインターをコードにフィードし、行を生成する SQL 文字列と引数を渡すことです。たまたま、「sqlArgs インターフェイス」のものを削除すれば、コードは正常に機能しますが、「より賢い」形式ではステートメントでエラーが発生します

sql: Exec 引数 $1 を変換しています タイプ: サポートされていないタイプ []interface {}、インターフェイスのスライス

ここに 2 つのバージョンがあります。最初のバージョンではエラーが発生し、2 番目のバージョンでは機能しますが、パラメーター化されていません。

//GetRows (doesn't work)
func GetRows(parseRows func(*sqlx.Rows), sql string, sqlArgs ...interface{}) {
    db := sqlx.MustConnect("mysql", ConnString)

    defer db.Close()

    rows, err := db.Queryx(sql, sqlArgs)

    defer rows.Close()

    if err != nil {
        panic(err)
    }

    parseRows(rows)

}

//GetRows ... (works, but doesn't allow parameterization)
func GetRows(fp func(*sqlx.Rows), sql string) {

    db := sqlx.MustConnect("mysql", ConnString)

    defer db.Close()

    rows, err := db.Queryx(sql)

    defer rows.Close()

    if err != nil {
        panic(err)
    }

    fp(rows)

}

アイデアは、コードを次のように呼び出すことです。

func getUser(userID string) User {

    var users []*User

    parseRows := func(rows *sqlx.Rows) {
        for rows.Next() {
            var u User
            err := rows.StructScan(&u)

            if err != nil {
                panic(err)
            }

            users = append(users, u)
        }
    }

    sql := "SELECT * FROM users WHERE userid = ?;"

    sqlutils.GetRows(parseRows, sql, userID)

    if len(users) == 1{
        return users[0]
    }

    return User{}

}

私のコードは実際には呼び出しから呼び出しへと userID を通過するのではなく、SQL パッケージが処理できない []interface{} を通過すると思います。しかし、それについてはよくわかりません。いずれにせよ、このアイデアを実現する方法はありますか? ありがとう。

4

0 に答える 0