Browse Source

Imported codes from gienah.

v0.4
Mingcai SHEN 8 years ago
parent
commit
b89d95e32f
5 changed files with 459 additions and 0 deletions
  1. +29
    -0
      models/query.go
  2. +246
    -0
      models/types.go
  3. +38
    -0
      utils/crc16.go
  4. +99
    -0
      utils/hashmap.go
  5. +47
    -0
      utils/miscs.go

+ 29
- 0
models/query.go View File

@ -0,0 +1,29 @@
package models
type ConditionType uint
const (
CONDITION_AND ConditionType = iota
CONDITION_OR
)
type OrderType uint
const (
ORDERTYPE_ASC OrderType = iota
ORDERTYPE_DESC
)
type QueryFilter struct {
Condition ConditionType // AND , OR
Reversed bool // Reversed Field and Value if it is true
Field string
Operator string // Value will not used if empty.
Value interface{}
}
type QueryOrder struct {
Type OrderType
Field string
}

+ 246
- 0
models/types.go View File

@ -1 +1,247 @@
package models package models
import (
"errors"
"encoding/json"
"database/sql/driver"
"database/sql"
"regexp"
"strings"
"fmt"
)
type JASONDictionary map[string]interface{}
func (p *JASONDictionary) Scan(src interface{}) error {
if nil == src {
*p = nil
return nil
}
source, ok := src.([]byte)
if !ok {
return errors.New("Type assertion .([]byte) failed.")
}
var i JASONDictionary
err := json.Unmarshal(source, &i)
if err != nil {
return err
}
*p = i
return nil
}
func (p JASONDictionary) Value() (driver.Value, error) {
j, err := json.Marshal(p)
return j, err
}
type JSONDictionaryArray []JASONDictionary
func (p *JSONDictionaryArray) Scan(src interface{}) error {
source, ok := src.([]byte)
if !ok {
return errors.New("Type assertion .([]byte) failed.")
}
var i JSONDictionaryArray
err := json.Unmarshal(source, &i)
if err != nil {
return err
}
*p = i
return nil
}
func (p JSONDictionaryArray) Value() (driver.Value, error) {
j, err := json.Marshal(p)
return j, err
}
type StringArray []string
// PARSING ARRAYS
// SEE http://www.postgresql.org/docs/9.1/static/arrays.html#ARRAYS-IO
// Arrays are output within {} and a delimiter, which is a comma for most
// postgres types (; for box)
//
// Individual values are surrounded by quotes:
// The array output routine will put double quotes around element values if
// they are empty strings, contain curly braces, delimiter characters,
// double quotes, backslashes, or white space, or match the word NULL.
// Double quotes and backslashes embedded in element values will be
// backslash-escaped. For numeric data types it is safe to assume that double
// quotes will never appear, but for textual data types one should be prepared
// to cope with either the presence or absence of quotes.
// construct a regexp to extract values:
var (
// unquoted array values must not contain: (" , \ { } whitespace NULL)
// and must be at least one char
unquotedChar = `[^",\\{}\s(NULL)]`
unquotedValue = fmt.Sprintf("(%s)+", unquotedChar)
// quoted array values are surrounded by double quotes, can be any
// character except " or \, which must be backslash escaped:
quotedChar = `[^"\\]|\\"|\\\\`
quotedValue = fmt.Sprintf("\"(%s)*\"", quotedChar)
// an array value may be either quoted or unquoted:
arrayValue = fmt.Sprintf("(?P<value>(%s|%s))", unquotedValue, quotedValue)
// Array values are separated with a comma IF there is more than one value:
arrayExp = regexp.MustCompile(fmt.Sprintf("((%s)(,)?)", arrayValue))
valueIndex int
)
// Find the index of the 'value' named expression
func init() {
for i, subexp := range arrayExp.SubexpNames() {
if subexp == "value" {
valueIndex = i
break
}
}
}
// Parse the output string from the array type.
// Regex used: (((?P<value>(([^",\\{}\s(NULL)])+|"([^"\\]|\\"|\\\\)*")))(,)?)
func parseArray(array string) []string {
results := make([]string, 0)
matches := arrayExp.FindAllStringSubmatch(array, -1)
for _, match := range matches {
s := match[valueIndex]
// the string _might_ be wrapped in quotes, so trim them:
s = strings.Trim(s, "\"")
results = append(results, s)
}
return results
}
func (p *StringArray) Scan(src interface{}) error {
asBytes, ok := src.([]byte)
if !ok {
return error(errors.New("Scan source was not []bytes"))
}
asString := string(asBytes)
parsed := parseArray(asString)
(*p) = StringArray(parsed)
return nil
}
func (p StringArray) Value() (driver.Value, error) {
j, err := json.Marshal(p)
return j, err
}
type HSTOREDictionary map[string]interface{}
// escapes and quotes hstore keys/values
// s should be a sql.NullString or string
func hQuote(s interface{}) string {
var str string
switch v := s.(type) {
case sql.NullString:
if !v.Valid {
return "NULL"
}
str = v.String
case string:
str = v
default:
panic("not a string or sql.NullString")
}
str = strings.Replace(str, "\\", "\\\\", -1)
return `"` + strings.Replace(str, "\"", "\\\"", -1) + `"`
}
// Scan implements the Scanner interface.
//
// Note h.Map is reallocated before the scan to clear existing values. If the
// hstore column's database value is NULL, then h.Map is set to nil instead.
func (h *HSTOREDictionary) Scan(value interface{}) error {
if value == nil {
*h = nil
return nil
}
m := make(map[string]interface{})
var b byte
pair := [][]byte{{}, {}}
pi := 0
inQuote := false
didQuote := false
sawSlash := false
bindex := 0
for bindex, b = range value.([]byte) {
if sawSlash {
pair[pi] = append(pair[pi], b)
sawSlash = false
continue
}
switch b {
case '\\':
sawSlash = true
continue
case '"':
inQuote = !inQuote
if !didQuote {
didQuote = true
}
continue
default:
if !inQuote {
switch b {
case ' ', '\t', '\n', '\r':
continue
case '=':
continue
case '>':
pi = 1
didQuote = false
continue
case ',':
s := string(pair[1])
if !didQuote && len(s) == 4 && strings.ToLower(s) == "null" {
m[string(pair[0])] = nil // sql.NullString{String: "", Valid: false}
} else {
m[string(pair[0])] = string(pair[1]) // sql.NullString{String: string(pair[1]), Valid: true}
}
pair[0] = []byte{}
pair[1] = []byte{}
pi = 0
continue
}
}
}
pair[pi] = append(pair[pi], b)
}
if bindex > 0 {
s := string(pair[1])
if !didQuote && len(s) == 4 && strings.ToLower(s) == "null" {
m[string(pair[0])] = nil // sql.NullString{String: "", Valid: false}
} else {
m[string(pair[0])] = string(pair[1]) // sql.NullString{String: string(pair[1]), Valid: true}
}
}
*h = m
return nil
}
// Value implements the driver Valuer interface. Note if h.Map is nil, the
// database column value will be set to NULL.
func (h HSTOREDictionary) Value() (driver.Value, error) {
if h == nil {
return nil, nil
}
parts := []string{}
for key, val := range h {
thispart := hQuote(key) + "=>" + hQuote(val)
parts = append(parts, thispart)
}
return []byte(strings.Join(parts, ",")), nil
}

+ 38
- 0
utils/crc16.go View File

@ -0,0 +1,38 @@
package utils
const (
iBm = 0xA001
)
type tABLe [256]uint16
var ibmTable = makeTable(iBm)
func makeTable(poly uint16) *tABLe {
t := new(tABLe)
for i := 0; i < 256; i++ {
crc := uint16(i)
for j := 0; j < 8; j++ {
if crc & 1 == 1 {
crc = (crc >> 1) ^ poly
} else {
crc >>= 1
}
}
t[i] = crc
}
return t
}
func update(crc uint16, tab *tABLe, p []byte) uint16 {
crc = ^crc
for _, v := range p {
crc = tab[byte(crc) ^ v] ^ (crc >> 8)
}
return ^crc
}
func CRC16(data []byte) uint16 {
return update(0, ibmTable, data)
}

+ 99
- 0
utils/hashmap.go View File

@ -0,0 +1,99 @@
package utils
import (
"strconv"
"strings"
"github.com/archsh/go.uuid"
)
type HashMap map[string]string
func (h HashMap)HasKey(k string) bool {
if nil == h {
return false
}
_, ok := h[k]
return ok
}
func (h HashMap)GetInt(k string, defaults... int) (int, bool) {
d := 0
if len(defaults) > 0 {
d = defaults[0]
}
if nil == h {
return d, false
}
if ns, ok := h[k]; ok {
if n, e := strconv.Atoi(ns); e == nil {
return n, true
}
}
return d, false
}
func (h HashMap)GetUInt(k string, defaults... uint) (uint, bool) {
var d uint = 0
if len(defaults) > 0 {
d = defaults[0]
}
if nil == h {
return d, false
}
if ns, ok := h[k]; ok {
if n, e := strconv.ParseUint(ns, 10, 32); e == nil {
return uint(n), true
}
}
return d, false
}
func (h HashMap)GetString(k string, defaults... string) (string, bool) {
d := ""
if len(defaults) > 0 {
d = defaults[0]
}
if nil == h {
return d, false
}
if ns, ok := h[k]; ok {
return ns, true
}
return d, false
}
func (h HashMap)GetBool(k string, defaults... bool) (bool, bool) {
d := false
if len(defaults) > 0 {
d = defaults[0]
}
if nil == h {
return d, false
}
if ns, ok := h[k]; ok {
switch strings.ToLower(ns) {
case "t", "true", "yes", "ok":
return true, true
case "f", "false", "no":
return false, true
}
}
return d, false
}
func (h HashMap)GetUUID(k string, defaults ... uuid.UUID) (uuid.UUID, bool) {
d := uuid.UUID{}
if len(defaults) > 0 {
d = defaults[0]
}
if nil == h {
return d, false
}
if ns, ok := h[k]; ok {
if uid, e := uuid.FromString(ns); nil == e {
return uid, true
}
}
return d, false
}

+ 47
- 0
utils/miscs.go View File

@ -0,0 +1,47 @@
package utils
import (
"errors"
"encoding/hex"
)
func EqualBytes(a, b []byte) bool {
if a == nil && b == nil {
return true;
}
if a == nil || b == nil {
return false;
}
if len(a) != len(b) {
return false
}
for i := range a {
if a[i] != b[i] {
return false
}
}
return true
}
func StringInSlice(a string, ls []string) bool {
for _, s := range ls {
if a == s {
return true
}
}
return false
}
func MacAddr2Bytes(mac string) ([]byte, error) {
b, e := hex.DecodeString(mac)
if nil != e {
return nil, e
}
if len(b) != 6 {
return nil, errors.New("Length not match")
}
return b, e
}

Loading…
Cancel
Save