first of all: I am totally newbie in golang, so I may not understand well.
I am tasked to write a Go data extractor from one database using "gorp". The problem is with one table, that has custom field "TimeRange".
It is defined as:
type TimeRange struct {
From string
To string
}
Sadly when I try to fetch row I am getting scanner error, so I realised I need a custom scanner.
// Scan - Implement the database/sql scanner interface
func (tr *TimeRange) Scan(value interface{}) error {
tr.From = "mis"
tr.To = "lala"
fmt.Printf("%v\n", *tr)
return nil
}
So I expect to see fixed '{mis lala}' in returned string.
Why I am getting:
var q2 []models.Dashboard
result, err := dbmap.Select(&q2, "select * from dashboard where id=3")
fmt.Printf("q2=%v\n", q2)
prints:
p2=[{{<nil> Tomek b1f6f0ba-f618-00d6-6d24-8410a9219c95}}]
which is:
TimeRange, UserName and UUID
Might be important: using "gorp" for DB managment
the scan function would be called on passed value type to dbmap.Select() so in your case, you need to implement Dashboard as scanner.
Related
I've been playing around and learning how to make Word docs programmatically. I know it can easily be done using pywin32. This simple snippet retrieves the default Visual Basic "code" inside the new Word doc.
import win32com.client
word = win32com.client.Dispatch("Word.Application")
word.Visible = True
document = word.Documents.Add()
document.VBProject.Name = "TEST"
wordModule = document.VBProject.VBComponents("ThisDocument") # WORKS
input()
You can then add VB code to wordModule.
I wanted to do the same using Golang. There is a OLE binding for Go, the code is on Github -> https://github.com/go-ole/go-ole
It's a bit less user friendly but I managed to make it work, except that I'm not able to retrieve the default VBComponents.
The default code resides in "ThisDocument" and can be retrieved with the simple python code document.VBProject.VBComponents("ThisDocument") except that, it doesn't work in Go...
You can see in the code below that I tried to get "ThisDocument" using multiple ways, without success. Each time, the error message is panic: Unknown name.
// +build windows
package main
import (
"fmt"
ole "github.com/go-ole/go-ole"
"github.com/go-ole/go-ole/oleutil"
)
func main() {
defer ole.CoUninitialize()
ole.CoInitialize(0)
unknown, _ := oleutil.CreateObject("Word.Application")
word, _ := unknown.QueryInterface(ole.IID_IDispatch)
oleutil.PutProperty(word, "Visible", true)
documents := oleutil.MustGetProperty(word, "Documents").ToIDispatch()
document := oleutil.MustCallMethod(documents, "Add").ToIDispatch()
vbproject := oleutil.MustGetProperty(document, "VBProject").ToIDispatch()
oleutil.PutProperty(vbproject, "Name", "TEST")
// oleutil.MustCallMethod(vbproject, "VBComponents", "ThisDocument").ToIDispatch() --> panic: Unknown name.
// oleutil.MustGetProperty(vbproject, "VBComponents", "ThisDocument").ToIDispatch() --> panic: Unknown name.
// vbcomponents := oleutil.MustGetProperty(vbproject, "VBComponents").ToIDispatch()
// oleutil.MustGetProperty(vbcomponents, "ThisDocument").ToIDispatch() --> panic: Unknown name.
var input string
fmt.Scanln(&input)
oleutil.PutProperty(document, "Saved", true)
oleutil.CallMethod(documents, "Close", false)
oleutil.CallMethod(word, "Quit")
word.Release()
}
Any ideas on why it doesn't work?
Thanks a lot.
Turns out "github.com/go-ole/go-ole" has a bug when using ForEach. VBComponets is a Collection, so you have to iterate as stated by Microsoft doc
Use the VBComponents collection to access, add, or remove components in a project. A component can be a form, module, or class. The VBComponents collection is a standard collection that can be used in a For...Each block.
This line -> https://github.com/go-ole/go-ole/blob/master/oleutil/oleutil.go#L106
should be replace by
newEnum, err := disp.CallMethod("_NewEnum")
Now it works as intended.
I have nullable variables I'm trying to use in my app, and also send to a database which has columns that are default null.
This is a sample struct:
// Location type
type Location struct {
ID int `schema:"id"`
Title *string `schema:"title"`
}
Title is defined as *string, as it could be null (e.g. no user input or client app sends it as null).
Here’s my function receiving form data:
// JSONLocationCreate func
func (a *App) JSONLocationCreate(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
var e Location
err := decoder.Decode(&e, r.PostForm)
if err != nil {
respondWithError(w, http.StatusBadRequest, "Invalid request payload")
return
}
// --- SUCCESS ---
// If e.Title has data, the following line works.
// --- FAIL ---
// If e.Title doesn’t have data (for whatever reason), it’s null, and crashes the app:
log.Println(*e.Title)
// Ultimately the variable would be sent off to a database.
// Below I’m removing other functions and such, just including my statement line.
// --- SUCCESS ---
// If e.Title has data, the following line works.
// --- FAIL ---
// If e.Title is null (e.g. no user input), this crashes the app.
statement := fmt.Sprintf("INSERT INTO locations(title) VALUES('%s')", *e.Title)
// In either case, the crash error is similar to this:
// panic serving [::1]:52459: runtime error: invalid memory address or nil pointer dereference
}
CONCERN 1: How can I make use of nullable variables (like e.Title), throughout the app, without throwing panic errors when the variable is null? Is the best practice to wrap it in a function that converts null to “” strings? How can such a function be applied transparently, so I don’t have to have something like “nullCheck(*e.Title)” on every instance of the variable?
CONCERN 2: In the case of my DB queries, I can’t be sending “” string values into the database in place of nulls. Up to now my queries are manually built. I suppose I need a function to generate the SQL queries automatically excluding columns and variables when the variables are null.
Am I on the right track? Any examples?
I haven’t understood all the threads/tutorials after hours of searching.
CONCERN 1 is easily remedied by adding a getter method for your fields
func (l Location) GetTitle() string {
if l.Title == nil {
return ""
}
return *l.Title
}
CONCERN 2:
It depends on what sql queries do you want to make, I would suggest that you look into some ORM libraries, which automate a lot of DB-specific code for you. Gorm is a good example of such library: https://github.com/jinzhu/gorm
I am trying to understand the code that is used at my company. I am new to go lang, and I have already gone through the tutorial on their official website. However, I am having a hard time wrapping my head around empty interfaces, i.e. interface{}. From various sources online, I figured out that the empty interface can hold any type. But, I am having a hard time figuring out the codebase, especially some of the functions. I will not be posting the entire thing here, but just the minimal functions in which it has been used. Please bear with me!
Function (I am trying to understand):
func (this *RequestHandler) CreateAppHandler(rw http.ResponseWriter, r *http.Request) *foo.ResponseError {
var data *views.Data = &views.Data{Attributes: &domain.Application{}}
var request *views.Request = &views.Request{Data: data}
if err := json.NewDecoder(r.Body).Decode(request); err != nil {
logrus.Error(err)
return foo.NewResponsePropogateError(foo.STATUS_400, err)
}
requestApp := request.Data.Attributes.(*domain.Application)
requestApp.CreatedBy = user
Setting some context, RequestHandler is a struct defined in the same package as this code. domain and views are seperate packages. Application is a struct in the package domain. The following two structs are part of the package views:
type Data struct {
Id string `json:"id"`
Type string `json:"type"`
Attributes interface{} `json:"attributes"`
}
type Request struct {
Data *Data `json:"data"`
}
The following are part of the package json:
func NewDecoder(r io.Reader) *Decoder {
return &Decoder{r: r}
}
func (dec *Decoder) Decode(v interface{}) error {
if dec.err != nil {
return dec.err
}
if err := dec.tokenPrepareForDecode(); err != nil {
return err
}
if !dec.tokenValueAllowed() {
return &SyntaxError{msg: "not at beginning of value"}
}
// Read whole value into buffer.
n, err := dec.readValue()
if err != nil {
return err
}
dec.d.init(dec.buf[dec.scanp : dec.scanp+n])
dec.scanp += n
// Don't save err from unmarshal into dec.err:
// the connection is still usable since we read a complete JSON
// object from it before the error happened.
err = dec.d.unmarshal(v)
// fixup token streaming state
dec.tokenValueEnd()
return err
}
type Decoder struct {
r io.Reader
buf []byte
d decodeState
scanp int // start of unread data in buf
scan scanner
err error
tokenState int
tokenStack []int
}
Now, I understood that, in the struct Data in package views, Application is being set as a type for the empty interface. After that, a pointer to Request in the same package is created which points to the variable data.
I have the following doubts:
What exactly does this keyword mean in Go? What is the purpose of writing this * RequestHandler?
Initialization of a structure in Go can be done while assigning it to a variable by specifying the values of all it's members. However, here, for the struct Data, only the empty interface value is assigned and the values for the other two fields are not assigned?
What is the advantage of assigning the Application struct to an empty interface? Does it mean I can use the struct members using the interface variable directly?
Can someone help me figure out the meaning of this statement? json.NewDecoder(r.Body).Decode(request)?
While I know this is too much, but I am having a hard time figuring out the meaning of interfaces in Go. Please help!
this is not a keyword in go; any variable name can be used there. That is called the receiver. A function declared in that way must be called like thing.func(params), where "thing" is an expression of the type of the receiver. Within the function, the receiver is set to the value of thing.
A struct literal does not have to contain values for all the fields (or any of them). Any fields not explicitly set will have the zero value for their types.
As you said, an empty interface can take on a value of any type. To use a value of type interface{}, you would use type assertion or a type switch to determine the type of the value, or you could use reflection to use the value without having to have code for the specific type.
What specifically about that statement do you not understand? json is the name of a package in which the function NewDecoder is declared. That function is called, and then the Decode function (which is implemented by the type of the return value of NewDecoder) is called on that return value.
You may want to take a look at Effective Go and/or The Go Programming Language Specification for more information.
I am writing a web application in Go and use Neo4j database for storing data. As Neo4j api to Go, i choose neoism.
However, look at the following code snippet.
db, _ := neoism.Connect("http://localhost:7474/db/data")
// Create a node with a Cypher quer
// Issue a query
//
res1 := []struct {
A string `json:"n.email"`
}{}
cq1 := neoism.CypherQuery{
//Use backticks for long statements - Cypher is whitespace indifferent
Statement: `
MATCH (n:Account {email: {email}})
RETURN n.email
`,
Parameters: neoism.Props{"email": "hans#ueli.com"},
Result: &res1,
}
db.Cypher(&cq1)
fmt.Println(res1)
I query here data from node Account and got a result return, everything works fine here.
The second code almost the same, but I am creating here directly(variable res2) a pointer slice.
// Validate, if email already available in db
res2 := []*struct {
A string `json:"n.email"`
}{}
cq := &neoism.CypherQuery{
Statement: `
MATCH (n:Account {email: {email}})
RETURN n.email
`,
Parameters: neoism.Props{"email": "hans#ueli.com"},
Result: res2,
}
db.Cypher(cq)
fmt.Println(res2)
The difference between them are, I've got by the first sample a result but second not.
Result:
[{hans#ueli.com}]
[]
What do I wrong with pointer res2 here?
From the neoism documentation:
Result must be a pointer to a slice of structs - e.g. &[]someStruct{}
Nothing is said about slices of struct pointers, so I assume that your slice is empty because the function is not expecting pointers, so it couldn't put anything in the slice.
I encountered the same behavior when giving sqlx.Query the wrong type of slice. The lacks of error is quite frustrating the first times, but it quickly becomes a reflex.
From logic point of view I am trying to preserve partial form data between redirects for better user experience so user won't have to fill entire form again, just the part that was invalid.
From programing point of view I am trying to save request.PostForm data structure in gorilla session's flashes. The only thing I manage to retrieve after redirect is string representation of memory address like this [0xc2001c8b10].
Here is the part where I save flashes data after validation error (request.ParseForm() was executed before this):
session, _ := store.Get(request, "test")
session.AddFlash(err.Error(), "messages")
session.AddFlash(request.PostForm, "form_data")
session.Save(request, response)
http.Redirect(response, request, "/", http.StatusFound)
return
Also I tried registering structure with gob without effect:
func init() {
gob.Register(&url.Values{})
}
Form values are in lower case, eg. "first_name", "last_name" if that could have any influence on this behavior.
Please keep in mind that I successfully manage to retrieve "messages" after redirect, only problem I have is with structural data.
Am I doing something wrong or is there maybe another approach to fill partial forms after redirect that I am not aware of?
Your problem is that you're working with values of type interface{}, which is the generic type
and used when there can be more than one type. This is the case for gorilla's session.Flashes()
method as it can return arbitrary user data (whatever you put in).
You can reproduce what you're experiencing with this code (on play):
type MyData struct {
X int
}
// Simulate Flashes() from gorilla, which returns a slice of interface{} values.
func Flashes() []interface{} {
x := &MyData{2}
// Convert x to type interface{}
interfaceValue := interface{}(x)
// Put converted x into a slice of type []interface{}
return []interface{}{interfaceValue}
}
func main() {
// See that [0xSOMETHING] is printed
fmt.Println("Some data:", Flashes())
}
When running this program you will see output like this:
Some data: [0xc010000000]
This is the same you're experiencing. The reason for this is that fmt.Println does
not step through all levels of abstraction of pointers and interfaces and stops at
a certain level unless you tell it to print everything. So if you use
fmt.Printf("Some data: %#v\n", Flashes())
you will indeed see your data:
Some data: []interface {}{(*main.MyData)(0xc010000000)}
What you have to do to access the data is to match the resulted data for the type
you're expecting. You have to do a type assertion (example on play):
func main() {
value := Flashes()[0]
v, ok := value.(*MyData)
if ok {
fmt.Println("Some data:", v)
} else {
fmt.Println("Oh no, there's something else stored than expected")
}
}
In the example above the first flash returned by Flashes() is used and asserted to be
of type *MyData. If it is indeed this type, then it's value is printed to the console.
Otherwise an error message (albeit not a good one) is printed to the console.
After asserting a variable of being some type, the asserted value is of the asserted
type. That is the v in the example above is of type *MyType.