Sylvain
unread,Jul 29, 2011, 3:43:04 AM7/29/11Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to golan...@googlegroups.com
Hi,
I defined a function to load all of an sqlite table into a struct.
I have working functions that,
- given a struct, creates the table
- given a slice of struct objects, fills the data into the db
In order to load the data into a struct, I wrote the LoadDataFromDb function (given at the end of this message).
I pass as input a struct object as interface{}, and a pointer to an interface{} slice
I manage to get the data for each row using the reflect package, but cannot find a way to put the real data into the result slice instead of a pointer. So each time I iterate over a new row, all previous data in the slice gets the value of the new row.
I tried the following
- get the type of s and create a new object using clone:=new(reflect.TypeOf(s).Elem()) but get the following error:
reflect.TypeOf(s).Elem() is not a type
- define (actually, copypaste from another post in this mailing list) a clone function and try to get a new object for each iteration:
func Clone(source,dest interface{}) {
buff := new(bytes.Buffer)
enc := gob.NewEncoder(buff)
dec := gob.NewDecoder(buff)
enc.Encode(source)
dec.Decode(dest)
}
But I have to define dest as an interface{}, so I cannot reflect on it after.
Is there a way to fill my results array with s's value instead of its memory address ?
Here is the content of my Sqlite Person table
"4654","1","Sylvain","32"
"42357","2","Vincent","31"
And here is the content of results after loading:
N° 0 : 2 Vincent 31 42357
N° 1 : 2 Vincent 31 42357
Here is my function:
func LoadDataFromDb(db *sqlite3.Database, s interface{}, results *[]interface{}) (err os.Error) {
sql := fmt.Sprintf("SELECT * FROM %v;",
StructName(s))
//get Records
enr, err := db.Prepare(sql)
if err != nil {
fmt.Println("db Prepare error: %s", err)
return
}
//iterate over statements from db
cpt := 0
for rs := enr.Step(); rs != nil; rs = enr.Step() {
structure := reflect.Indirect(reflect.ValueOf(s))
cpt++
for a, b := range enr.Row() {
champ := structure.FieldByName(enr.ColumnName(a))
switch champ.Type().Kind() {
case reflect.String:
champ.SetString(b.(string))
case reflect.Int, reflect.Int16, reflect.Int32, reflect.Int64:
champ.SetInt(b.(int64))
case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64:
champ.SetUint(b.(uint64))
case reflect.Float32, reflect.Float64:
champ.SetFloat(b.(float64))
default:
fmt.Println(champ, "not dealt with yet")
}
}
//DOES NOT WORK, APPENDS A POINTER SO AT THE END EACH ELEM OF THE ARRAY CONTAINS THE LAST ROW
*results = append(*results, s)
}
}
return
}