You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							107 lines
						
					
					
						
							2.1 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							107 lines
						
					
					
						
							2.1 KiB
						
					
					
				| package json | |
| 
 | |
| import ( | |
| 	"strconv" | |
| 
 | |
| 	"github.com/seaweedfs/seaweedfs/weed/query/sqltypes" | |
| 	"github.com/tidwall/gjson" | |
| 	"github.com/tidwall/match" | |
| ) | |
| 
 | |
| type Query struct { | |
| 	Field string | |
| 	Op    string | |
| 	Value string | |
| } | |
| 
 | |
| func QueryJson(jsonLine string, projections []string, query Query) (passedFilter bool, values []sqltypes.Value) { | |
| 	if filterJson(jsonLine, query) { | |
| 		passedFilter = true | |
| 		fields := gjson.GetMany(jsonLine, projections...) | |
| 		for _, f := range fields { | |
| 			values = append(values, sqltypes.MakeTrusted(sqltypes.Type(f.Type), sqltypes.StringToBytes(f.Raw))) | |
| 		} | |
| 		return | |
| 	} | |
| 	return false, nil | |
| } | |
| 
 | |
| func filterJson(jsonLine string, query Query) bool { | |
| 
 | |
| 	value := gjson.Get(jsonLine, query.Field) | |
| 
 | |
| 	// copied from gjson.go queryMatches() function | |
| 	rpv := query.Value | |
| 
 | |
| 	if !value.Exists() { | |
| 		return false | |
| 	} | |
| 	if query.Op == "" { | |
| 		// the query is only looking for existence, such as: | |
| 		//   friends.#(name) | |
| 		// which makes sure that the array "friends" has an element of | |
| 		// "name" that exists | |
| 		return true | |
| 	} | |
| 	switch value.Type { | |
| 	case gjson.String: | |
| 		switch query.Op { | |
| 		case "=": | |
| 			return value.Str == rpv | |
| 		case "!=": | |
| 			return value.Str != rpv | |
| 		case "<": | |
| 			return value.Str < rpv | |
| 		case "<=": | |
| 			return value.Str <= rpv | |
| 		case ">": | |
| 			return value.Str > rpv | |
| 		case ">=": | |
| 			return value.Str >= rpv | |
| 		case "%": | |
| 			return match.Match(value.Str, rpv) | |
| 		case "!%": | |
| 			return !match.Match(value.Str, rpv) | |
| 		} | |
| 	case gjson.Number: | |
| 		rpvn, _ := strconv.ParseFloat(rpv, 64) | |
| 		switch query.Op { | |
| 		case "=": | |
| 			return value.Num == rpvn | |
| 		case "!=": | |
| 			return value.Num != rpvn | |
| 		case "<": | |
| 			return value.Num < rpvn | |
| 		case "<=": | |
| 			return value.Num <= rpvn | |
| 		case ">": | |
| 			return value.Num > rpvn | |
| 		case ">=": | |
| 			return value.Num >= rpvn | |
| 		} | |
| 	case gjson.True: | |
| 		switch query.Op { | |
| 		case "=": | |
| 			return rpv == "true" | |
| 		case "!=": | |
| 			return rpv != "true" | |
| 		case ">": | |
| 			return rpv == "false" | |
| 		case ">=": | |
| 			return true | |
| 		} | |
| 	case gjson.False: | |
| 		switch query.Op { | |
| 		case "=": | |
| 			return rpv == "false" | |
| 		case "!=": | |
| 			return rpv != "false" | |
| 		case "<": | |
| 			return rpv == "true" | |
| 		case "<=": | |
| 			return true | |
| 		} | |
| 	} | |
| 	return false | |
| 
 | |
| }
 |