/* Appends items into the table. An item could be either a map or a struct. */ func (self *Table) Append(items ...interface{}) ([]db.Id, error) { ids := make([]db.Id, len(items)) for i, item := range items { fields, values, err := self.FieldValues(item, toInternal) // Error ocurred, stop appending. if err != nil { return ids, err } res, err := self.source.doExec( fmt.Sprintf("INSERT INTO `%s`", self.Name()), sqlFields(fields), "VALUES", sqlValues(values), ) // Error ocurred, stop appending. if err != nil { return ids, err } // Last inserted ID could be zero too. id, _ := res.LastInsertId() ids[i] = db.Id(to.String(id)) } return ids, nil }
/* Appends items into the table. An item could be either a map or a struct. */ func (self *Table) Append(items ...interface{}) ([]db.Id, error) { ids := make([]db.Id, len(items)) for i, item := range items { fields, values, err := self.FieldValues(item, toInternal) // Error ocurred, stop appending. if err != nil { return ids, err } tail := "" if _, ok := self.ColumnTypes[self.PrimaryKey]; ok == true { tail = fmt.Sprintf("RETURNING %s", self.PrimaryKey) } row, err := self.source.doQueryRow( fmt.Sprintf(`INSERT INTO "%s"`, self.Name()), sqlFields(fields), "VALUES", sqlValues(values), tail, ) // Error ocurred, stop appending. if err != nil { return ids, err } var id int err = row.Scan(&id) // Error ocurred, stop appending. if err != nil { return ids, err } // Last inserted ID could be zero too. ids[i] = db.Id(to.String(id)) } return ids, nil }
/* Appends items to the collection. An item could be either a map or a struct. */ func (self *SourceCollection) Append(items ...interface{}) ([]db.Id, error) { var id db.Id ids := make([]db.Id, len(items)) for i, item := range items { id = "" // Dirty trick to return the Id with ease. res, err := self.collection.Upsert(bson.M{"_id": nil}, toInternal(item)) if err != nil { return ids, err } if res.UpsertedId != nil { id = db.Id(res.UpsertedId.(bson.ObjectId).Hex()) } ids[i] = id } return ids, nil }
// Transforms data from mgo format into db.Item format. func toNative(val interface{}) interface{} { // TODO: use reflection to target kinds and not just types. switch t := val.(type) { case bson.M: v := map[string]interface{}{} for i, _ := range t { v[i] = toNative(t[i]) } return v case bson.ObjectId: return db.Id(t.Hex()) } return val }
// Tests datatype conversions. func TestDataTypes(t *testing.T) { var res db.Result var items []db.Item sess, err := db.Open(wrapperName, settings) if err != nil { t.Fatalf(err.Error()) } defer sess.Close() dataTypes := sess.ExistentCollection("data_types") dataTypes.Truncate() ids, err := dataTypes.Append(testValues) if err != nil { t.Fatalf(err.Error()) } found, err := dataTypes.Count(db.Cond{"id": db.Id(ids[0])}) if err != nil { t.Fatalf(err.Error()) } if found == 0 { t.Errorf("Expecting an item.") } // Getting and reinserting (a db.Item). item, _ := dataTypes.Find() _, err = dataTypes.Append(item) if err == nil { t.Fatalf("Expecting duplicated-key error.") } delete(item, "id") _, err = dataTypes.Append(item) if err != nil { t.Fatalf(err.Error()) } // Testing date ranges items, err = dataTypes.FindAll(db.Cond{ "_date": time.Now(), }) if err != nil { t.Fatalf(err.Error()) } if len(items) > 0 { t.Fatalf("Expecting no results.") } items, err = dataTypes.FindAll(db.Cond{ "_date <=": time.Now(), }) if err != nil { t.Fatalf(err.Error()) } if len(items) != 2 { t.Fatalf("Expecting some results.") } // Testing struct sresults := []testValuesStruct{} res, err = dataTypes.Query() if err != nil { t.Fatalf(err.Error()) } err = res.All(&sresults) if err != nil { t.Fatalf(err.Error()) } // Testing struct equality for _, item := range sresults { if reflect.DeepEqual(item, testValues) == false { t.Errorf("Struct is different.") } } // Testing maps results, _ := dataTypes.FindAll() for _, item := range results { for key, _ := range item { switch key { // Signed integers. case "_int", "_int8", "_int16", "_int32", "_int64": if to.Int64(item[key]) != testValues.Int64 { t.Fatalf("Wrong datatype %v.", key) } // Unsigned integers. case "_uint", "_uint8", "_uint16", "_uint32", "_uint64": if to.Uint64(item[key]) != testValues.Uint64 { t.Fatalf("Wrong datatype %v.", key) } // Floating point. case "_float32": case "_float64": if to.Float64(item[key]) != testValues.Float64 { t.Fatalf("Wrong datatype %v.", key) } // Boolean case "_bool": if to.Bool(item[key]) != testValues.Bool { t.Fatalf("Wrong datatype %v.", key) } // String case "_string": if to.String(item[key]) != testValues.String { t.Fatalf("Wrong datatype %v.", key) } // Date case "_date": if to.Time(item[key]).Equal(testValues.Date) == false { t.Fatalf("Wrong datatype %v.", key) } } } } }