func (q *Query) generateIndex(filters []*dbox.Filter) (output []int, e error) { var n int = 0 for { tdread, e := q.reader.Read() if e != nil && e != io.EOF { break } n++ tm := toolkit.M{} for i, v := range tdread { tolower := strings.ToLower(q.headerColumn[i].name) tm.Set(tolower, v) if q.headerColumn[i].dataType == "int" { tm[tolower] = cast.ToInt(v, cast.RoundingAuto) } else if q.headerColumn[i].dataType == "float" { tm[tolower] = cast.ToF64(v, (len(v) - (strings.IndexAny(v, "."))), cast.RoundingAuto) } } match := dbox.MatchM(tm, filters) if (len(filters) == 0 || match) && len(tm) > 0 { output = append(output, n) } if e == io.EOF { break } } e = q.resetReader() return }
func (q *Query) execQueryPartDelete(Cond QueryCondition) error { writer := q.Connection().(*Connection).writer reader := q.Connection().(*Connection).reader tempHeader := []string{} for _, val := range q.Connection().(*Connection).headerColumn { tempHeader = append(tempHeader, val.name) } for { foundDelete := true recData := toolkit.M{} dataTemp, e := reader.Read() for i, val := range dataTemp { recData.Set(tempHeader[i], val) if q.Connection().(*Connection).headerColumn[i].dataType == "int" { recData[tempHeader[i]] = cast.ToInt(val, cast.RoundingAuto) } else if q.Connection().(*Connection).headerColumn[i].dataType == "float" { recData[tempHeader[i]] = cast.ToF64(val, (len(val) - (strings.IndexAny(val, "."))), cast.RoundingAuto) } } foundDelete = Cond.getCondition(recData) if e == io.EOF { if !foundDelete && dataTemp != nil { writer.Write(dataTemp) writer.Flush() } break } else if e != nil { return errorlib.Error(packageName, modQuery, "Delete", e.Error()) } if !foundDelete && dataTemp != nil { writer.Write(dataTemp) writer.Flush() } } return nil }
func (c *Cursor) generateIndexes() error { var e error output := []int{} var n int = 0 for { tdread, e := c.reader.Read() if e != nil && e != io.EOF { break } n++ tm := toolkit.M{} for i, v := range tdread { lowername := strings.ToLower(c.headerColumn[i].name) tm.Set(lowername, v) if c.headerColumn[i].dataType == "int" { tm[lowername] = cast.ToInt(v, cast.RoundingAuto) } else if c.headerColumn[i].dataType == "float" { tm[lowername] = cast.ToF64(v, (len(v) - (strings.IndexAny(v, "."))), cast.RoundingAuto) } } if c.ConditionVal.getCondition(tm) && len(tm) > 0 { //len(c.ConditionVal.where) == 0 || dbox.MatchM(tm, c.ConditionVal.where) { output = append(output, n) } if e == io.EOF { break } } c.ConditionVal.indexes = output e = c.resetConnection() if e != nil { return errorlib.Error(packageName, modCursor, "Reset Fetch", e.Error()) } return e }
func (c *Cursor) Fetch(m interface{}, n int, closeWhenDone bool) error { if closeWhenDone { defer c.Close() } e := c.prepIter() if e != nil { return errorlib.Error(packageName, modCursor, "Fetch", e.Error()) } if !toolkit.IsPointer(m) { return errorlib.Error(packageName, modCursor, "Fetch", "Model object should be pointer") } if n != 1 && reflect.ValueOf(m).Elem().Kind() != reflect.Slice { return errorlib.Error(packageName, modCursor, "Fetch", "Model object should be pointer of slice") } var v reflect.Type if n == 1 { v = reflect.TypeOf(m).Elem() } else { v = reflect.TypeOf(m).Elem().Elem() } ivs := reflect.MakeSlice(reflect.SliceOf(v), 0, 0) lineCount := 0 //============================= // fmt.Println("Qursor 133 : ", c.ConditionVal.Find) for { iv := reflect.New(v).Interface() isAppend := true c.count += 1 recData := toolkit.M{} appendData := toolkit.M{} dataTemp, e := c.reader.Read() for i, val := range dataTemp { orgname := c.headerColumn[i].name lowername := strings.ToLower(c.headerColumn[i].name) switch c.headerColumn[i].dataType { case "int": recData[lowername] = cast.ToInt(val, cast.RoundingAuto) case "float": recData[lowername] = cast.ToF64(val, 2, cast.RoundingAuto) default: recData[lowername] = val } if len(c.ConditionVal.Select) == 0 || c.ConditionVal.Select.Get("*", 0).(int) == 1 { appendData[orgname] = recData[lowername] } else { if c.ConditionVal.Select.Get(strings.ToLower(c.headerColumn[i].name), 0).(int) == 1 { appendData[orgname] = recData[lowername] } } } isAppend = c.ConditionVal.getCondition(recData) if c.count < c.ConditionVal.skip || (c.count > (c.ConditionVal.skip+c.ConditionVal.limit) && c.ConditionVal.limit > 0) { isAppend = false } if v.Kind() == reflect.Struct { for i := 0; i < v.NumField(); i++ { if appendData.Has(v.Field(i).Name) { switch v.Field(i).Type.Kind() { case reflect.Int: appendData.Set(v.Field(i).Name, cast.ToInt(appendData[v.Field(i).Name], cast.RoundingAuto)) } } } } if e == io.EOF { if isAppend && len(appendData) > 0 { toolkit.Serde(appendData, iv, "json") ivs = reflect.Append(ivs, reflect.ValueOf(iv).Elem()) lineCount += 1 } break } else if e != nil { return errorlib.Error(packageName, modCursor, "Fetch", e.Error()) } if isAppend && len(appendData) > 0 { toolkit.Serde(appendData, iv, "json") ivs = reflect.Append(ivs, reflect.ValueOf(iv).Elem()) lineCount += 1 } if n > 0 { if lineCount >= n { break } } } if e != nil { return errorlib.Error(packageName, modCursor, "Fetch", e.Error()) } if n == 1 { if ivs.Len() > 0 { reflect.ValueOf(m).Elem().Set(ivs.Index(0)) } } else { reflect.ValueOf(m).Elem().Set(ivs) } return nil }
func generateFilterQuerySQL(strwhere string) (fb *Filter) { strwhere = strings.TrimSpace(strwhere) rbracket := regexp.MustCompile(`^\(.*\)$`) if rbracket.MatchString(strwhere) { if cond, _ := regexp.MatchString(`^\(.*\) ([Oo][Rr]|[Aa][Nn][Dd]) (.*)$`, strwhere); !cond { strwhere = strings.TrimSuffix(strings.TrimPrefix(strwhere, "("), ")") } } // toolkit.Printf("Connection 161 : %#v\n", strwhere) r := regexp.MustCompile(`^(?P<lastprocess01>(.*))(?P<firstprocess>(\(.*([Aa][Nn][Dd]|[Oo][Rr]).*\)))(?P<lastprocess02>(.*))$`) if !r.MatchString(strwhere) { r = regexp.MustCompile(`(.*) (?P<oprandor>([Oo][Rr])) (.*)`) } if !r.MatchString(strwhere) { r = regexp.MustCompile(`(.*) (?P<oprandor>([Aa][Nn][Dd])) (.*)`) } if !r.MatchString(strwhere) { r = regexp.MustCompile(`(?P<field>([a-zA-Z][_a-zA-Z]+[_a-zA-Z0-1]*))(?P<opr>((\s)*(=|<>|[><](=)?)|(\s(I|i)(N|n)\s)|(\s(L|l)(I|i)(K|k)(E|e)\s)))(?P<value>(.*))`) } temparray := r.FindStringSubmatch(strwhere) condpart := toolkit.M{} for i, val := range r.SubexpNames() { if val != "" { condpart.Set(val, temparray[i]) } } arstrwhere := make([]string, 0, 0) oprstr := "or" if condpart.Has("firstprocess") { oprstr, arstrwhere = generateWhereCondition(strwhere) // for _, val := range generateWhereCondition(strwhere) { // arstrwhere = append(arstrwhere, val) // } // next01 := condpart.Get("lastprocess01", "").(string) // next02 := condpart.Get("lastprocess01", "").(string) // if condition { // } // //parsing check operator to and insert to arstwhere } else if condpart.Has("oprandor") { arstrwhere = strings.Split(strwhere, condpart["oprandor"].(string)) if strings.ToLower(condpart["oprandor"].(string)) == "and" { oprstr = "and" } } if len(arstrwhere) > 0 { var arfilter []*Filter for _, swhere := range arstrwhere { arfilter = append(arfilter, generateFilterQuerySQL(swhere)) } if oprstr == "and" { fb = And(arfilter...) } else { fb = Or(arfilter...) } // //Check Bracket if regexp.MatchString(`^(.*)\(.*([Aa][Nn][Dd]|[Oo][Rr]).*\)(.*)$`, strwhere) { // if strings.TrimSpace(condpart.Get("oprandor", "").(string)) == "and" { // fb = And(generateFilterQuerySQL(condpart.Get("currcond", "").(string)), generateFilterQuerySQL(condpart.Get("nextcond", "").(string))) // } else { // fb = Or(generateFilterQuerySQL(condpart.Get("currcond", "").(string)), generateFilterQuerySQL(condpart.Get("nextcond", "").(string))) // } } else { var ( asv []interface{} iv interface{} ) c1 := strings.TrimSpace(condpart.Get("field", "").(string)) tv := strings.TrimSpace(condpart.Get("value", "").(string)) opr := strings.ToLower(strings.TrimSpace(condpart.Get("opr", "").(string))) // if condition { tv = strings.TrimSuffix(tv, ")") // } if opr != "in" { if strings.Contains(tv, `'`) || strings.Contains(tv, `"`) { sv := strings.Replace(strings.Replace(tv, `'`, "", -1), `"`, "", -1) if opr == "like" { sv = strings.Replace(strings.Replace(sv, "%", "(.)*", -1), "_", "(.)?", -1) } iv = sv } else if strings.Contains(tv, `.`) { iv = cast.ToF64(tv, (len(tv) - (strings.IndexAny(tv, "."))), cast.RoundingAuto) } else { iv = cast.ToInt(tv, cast.RoundingAuto) } } else { tv = strings.Replace(strings.Replace(tv, "(", "", 1), ")", "", 1) // asv = strings.Split(tv, ",") for _, val := range strings.Split(tv, ",") { var tiv interface{} ttv := strings.TrimSpace(val) if strings.Contains(ttv, `'`) || strings.Contains(ttv, `"`) { tiv = strings.Replace(strings.Replace(ttv, `'`, "", -1), `"`, "", -1) } else if strings.Contains(ttv, `.`) { tiv = cast.ToF64(ttv, (len(ttv) - (strings.IndexAny(ttv, "."))), cast.RoundingAuto) } else { tiv = cast.ToInt(ttv, cast.RoundingAuto) } asv = append(asv, tiv) } } switch opr { case "=": fb = Eq(c1, iv) case "<>": fb = Ne(c1, iv) case ">": fb = Lt(c1, iv) case "<": fb = Gt(c1, iv) case ">=": fb = Lte(c1, iv) case "<=": fb = Gte(c1, iv) case "like": fb = Contains(c1, iv.(string)) case "in": fb = In(c1, asv...) } } return }
func (c *Cursor) Fetch(m interface{}, n int, closeWhenDone bool) error { if closeWhenDone { defer c.Close() } e := c.prepIter() if e != nil { return errorlib.Error(packageName, modCursor, "Fetch", e.Error()) } if !toolkit.IsPointer(m) { return errorlib.Error(packageName, modCursor, "Fetch", "Model object should be pointer") } if n != 1 && reflect.ValueOf(m).Elem().Kind() != reflect.Slice { return errorlib.Error(packageName, modCursor, "Fetch", "Model object should be pointer of slice") } var v reflect.Type if n == 1 && reflect.ValueOf(m).Elem().Kind() != reflect.Slice { v = reflect.TypeOf(m).Elem() } else { v = reflect.TypeOf(m).Elem().Elem() } ivs := reflect.MakeSlice(reflect.SliceOf(v), 0, 0) lineCount := 0 //============================= // fmt.Println("Qursor 191 : ", c.headerColumn) for { iv := reflect.New(v).Interface() isAppend := true // c.count += 1 recData := toolkit.M{} appendData := toolkit.M{} dataTemp, e := c.reader.Read() for i, val := range dataTemp { orgname := c.headerColumn[i].name lowername := strings.ToLower(c.headerColumn[i].name) switch c.headerColumn[i].dataType { case "int": recData[lowername] = cast.ToInt(val, cast.RoundingAuto) case "float": decimalPoint := len(val) - (strings.Index(val, ".") + 1) recData[lowername] = cast.ToF64(val, decimalPoint, cast.RoundingAuto) case "date": recData[lowername] = toolkit.String2Date(val, c.headerColumn[i].format) // Just for test // fmt.Printf("FOR DEBUG : %v \n", c.headerColumn[i].format) default: recData[lowername] = val } if len(c.ConditionVal.Select) == 0 || c.ConditionVal.Select.Get("*", 0).(int) == 1 { appendData[orgname] = recData[lowername] } else { if c.ConditionVal.Select.Get(strings.ToLower(c.headerColumn[i].name), 0).(int) == 1 { appendData[orgname] = recData[lowername] } } } isAppend = c.ConditionVal.getCondition(recData) if isAppend { c.count += 1 } if c.count <= c.ConditionVal.skip || (c.count > (c.ConditionVal.skip+c.ConditionVal.limit) && c.ConditionVal.limit > 0) { isAppend = false } // fmt.Printf("%v - %v \n", v.Elem().Kind(), toolkit.TypeName(v)) if v.Kind() == reflect.Struct || v.Elem().Kind() == reflect.Struct { tv := v if v.Elem().Kind() == reflect.Struct { tv = v.Elem() } for i := 0; i < tv.NumField(); i++ { str := tv.Field(i).Name fcond := false if appendData.Has(str) { fcond = true } else if appendData.Has(strings.ToLower(str)) { fcond = true str = strings.ToLower(str) } else if strings.ToLower(str) == "id" && appendData.Has("_id") { str = "_id" fcond = true } if fcond { switch tv.Field(i).Type.Kind() { case reflect.Int: appendData.Set(str, cast.ToInt(appendData[str], cast.RoundingAuto)) case reflect.String: appendData.Set(str, toolkit.ToString(appendData[str])) case reflect.Float64: tstr := toolkit.ToString(appendData[str]) decimalPoint := len(tstr) - (strings.Index(tstr, ".") + 1) appendData.Set(str, toolkit.ToFloat64(tstr, decimalPoint, toolkit.RoundingAuto)) } } } } if e == io.EOF { if isAppend && len(appendData) > 0 { toolkit.Serde(appendData, iv, "json") ivs = reflect.Append(ivs, reflect.ValueOf(iv).Elem()) lineCount += 1 } break } else if e != nil { return errorlib.Error(packageName, modCursor, "Fetch", e.Error()) } if isAppend && len(appendData) > 0 { toolkit.Serde(appendData, iv, "json") ivs = reflect.Append(ivs, reflect.ValueOf(iv).Elem()) lineCount += 1 } if n > 0 { if lineCount >= n { break } } } if e != nil { return errorlib.Error(packageName, modCursor, "Fetch", e.Error()) } if n == 1 && reflect.ValueOf(m).Elem().Kind() != reflect.Slice { if ivs.Len() > 0 { reflect.ValueOf(m).Elem().Set(ivs.Index(0)) } } else { reflect.ValueOf(m).Elem().Set(ivs) } return nil }
func (q *Query) execQueryPartUpdate(dt toolkit.M, Cond QueryCondition) error { if len(dt) == 0 { return errorlib.Error(packageName, "Query", modQuery, "data to update is not found") } writer := q.Connection().(*Connection).writer reader := q.Connection().(*Connection).reader tempHeader := []string{} for _, val := range q.Connection().(*Connection).headerColumn { tempHeader = append(tempHeader, val.name) } for { foundChange := false recData := toolkit.M{} dataTemp, e := reader.Read() for i, val := range dataTemp { recData.Set(tempHeader[i], val) if q.Connection().(*Connection).headerColumn[i].dataType == "int" { recData[tempHeader[i]] = cast.ToInt(val, cast.RoundingAuto) } else if q.Connection().(*Connection).headerColumn[i].dataType == "float" { recData[tempHeader[i]] = cast.ToF64(val, (len(val) - (strings.IndexAny(val, "."))), cast.RoundingAuto) } } if len(Cond.where) > 0 { //|| (len(Cond.where) == 0 && toolkit.IdField(dt) == "") { foundChange = Cond.getCondition(recData) } // Check ID IF Condition Not Found if nameid := toolkit.IdField(dt); nameid != "" && !foundChange { if recData.Has(nameid) && dt[nameid] == recData[nameid] { foundChange = true } } if foundChange && len(dataTemp) > 0 { for n, v := range tempHeader { if dt.Has(v) { dataTemp[n] = cast.ToString(dt[v]) } } } if e == io.EOF { if dataTemp != nil { writer.Write(dataTemp) writer.Flush() } break } else if e != nil { return errorlib.Error(packageName, modQuery, "Update", e.Error()) } if dataTemp != nil { writer.Write(dataTemp) writer.Flush() } } return nil }