From 724ffec683c8f5fc48cd42b1919960630102604c Mon Sep 17 00:00:00 2001 From: Jinzhu Date: Thu, 31 Oct 2013 17:31:00 +0800 Subject: [PATCH] Add Method Not --- chain.go | 7 +++++++ do.go | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ main.go | 4 ++++ 3 files changed, 72 insertions(+) diff --git a/chain.go b/chain.go index fe99b862..7354154d 100644 --- a/chain.go +++ b/chain.go @@ -20,6 +20,7 @@ type Chain struct { whereClause []map[string]interface{} orClause []map[string]interface{} + notClause []map[string]interface{} initAttrs []interface{} assignAttrs []interface{} selectStr string @@ -61,6 +62,7 @@ func (s *Chain) do(value interface{}) *Do { do.whereClause = s.whereClause do.orClause = s.orClause + do.notClause = s.notClause do.selectStr = s.selectStr do.orderStrs = s.orderStrs do.offsetStr = s.offsetStr @@ -83,6 +85,11 @@ func (s *Chain) Where(querystring interface{}, args ...interface{}) *Chain { return s } +func (s *Chain) Not(querystring interface{}, args ...interface{}) *Chain { + s.notClause = append(s.notClause, map[string]interface{}{"query": querystring, "args": args}) + return s +} + func (s *Chain) Limit(value interface{}) *Chain { switch value := value.(type) { case string: diff --git a/do.go b/do.go index 98126026..b9a292a6 100644 --- a/do.go +++ b/do.go @@ -28,6 +28,7 @@ type Do struct { whereClause []map[string]interface{} orClause []map[string]interface{} + notClause []map[string]interface{} selectStr string orderStrs []string offsetStr string @@ -423,6 +424,62 @@ func (s *Do) buildWhereCondition(clause map[string]interface{}) (str string) { return } +func (s *Do) buildNotCondition(clause map[string]interface{}) (str string) { + query := clause["query"] + var not_equal_sql string + + switch query.(type) { + case string: + value := query.(string) + if regexp.MustCompile("^\\s*\\d+\\s*$").MatchString(value) { + id, _ := strconv.Atoi(value) + return fmt.Sprintf("(%v <> %v)", s.model.primaryKeyDb(), id) + } else { + str = "( \"" + value + "\" NOT INT (?))" + not_equal_sql = " (%v <> ?) " + } + case int, int64, int32: + return fmt.Sprintf("(%v <> %v)", s.model.primaryKeyDb(), query) + case []int64, []int, []int32, []string: + if reflect.ValueOf(query).Len() > 0 { + str = fmt.Sprintf("(%v not in (?))", s.model.primaryKeyDb()) + clause["args"] = []interface{}{query} + } else { + s.err(errors.New(fmt.Sprintf("%+v not supported", query))) + return + } + case map[string]interface{}: + var sqls []string + for key, value := range query.(map[string]interface{}) { + sqls = append(sqls, fmt.Sprintf(" ( %v <> %v ) ", key, s.addToVars(value))) + } + return strings.Join(sqls, " AND ") + case interface{}: + m := &Model{data: query, driver: s.driver} + var sqls []string + for _, field := range m.columnsHasValue("") { + sqls = append(sqls, fmt.Sprintf(" ( %v <> %v ) ", field.DbName, s.addToVars(field.Value))) + } + return strings.Join(sqls, " AND ") + } + + args := clause["args"].([]interface{}) + for _, arg := range args { + switch reflect.TypeOf(arg).Kind() { + case reflect.Slice: // For where("id in (?)", []int64{1,2}) + values := reflect.ValueOf(arg) + var temp_marks []string + for i := 0; i < values.Len(); i++ { + temp_marks = append(temp_marks, s.addToVars(values.Index(i).Addr().Interface())) + } + str = strings.Replace(str, "?", strings.Join(temp_marks, ","), 1) + default: + str = strings.Replace(not_equal_sql, "?", s.addToVars(arg), 1) + } + } + return +} + func (s *Do) whereSql() (sql string) { var primary_condiations, and_conditions, or_conditions []string @@ -442,6 +499,10 @@ func (s *Do) whereSql() (sql string) { or_conditions = append(or_conditions, s.buildWhereCondition(clause)) } + for _, clause := range s.notClause { + and_conditions = append(and_conditions, s.buildNotCondition(clause)) + } + and_sql := strings.Join(and_conditions, " AND ") or_sql := strings.Join(or_conditions, " OR ") combined_conditions := and_sql diff --git a/main.go b/main.go index ea56b7bc..9d093287 100644 --- a/main.go +++ b/main.go @@ -26,6 +26,10 @@ func (s *DB) Where(querystring interface{}, args ...interface{}) *Chain { return s.buildChain().Where(querystring, args...) } +func (s *DB) Not(querystring interface{}, args ...interface{}) *Chain { + return s.buildChain().Not(querystring, args...) +} + func (s *DB) First(out interface{}, where ...interface{}) *Chain { return s.buildChain().First(out, where...) }