I am trying to connect a Go REST API to a backend FileMaker based database over ODBC.
I have successfully installed the FileMaker ODBC drivers on Windows and the DSN is working.
I am using the mgodbc
package in Go to connect to the DB.
However, while the connection works (no runtime error), I just get blank/null records back when I run a query. I have the following code to create a DB connection:
func NewDB(dataSourceName string) (*DB, error) {
db, err := sql.Open("mgodbc", dataSourceName)
if err != nil {
return nil, err
}
if err = db.Ping(); err != nil {
return nil, err
}
// TEST
return &DB{db}, nil
}
This gets called from my main
method as follows: db, err := md.NewDB("DSN=cet_registrations2;Uid=*****;Pwd=*****;")
. I then call one of my query methods and try to read it into a model struct
. I have simplified my query to make it easier:
func (db *DB) GetStudent(id int) (*Student, error) {
s := new(Student)
p := new(PersonalDetails)
log.Println(id)
rows, err := db.Query("SELECT FN_Gn_Pn FROM STUDENTS")
i := 0
if err != nil {
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
i++
err := rows.Scan(&p.FirstName)
log.Print(p.FirstName.String)
log.Printf(strconv.Itoa(i))
if err != nil {
log.Fatal(err)
}
}
err = rows.Err()
if err != nil {
log.Fatal(err)
}
s.ID = 34114
s.Details = p
return s, err
}
and I am reading into the following struct
:
import (
"database/sql"
u "sydney.edu.au/bric9018/cet.api/util"
)
type PersonalDetails struct {
// Unique identifier for person
ID int32 `json:"id,omitempty"`
// First name of person
FirstName sql.NullString `json:"firstName,omitempty"`
// Last name of person.
LastName sql.NullString `json:"lastName,omitempty"`
// Person nominated preferrered name.
PreferredName sql.NullString `json:"preferredName,omitempty"`
// Person's SSO username for University systems
Unikey sql.NullString `json:"unikey,omitempty"`
// Person's personal email
PersonalEmail sql.NullString `json:"personalEmail,omitempty"`
// Sydney University email
UniEmail sql.NullString `json:"uniEmail,omitempty"`
// Person's date of birth
Dob u.NullTime `json:"dob,omitempty"`
}
However, I just get completely blank rows when I print the value scanned into the model using log.Print(p.FirstName.String)
. I don't seem to be getting any values read back by scan into my struct
. Why is this?
P.S. the query definitely returns values when I run it in SQL Server over a linked server connection against the FileMaker DB.
Golang odbc driver is a wrapper of system's odbc driver (odbc32.dll, unixODBC
, etc). If you got any result when executing the query in SQL Server, it eliminates the probability of query error or system's driver problem. Then the problem will be in golang's driver (mgodbc
) side. Possible issues:
scan the result to []byte
.Because the database in question is not available to us, its impossible for us to reproduce the problem. To learn what was the problem, please use debugger. Personally I'm using Visual Studio Code. To setup the debugger, please refer to VS Code and delve debugger.
My guess, the problem exist in mgodbc's Next
function (line number 781-1011). The odbc's
implementation of Next
function is available here (line 35). The function relies on column.Value
function (line 116-165) to convert the query result. Using debugger, you can observe variable(s), expression(s) and compare how these drivers handle query result conversion.