-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
897 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
module github.com/twiglab/sqlt | ||
|
||
require ( | ||
github.com/jmoiron/sqlx v1.2.0 | ||
github.com/lib/pq v1.0.0 | ||
google.golang.org/appengine v1.4.0 // indirect | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
github.com/go-sql-driver/mysql v1.4.0 h1:7LxgVwFb2hIQtMm87NdgAVfXjnt4OePseqT1tKx+opk= | ||
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= | ||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | ||
github.com/jmoiron/sqlx v1.2.0 h1:41Ip0zITnmWNR/vHV+S4m+VoUivnWY5E4OJfLZjCJMA= | ||
github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= | ||
github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A= | ||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= | ||
github.com/mattn/go-sqlite3 v1.9.0 h1:pDRiWfl+++eC2FEFRy6jXmQlvp4Yh3z1MJKg4UeYM/4= | ||
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= | ||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= | ||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package mapper | ||
|
||
import ( | ||
"errors" | ||
"reflect" | ||
) | ||
|
||
type ColScanner interface { | ||
Columns() ([]string, error) | ||
Scan(dest ...interface{}) error | ||
Err() error | ||
} | ||
|
||
func MapScan(r ColScanner, dest map[string]interface{}) error { | ||
columns, err := r.Columns() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
values := make([]interface{}, len(columns)) | ||
for i := range values { | ||
values[i] = new(interface{}) | ||
} | ||
|
||
err = r.Scan(values...) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
for i, column := range columns { | ||
dest[column] = *(values[i].(*interface{})) | ||
} | ||
|
||
return r.Err() | ||
} | ||
|
||
func StructScan(rows ColScanner, dest interface{}) (err error) { | ||
destValue := reflect.ValueOf(dest) | ||
elemType := destValue.Type() | ||
|
||
if elemType.Kind() != reflect.Ptr { | ||
return errors.New("slice elem must ptr ") | ||
} | ||
|
||
rowMap := make(map[string]interface{}) | ||
if err = MapScan(rows, rowMap); err != nil { | ||
return | ||
} | ||
if err = MapperMap(rowMap, dest); err != nil { | ||
return | ||
} | ||
|
||
return | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,233 @@ | ||
package mapper | ||
|
||
import ( | ||
"fmt" | ||
"math/big" | ||
"reflect" | ||
"strconv" | ||
"time" | ||
) | ||
|
||
// Convert is the target string | ||
type Convert string | ||
|
||
// Set string | ||
func (f *Convert) Set(v string) { | ||
if v != "" { | ||
*f = Convert(v) | ||
} else { | ||
f.Clear() | ||
} | ||
} | ||
|
||
// Clear string | ||
func (f *Convert) Clear() { | ||
*f = Convert(0x1E) | ||
} | ||
|
||
// Exist check string exist | ||
func (f Convert) Exist() bool { | ||
return string(f) != string(0x1E) | ||
} | ||
|
||
// Bool string to bool | ||
func (f Convert) Bool() (bool, error) { | ||
return strconv.ParseBool(f.String()) | ||
} | ||
|
||
// Float32 string to float32 | ||
func (f Convert) Float32() (float32, error) { | ||
v, err := strconv.ParseFloat(f.String(), 32) | ||
return float32(v), err | ||
} | ||
|
||
// Float64 string to float64 | ||
func (f Convert) Float64() (float64, error) { | ||
return strconv.ParseFloat(f.String(), 64) | ||
} | ||
|
||
// Int string to int | ||
func (f Convert) Int() (int, error) { | ||
v, err := strconv.ParseInt(f.String(), 10, 32) | ||
return int(v), err | ||
} | ||
|
||
// Int8 string to int8 | ||
func (f Convert) Int8() (int8, error) { | ||
v, err := strconv.ParseInt(f.String(), 10, 8) | ||
return int8(v), err | ||
} | ||
|
||
// Int16 string to int16 | ||
func (f Convert) Int16() (int16, error) { | ||
v, err := strconv.ParseInt(f.String(), 10, 16) | ||
return int16(v), err | ||
} | ||
|
||
// Int32 string to int32 | ||
func (f Convert) Int32() (int32, error) { | ||
v, err := strconv.ParseInt(f.String(), 10, 32) | ||
return int32(v), err | ||
} | ||
|
||
// Int64 string to int64 | ||
func (f Convert) Int64() (int64, error) { | ||
v, err := strconv.ParseInt(f.String(), 10, 64) | ||
if err != nil { | ||
i := new(big.Int) | ||
ni, ok := i.SetString(f.String(), 10) // octal | ||
if !ok { | ||
return v, err | ||
} | ||
return ni.Int64(), nil | ||
} | ||
return v, err | ||
} | ||
|
||
// Uint string to uint | ||
func (f Convert) Uint() (uint, error) { | ||
v, err := strconv.ParseUint(f.String(), 10, 32) | ||
return uint(v), err | ||
} | ||
|
||
// Uint8 string to uint8 | ||
func (f Convert) Uint8() (uint8, error) { | ||
v, err := strconv.ParseUint(f.String(), 10, 8) | ||
return uint8(v), err | ||
} | ||
|
||
// Uint16 string to uint16 | ||
func (f Convert) Uint16() (uint16, error) { | ||
v, err := strconv.ParseUint(f.String(), 10, 16) | ||
return uint16(v), err | ||
} | ||
|
||
// Uint32 string to uint32 | ||
func (f Convert) Uint32() (uint32, error) { | ||
v, err := strconv.ParseUint(f.String(), 10, 32) | ||
return uint32(v), err | ||
} | ||
|
||
// Uint64 string to uint64 | ||
func (f Convert) Uint64() (uint64, error) { | ||
v, err := strconv.ParseUint(f.String(), 10, 64) | ||
if err != nil { | ||
i := new(big.Int) | ||
ni, ok := i.SetString(f.String(), 10) | ||
if !ok { | ||
return v, err | ||
} | ||
return ni.Uint64(), nil | ||
} | ||
return v, err | ||
} | ||
|
||
// String string to string | ||
func (f Convert) String() string { | ||
if f.Exist() { | ||
return string(f) | ||
} | ||
return "" | ||
} | ||
|
||
// ToString interface to string | ||
func ToString(value interface{}, args ...int) (s string) { | ||
switch v := value.(type) { | ||
case bool: | ||
s = strconv.FormatBool(v) | ||
case float32: | ||
s = strconv.FormatFloat(float64(v), 'f', argInt(args).Get(0, -1), argInt(args).Get(1, 32)) | ||
case float64: | ||
s = strconv.FormatFloat(v, 'f', argInt(args).Get(0, -1), argInt(args).Get(1, 64)) | ||
case int: | ||
s = strconv.FormatInt(int64(v), argInt(args).Get(0, 10)) | ||
case int8: | ||
s = strconv.FormatInt(int64(v), argInt(args).Get(0, 10)) | ||
case int16: | ||
s = strconv.FormatInt(int64(v), argInt(args).Get(0, 10)) | ||
case int32: | ||
s = strconv.FormatInt(int64(v), argInt(args).Get(0, 10)) | ||
case int64: | ||
s = strconv.FormatInt(v, argInt(args).Get(0, 10)) | ||
case uint: | ||
s = strconv.FormatUint(uint64(v), argInt(args).Get(0, 10)) | ||
case uint8: | ||
s = strconv.FormatUint(uint64(v), argInt(args).Get(0, 10)) | ||
case uint16: | ||
s = strconv.FormatUint(uint64(v), argInt(args).Get(0, 10)) | ||
case uint32: | ||
s = strconv.FormatUint(uint64(v), argInt(args).Get(0, 10)) | ||
case uint64: | ||
s = strconv.FormatUint(v, argInt(args).Get(0, 10)) | ||
case string: | ||
s = v | ||
case []byte: | ||
s = string(v) | ||
default: | ||
s = fmt.Sprintf("%v", v) | ||
} | ||
return s | ||
} | ||
|
||
// ToInt64 interface to int64 | ||
func ToInt64(value interface{}) (d int64) { | ||
val := reflect.ValueOf(value) | ||
switch value.(type) { | ||
case int, int8, int16, int32, int64: | ||
d = val.Int() | ||
case uint, uint8, uint16, uint32, uint64: | ||
d = int64(val.Uint()) | ||
default: | ||
panic(fmt.Errorf("ToInt64 need numeric not `%T`", value)) | ||
} | ||
return | ||
} | ||
|
||
type argInt []int | ||
|
||
// get int by index from int slice | ||
func (a argInt) Get(i int, args ...int) (r int) { | ||
if i >= 0 && i < len(a) { | ||
r = a[i] | ||
} | ||
if len(args) > 0 { | ||
r = args[0] | ||
} | ||
return | ||
} | ||
|
||
// TimeToUnix transform time to Unix time, the number of seconds elapsed | ||
func TimeToUnix(t time.Time) int64 { | ||
return t.Unix() | ||
} | ||
|
||
// UnixToTime transform Unix time to local Time | ||
func UnixToTime(tt int64) time.Time { | ||
return time.Unix(tt, 0) | ||
} | ||
|
||
// TimeToUnixLocation transform time to Unix time with time location | ||
// location like "Asia/Shanghai" | ||
func TimeToUnixLocation(t time.Time, location string) (int64, error) { | ||
timeStr := t.Format("2006-01-02 15:04:05") | ||
loc, err := time.LoadLocation(location) | ||
if err != nil { | ||
return 0, err | ||
} | ||
tt, err := time.ParseInLocation("2006-01-02 15:04:05", timeStr, loc) | ||
if err != nil { | ||
return 0, err | ||
} | ||
return tt.Unix(), err | ||
} | ||
|
||
// UnixToTimeLocation transform Unix time to local Time with time location | ||
// location like "Asia/Shanghai" | ||
func UnixToTimeLocation(tt int64, location string) (time.Time, error) { | ||
loc, err := time.LoadLocation(location) | ||
if err != nil { | ||
return time.Now(), err | ||
} | ||
time.Local = loc | ||
return time.Unix(tt, 0), nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package mapper | ||
|
||
import "time" | ||
|
||
type JSONTime time.Time | ||
|
||
var ( | ||
timeJSONFormat = "2006-01-02 15:04:05" | ||
) | ||
|
||
func SetTimeJSONFormat(format string) { | ||
timeJSONFormat = format | ||
} | ||
|
||
func GetTimeJSONFormat() string { | ||
return timeJSONFormat | ||
} | ||
|
||
func (t *JSONTime) UnmarshalJSON(data []byte) (err error) { | ||
now, err := time.ParseInLocation(`"`+timeJSONFormat+`"`, string(data), time.Local) | ||
*t = JSONTime(now) | ||
return | ||
} | ||
|
||
func (t JSONTime) MarshalJSON() ([]byte, error) { | ||
b := make([]byte, 0, len(timeJSONFormat)+2) | ||
b = append(b, '"') | ||
b = time.Time(t).AppendFormat(b, timeJSONFormat) | ||
b = append(b, '"') | ||
return b, nil | ||
} | ||
|
||
func (t JSONTime) String() string { | ||
return time.Time(t).Format(timeJSONFormat) | ||
} |
Oops, something went wrong.