Postgresql PSQL写查询的抽象

Postgresql PSQL写查询的抽象,postgresql,go,interface,abstraction,Postgresql,Go,Interface,Abstraction,我有一个典型的函数,它从前端接收post请求,并将数据解码为结构,以便将其放入psql数据库。您可以看到下面的代码。我的问题是,我希望能够抽象这个函数,这样我就可以给它任何数量的任何类型的变量,这样对于每个请求,我就不必有单独的写处理程序 这看起来很难,因为我必须以某种方式传递到abstractvar profitReq profitReq,才能为任何结构工作。如果golang有某种求值字符串方法,我会知道怎么做,但如果我错了,有人会纠正我,但我认为不会 我需要改变的另一个地方是QueryRow

我有一个典型的函数,它从前端接收post请求,并将数据解码为结构,以便将其放入psql数据库。您可以看到下面的代码。我的问题是,我希望能够抽象这个函数,这样我就可以给它任何数量的任何类型的变量,这样对于每个请求,我就不必有单独的写处理程序

这看起来很难,因为我必须以某种方式传递到abstract
var profitReq profitReq
,才能为任何结构工作。如果golang有某种求值字符串方法,我会知道怎么做,但如果我错了,有人会纠正我,但我认为不会

我需要改变的另一个地方是QueryRow——我必须能够以可变数量的变量传递它。我可以很容易地构造字符串,但我不确定如何将变量附加到该查询中。例如,如果我将所有变量附加到一个数组中,我就不能将该数组传递到QueryRow中,因为它不是这样构造的。同样,这里某种形式的eval语句也会有所帮助

我是刚来golang的,但我见过很多与界面相关的很酷的东西,我承认我不太了解这些东西。有没有一种方法可以在这里使用一个有帮助的界面

感谢所有能帮忙的人

func Write_profit_table(profitWriteChannel chan string, profitType string, req *http.Request) {
    var profitReq profitReq;
    err := json.NewDecoder(req.Body).Decode(&profitReq);
    if err!=nil{
        log.Panic(err)
    }

    NotInDB, _ := Search_userinfo_table(profitReq.Email)

    if NotInDB == false {
        var lastInsertId int
        err2 := db.QueryRow("INSERT INTO profit(email, type, dateArray, amount, interest, compounded, recurring, name, description, profitFrom) 
                VALUES($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) returning uid;", 
                profitReq.Email, profitReq.Type, pq.Array(profitReq.DateArray), profitReq.Profit, profitReq.Interest, 
                profitReq.Compounded, profitReq.Recurring, profitReq.Name, profitReq.Description, profitReq.ProfitFrom).Scan(&lastInsertId);
        if err2!=nil{
            log.Panic(err2)
        }
    }

    profitWriteChannel<-"finished writing to profit"
}
func Write_profit_table(PROFITWriteChan字符串、profitType字符串、req*http.Request){
var profitReq profitReq;
err:=json.NewDecoder(req.Body).Decode(&profitReq);
如果错误!=零{
log.Panic(错误)
}
NotInDB,:=搜索用户信息表(profitReq.Email)
如果NotInDB==false{
var lastInsertId int
err2:=db.QueryRow(“插入利润(电子邮件、类型、日期数组、金额、利息、复利、周期性、名称、说明、利润来源))
返回uid的值($1、$2、$3、$4、$5、$6、$7、$8、$9、$10)。“,
profitReq.Email,profitReq.Type,pq.Array(profitReq.DateArray),profitReq.proit,profitReq.Interest,
profitReq.composited、profitReq.recurtive、profitReq.Name、profitReq.Description、profitReq.ProfitFrom.Scan(&lastInsertId);
如果err2!=nil{
log.Panic(错误2)
}
}

profitWriteChannel您正在寻找的功能称为泛型。
Go 1.x不支持泛型
幸运的是,有一个

在那之前你能做什么

  • 复制您的代码(可能是您现在正在做的事情)
  • 使用接口
    如果您知道此方法将始终通过电子邮件进行查询,您可以为此创建简单的接口:
    type Emailer interface{email()string}

  • 使用空接口(
    interface{}
    )和反射来确定您有哪些列

  • 编写您自己的生成器。有点像(1),但您不必自己编写

  • 以下是它的要点:

    您正在寻找的功能称为泛型。
    Go 1.x不支持泛型
    幸运的是,有一个

    在那之前你能做什么

  • 复制您的代码(可能是您现在正在做的事情)
  • 使用接口
    如果您知道此方法将始终通过电子邮件进行查询,您可以为此创建简单的接口:
    type Emailer interface{email()string}

  • 使用空接口(
    interface{}
    )和反射来确定您有哪些列

  • 编写您自己的生成器。有点像(1),但您不必自己编写

  • 以下是它的要点:

    如果这正是你想要的,那就接受你为了方便而放弃性能的事实,要么像Go一样使用ORM包,要么使用Go以外的语言。我不建议尝试编写你自己的ORM——这听起来像是你目前正在走向的方向——因为这是一个臭名昭著的诱人的泥潭,请参见例如(“计算机科学的越南”)。如果您想要性能和方便,请转而考虑代码生成(甚至只是一个功能强大的文本编辑器和一些手肘润滑脂)。也许这是一种血腥的纯粹主义,但我真的不想通过在我和db之间添加一个抽象来解决我的问题。除非我不得不这样做,否则我会小心使用依赖项(如图形库或类似的库),因为它增加了另一个黑盒,在那里可能会发生错误,我必须进行调试。我不相信postgres驱动程序还不够好,抱歉:我不支持GORM,除非您正在寻求真正快速的开发。我的纯粹主义会阻止我使用单个写处理程序——您说您想要这样做——反射太高对于我来说,在大多数应用程序中,性能成本是我无法接受的,同时也增加了复杂性,这为许多错误留出了空间。因此,从我的角度来看,基本上只有缺点。相反,我只会解析DDL并自动生成查询函数:编译时工作,而不是运行时工作。但每个人都有自己的工作。嗯,是的,idk。我可能是我不打算使用下面写的反射抽象,因为我担心以后如何对代码进行推理(DRY vs.“我6个月前是怎么做到的?”.耸耸肩。Go需要泛型。如果你想找的就是这样,那就接受你为了方便而放弃性能的事实,要么像Go一样使用ORM包,要么使用Go以外的语言。我不建议尝试编写你自己的ORM——这听起来像你目前正在走向的方向——因为这是一个臭名昭著的诱人的泥潭,请参见e(“计算机科学的越南”)。如果你想要性能和便利性,请转而考虑代码生成(甚至只是一个功能强大的文本编辑器和一些手肘润滑脂)。也许这是一种思想血腥的纯粹主义,但我真的不想通过在我和db之间添加抽象来解决我的问题。除非我不得不这样做,否则我会小心使用依赖项(像一个图形库或类似的),因为它添加了另一个黑盒,在那里可能会发生错误,我必须调试