dongzhong8834 2018-01-24 20:49
浏览 28
已采纳

Golang标准包装结构

I am faily new to Go and I am trying to create a structured application using guidance from Ben Johnson's webpage. Unfortunately, his example is not a complete working application.

His webpage is https://medium.com/@benbjohnson/standard-package-layout-7cdbc8391fc1

I have tried to use his methods and I keep getting "Undefined: db" error. It doesn't tell me what line is causing the error, just the file "MSSQL.go"

Could someone help with guidance to help me fix this error?

Edited code with accepted solution.

StatementPrinter.go

    package statementprinter

    type Statement struct {
      CustomerId   string
      CustomerName string
    }

    type StatementService interface {
      Statement(id string) (*Statement, error)
    }

main.go

            package main

            import (
              "fmt"
              "log"
              "github.com/ybenjolin/StatementPrinter"
              "github.com/ybenjolin/StatementPrinter/mssql"
              "database/sql"
              _ "github.com/alexbrainman/odbc"
            )

            const DB_INFO = "Driver={SQL Server};Server=cdc-edb2;Database=CostarReports;Trusted_Connection=yes;"

            var db *sql.DB

            func init() {
              var err error
              db, err = sql.Open("odbc", DB_INFO)
              if err != nil {
                log.Fatal("Error opening database connection.
", err.Error())
              }
              err = db.Ping()
              if err != nil {
                log.Fatal("Error pinging database server.
", err.Error())
              }
              fmt.Println("Database connection established.")
            }

            func main () {
              var err error
              defer db.Close()

              // Create services
              // Changes required here. Was ss := &statementprinter.Stat..
              ss := &mssql.StatementService{DB: db}

              // Use service
              var s *statementprinter.Statement
              s, err = ss.Statement("101583")
              if err != nil {
                log.Fatal("Query failed:", err.Error())
              }
              fmt.Printf("Statement: %+v
", s)
            }

mssql.go

    package mssql  

    import (
      _ "github.com/alexbrainman/odbc"
      "database/sql"
      "github.com/ybenjolin/StatementPrinter"
    )

    // StatementService represents a MSSQL implementation of statemenetprinter.StatementService.
    type StatementService struct {
      DB *sql.DB
    }

    // Statement returns a statement for a given customer.
    func (s *StatementService) Statement(customer string) (*statementprinter.Statement, error) {
      var err error
      var t statementprinter.Statement
      // Changes required here. Was row := db.Query......
      row := s.DB.QueryRow(`Select Customer, CustomerName From AccountsReceivable.rptfARStatementHeader(?)`, customer)
      if row.Scan(&t.CustomerId, &t.CustomerName); err != nil {
        return nil, err
      }
      return &t, nil
  • 写回答

1条回答 默认 最新

  • duanjia8215 2018-01-24 21:39
    关注

    This seems like it's just a typo. It seems like the problematic line is in the method

     func (s *StatementService) Statement(customer string) 
    

    in mssql.go,

      row := db.QueryRow(`Select Customer, CustomerName From AccountsReceivable.rptfARStatementHeader(?)`, customer)
    

    QueryRow is supposed to be a method of db, but db is not defined. However, in the struct

    type StatementService struct {
      DB *sql.DB
    }
    

    there's a *sql.DB instance. The method you're using has a *StatementService parameter, s. So, my guess is the intention would be to access the sql.DB field in s like so

    func (s *StatementService) Statement(customer string) (*statementprinter.Statement, error) {
      var err error
      var t statementprinter.Statement
       //CHANGED LINE:
      row := s.DB.QueryRow(`Select Customer, CustomerName From AccountsReceivable.rptfARStatementHeader(?)`, customer)
      if row.Scan(&t.CustomerId, &t.CustomerName); err != nil {
        return nil, err
      }
      return &t, nil
    

    Then, the method is called in main.go, and is passed a StatementService instance that contains a database:

    ss := &statementprinter.StatementService{DB: db}
    

    I believe you need to change this line to

    ss := &mssql.StatementService{DB: db}
    

    becuase that's the actual interface implementation. The line you have now treats the StatementService interface like a struct which will not compile. The global db in main.go lives for the lifetime of the application. It's just a pointer which is copied around for use.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥170 如图所示配置eNSP
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改
  • ¥20 wireshark抓不到vlan
  • ¥20 关于#stm32#的问题:需要指导自动酸碱滴定仪的原理图程序代码及仿真
  • ¥20 设计一款异域新娘的视频相亲软件需要哪些技术支持
  • ¥15 stata安慰剂检验作图但是真实值不出现在图上
  • ¥15 c程序不知道为什么得不到结果
  • ¥15 键盘指令混乱情况下的启动盘系统重装