//func Find(ms []toolkit.M, filters []*Filter) (output []int) { func Find(ms interface{}, filters []*Filter) (output []int) { //-- is not a slice if !toolkit.IsSlice(ms) { toolkit.Println("Data is not slice") return []int{} } //toolkit.Printf("Find:%s Filter:%s\n", toolkit.JsonString(ms), toolkit.JsonString(filters)) sliceLen := toolkit.SliceLen(ms) for i := 0; i < sliceLen; i++ { var v toolkit.M item := toolkit.SliceItem(ms, i) e := toolkit.Serde(item, &v, "json") if e == nil { match := MatchM(v, filters) if match { output = append(output, i) } } else { //toolkit.Println("Serde Fail: ", e.Error(), " Data: ", item) } } return }
func (q *Query) Exec(in toolkit.M) error { setting, e := q.prepare(in) commandType := setting["commandtype"].(string) //toolkit.Printf("Command type: %s\n", commandType) if e != nil { return err.Error(packageName, modQuery, "Exec: "+commandType, e.Error()) } if setting.GetString("commandtype") == dbox.QueryPartSelect { return err.Error(packageName, modQuery, "Exec: "+commandType, "Exec is not working with select command, please use .Cursor instead") } q.Lock() defer q.Unlock() var dataM toolkit.M var dataMs []toolkit.M hasData := in.Has("data") dataIsSlice := false data := in.Get("data") if toolkit.IsSlice(data) { dataIsSlice = true e = toolkit.Unjson(toolkit.Jsonify(data), dataMs) if e != nil { return err.Error(packageName, modQuery, "Exec: "+commandType, "Data encoding error: "+e.Error()) } } else { dataM, e = toolkit.ToM(data) dataMs = append(dataMs, dataM) if e != nil { return err.Error(packageName, modQuery, "Exec: "+commandType, "Data encoding error: "+e.Error()) } } hasWhere := setting.Has("where") where := setting.Get("where", []*dbox.Filter{}).([]*dbox.Filter) if hasWhere && len(where) == 0 { inWhere := in.Get("where") if inWhere == nil { hasWhere = false where = nil } else { if !toolkit.IsSlice(inWhere) { where = append(where, inWhere.(*dbox.Filter)) } else { where = inWhere.([]*dbox.Filter) } } } if hasData && hasWhere == false && toolkit.HasMember([]interface{}{dbox.QueryPartInsert, dbox.QueryPartDelete, dbox.QueryPartUpdate, dbox.QueryPartSave}, commandType) { hasWhere = true //toolkit.Println("check where") if toolkit.IsSlice(data) { ids := []interface{}{} idField := "" if idField == "" { return err.Error(packageName, modQuery, "Exec: "+commandType, "Data send is a slice, but its element has no ID") } dataCount := toolkit.SliceLen(data) for i := 0; i < dataCount; i++ { dataI := toolkit.SliceItem(data, i) if i == 0 { idField = toolkit.IdField(dataI) } ids = append(ids, toolkit.Id(dataI)) } where = []*dbox.Filter{dbox.In(idField, ids)} } else { idfield := "_id" id := toolkit.Id(data) if !toolkit.IsNilOrEmpty(id) { where = []*dbox.Filter{dbox.Eq(idfield, id)} } else { where = nil hasWhere = false } } } /* toolkit.Printf("CommandType: %s HasData: %v HasWhere: %v Where: %s\n", commandType, hasData, hasWhere, toolkit.JsonString(where)) */ e = q.openFile(commandType) //toolkit.Printf(commandType+" Open File, found record: %d\nData:%s\n", len(q.data), toolkit.JsonString(q.data)) if e != nil { return err.Error(packageName, modQuery, "Exec: "+commandType, e.Error()) } var indexes []interface{} if hasWhere && commandType != dbox.QueryPartInsert { whereIndex := dbox.Find(q.data, where) indexes = toolkit.ToInterfaceArray(&whereIndex) //toolkit.Printf("Where Index: %s Index:%s\n", toolkit.JsonString(whereIndex), toolkit.JsonString(indexes)) } if commandType == dbox.QueryPartInsert { if !hasData { return err.Error(packageName, modQuery, "Exec: "+commandType, "Data is empty") } if !dataIsSlice { dataMs = []toolkit.M{dataM} } //-- validate for _, datam := range dataMs { idField, idValue := toolkit.IdInfo(datam) toolkit.Serde(dbox.Find(q.data, []*dbox.Filter{dbox.Eq(idField, idValue)}), &indexes, "") if len(indexes) > 0 { return err.Error(packageName, modQuery, "Exec: "+commandType, toolkit.Sprintf("Data %v already exist", idValue)) } } //-- insert the data q.data = append(q.data, dataMs...) } else if commandType == dbox.QueryPartUpdate { //-- valida if !hasData { return err.Error(packageName, modQuery, "Exec: "+commandType, "Data is empty") } var dataUpdate toolkit.M var updateDataIndex int // if it is a slice then we need to update each data passed on its slice isDataSlice := toolkit.IsSlice(data) if isDataSlice == false { isDataSlice = false e = toolkit.Serde(data, &dataUpdate, "") if e != nil { return err.Error(packageName, modQuery, "Exec: "+commandType, "Serde data fail"+e.Error()) } } var idField string //toolkit.Printf("Indexes: %s\n", toolkit.JsonString(indexes)) for i, v := range q.data { // update only data that match given inde if toolkit.HasMember(indexes, i) || !hasWhere { if idField == "" { idField = toolkit.IdField(v) if idField == "" { return err.Error(packageName, modQuery, "Exec: "+commandType, "No ID") } } // If dataslice is sent, iterate f if isDataSlice { e = toolkit.Serde(toolkit.SliceItem(data, updateDataIndex), &dataUpdate, "") if e != nil { return err.Error(packageName, modQuery, "Exec: "+commandType, "Serde data fail "+e.Error()) } updateDataIndex++ } dataOrigin := q.data[i] toolkit.CopyM(&dataUpdate, &dataOrigin, false, []string{"_id"}) toolkit.Serde(dataOrigin, &v, "") q.data[i] = v } } } else if commandType == dbox.QueryPartDelete { if hasWhere && len(where) > 0 { indexes := dbox.Find(q.data, where) if len(indexes) > 0 { newdata := []toolkit.M{} for index, v := range q.data { partOfIndex := toolkit.HasMember(indexes, index) if partOfIndex == false { newdata = append(newdata, v) } //toolkit.Println("i:", indexes, ", index:", index, ", p.ofIndex: ", partOfIndex, ", data: ", toolkit.JsonString(newdata)) } q.data = newdata } } else { q.data = []toolkit.M{} } //toolkit.Printf("Data now: %s\n", toolkit.JsonString(q.data)) } else if commandType == dbox.QueryPartSave { if !hasData { return err.Error(packageName, modQuery, "Exec: "+commandType, "Data is empty") } var dataMs []toolkit.M var dataM toolkit.M if !toolkit.IsSlice(data) { e = toolkit.Serde(&data, &dataM, "json") if e != nil { return err.Error(packageName, modQuery, "Exec: "+commandType+" Serde data fail", e.Error()) } dataMs = append(dataMs, dataM) } else { e = toolkit.Serde(&data, &dataMs, "json") if e != nil { return err.Error(packageName, modQuery, "Exec: "+commandType+" Serde data fail", e.Error()) } } //toolkit.Printf("Saving: %s\n", toolkit.JsonString(dataMs)) for _, v := range dataMs { idField, idValue := toolkit.IdInfo(v) indexes := dbox.Find(q.data, []*dbox.Filter{dbox.Eq(idField, idValue)}) if len(indexes) == 0 { q.data = append(q.data, v) } else { dataOrigin := q.data[indexes[0]] //toolkit.Printf("Copy data %s to %s\n", toolkit.JsonString(v), toolkit.JsonString(dataOrigin)) toolkit.CopyM(&v, &dataOrigin, false, []string{idField}) q.data[indexes[0]] = dataOrigin } } } e = q.writeFile() if e != nil { return err.Error(packageName, modQuery, "Exec: "+commandType+" Write fail", e.Error()) } return nil }
func (s *SliceBase) Item(i int) interface{} { return toolkit.SliceItem(s.data, i) }
func (q *Query) Exec(parm toolkit.M) error { var ( e error updatedValue, dataMs []toolkit.M dataM toolkit.M ) filters, e := q.Filters(parm) if e != nil { return errorlib.Error(packageName, modQuery, "Exec", e.Error()) } if parm == nil { parm = toolkit.M{} } data := parm.Get("data", nil) filePath := q.Connection().(*Connection).filePath commandType := filters.Get("cmdType").(string) hasWhere := filters.Has("where") hasCmdType := toolkit.M{} hasData := parm.Has("data") getWhere := filters.Get("where", []*dbox.Filter{}).([]*dbox.Filter) dataIsSlice := toolkit.IsSlice(data) if dataIsSlice { e = toolkit.Unjson(toolkit.Jsonify(data), &dataMs) if e != nil { return errorlib.Error(packageName, modQuery, "Exec: "+commandType, "Data encoding error: "+e.Error()) } for _, v := range dataMs { id := toolkit.Id(v) idF := toolkit.IdField(v) if toolkit.IsNilOrEmpty(id) { return errorlib.Error(packageName, modCursor+".Exec", commandType, "Unable to find ID in slice data") } else { getWhere = []*dbox.Filter{dbox.Eq(idF, id)} } } } else { dataM, e = toolkit.ToM(data) if e != nil { return errorlib.Error(packageName, modQuery, "Exec: "+commandType, "Unable to Map, error: "+e.Error()) } id := toolkit.Id(dataM) if !toolkit.IsNilOrEmpty(id) { getWhere = []*dbox.Filter{dbox.Eq(toolkit.IdField(dataM), id)} } } var dataMaps []toolkit.M q.ReadFile(&dataMaps, filePath) if commandType == dbox.QueryPartInsert { hasCmdType.Set("hasInsert", true) if !hasData { return errorlib.Error(packageName, modCursor+".Exec", commandType, "Sorry data not found!, unable to insert data") } result := dbox.Find(dataMaps, getWhere) if len(result) > 0 { return errorlib.Error(packageName, modCursor+".Exec", commandType, "ID already exist, unable insert data ") } if dataIsSlice { var sliceData []toolkit.M for _, v := range dataMs { sliceData = finUpdateObj(dataMaps, v, "insert") } updatedValue = sliceData } else { updatedValue = finUpdateObj(dataMaps, dataM, "insert") } } else if commandType == dbox.QueryPartUpdate { hasCmdType.Set("hasUpdate", true) if !hasData { return errorlib.Error(packageName, modCursor+".Exec", commandType, "Sorry data not found!, unable to update data") } if hasWhere { var indexes []interface{} whereIndex := dbox.Find(dataMaps, getWhere) indexes = toolkit.ToInterfaceArray(&whereIndex) // toolkit.Printf("whereIndex>%v indexes%v\n", whereIndex, indexes) var dataUpdate toolkit.M var updateDataIndex int isDataSlice := toolkit.IsSlice(data) if isDataSlice == false { isDataSlice = false data, e = toolkit.ToM(data) if e != nil { return errorlib.Error(packageName, modQuery, "Exec: "+commandType, "Serde data fail"+e.Error()) } e = toolkit.Serde(data, &dataUpdate, "") if e != nil { return errorlib.Error(packageName, modQuery, "Exec: "+commandType, "Serde data fail"+e.Error()) } } for i, v := range dataMaps { if toolkit.HasMember(indexes, i) || !hasWhere { if isDataSlice { e = toolkit.Serde(toolkit.SliceItem(data, updateDataIndex), &dataUpdate, "") if e != nil { return errorlib.Error(packageName, modQuery, "Exec: "+commandType, "Serde data fail"+e.Error()) } updateDataIndex++ } dataOrigin := dataMaps[i] toolkit.CopyM(&dataUpdate, &dataOrigin, false, []string{"_id"}) toolkit.Serde(dataOrigin, &v, "") dataMaps[i] = v } } updatedValue = dataMaps } else { updatedValue = finUpdateObj(dataMaps, dataM, "update") } } else if commandType == dbox.QueryPartDelete { hasCmdType.Set("hasDelete", true) // if multi { if hasWhere { result := dbox.Find(dataMaps, getWhere) if len(result) > 0 { for i, v := range dataMaps { if toolkit.HasMember(result, i) == false { updatedValue = append(updatedValue, v) } } } } else { updatedValue = []toolkit.M{} } } else if commandType == dbox.QueryPartSave { hasCmdType.Set("hasSave", true) if !hasData { return errorlib.Error(packageName, modCursor+".Exec", commandType, "Sorry data not found!, unable to update data") } q.dataType = "save" q.whereData = append(q.whereData, getWhere...) q.sliceData = append(q.sliceData, dataM) } if hasCmdType.Has("hasInsert") || hasCmdType.Has("hasUpdate") || hasCmdType.Has("hasDelete") { e = q.WriteFile(updatedValue) if e != nil { return errorlib.Error(packageName, modQuery+".Exec", commandType, e.Error()) } } return nil }
func (q *Query) Exec(in toolkit.M) error { setting, e := q.prepare(in) commandType := setting["commandtype"].(string) if e != nil { return err.Error(packageName, modQuery, "Exec: "+commandType, e.Error()) } if setting.GetString("commandtype") == dbox.QueryPartSelect { return err.Error(packageName, modQuery, "Exec: "+commandType, "Exec is not working with select command, please use .Cursor instead") } q.Lock() defer q.Unlock() var dataM toolkit.M var dataMs []toolkit.M hasData := in.Has("data") dataIsSlice := false data := in.Get("data") if toolkit.IsSlice(data) { dataIsSlice = true e = toolkit.Unjson(toolkit.Jsonify(data), dataMs) if e != nil { return err.Error(packageName, modQuery, "Exec: "+commandType, "Data encoding error: "+e.Error()) } } else { dataM, e = toolkit.ToM(data) dataMs = append(dataMs, dataM) if e != nil { return err.Error(packageName, modQuery, "Exec: "+commandType, "Data encoding error: "+e.Error()) } } hasWhere := in.Has("where") where := in.Get("where", []*dbox.Filter{}).([]*dbox.Filter) if hasData && hasWhere == false && toolkit.HasMember([]interface{}{dbox.QueryPartInsert, dbox.QueryPartUpdate, dbox.QueryPartSave}, commandType) { hasWhere = true if toolkit.IsSlice(data) { ids := []interface{}{} idField := "" if idField == "" { return err.Error(packageName, modQuery, "Exec:"+commandType, "Data send is a slice, but its element has no ID") } dataCount := toolkit.SliceLen(data) for i := 0; i < dataCount; i++ { dataI := toolkit.SliceItem(data, i) if i == 0 { idField = toolkit.IdField(dataI) } ids = append(ids, toolkit.Id(dataI)) } where = []*dbox.Filter{dbox.In(idField, ids)} } else { id := toolkit.Id(data) if toolkit.IsNilOrEmpty(id) { where = []*dbox.Filter{dbox.Eq(toolkit.IdField(id), id)} } else { where = nil hasWhere = false } } } q.openFile() if commandType == dbox.QueryPartInsert { if !hasData { return err.Error(packageName, modQuery, "Exec:"+commandType, "Data is empty") } if dataIsSlice { q.data = append(q.data, dataMs...) } else { q.data = append(q.data, dataM) } } else if commandType == dbox.QueryPartUpdate { if !hasData { return err.Error(packageName, modQuery, "Exec:"+commandType, "Data is empty") } var indexes []interface{} if hasWhere { toolkit.Serde(dbox.Find(q.data, where), &indexes, "") } var dataUpdate toolkit.M var updateDataIndex int isDataSlice := toolkit.IsSlice(data) if isDataSlice == false { isDataSlice = false e = toolkit.Serde(data, &dataUpdate, "") if e != nil { return err.Error(packageName, modQuery, "Exec:"+commandType, "Unable to serialize data. "+e.Error()) } } var idField string for i, v := range q.data { if toolkit.HasMember(indexes, i) || len(indexes) == 0 { if idField == "" { idField = toolkit.IdField(v) if idField == "" { return err.Error(packageName, modQuery, "Exec:"+commandType, "No ID") } } var dataOrigin toolkit.M e = toolkit.Serde(v, &dataOrigin, "") if e != nil { return err.Error(packageName, modQuery, "Exec:"+commandType, "Unable to serialize data origin. "+e.Error()) } if isDataSlice { e = toolkit.Serde(toolkit.SliceItem(data, updateDataIndex), &dataUpdate, "") if e != nil { return err.Error(packageName, modQuery, "Exec:"+commandType, "Unable to serialize data. "+e.Error()) } updateDataIndex++ } for fieldName, fieldValue := range dataUpdate { if fieldName != idField { if dataOrigin.Has(fieldName) { dataOrigin.Set(fieldName, fieldValue) } } } toolkit.Serde(dataOrigin, &v, "") q.data[i] = v } } } else if commandType == dbox.QueryPartDelete { if hasWhere { var indexes []interface{} toolkit.Serde(dbox.Find(q.data, where), &indexes, "") if len(indexes) > 0 { newdata := []toolkit.M{} for index, v := range q.data { if toolkit.HasMember(indexes, index) == false { newdata = append(newdata, v) } } q.data = newdata } } else { q.data = []toolkit.M{} } } else if commandType == dbox.QueryPartSave { if !hasData { return err.Error(packageName, modQuery, "Exec:"+commandType, "Data is empty") } } q.writeFile() return nil }
func (cmd *Command) Exec(c *Crowd) error { if c.data == nil { return errors.New("Exec: Data is empty") } l := c.Len() if cmd.CommandType == CommandSum { fn := cmd.Fns[0] sum := float64(0) for i := 0; i < l; i++ { el := fn(c.Item(i)) if !toolkit.IsNumber(el) { c.Result.Sum = 0 return nil } item := toolkit.ToFloat64(el, 4, toolkit.RoundingAuto) sum += item } c.Result.Sum = sum } else if cmd.CommandType == CommandMin { fn := cmd.Fns[0] var ret interface{} for i := 0; i < l; i++ { item := fn(c.Item(i)) if i == 0 { ret = item } else if toolkit.Compare(ret, item, "$gt") { ret = item } } c.Result.Min = ret } else if cmd.CommandType == CommandMax { fn := cmd.Fns[0] var ret interface{} for i := 0; i < l; i++ { item := fn(c.Item(i)) if i == 0 { ret = item } else if toolkit.Compare(ret, item, "$lt") { ret = item } } c.Result.Max = ret } else if cmd.CommandType == CommandAvg { fn := cmd.Fns[0] ret := float64(0) for i := 0; i < l; i++ { el := fn(c.Item(i)) if !toolkit.IsNumber(el) { c.Result.Sum = 0 return nil } item := toolkit.ToFloat64(el, 4, toolkit.RoundingAuto) ret += item } c.Result.Avg = toolkit.Div(ret, toolkit.ToFloat64(l, 0, toolkit.RoundingAuto)) } else if cmd.CommandType == CommandWhere { fn := cmd.Fns[0] el, _ := toolkit.GetEmptySliceElement(c.data) tel := reflect.TypeOf(el) array := reflect.MakeSlice(reflect.SliceOf(tel), 0, 0) for i := 0; i < l; i++ { item := c.Item(i) if fn(item).(bool) { //toolkit.Printfn("Where data %d: %v", i, item) array = reflect.Append(array, reflect.ValueOf(item)) } } c.Result.data = array.Interface() } else if cmd.CommandType == CommandApply { fn := cmd.Fns[0] var array reflect.Value for i := 0; i < l; i++ { item := fn(c.Item(i)) //toolkit.Printfn("Applying data %d of %d: %v", i, l, item) if i == 0 { //toolkit.Println(reflect.ValueOf(item).Type().String()) array = reflect.MakeSlice(reflect.SliceOf(reflect.TypeOf(item)), 0, 0) } array = reflect.Append(array, reflect.ValueOf(item)) } c.Result.data = array.Interface() c.data = c.Result.data } else if cmd.CommandType == CommandGroup { fng := cmd.Fns[0] fnc := cmd.Fns[1] mvs := map[interface{}]reflect.Value{} //mvo := map[interface{}]interface{}{} var mvo []KV for i := 0; i < l; i++ { item := c.Item(i) //toolkit.Printfn("Processing data %d of %d: %v", i, l, item) g := fng(item) gi := fnc(item) array, exist := mvs[g] if !exist { //array = []interface{}{} array = reflect.MakeSlice(reflect.SliceOf(reflect.TypeOf(gi)), 0, 0) } array = reflect.Append(array, reflect.ValueOf(gi)) //toolkit.Println("Data:",g,array) mvs[g] = array } for k, v := range mvs { mvo = append(mvo, KV{k, v.Interface()}) } c.Result.data = mvo c.data = mvo } else if cmd.CommandType == CommandSort { sorter, e := NewSorter(c.data, cmd.Fns[0]) if e != nil { return e } var direction SortDirection direction = cmd.Parms.Get("direction", SortAscending).(SortDirection) c.Result.data = sorter.Sort(direction) c.data = c.Result.data } else if cmd.CommandType == CommandJoin { joinData := cmd.Parms.Get("joindata") if joinData == nil { return errors.New("crowd.join: Right side join data is nil") } if cmd.FnJoinKey == nil { cmd.FnJoinKey = func(x, y interface{}) bool { return x == y } } if cmd.FnJoinSelect == nil { cmd.FnJoinSelect = func(x, y interface{}) interface{} { return toolkit.M{}.Set("data1", x).Set("data2", y) } } l1 := toolkit.SliceLen(joinData) var array reflect.Value arrayBuilt := false for i := 0; i < l; i++ { item1 := c.Item(i) for i1 := 0; i1 < l1; i1++ { item2 := toolkit.SliceItem(joinData, i1) joinOK := cmd.FnJoinKey(item1, item2) if joinOK { outObj := cmd.FnJoinSelect(item1, item2) if !arrayBuilt { arrayBuilt = true array = reflect.MakeSlice(reflect.SliceOf(reflect.TypeOf(outObj)), 0, 0) } array = reflect.Append(array, reflect.ValueOf(outObj)) } } } if !arrayBuilt { return errors.New("crowd.join: No match") } c.Result.data = array.Interface() c.data = array.Interface() } else { return errors.New(string(cmd.CommandType) + ": not yet applicable") } return nil }