func (s *SliceBase) SetData(data interface{}) error { if !toolkit.IsPointer(data) || !toolkit.IsSlice(data) { return errors.New("crowd.SliceBase.SetData: data is not pointer of slice") } s.data = data return nil }
func (q *Query) Exec(parm toolkit.M) (e error) { data := parm.Get("data") driverName := q.GetDriverDB() if toolkit.IsSlice(data) && driverName == "mssql" { e = q.insertBulk(parm) } else { _, e = q.ExecOut(parm) } return e }
func NewSorter(data interface{}, fnsort FnCrowd) (s *Sorter, e error) { if !toolkit.IsPointer(data) || !toolkit.IsSlice(data) { e = errors.New("crowd.NewSorter: data is not pointer of slice") return } s = new(Sorter) s.data = data s.FnSort = _fn(fnsort) return }
//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) insertBulk(parm toolkit.M) error { var e error if parm == nil { parm = toolkit.M{} } driverName := q.GetDriverDB() // driverName = "oracle" tablename := "" data := parm.Get("data") var attributes string var dataM toolkit.M var dataMs []toolkit.M if toolkit.IsSlice(data) { e = toolkit.Unjson(toolkit.Jsonify(data), &dataMs) if e != nil { return errorlib.Error(packageName, modQuery, "Exec: data extraction", "Data encoding error: "+e.Error()) } } else { dataM, e = toolkit.ToM(data) dataMs = append(dataMs, dataM) if e != nil { return errorlib.Error(packageName, modQuery, "Exec: data extraction", "Data encoding error: "+e.Error()) } } temp := "" quyerParts := q.Parts() c := crowd.From(&quyerParts) groupParts := c.Group(func(x interface{}) interface{} { qp := x.(*dbox.QueryPart) temp = toolkit.JsonString(qp) return qp.PartType }, nil).Exec() parts := map[interface{}]interface{}{} if len(groupParts.Result.Data().([]crowd.KV)) > 0 { for _, kv := range groupParts.Result.Data().([]crowd.KV) { parts[kv.Key] = kv.Value } } commandType := "" _, hasInsert := parts[dbox.QueryPartInsert] if hasInsert { commandType = dbox.QueryPartInsert } else { _, e = q.ExecOut(parm) return e // return errorlib.Error(packageName, "Query", modQuery+".InsertBulk", "Invalid Operation") } fromParts, hasFrom := parts[dbox.QueryPartFrom] if !hasFrom { return errorlib.Error(packageName, "Query", modQuery, "Invalid table name") } tablename = fromParts.([]*dbox.QueryPart)[0].Value.(string) session := q.Session() attributeList := extractFields(dataMs[0]) var datas []string for _, dataVal := range dataMs { var values string tmp := toolkit.M{} for _, attr := range attributeList { tmp.Set(attr, dataVal.Get(attr)) } values = extractDataBulk(attributeList, tmp, driverName) // toolkit.Printf("test: \n %v \n------\n %v \n------\n %v \n------\n %v \n", attributeList, dataVal, tmp, values) datas = append(datas, values) } attributes = "(" + strings.Join(attributeList, ",") + ")" if attributes != "" && nil != datas { var statement string if driverName == "hive" { /*statement = "INSERT INTO " + tablename + " VALUES " + values e = sessionHive.Exec(statement, nil)*/ return errorlib.Error(packageName, modQuery+".Exec", commandType, "Not Implemented Yet for HIVE") } else { statement = fmt.Sprintf("INSERT INTO "+tablename+" "+attributes+" VALUES %s", strings.Join(datas, ",")) _, e = session.Exec(statement) } if e != nil { return errorlib.Error(packageName, modQuery+".Exec", commandType, cast.ToString(e.Error())) } } else { return errorlib.Error(packageName, modQuery+".Exec", commandType, "please provide the data") } return nil }
func (q *Query) ExecOut(parm toolkit.M) (int64, error) { var e error if parm == nil { parm = toolkit.M{} } driverName := q.GetDriverDB() // driverName = "oracle" tablename := "" data := parm.Get("data") var attributes string var values string var setUpdate string var dataM toolkit.M var dataMs []toolkit.M var returnId int64 if toolkit.IsSlice(data) { e = toolkit.Unjson(toolkit.Jsonify(data), &dataMs) if e != nil { return returnId, errorlib.Error(packageName, modQuery, "Exec: data extraction", "Data encoding error: "+e.Error()) } } else { dataM, e = toolkit.ToM(data) dataMs = append(dataMs, dataM) if e != nil { return returnId, errorlib.Error(packageName, modQuery, "Exec: data extraction", "Data encoding error: "+e.Error()) } } for _, dataVal := range dataMs { temp := "" quyerParts := q.Parts() c := crowd.From(&quyerParts) groupParts := c.Group(func(x interface{}) interface{} { qp := x.(*dbox.QueryPart) temp = toolkit.JsonString(qp) return qp.PartType }, nil).Exec() parts := map[interface{}]interface{}{} if len(groupParts.Result.Data().([]crowd.KV)) > 0 { for _, kv := range groupParts.Result.Data().([]crowd.KV) { parts[kv.Key] = kv.Value } } commandType := "" _, hasDelete := parts[dbox.QueryPartDelete] _, hasInsert := parts[dbox.QueryPartInsert] _, hasUpdate := parts[dbox.QueryPartUpdate] _, hasSave := parts[dbox.QueryPartSave] if hasDelete { commandType = dbox.QueryPartDelete } else if hasInsert { commandType = dbox.QueryPartInsert } else if hasUpdate { commandType = dbox.QueryPartUpdate } else if hasSave { commandType = dbox.QueryPartSave } if hasInsert || hasUpdate || hasSave { attributes, setUpdate, values = extractData(dataVal, driverName) } else if hasDelete { } fromParts, hasFrom := parts[dbox.QueryPartFrom] if !hasFrom { return returnId, errorlib.Error(packageName, "Query", modQuery, "Invalid table name") } tablename = fromParts.([]*dbox.QueryPart)[0].Value.(string) var where interface{} whereParts, hasWhere := parts[dbox.QueryPartWhere] if hasWhere { fb := q.Connection().Fb() for _, p := range whereParts.([]*dbox.QueryPart) { fs := p.Value.([]*dbox.Filter) for _, f := range fs { fb.AddFilter(f) } } where, e = fb.Build() if e != nil { } else { } } var id string var idVal interface{} if where == nil { id, idVal = toolkit.IdInfo(dataVal) if id != "" { where = id + " = " + StringValue(idVal, "non") } } session := q.Session() sessionHive := q.SessionHive() if commandType == dbox.QueryPartInsert { if attributes != "" && values != "" { var statement string if driverName == "hive" { statement = "INSERT INTO " + tablename + " VALUES " + values e = sessionHive.Exec(statement, nil) } else { statement = "INSERT INTO " + tablename + " " + attributes + " VALUES " + values var res sql.Result res, e = session.Exec(statement) if res != nil { returnId, _ = res.LastInsertId() } } if e != nil { return returnId, errorlib.Error(packageName, modQuery+".Exec", commandType, cast.ToString(e.Error())) } } else { return returnId, errorlib.Error(packageName, modQuery+".Exec", commandType, "please provide the data") } } else if commandType == dbox.QueryPartUpdate { if setUpdate != "" { var statement string if where != nil { statement = "UPDATE " + tablename + " SET " + setUpdate + " WHERE " + cast.ToString(where) } else { statement = "UPDATE " + tablename + " SET " + setUpdate } if driverName == "hive" { e = sessionHive.Exec(statement, nil) } else { _, e = session.Exec(statement) } if e != nil { return returnId, errorlib.Error(packageName, modQuery+".Exec", commandType, cast.ToString(e.Error())) } } else { return returnId, errorlib.Error(packageName, modQuery+".Exec", commandType, "please provide the data") } } else if commandType == dbox.QueryPartDelete { var statement string if where != nil { statement = "DELETE FROM " + tablename + " where " + cast.ToString(where) } else { statement = "DELETE FROM " + tablename } if driverName == "hive" { e = sessionHive.Exec(statement, nil) } else { _, e = session.Exec(statement) } if e != nil { return returnId, errorlib.Error(packageName, modQuery+".Exec", commandType, cast.ToString(e.Error())) } } else if commandType == dbox.QueryPartSave { if attributes != "" && values != "" { var querystmt string if where != nil { querystmt = "select 1 as data from " + tablename + " where " + cast.ToString(where) } var rowCount int if driverName == "hive" { rowCount = 0 // row := sessionHive.Exec(querystmt, nil) // rowCount = toolkit.ToInt(row[0], "auto") } else { if querystmt != "" { rows, _ := session.Query(querystmt) for rows.Next() { rows.Scan(&rowCount) } } } var statement string if rowCount == 0 || where == nil { if driverName == "hive" { statement = "INSERT INTO " + tablename + " VALUES " + values } else { statement = "INSERT INTO " + tablename + " " + attributes + " VALUES " + values } } else { statement = "UPDATE " + tablename + " SET " + setUpdate + " WHERE " + cast.ToString(where) } if driverName == "hive" { e = sessionHive.Exec(statement, nil) } else { _, e = session.Exec(statement) } if e != nil { return returnId, errorlib.Error(packageName, modQuery+".Exec", commandType, cast.ToString(e.Error())) } } else if values == "" { return returnId, errorlib.Error(packageName, modQuery+".Exec", commandType, "please provide the data") } } if e != nil { return returnId, errorlib.Error(packageName, modQuery+".Exec", commandType, e.Error()) } } return returnId, nil }
func (d *DataSourceController) ConnectToDataSourceDB(payload toolkit.M) (int, []toolkit.M, *colonycore.DataBrowser, error) { var hasLookup bool toolkit.Println("payload : ", payload) if payload.Has("haslookup") { hasLookup = payload.Get("haslookup").(bool) } _id := toolkit.ToString(payload.Get("browserid", "")) sort := payload.Get("sort") search := payload.Get("search") _ = search take := toolkit.ToInt(payload.Get("take", ""), toolkit.RoundingAuto) skip := toolkit.ToInt(payload.Get("skip", ""), toolkit.RoundingAuto) TblName := toolkit.M{} payload.Unset("browserid") //sorter = "" if sort != nil { tmsort, _ := toolkit.ToM(sort.([]interface{})[0]) fmt.Printf("====== sort %#v\n", tmsort["dir"]) if tmsort["dir"] == "asc" { sorter = tmsort["field"].(string) } else if tmsort["dir"] == "desc" { sorter = "-" + tmsort["field"].(string) } else if tmsort["dir"] == nil { sorter = " " } } else { sorter = " " } dataDS := new(colonycore.DataBrowser) err := colonycore.Get(dataDS, _id) if err != nil { return 0, nil, nil, err } dataConn := new(colonycore.Connection) err = colonycore.Get(dataConn, dataDS.ConnectionID) if err != nil { return 0, nil, nil, err } if err := d.checkIfDriverIsSupported(dataConn.Driver); err != nil { return 0, nil, nil, err } connection, err := helper.ConnectUsingDataConn(dataConn).Connect() if err != nil { return 0, nil, nil, err } if dataDS.QueryType == "" { TblName.Set("from", dataDS.TableNames) payload.Set("from", dataDS.TableNames) } else if dataDS.QueryType == "Dbox" { getTableName := toolkit.M{} toolkit.UnjsonFromString(dataDS.QueryText, &getTableName) payload.Set("from", getTableName.Get("from").(string)) if qSelect := getTableName.Get("select", "").(string); qSelect != "" { payload.Set("select", getTableName.Get("select").(string)) } } else if dataDS.QueryType == "SQL" { var QueryString string if dataConn.Driver == "mysql" || dataConn.Driver == "hive" { QueryString = " LIMIT " + toolkit.ToString(take) + " OFFSET " + toolkit.ToString(skip) } else if dataConn.Driver == "mssql" { QueryString = " OFFSET " + toolkit.ToString(skip) + " ROWS FETCH NEXT " + toolkit.ToString(take) + " ROWS ONLY " } else if dataConn.Driver == "postgres" { QueryString = " LIMIT " + toolkit.ToString(take) + " OFFSET " + toolkit.ToString(skip) } stringQuery := toolkit.Sprintf("%s %s", dataDS.QueryText, QueryString) payload.Set("freetext", stringQuery) // toolkit.Println(stringQuery) } qcount, _ := d.parseQuery(connection.NewQuery(), TblName) query, _ := d.parseQuery(connection.NewQuery() /*.Skip(skip).Take(take) .Order(sorter)*/, payload) var selectfield string for _, metadata := range dataDS.MetaData { tField := metadata.Field if payload.Has(tField) { selectfield = toolkit.ToString(tField) if toolkit.IsSlice(payload[tField]) { query = query.Where(dbox.In(tField, payload[tField].([]interface{})...)) qcount = qcount.Where(dbox.In(tField, payload[tField].([]interface{})...)) } else if !toolkit.IsNilOrEmpty(payload[tField]) { var hasPattern bool for _, val := range querypattern { if strings.Contains(toolkit.ToString(payload[tField]), val) { hasPattern = true } } if hasPattern { query = query.Where(dbox.ParseFilter(toolkit.ToString(tField), toolkit.ToString(payload[tField]), toolkit.ToString(metadata.DataType), "")) qcount = qcount.Where(dbox.ParseFilter(toolkit.ToString(tField), toolkit.ToString(payload[tField]), toolkit.ToString(metadata.DataType), "")) } else { switch toolkit.ToString(metadata.DataType) { case "int": query = query.Where(dbox.Eq(tField, toolkit.ToInt(payload[tField], toolkit.RoundingAuto))) qcount = qcount.Where(dbox.Eq(tField, toolkit.ToInt(payload[tField], toolkit.RoundingAuto))) case "float32": query = query.Where(dbox.Eq(tField, toolkit.ToFloat32(payload[tField], 2, toolkit.RoundingAuto))) qcount = qcount.Where(dbox.Eq(tField, toolkit.ToFloat32(payload[tField], 2, toolkit.RoundingAuto))) case "float64": query = query.Where(dbox.Eq(tField, toolkit.ToFloat64(payload[tField], 2, toolkit.RoundingAuto))) qcount = qcount.Where(dbox.Eq(tField, toolkit.ToFloat64(payload[tField], 2, toolkit.RoundingAuto))) default: query = query.Where(dbox.Contains(tField, toolkit.ToString(payload[tField]))) qcount = qcount.Where(dbox.Contains(tField, toolkit.ToString(payload[tField]))) } } } } } if hasLookup && selectfield != "" { if toolkit.HasMember(ds_flatfile, dataConn.Driver) { query = query.Select(selectfield) qcount = qcount.Select(selectfield) } else { query = query.Select(selectfield).Group(selectfield) qcount = qcount.Select(selectfield).Group(selectfield) } } ccount, err := qcount.Cursor(nil) if err != nil { return 0, nil, nil, err } defer ccount.Close() dcount := ccount.Count() cursor, err := query.Cursor(nil) if err != nil { return 0, nil, nil, err } defer cursor.Close() data := []toolkit.M{} cursor.Fetch(&data, 0, false) if err != nil { return 0, nil, nil, err } if hasLookup && selectfield != "" && !toolkit.HasMember(ds_rdbms, dataConn.Driver) && !toolkit.HasMember(ds_flatfile, dataConn.Driver) { dataMongo := []toolkit.M{} for _, val := range data { mVal, _ := toolkit.ToM(val.Get("_id")) dataMongo = append(dataMongo, mVal) } data = dataMongo } else if hasLookup && selectfield != "" && toolkit.HasMember(ds_flatfile, dataConn.Driver) { /*distinct value for flat file*/ dataFlat := []toolkit.M{} var existingVal = []string{""} for _, val := range data { valString := toolkit.ToString(val.Get(selectfield)) if !toolkit.HasMember(existingVal, valString) { dataFlat = append(dataFlat, val) existingVal = append(existingVal, valString) } } data = dataFlat } return dcount, data, dataDS, nil }
func (c *Cursor) Fetch(m interface{}, n int, closeWhenDone bool) error { var source []toolkit.M var lower, upper, lenData, lenIndex int if c.where == nil { lenData = len(c.q.data) if c.currentIndex == 0 { c.maxIndex = lenData } } else { lenIndex = len(c.indexes) if c.currentIndex == 0 { c.maxIndex = lenIndex } } if c.currentIndex == 0 && (c.skip > 0 || c.take > 0) { /*determine max data allowed to be fetched*/ c.maxIndex = c.skip + c.take } lower = c.currentIndex upper = lower + n if c.skip > 0 && c.currentIndex < 1 { lower += c.skip } if n == 0 { if c.where == nil { upper = lenData } else { upper = lenIndex } if c.take > 0 { upper = lower + c.take } } else if n == 1 { upper = lower + 1 } else { upper = lower + n if c.take > 0 && n > c.take { upper = lower + c.take } } if c.where == nil { if toolkit.SliceLen(c.q.data) > 0 { if lower >= lenData { return errorlib.Error(packageName, modCursor, "Fetch", "No more data to fetched!") } if upper >= lenData { upper = lenData } } } else { if toolkit.SliceLen(c.indexes) > 0 { if lower >= lenIndex { return errorlib.Error(packageName, modCursor, "Fetch", "No more data to fetched!") } if upper >= lenIndex { upper = lenIndex } } } if upper >= c.maxIndex { upper = c.maxIndex } if c.where == nil { source = c.q.data[lower:upper] } else if len(c.indexes) > 0 { for _, v := range c.indexes[lower:upper] { /* toolkit.Printf("Add index: %d. Source info now: %s \n", v, func() string { var ret []string for _, id := range source { ret = append(ret, id.Get("_id").(string)) } return strings.Join(ret, ",") }()) */ if v < len(c.q.data) { source = append(source, c.q.data[v]) } } } if toolkit.SliceLen(c.jsonSelect) > 0 { source = getSelected(source, c.jsonSelect) } var e error if n == 1 && !toolkit.IsSlice(m) { if len(source) > 0 { e = toolkit.Serde(&source[0], m, "json") } } else { e = toolkit.Serde(&source, m, "json") } c.currentIndex = upper if e != nil { return errorlib.Error(packageName, modCursor, "Fetch", e.Error()) } //toolkit.Printf("Data: %s\nLower, Upper = %d, %d\nSource: %s\nResult:%s\n\n", toolkit.JsonString(c.q.data), lower, upper, toolkit.JsonString(source), toolkit.JsonString(m)) return nil }
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 (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) prepare(in toolkit.M) (out toolkit.M, e error) { out = toolkit.M{} quyerParts := q.Parts() c := crowd.From(&quyerParts) groupParts := c.Group(func(x interface{}) interface{} { return x.(*dbox.QueryPart).PartType }, nil).Exec() parts := map[interface{}]interface{}{} if len(groupParts.Result.Data().([]crowd.KV)) > 0 { for _, kv := range groupParts.Result.Data().([]crowd.KV) { parts[kv.Key] = kv.Value } } _, hasUpdate := parts[dbox.QueryPartUpdate] _, hasInsert := parts[dbox.QueryPartInsert] _, hasDelete := parts[dbox.QueryPartDelete] _, hasSave := parts[dbox.QueryPartSave] _, hasFrom := parts[dbox.QueryPartFrom] procedureParts, hasProcedure := parts["procedure"] var tableName string if hasFrom { fromParts, _ := parts[dbox.QueryPartFrom] tableName = fromParts.([]*dbox.QueryPart)[0].Value.(string) } else { return nil, err.Error(packageName, "Query", "prepare", "Invalid table name") } out.Set("tableName", tableName) if freeQueryParts, hasFreeQuery := parts["freequery"]; hasFreeQuery { var syntax string qsyntax := freeQueryParts.([]*dbox.QueryPart)[0].Value.(interface{}) syntax = qsyntax.(toolkit.M)["syntax"].(string) out.Set("freequery", syntax) out.Set("cmdType", dbox.QueryPartSelect) } else if hasInsert || hasUpdate || hasDelete || hasSave { if hasUpdate { out.Set("cmdType", dbox.QueryPartUpdate) } else if hasInsert { out.Set("cmdType", dbox.QueryPartInsert) } else if hasDelete { out.Set("cmdType", dbox.QueryPartDelete) } else if hasSave { out.Set("cmdType", dbox.QueryPartSave) } var where interface{} whereParts, hasWhere := parts[dbox.QueryPartWhere] if hasWhere { fb := q.Connection().Fb() for _, p := range whereParts.([]*dbox.QueryPart) { fs := p.Value.([]*dbox.Filter) for _, f := range fs { fb.AddFilter(f) } } where, e = fb.Build() if e != nil { } out.Set("where", where) } var dataM toolkit.M var dataMs []toolkit.M hasData := in.Has("data") var dataIsSlice bool if hasData { data := in.Get("data") if toolkit.IsSlice(data) { dataIsSlice = true e = toolkit.Unjson(toolkit.Jsonify(data), dataMs) if e != nil { return nil, err.Error(packageName, modQuery, "Exec: ", "Data encoding error: "+e.Error()) } } else { dataM, e = toolkit.ToM(data) dataMs = append(dataMs, dataM) if e != nil { return nil, err.Error(packageName, modQuery, "Exec: ", "Data encoding error: "+e.Error()) } } var id string var idVal interface{} if where == nil { id, idVal = toolkit.IdInfo(data) if id != "" { where = id + " = " + StringValue(idVal, "non") } out.Set("where", where) } if !dataIsSlice { var fields string var values string var setUpdate string var inc int for field, val := range dataM { stringval := StringValue(val, "non") if inc == 0 { fields = "(" + field values = "(" + stringval setUpdate = field + " = " + stringval } else { fields += ", " + field values += ", " + stringval setUpdate += ", " + field + " = " + stringval } inc++ } fields += ")" values += ")" if hasInsert || hasSave { out.Set("fields", fields) out.Set("values", values) } if hasUpdate || hasSave { out.Set("setUpdate", setUpdate) } } } } else if hasProcedure { cmd := procedureParts.([]*dbox.QueryPart)[0].Value.(interface{}) spName := cmd.(toolkit.M)["name"].(string) + " " params, hasParams := cmd.(toolkit.M)["params"] orderparam, hasOrder := cmd.(toolkit.M)["orderparam"] ProcStatement := "" toolkit.Println(spName, params, hasParams, orderparam, hasOrder, ProcStatement) } else { var selectField string incAtt := 0 if selectParts, hasSelect := parts[dbox.QueryPartSelect]; hasSelect { for _, sl := range selectParts.([]*dbox.QueryPart) { for _, fid := range sl.Value.([]string) { if incAtt == 0 { selectField = fid } else { selectField = selectField + ", " + fid } incAtt++ } } } out.Set("cmdType", dbox.QueryPartSelect) out.Set("selectField", selectField) /// /// not yet iimplement var aggrExp string if aggrParts, hasAggr := parts[dbox.QueryPartAggr]; hasAggr { incAtt := 0 for _, aggr := range aggrParts.([]*dbox.QueryPart) { /* isi qp : &{AGGR {$sum 1 Total Item}}*/ aggrInfo := aggr.Value.(dbox.AggrInfo) /* isi Aggr Info : {$sum 1 Total Item}*/ if incAtt == 0 { aggrExp = strings.Replace(aggrInfo.Op, "$", "", 1) + "(" + toolkit.ToString(aggrInfo.Field) + ")" + " as \"" + aggrInfo.Alias + "\"" } else { aggrExp += ", " + strings.Replace(aggrInfo.Op, "$", "", 1) + "(" + toolkit.ToString(aggrInfo.Field) + ")" + " as \"" + aggrInfo.Alias + "\"" } incAtt++ } } out.Set("aggr", aggrExp) /// /// Where Condition var where interface{} if whereParts, hasWhere := parts[dbox.QueryPartWhere]; hasWhere { fb := q.Connection().Fb() for _, p := range whereParts.([]*dbox.QueryPart) { for _, f := range p.Value.([]*dbox.Filter) { if in != nil { f = rdbms.ReadVariable(f, in) } fb.AddFilter(f) } } where, e = fb.Build() if e != nil { return nil, err.Error(packageName, modQuery, "prepare", e.Error()) } } out.Set("where", where) /// /// Sort Condition var sort []string if sortParts, hasSort := parts[dbox.QueryPartOrder]; hasSort { sort = []string{} for _, sr := range sortParts.([]*dbox.QueryPart) { for _, s := range sr.Value.([]string) { sort = append(sort, s) } } } out.Set("sort", sort) /// /// Take Condition take := 0 isTake := false if takeParts, hasTake := parts[dbox.QueryPartTake]; hasTake { isTake = true take = takeParts.([]*dbox.QueryPart)[0].Value.(int) } out.Set("isTake", isTake) out.Set("take", take) /// /// Skip Condition skip := 0 isSkip := false if skipParts, hasSkip := parts[dbox.QueryPartSkip]; hasSkip { isSkip = true skip = skipParts.([]*dbox.QueryPart)[0].Value.(int) } out.Set("isSkip", isSkip) out.Set("skip", skip) /// /// Group By Condition var groupExp string hasAggr := false if groupParts, hasGroup := parts[dbox.QueryPartGroup]; hasGroup { hasAggr = true for _, pg := range groupParts.([]*dbox.QueryPart) { for i, grValue := range pg.Value.([]string) { if i == 0 { groupExp += grValue } else { groupExp += ", " + grValue } } } } out.Set("group", groupExp) out.Set("hasAggr", hasAggr) /// /// Order By Condition var orderExp string if orderParts, hasOrder := parts[dbox.QueryPartOrder]; hasOrder { for _, ordrs := range orderParts.([]*dbox.QueryPart) { for i, oVal := range ordrs.Value.([]string) { if i == 0 { if string(oVal[0]) == "-" { orderExp = strings.Replace(oVal, "-", "", 1) + " DESC" } else { orderExp = oVal + " ASC" } } else { if string(oVal[0]) == "-" { orderExp += ", " + strings.Replace(oVal, "-", "", 1) + " DESC" } else { orderExp += ", " + oVal + " ASC" } } } } } out.Set("order", orderExp) } return }
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 }