I would like to read results from a simple SQL table like the following
customer
key
A
12345
B
6789
Now, I'd like to structure a map[string]string which has key value pairs equal to the row values like such:
map[A:12345, B:6789]
However, I am having trouble just taking the values out of the query result and dynamically creating the key-val pairs. I'll provide a rough outline of the code (the SQL connection stuff is not an issue, I have that figured out)
import "database/sql"
func main() {
// Some code to connect to MSSQL...
db, _ := sql.Open("mssql", connString)
stmt := "SELECT customer, key from tbl"
rows, _ := db.Query(stmt)
defer rows.Close()
data := make(map[string]string)
for rows.Next() {
// Need help here grabbing each row pair and adding them to my map...
}
}
I'm open to trying to do this with an Empty struct as well, where the fields become the first column of my result set (dynamic) and the value becomes the 2nd column of my result set.
You could temporarily store the values in two variables and then store them in the map:
func main() {
stmt := "SELECT customer, key from tbl"
rows, _ := db.Query(stmt)
defer rows.Close()
data := make(map[string]string)
var (
consumer string
key string
)
for rows.Next() {
if err := rows.Scan(&consumer, &key); err != nil {
// Handle err
}
data[consumer] = key
}
for k, v := range data {
fmt.Println(k, v)
}
// "A" "12345"
// "B" "6789"
}
Note that the consumer and key variables are allocated outside of the loop so we can re-use them. Even if the values are empty strings, the variables will be overwritten on each iteration.
Related
[
{"id_A": 1, "name_A": "Value_A"},
{"id_B": 2, "name_B": "Value_B"}
]
"id_" and "name_" can change and I need to recover both the keys names to create a struct.
how can i do ?
https://play.golang.org/p/OXqpudiWWcH
if you have the key which is not fix, the only way you can use is interface{}
you need to unmarshal json to []interface{} and using type assertion to map[string]interface{}
var body []interface{}
_ = json.Unmarshal([]byte(json2), &body)
fmt.Printf("Unmarshaled: %v\n", body)
// range through array interface[]
for _, opt := range body {
// assert interface{} to map[string]interface{}
if item, ok := opt.(map[string]interface{}); ok {
for v, opt := range item {
fmt.Printf("[%s] key -> %s value -> %s\n", v, opt, "fake")
}
}
}
the complete code based on your example
https://play.golang.org/p/PepxOVlB7u4
I am writing a service for search functionality. when i am passing values in the body to get the specific record i am unable to get it based on the struct value.
ex:phone number or username
Edit1:
type PatientData struct {
ID int64 datastore:"-"
FirstName string json:"firstname,omitempty"
LastName string json:"lastname,omitempty"
UserName string json:"username,omitempty"
Phone string json:"phone,omitempty"
}
I want to get the full struct values based on Username or Phone. Below is my code:
func searchValue (res http.ResponseWriter, req *http.Request){
log.Printf("%#v Getting values url - x ", "called search")
patient := &PatientData{}
if err := json.NewDecoder(req.Body).Decode(patient); err != nil {
panic(err)
}
ctx := appengine.NewContext(req)
ctx, err := appengine.Namespace(ctx, NAMESPACENAME)
if err != nil {
panic(err)
}
m := patient.Phone
i, err := strconv.ParseInt(m, 10, 64)
log.Printf("%#v Getting values m ", m)
log.Printf("%#v Getting values url -yyy ",i)
key := datastore.NewKey(ctx, "Patient","" , i, nil)
log.Printf("%#v Getting values url - key ", key)
err = datastore.Get(ctx, key, patient)
if err := json.NewEncoder(res).Encode(patient); err != nil {
panic(err)
}
}
As i am passing PHONE in my Newkey i am unable to generate the values based on PHONE
I don't want to use Newkey in put functionality to generate a keyname and based on that KEYNAME i dont want to get Values.
datastore.Get() can only be used to get an entity from the datastore by its key, so its key must be known / present.
This is obviously not what you're trying to do. You are trying to fetch entities by properties which are not the key. To do that, you need to run a query.
Datastore queries are represented by the datastore.Query type. You need to create a query and set filters on it. In your case, you want to filter by the username and/or phone properties.
This is how it could look like. Fetch patient entities filtered by phone:
q := datastore.NewQuery("Patient").Filter("phone =", patient.Phone)
var patients []*Patient
keys, err := q.GetAll(ctx, &patients)
if err != nil {
// Handle error
return
}
// patients contains patients with the given phone number
An example fetching patients filtered by phone number AND user name:
q := datastore.NewQuery("Patient").
Filter("phone =", patient.Phone).
Filter("username =", patient.UserName)
var patients []*Patient
keys, err := q.GetAll(ctx, &patients)
if err != nil {
// Handle error
return
}
// patients contains patients with the given phone number and username
I have this query
site.com/?status[0]=1&status[1]=2&status[1]=3&name=John
I want to get all the values of status key like
1, 2, 3
I tried something like this
for _, status:= range r.URL.Query()["status"] {
fmt.Println(status)
}
but it only works if the query is without array key: site.com/?status=1&status=2&status=3&name=John
One approach is to loop over the possible values and append to a slice as you go:
r.ParseForm() // parses request body and query and stores result in r.Form
var a []string
for i := 0; ; i++ {
key := fmt.Sprintf("status[%d]", i)
values := r.Form[key] // form values are a []string
if len(values) == 0 {
// no more values
break
}
a = append(a, values[i])
i++
}
If you have control over the query string, then use this format:
site.com/?status=1&status=2&status=3&name=John
and get status values using:
r.ParseForm()
a := r.Form["status"] // a is []string{"1", "2", "3"}
I am using gorilla mux for my routes and I pass an id.
Using that Id how can I get a entity from datastore.
param := mux.Vars(r)
c := appengine.NewContext(r)
item := []Item{}
pr, err := datastore.NewQuery("Item").Filter("ID = ", param["id"]).GetAll(c, &item)
And here I'm stuck, I tried using filter but it doesn't work.
What do I have to do next?
If you have an id, you don't need to use a query. A faster and cheaper way is to create a key and retrieve this entity directly from the Datastore.
https://cloud.google.com/appengine/docs/go/datastore/entities#Go_Retrieving_an_entity
You don't say if you are using integer or string ids for entities. I'll assume integer because it requires a little more code. First, create a key:
n, err := strconv.ParseInt(param["id"], 10, 64)
if err != nil {
// handle error
}
key := datastore.NewKey(c, "Item", "", n, nil)
Now that you have key, you can fetch the entity:
var item Item
if err := datastore.Get(c, key, &item); err != nil {
// handle error
}
It's more efficient to get the entity than to query for the entity. If you do want to query by id, then see key filters in the App Engine docs.
I have a map which has as value an array of maps.
Example:
thisMap["coins"][0] = aMap["random":"something"]
thisMap["notes"][1] = aMap["not-random":"something else"]
thisMap["coins"][2] = aMap["not-random":"something else"]
I can't figure it out how to do this as go seems to allow setting data only at one level when you deal with maps [name][value] = value.
So far I have this code which fails
package main
func main() {
something := []string{"coins", "notes", "gold?", "coins", "notes"}
thisMap := make(map[string][]map[string]int)
for k, v := range something {
aMap := map[string]string{
"random": "something",
}
thisMap[v] = [k]aMap
}
}
Edit: The slice values ("coins", "notes" etc ) can repeat so this is the reason why I need use an index [] .
Working example (click to play):
something := []string{"coins", "notes", "gold?"}
thisMap := make(map[string][]map[string]int)
for _, v := range something {
aMap := map[string]int{
"random": 12,
}
thisMap[v] = append(thisMap[v], aMap)
}
When iterating over the newly created thisMap, you need to make room for the new value aMap. The builtin function append does that for you when using slices. It makes room and appends the value to the slice.
If you're using more complex data types that can't be initialized as easily as slices, you first have to check if the key is already in the map and, if it is not, initialize your data type. Checking for map elements is documented here. Example with maps (click to play):
thisMap := make(map[string]map[string]int)
for _, v := range something {
if _, ok := thisMap[v]; !ok {
thisMap[v] = make(map[string]int)
}
thisMap[v]["random"] = 12
}