diff --git a/archive.go b/archive.go index 3f52fdf..dd1df93 100644 --- a/archive.go +++ b/archive.go @@ -6,11 +6,17 @@ import ( "fmt" "io" "os" + "path/filepath" + "strings" ) // Unzip 读取位于src的zip文件,并解压到dst文件夹中 // shell传入当前解压的文件名称 func Unzip(src, dst string, shell func(string)) error { + dst, err := filepath.Abs(dst) + if err != nil { + return err + } if !IsFile(src) { return errors.New(src + " Not Exists") } @@ -18,9 +24,9 @@ func Unzip(src, dst string, shell func(string)) error { return errors.New(dst + " Exists And Not A Folder") } if !Exists(dst) { - err := os.MkdirAll(dst, 0644) + err := os.MkdirAll(dst, 0755) if err != nil { - return nil + return err } } zipreader, err := zip.OpenReader(src) @@ -29,8 +35,9 @@ func Unzip(src, dst string, shell func(string)) error { } defer zipreader.Close() for _, v := range zipreader.File { + name := strings.ReplaceAll(v.Name, "\\", string(os.PathSeparator)) if v.FileInfo().IsDir() { - err := os.MkdirAll(dst+string(os.PathSeparator)+v.Name, 0644) + err := os.MkdirAll(dst+string(os.PathSeparator)+name, 0755) if err != nil { fmt.Println(err) } @@ -41,8 +48,12 @@ func Unzip(src, dst string, shell func(string)) error { fmt.Println(err) continue } - go shell(v.Name) - fpdst, err := os.Create(dst + string(os.PathSeparator) + v.Name) + go shell(name) + dir := filepath.Dir(dst + string(os.PathSeparator) + name) + if !Exists(dir) { + os.MkdirAll(dir, 0755) + } + fpdst, err := os.Create(dst + string(os.PathSeparator) + name) if err != nil { fmt.Println(err) continue diff --git a/database.go b/database.go index 3b3221b..1dacabf 100644 --- a/database.go +++ b/database.go @@ -5,16 +5,22 @@ import ( "errors" "reflect" "strconv" + "time" ) +// DBRes 单连接下的数据库资源句柄 var DBRes *sql.DB + +// DBRows 单连接下的数据库查询句柄 var DBRows *sql.Rows +// StarDB 一个简单封装的DB库 type StarDB struct { DB *sql.DB Rows *sql.Rows } +// StarRows 为查询结果集(按行) type StarRows struct { Rows *sql.Rows Length int @@ -25,6 +31,7 @@ type StarRows struct { result [][]interface{} } +// StarResult 为查询结果集(总) type StarResult struct { Result []interface{} Columns []string @@ -32,35 +39,56 @@ type StarResult struct { ColumnsType []reflect.Type } +// StarResultCol 为查询结果集(按列) type StarResultCol struct { Result []interface{} } -func (this *StarResultCol) MustBytes() [][]byte { +// MustBytes 列查询结果转Bytes +func (star *StarResultCol) MustBytes() [][]byte { var res [][]byte - for _, v := range this.Result { + for _, v := range star.Result { res = append(res, v.([]byte)) } return res } -func (this *StarResultCol) MustBool() []bool { +// MustBool 列查询结果转Bool +func (star *StarResultCol) MustBool() []bool { var res []bool var tmp bool - for _, v := range this.Result { + for _, v := range star.Result { switch vtype := v.(type) { case nil: tmp = false case bool: tmp = vtype - case float64, float32: - if vtype.(float64) > 0 { + case float64: + if vtype > 0 { + tmp = true + } else { + tmp = false + } + case float32: + if vtype > 0 { + tmp = true + } else { + tmp = false + } + case int: + if vtype > 0 { + tmp = true + } else { + tmp = false + } + case int32: + if vtype > 0 { tmp = true } else { tmp = false } - case int, int32, int64: - if vtype.(int) > 0 { + case int64: + if vtype > 0 { tmp = true } else { tmp = false @@ -74,52 +102,77 @@ func (this *StarResultCol) MustBool() []bool { } return res } -func (this *StarResultCol) MustFloat32() []float32 { + +// MustFloat32 列查询结果转Float32 +func (star *StarResultCol) MustFloat32() []float32 { var res []float32 var tmp float32 - for _, v := range this.Result { + for _, v := range star.Result { switch vtype := v.(type) { case nil: tmp = 0 - case float64, float32: - tmp = float32(vtype.(float64)) + case float32: + tmp = vtype + case float64: + tmp = float32(vtype) case string: tmps, _ := strconv.ParseFloat(vtype, 32) tmp = float32(tmps) - case int, int32, int64: - tmp = float32(vtype.(int64)) + case int: + tmp = float32(vtype) + case int32: + tmp = float32(vtype) + case int64: + tmp = float32(vtype) + case time.Time: + tmp = float32(vtype.Unix()) default: - tmp = v.(float32) + tmpt := string(vtype.([]byte)) + tmps, _ := strconv.ParseFloat(tmpt, 32) + tmp = float32(tmps) } res = append(res, tmp) } return res } -func (this *StarResultCol) MustFloat64() []float64 { + +// MustFloat64 列查询结果转Float64 +func (star *StarResultCol) MustFloat64() []float64 { var res []float64 var tmp float64 - for _, v := range this.Result { + for _, v := range star.Result { switch vtype := v.(type) { case nil: tmp = 0 - case float64, float32: - tmp = vtype.(float64) + case float64: + tmp = vtype + case float32: + tmp = float64(vtype) case string: tmp, _ = strconv.ParseFloat(vtype, 64) - case int, int32, int64: - tmp = float64(vtype.(int64)) + case int: + tmp = float64(vtype) + case int32: + tmp = float64(vtype) + case int64: + tmp = float64(vtype) + case time.Time: + tmp = float64(vtype.Unix()) default: - tmp = v.(float64) + tmpt := string(vtype.([]byte)) + tmps, _ := strconv.ParseFloat(tmpt, 64) + tmp = float64(tmps) } res = append(res, tmp) } return res } -func (this *StarResultCol) MustString() []string { +// MustString 列查询结果转String +func (star *StarResultCol) MustString() []string { var res []string var tmp string - for _, v := range this.Result { + for _, v := range star.Result { switch vtype := v.(type) { case nil: tmp = "" @@ -137,6 +190,8 @@ func (this *StarResultCol) MustString() []string { tmp = strconv.FormatFloat(float64(vtype), 'f', 10, 32) case int: tmp = strconv.Itoa(vtype) + case time.Time: + tmp = vtype.String() default: tmp = string(vtype.([]byte)) } @@ -145,120 +200,269 @@ func (this *StarResultCol) MustString() []string { return res } -func (this *StarResultCol) MustInt32() []int32 { +// MustInt32 列查询结果转Int32 +func (star *StarResultCol) MustInt32() []int32 { var res []int32 var tmp int32 - for _, v := range this.Result { + for _, v := range star.Result { switch vtype := v.(type) { case nil: tmp = 0 - case float64, float32: - tmp = int32(vtype.(float64)) + case float64: + tmp = int32(vtype) + case float32: + tmp = int32(vtype) case string: tmps, _ := strconv.ParseInt(vtype, 10, 32) tmp = int32(tmps) - case int, int32, int64: - tmp = int32(vtype.(int64)) + case int: + tmp = int32(vtype) + case int64: + tmp = int32(vtype) + case int32: + tmp = vtype + case time.Time: + tmp = int32(vtype.Unix()) default: - tmp = v.(int32) + tmpt := string(vtype.([]byte)) + tmps, _ := strconv.ParseInt(tmpt, 10, 32) + tmp = int32(tmps) } res = append(res, tmp) } return res } -func (this *StarResultCol) MustInt64() []int64 { + +// MustInt64 列查询结果转Int64 +func (star *StarResultCol) MustInt64() []int64 { var res []int64 var tmp int64 - for _, v := range this.Result { + for _, v := range star.Result { switch vtype := v.(type) { case nil: tmp = 0 - case float64, float32: - tmp = int64(vtype.(float64)) + case float64: + tmp = int64(vtype) + case float32: + tmp = int64(vtype) case string: - tmp, _ = strconv.ParseInt(vtype, 10, 64) - case int, int32, int64: - tmp = (vtype.(int64)) + tmps, _ := strconv.ParseInt(vtype, 10, 64) + tmp = int64(tmps) + case int: + tmp = int64(vtype) + case int32: + tmp = int64(vtype) + case int64: + tmp = vtype + case time.Time: + tmp = vtype.Unix() default: - tmp = v.(int64) + tmpt := string(vtype.([]byte)) + tmp, _ = strconv.ParseInt(tmpt, 10, 64) } res = append(res, tmp) } return res } -func (this *StarResultCol) MustInt() []int { + +// MustInt 列查询结果转Int +func (star *StarResultCol) MustInt() []int { var res []int var tmp int - for _, v := range this.Result { + for _, v := range star.Result { switch vtype := v.(type) { case nil: tmp = 0 - case float64, float32: - tmp = int(vtype.(float64)) + case float64: + tmp = int(vtype) + case float32: + tmp = int(vtype) case string: tmps, _ := strconv.ParseInt(vtype, 10, 64) tmp = int(tmps) - case int, int32, int64: - tmp = int(vtype.(int64)) + case int: + tmp = vtype + case int32: + tmp = int(vtype) + case int64: + tmp = int(vtype) + case time.Time: + tmp = int(vtype.Unix()) + default: + tmpt := string(vtype.([]byte)) + tmps, _ := strconv.ParseInt(tmpt, 10, 64) + tmp = int(tmps) + } + res = append(res, tmp) + } + return res +} + +// MustDate 列查询结果转Date(time.Time) +func (star *StarResultCol) MustDate(layout string) []time.Time { + var res []time.Time + var tmp time.Time + for _, v := range star.Result { + switch vtype := v.(type) { + case nil: + tmp = time.Time{} + case float64: + tmp = time.Unix(int64(vtype), int64(vtype-float64(int64(vtype)))*1000000000) + case float32: + tmp = time.Unix(int64(vtype), int64(vtype-float32(int64(vtype)))*1000000000) + case string: + tmp, _ = time.Parse(layout, vtype) + case int: + tmp = time.Unix(int64(vtype), 0) + case int32: + tmp = time.Unix(int64(vtype), 0) + case int64: + tmp = time.Unix(vtype, 0) + case time.Time: + tmp = vtype + default: + tmpt := string(vtype.([]byte)) + tmp, _ = time.Parse(layout, tmpt) + } + res = append(res, tmp) + } + return res +} + +// IsNil 检测是不是nil 列查询结果是不是nil +func (star *StarResultCol) IsNil(name string) []bool { + var res []bool + var tmp bool + for _, v := range star.Result { + switch v.(type) { + case nil: + tmp = true default: - tmp = int(v.(int64)) + tmp = false } res = append(res, tmp) } return res } -func (this *StarResult) MustInt64(name string) int64 { +// IsNil 检测是不是nil +func (star *StarResult) IsNil(name string) bool { + num, ok := star.columnref[name] + if !ok { + return false + } + tmp := star.Result[num] + switch tmp.(type) { + case nil: + return true + default: + return false + } +} + +// MustDate 列查询结果转Date +func (star *StarResult) MustDate(name, layout string) time.Time { + var res time.Time + num, ok := star.columnref[name] + if !ok { + return time.Time{} + } + tmp := star.Result[num] + switch vtype := tmp.(type) { + case nil: + res = time.Time{} + case float64: + res = time.Unix(int64(vtype), int64(vtype-float64(int64(vtype)))*1000000000) + case float32: + res = time.Unix(int64(vtype), int64(vtype-float32(int64(vtype)))*1000000000) + case string: + res, _ = time.Parse(layout, vtype) + case int: + res = time.Unix(int64(vtype), 0) + case int32: + res = time.Unix(int64(vtype), 0) + case int64: + res = time.Unix(vtype, 0) + case time.Time: + res = vtype + default: + res, _ = time.Parse(layout, string(tmp.([]byte))) + } + return res +} + +// MustInt64 列查询结果转int64 +func (star *StarResult) MustInt64(name string) int64 { var res int64 - num, ok := this.columnref[name] + num, ok := star.columnref[name] if !ok { return 0 } - tmp := this.Result[num] + tmp := star.Result[num] switch vtype := tmp.(type) { case nil: res = 0 - case float64, float32: - res = int64(vtype.(float64)) + case float64: + res = int64(vtype) + case float32: + res = int64(vtype) case string: res, _ = strconv.ParseInt(vtype, 10, 64) - case int, int32, int64: - res = (vtype.(int64)) + case int: + res = int64(vtype) + case int32: + res = int64(vtype) + case int64: + res = vtype + case time.Time: + res = int64(vtype.Unix()) default: res, _ = strconv.ParseInt(string(tmp.([]byte)), 10, 64) } return res } -func (this *StarResult) MustInt32(name string) int32 { + +// MustInt32 列查询结果转Int32 +func (star *StarResult) MustInt32(name string) int32 { var res int32 - num, ok := this.columnref[name] + num, ok := star.columnref[name] if !ok { return 0 } - tmp := this.Result[num] + tmp := star.Result[num] switch vtype := tmp.(type) { case nil: res = 0 - case float64, float32: - res = int32(vtype.(float64)) + case float64: + res = int32(vtype) + case float32: + res = int32(vtype) case string: ress, _ := strconv.ParseInt(vtype, 10, 32) res = int32(ress) - case int, int32, int64: - res = int32(vtype.(int64)) + case int: + res = int32(vtype) + case int32: + res = vtype + case int64: + res = int32(vtype) + case time.Time: + res = int32(vtype.Unix()) default: ress, _ := strconv.ParseInt(string(tmp.([]byte)), 10, 32) res = int32(ress) } return res } -func (this *StarResult) MustString(name string) string { + +// MustString 列查询结果转string +func (star *StarResult) MustString(name string) string { var res string - num, ok := this.columnref[name] + num, ok := star.columnref[name] if !ok { return "" } - switch vtype := this.Result[num].(type) { + switch vtype := star.Result[num].(type) { case nil: res = "" case string: @@ -275,40 +479,52 @@ func (this *StarResult) MustString(name string) string { res = strconv.FormatFloat(float64(vtype), 'f', 10, 32) case int: res = strconv.Itoa(vtype) + case time.Time: + res = vtype.String() default: res = string(vtype.([]byte)) } return res } -func (this *StarResult) MustFloat64(name string) float64 { +// MustFloat64 列查询结果转float64 +func (star *StarResult) MustFloat64(name string) float64 { var res float64 - num, ok := this.columnref[name] + num, ok := star.columnref[name] if !ok { return 0 } - switch vtype := this.Result[num].(type) { + switch vtype := star.Result[num].(type) { case nil: res = 0 case string: res, _ = strconv.ParseFloat(vtype, 64) case float64: res = vtype - case int, int64, int32, float32: - res = vtype.(float64) + case int: + res = float64(vtype) + case int64: + res = float64(vtype) + case int32: + res = float64(vtype) + case float32: + res = float64(vtype) + case time.Time: + res = float64(vtype.Unix()) default: res, _ = strconv.ParseFloat(string(vtype.([]byte)), 64) } return res } -func (this *StarResult) MustFloat32(name string) float32 { +// MustFloat32 列查询结果转float32 +func (star *StarResult) MustFloat32(name string) float32 { var res float32 - num, ok := this.columnref[name] + num, ok := star.columnref[name] if !ok { return 0 } - switch vtype := this.Result[num].(type) { + switch vtype := star.Result[num].(type) { case nil: res = 0 case string: @@ -318,8 +534,14 @@ func (this *StarResult) MustFloat32(name string) float32 { res = float32(vtype) case float32: res = vtype - case int, int64, int32: - res = vtype.(float32) + case int: + res = float32(vtype) + case int64: + res = float32(vtype) + case int32: + res = float32(vtype) + case time.Time: + res = float32(vtype.Unix()) default: tmp, _ := strconv.ParseFloat(string(vtype.([]byte)), 32) res = float32(tmp) @@ -327,23 +549,32 @@ func (this *StarResult) MustFloat32(name string) float32 { return res } -func (this *StarResult) MustInt(name string) int { +// MustInt 列查询结果转int +func (star *StarResult) MustInt(name string) int { var res int - num, ok := this.columnref[name] + num, ok := star.columnref[name] if !ok { return 0 } - tmp := this.Result[num] + tmp := star.Result[num] switch vtype := tmp.(type) { case nil: res = 0 - case float64, float32: - res = int(vtype.(float64)) + case float64: + res = int(vtype) + case float32: + res = int(vtype) case string: ress, _ := strconv.ParseInt(vtype, 10, 64) res = int(ress) - case int, int32, int64: - res = int(vtype.(int64)) + case int: + res = vtype + case int32: + res = int(vtype) + case int64: + res = int(vtype) + case time.Time: + res = int(vtype.Unix()) default: ress, _ := strconv.ParseInt(string(tmp.([]byte)), 10, 64) res = int(ress) @@ -351,26 +582,45 @@ func (this *StarResult) MustInt(name string) int { return res } -func (this *StarResult) MustBool(name string) bool { +// MustBool 列查询结果转bool +func (star *StarResult) MustBool(name string) bool { var res bool - num, ok := this.columnref[name] + num, ok := star.columnref[name] if !ok { return false } - tmp := this.Result[num] + tmp := star.Result[num] switch vtype := tmp.(type) { case nil: res = false case bool: res = vtype - case float64, float32: - if vtype.(float64) > 0 { + case float64: + if vtype > 0 { + res = true + } else { + res = false + } + case float32: + if vtype > 0 { + res = true + } else { + res = false + } + case int: + if vtype > 0 { + res = true + } else { + res = false + } + case int32: + if vtype > 0 { res = true } else { res = false } - case int, int32, int64: - if vtype.(int) > 0 { + case int64: + if vtype > 0 { res = true } else { res = false @@ -382,65 +632,71 @@ func (this *StarResult) MustBool(name string) bool { } return res } -func (this *StarResult) MustBytes(name string) []byte { - num, ok := this.columnref[name] + +// MustBytes 列查询结果转byte +func (star *StarResult) MustBytes(name string) []byte { + num, ok := star.columnref[name] if !ok { return []byte{} } - res := this.Result[num].([]byte) + res := star.Result[num].([]byte) return res } -func (this *StarRows) Rescan() { - this.parserows() +// Rescan 重新分析结果集 +func (star *StarRows) Rescan() { + star.parserows() } -func (this *StarRows) Col(name string) *StarResultCol { +// Col 选择需要进行操作的数据结果列 +func (star *StarRows) Col(name string) *StarResultCol { result := new(StarResultCol) - if _, ok := this.columnref[name]; !ok { + if _, ok := star.columnref[name]; !ok { return result } var rescol []interface{} - for _, v := range this.result { - rescol = append(rescol, v[this.columnref[name]]) + for _, v := range star.result { + rescol = append(rescol, v[star.columnref[name]]) } result.Result = rescol return result } -func (this *StarRows) Row(id int) *StarResult { +// Row 选择需要进行操作的数据结果行 +func (star *StarRows) Row(id int) *StarResult { result := new(StarResult) - if id+1 > len(this.result) { + if id+1 > len(star.result) { return result } - result.Result = this.result[id] - result.Columns = this.Columns - result.ColumnsType = this.ColumnsType - result.columnref = this.columnref + result.Result = star.result[id] + result.Columns = star.Columns + result.ColumnsType = star.ColumnsType + result.columnref = star.columnref return result } -func (this *StarRows) Close() error { - return this.Rows.Close() +// Close 关闭打开的结果集 +func (star *StarRows) Close() error { + return star.Rows.Close() } -func (this *StarRows) parserows() { - this.result = [][]interface{}{} - this.columnref = make(map[string]int) - this.StringResult = []map[string]string{} - this.Columns, _ = this.Rows.Columns() - types, _ := this.Rows.ColumnTypes() +func (star *StarRows) parserows() { + star.result = [][]interface{}{} + star.columnref = make(map[string]int) + star.StringResult = []map[string]string{} + star.Columns, _ = star.Rows.Columns() + types, _ := star.Rows.ColumnTypes() for _, v := range types { - this.ColumnsType = append(this.ColumnsType, v.ScanType()) + star.ColumnsType = append(star.ColumnsType, v.ScanType()) } - scanArgs := make([]interface{}, len(this.Columns)) - values := make([]interface{}, len(this.Columns)) - for i, _ := range values { - this.columnref[this.Columns[i]] = i + scanArgs := make([]interface{}, len(star.Columns)) + values := make([]interface{}, len(star.Columns)) + for i := range values { + star.columnref[star.Columns[i]] = i scanArgs[i] = &values[i] } - for this.Rows.Next() { - if err := this.Rows.Scan(scanArgs...); err != nil { + for star.Rows.Next() { + if err := star.Rows.Scan(scanArgs...); err != nil { return } record := make(map[string]string) @@ -448,28 +704,39 @@ func (this *StarRows) parserows() { for i, col := range values { rescopy = append(rescopy, col) switch vtype := col.(type) { + case float32: + record[star.Columns[i]] = strconv.FormatFloat(float64(vtype), 'f', -1, 64) case float64: - record[this.Columns[i]] = strconv.FormatFloat(vtype, 'f', -1, 64) + record[star.Columns[i]] = strconv.FormatFloat(vtype, 'f', -1, 64) case int64: - record[this.Columns[i]] = strconv.FormatInt(vtype, 10) + record[star.Columns[i]] = strconv.FormatInt(vtype, 10) + case int32: + record[star.Columns[i]] = strconv.FormatInt(int64(vtype), 10) + case int: + record[star.Columns[i]] = strconv.Itoa(vtype) case string: - record[this.Columns[i]] = vtype + record[star.Columns[i]] = vtype + case bool: + record[star.Columns[i]] = strconv.FormatBool(vtype) + case time.Time: + record[star.Columns[i]] = vtype.String() case nil: - record[this.Columns[i]] = "" + record[star.Columns[i]] = "" default: - record[this.Columns[i]] = string(vtype.([]byte)) + record[star.Columns[i]] = string(vtype.([]byte)) } } - this.result = append(this.result, rescopy) - this.StringResult = append(this.StringResult, record) + star.result = append(star.result, rescopy) + star.StringResult = append(star.StringResult, record) } - this.Length = len(this.StringResult) + star.Length = len(star.StringResult) } -func (this *StarDB) Query(args ...interface{}) (*StarRows, error) { +// Query 进行Query操作 +func (star *StarDB) Query(args ...interface{}) (*StarRows, error) { var err error effect := new(StarRows) - if err = this.DB.Ping(); err != nil { + if err = star.DB.Ping(); err != nil { return effect, err } if len(args) == 0 { @@ -477,15 +744,15 @@ func (this *StarDB) Query(args ...interface{}) (*StarRows, error) { } if len(args) == 1 { sql := args[0] - if this.Rows, err = this.DB.Query(sql.(string)); err != nil { + if star.Rows, err = star.DB.Query(sql.(string)); err != nil { return effect, err } - effect.Rows = this.Rows + effect.Rows = star.Rows effect.parserows() return effect, nil } sql := args[0] - stmt, err := this.DB.Prepare(sql.(string)) + stmt, err := star.DB.Prepare(sql.(string)) if err != nil { return effect, err } @@ -499,35 +766,38 @@ func (this *StarDB) Query(args ...interface{}) (*StarRows, error) { } } } - if this.Rows, err = stmt.Query(para...); err != nil { + if star.Rows, err = stmt.Query(para...); err != nil { return effect, err } - effect.Rows = this.Rows + effect.Rows = star.Rows effect.parserows() return effect, nil } -func (this *StarDB) Open(Method, ConnStr string) error { +// Open 打开一个新的数据库 +func (star *StarDB) Open(Method, ConnStr string) error { var err error - this.DB, err = sql.Open(Method, ConnStr) + star.DB, err = sql.Open(Method, ConnStr) if err != nil { return err } - err = this.DB.Ping() + err = star.DB.Ping() return err } -func (this *StarDB) Close() error { - if err := this.DB.Close(); err != nil { +// Close 关闭打开的数据库 +func (star *StarDB) Close() error { + if err := star.DB.Close(); err != nil { return err } - return this.DB.Close() + return star.DB.Close() } -func (this *StarDB) Exec(args ...interface{}) (sql.Result, error) { +// Exec 执行Exec操作 +func (star *StarDB) Exec(args ...interface{}) (sql.Result, error) { var err error var effect sql.Result - if err = this.DB.Ping(); err != nil { + if err = star.DB.Ping(); err != nil { return effect, err } if len(args) == 0 { @@ -535,17 +805,17 @@ func (this *StarDB) Exec(args ...interface{}) (sql.Result, error) { } if len(args) == 1 { sql := args[0] - if _, err = this.DB.Exec(sql.(string)); err != nil { + if _, err = star.DB.Exec(sql.(string)); err != nil { return effect, err } return effect, nil } sql := args[0] - stmt, err := this.DB.Prepare(sql.(string)) - defer stmt.Close() + stmt, err := star.DB.Prepare(sql.(string)) if err != nil { return effect, err } + defer stmt.Close() var para []interface{} for k, v := range args { if k != 0 { @@ -561,6 +831,7 @@ func (this *StarDB) Exec(args ...interface{}) (sql.Result, error) { return effect, nil } +// FetchAll 把结果集全部转为key-value型数据 func FetchAll(rows *sql.Rows) (error, map[int]map[string]string) { var ii int = 0 records := make(map[int]map[string]string) @@ -598,6 +869,7 @@ func FetchAll(rows *sql.Rows) (error, map[int]map[string]string) { return nil, records } +// OpenDB 打开一个数据库 func OpenDB(Method, ConnStr string) error { var err error DBRes, err = sql.Open(Method, ConnStr) @@ -607,11 +879,14 @@ func OpenDB(Method, ConnStr string) error { err = DBRes.Ping() return err } + +// CloseDB 关闭打开的数据库 func CloseDB() { DBRes.Close() DBRows.Close() } +// Query 进行数据库查询操作 func Query(args ...interface{}) (error, map[int]map[string]string) { var err error records := make(map[int]map[string]string) @@ -650,6 +925,7 @@ func Query(args ...interface{}) (error, map[int]map[string]string) { } +// DBExec 进行数据库EXEC查询操作 func DBExec(args ...interface{}) error { var err error if err = DBRes.Ping(); err != nil { diff --git a/ini.go b/ini.go index 39d520d..eb6d6a0 100644 --- a/ini.go +++ b/ini.go @@ -3,9 +3,11 @@ package starainrt import ( "bufio" "errors" + "fmt" "io" "io/ioutil" "os" + "reflect" "regexp" "strconv" "strings" @@ -198,9 +200,10 @@ jump: } type StarCfg struct { - Data []*CfgSegment - segmap map[string]int - nodemap map[int]map[string]int + Data []*CfgSegment + segmap map[string]int + //nodemap map[int]map[string]int + segid int } type CfgNode struct { @@ -210,11 +213,12 @@ type CfgNode struct { } type CfgSegment struct { - Name string - cmap map[string]int - Comment string - Node []*CfgNode - InsertNode []*CfgNode + Name string + cmap map[string]int + Comment string + Node []*CfgNode + nodeid int + //InsertNode []*CfgNode } func (this *StarCfg) ParseFromFile(filepath string) error { @@ -234,28 +238,33 @@ func (this *StarCfg) WriteToFile(filepath string) error { return ioutil.WriteFile(filepath, data, 0644) } +// Parse 生成INI文件结构 func (this *StarCfg) Parse(data []byte) { var newnode *CfgNode - segint := 0 + this.segid = 0 //segment序号 nodeint := 0 - this.segmap = make(map[string]int) - this.nodemap = make(map[int]map[string]int) - strdata := string(data) - list := strings.Split(strdata, "\n") + this.segmap = make(map[string]int) //segment名 序号 + //this.nodemap = make(map[int]map[string]int) + nodemap := make(map[string]int) + strdata := string(data) //转换成字符串 + list := strings.Split(strdata, "\n") //分割 newseg := new(CfgSegment) - newseg.Name = "unnamed" - newseg.InsertNode = []*CfgNode{} + newseg.Name = "unnamed" //默认名 + //newseg.InsertNode = []*CfgNode{} this.segmap["unnamed"] = 0 lastiseg := true for _, v := range list { istrans := false - isseg := false - isnote := false - isequal := false + isseg := false //是否为新seg + isnote := false //是否为注释 + isequal := false // 是否为等号 tmp1 := []rune{} tmp2 := []rune{} note := []rune{} v = strings.TrimSpace(v) + if len(v) > 0 && v[0:1] == ";" { + isnote = true //首字母是;时,代表注释 + } for k, v2 := range v { if k == 0 { if v2 == '[' { @@ -291,14 +300,18 @@ func (this *StarCfg) Parse(data []byte) { } if isseg { this.Data = append(this.Data, newseg) + newseg.nodeid = nodeint + //newseg.cmap = make(map[string]int) + newseg.cmap = nodemap + nodemap = make(map[string]int) newseg = new(CfgSegment) - newseg.InsertNode = []*CfgNode{} + //newseg.InsertNode = []*CfgNode{} newseg.Name = strings.TrimSpace(string(tmp1)) if isnote { newseg.Comment = strings.TrimSpace(string(note)) } - segint++ - this.segmap[newseg.Name] = segint + this.segid++ + this.segmap[newseg.Name] = this.segid nodeint = 0 lastiseg = true continue @@ -311,10 +324,7 @@ func (this *StarCfg) Parse(data []byte) { newnode.Comment = strings.TrimSpace(string(note)) } newseg.Node = append(newseg.Node, newnode) - if this.nodemap[segint] == nil { - this.nodemap[segint] = make(map[string]int) - } - this.nodemap[segint][newnode.Key] = nodeint + nodemap[newnode.Key] = nodeint nodeint++ lastiseg = false continue @@ -330,18 +340,137 @@ func (this *StarCfg) Parse(data []byte) { } } + newseg.nodeid = nodeint + //newseg.cmap = make(map[string]int) + newseg.cmap = nodemap this.Data = append(this.Data, newseg) } +// Unmarshal 输出结果到结构体中 +func (cfg *StarCfg) Unmarshal(ins interface{}) error { + var structSet func(t reflect.Type, v reflect.Value) error + t := reflect.TypeOf(ins) + v := reflect.ValueOf(ins).Elem() + if v.Kind() != reflect.Struct { + return errors.New("Not a Struct") + } + if t.Kind() != reflect.Ptr || !v.CanSet() { + return errors.New("Cannot Write!") + } + t = t.Elem() + structSet = func(t reflect.Type, v reflect.Value) error { + for i := 0; i < t.NumField(); i++ { + tp := t.Field(i) + vl := v.Field(i) + if !vl.CanSet() { + continue + } + if vl.Type().Kind() == reflect.Struct { + structSet(vl.Type(), vl) + continue + } + seg := tp.Tag.Get("seg") + key := tp.Tag.Get("key") + if seg == "" || key == "" { + continue + } + if _, ok := cfg.segmap[seg]; !ok { + continue + } + segs := cfg.Data[cfg.segmap[seg]] + if segs.Get(key) == "" { + continue + } + switch vl.Kind() { + case reflect.String: + vl.SetString(segs.Get(key)) + case reflect.Int, reflect.Int32, reflect.Int64: + vl.SetInt(segs.Int64(key)) + case reflect.Float32, reflect.Float64: + vl.SetFloat(segs.Float64(key)) + case reflect.Bool: + vl.SetBool(segs.Bool(key)) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + vl.SetUint(uint64(segs.Int64(key))) + default: + continue + } + } + return nil + } + return structSet(t, v) +} + +// Marshal 输出结果到结构体中 +func (cfg *StarCfg) Marshal(ins interface{}) ([]byte, error) { + var structSet func(t reflect.Type, v reflect.Value) + t := reflect.TypeOf(ins) + v := reflect.ValueOf(ins) + if v.Kind() != reflect.Struct { + return nil, errors.New("Not a Struct") + } + if t.Kind() == reflect.Ptr { + t = t.Elem() + v = v.Elem() + } + structSet = func(t reflect.Type, v reflect.Value) { + for i := 0; i < t.NumField(); i++ { + var seg, key, comment string = "", "", "" + tp := t.Field(i) + vl := v.Field(i) + if vl.Type().Kind() == reflect.Struct { + structSet(vl.Type(), vl) + continue + } + seg = tp.Tag.Get("seg") + key = tp.Tag.Get("key") + comment = tp.Tag.Get("comment") + if seg == "" || key == "" { + continue + } + if _, ok := cfg.segmap[seg]; !ok { + cfg.AddSeg(seg) + } + cfg.Seg(seg).Set(key, fmt.Sprint(vl), comment) + } + + } + structSet(t, v) + return cfg.Build(), nil +} + func (this *StarCfg) Seg(name string) *CfgSegment { if _, ok := this.segmap[name]; !ok { return nil } seg := this.Data[this.segmap[name]] - if seg.Name == name { - seg.cmap = this.nodemap[this.segmap[name]] - return seg + return seg +} + +func (cfg *StarCfg) AddSeg(name string) *CfgSegment { + if _, ok := cfg.segmap[name]; !ok { + newseg := new(CfgSegment) + newseg.Name = name + newseg.cmap = make(map[string]int) + cfg.Data = append(cfg.Data, newseg) + cfg.segid++ + if cfg.segmap == nil { + cfg.segid = 0 + cfg.segmap = make(map[string]int) + } + cfg.segmap[newseg.Name] = cfg.segid + return newseg } + seg := cfg.Data[cfg.segmap[name]] + return seg +} + +func (cfg *StarCfg) DeleteSeg(name string) error { + if _, ok := cfg.segmap[name]; !ok { + return errors.New("Seg Not Exists") + } + cfg.Data[cfg.segmap[name]] = nil + delete(cfg.segmap, name) return nil } @@ -349,6 +478,9 @@ func (this *StarCfg) Build() []byte { var res, comm string for _, v := range this.Data { comm = "" + if v == nil { + continue + } if v.Name != "unnamed" { res += `[ ` + this.repkv(v.Name) + ` ]` } @@ -360,19 +492,11 @@ func (this *StarCfg) Build() []byte { } res += comm + "\n" - comm = "" for _, v2 := range v.Node { - res += this.repkv(v2.Key) + " = " + this.repkv(v2.Value) - if v2.Comment != "" { - comm = strings.Replace(v2.Comment, "\n", "\n#", -1) - if comm[0:1] != "\n" { - comm = " #" + comm - } + comm = "" + if v2 == nil { + continue } - res += comm + "\n" - } - comm = "" - for _, v2 := range v.InsertNode { res += this.repkv(v2.Key) + " = " + this.repkv(v2.Value) if v2.Comment != "" { comm = strings.Replace(v2.Comment, "\n", "\n#", -1) @@ -397,24 +521,23 @@ func (this *StarCfg) repkv(value string) string { func (this *CfgSegment) GetComment(key string) string { if v, ok := this.cmap[key]; !ok { - for _, v2 := range this.InsertNode { - if v2.Key == key { - return this.Node[v].Comment - } - } return "" } else { return this.Node[v].Comment } } +func (this *CfgSegment) SetComment(key, comment string) error { + if v, ok := this.cmap[key]; !ok { + return errors.New("Key Not Exists") + } else { + this.Node[v].Comment = comment + return nil + } +} + func (this *CfgSegment) Exist(key string) bool { if _, ok := this.cmap[key]; !ok { - for _, v2 := range this.InsertNode { - if v2.Key == key { - return true - } - } return false } else { return true @@ -423,11 +546,6 @@ func (this *CfgSegment) Exist(key string) bool { func (this *CfgSegment) Get(key string) string { if v, ok := this.cmap[key]; !ok { - for _, v2 := range this.InsertNode { - if v2.Key == key { - return this.Node[v].Value - } - } return "" } else { return this.Node[v].Value @@ -520,20 +638,13 @@ func (this *CfgSegment) SetInt(key string, value int, comment string) error { func (this *CfgSegment) Set(key, value, comment string) error { if v, ok := this.cmap[key]; !ok { - for _, v2 := range this.InsertNode { - if v2.Key == key { - this.Node[v].Value = value - if comment != "" { - this.Node[v].Comment = comment - } - return nil - } - } node := new(CfgNode) node.Key = key node.Value = value node.Comment = comment - this.InsertNode = append(this.InsertNode, node) + this.Node = append(this.Node, node) + this.cmap[key] = this.nodeid + this.nodeid++ return nil } else { this.Node[v].Value = value @@ -543,3 +654,13 @@ func (this *CfgSegment) Set(key, value, comment string) error { } return nil } + +func (this *CfgSegment) Delete(key string) error { + if v, ok := this.cmap[key]; !ok { + return errors.New("Key not exists!") + } else { + this.Node[v] = nil + delete(this.cmap, key) + } + return nil +} diff --git a/ini_test.go b/ini_test.go index dfaa9ed..98a9a1b 100644 --- a/ini_test.go +++ b/ini_test.go @@ -21,3 +21,69 @@ func Test_CfgParse(t *testing.T) { ini.Seg("happy").SetInt64("sakura", 986787, "") fmt.Println(string(ini.Build())) } + +type Ntest struct { + N string `seg:"happy" key:"me"` +} +type Testsss struct { + Okk string `seg:"unnamed" key:"ok"` + Migrate string `seg:"happy" key:"migrate" comment:"whnb"` + Ntest +} + +func Test_CfgParseStruct(t *testing.T) { + data := `#lalala + ok =true\# #ok + [happy] #ok + #kkk + me = \=tru + sa = p\\k + migrate = ok #oooo + [siki] + sakurs = ssss #[ossk]` + //data, _ := ioutil.ReadFile(`c:\Users\Starainrt\Desktop\postgresql.conf`) + okk := Testsss{} + ini := new(StarCfg) + ini.Parse([]byte(data)) + //fmt.Println(ini.Seg("happy").Get("migrate")) + fmt.Println(ini.Unmarshal(&okk)) + fmt.Println(okk) +} + +func Test_DeleteAdd(t *testing.T) { + data := `[A] +a=1 +b=2 +c=3 +[B] +a=1 +b=2 +c=3 +[C] +a=1 +b=2 +c=3 +` + ini := new(StarCfg) + ini.Parse([]byte(data)) + fmt.Println(ini.Seg("A").Int("a")) + fmt.Println(ini.Seg("A").Int("b")) + fmt.Println(ini.Seg("B").Int("c")) + fmt.Println("-----------------------") + ini.Seg("A").Set("d", "4", "") + ini.DeleteSeg("B") + ini.AddSeg("D") + ini.AddSeg("E").SetInt("a", 1, "") + ini.Seg("C").Delete("a") + fmt.Println(string(ini.Build())) +} + +func Test_Marshal(t *testing.T) { + var a Testsss + a.Migrate = "1" + a.N = "2" + a.Okk = "okkkkk" + ini := StarCfg{} + data, err := ini.Marshal(a) + fmt.Println(string(data), err) +} diff --git a/net.go b/net.go index 6098632..4ca3600 100644 --- a/net.go +++ b/net.go @@ -2,141 +2,283 @@ package starainrt import ( "bytes" + "context" + "encoding/binary" "errors" + "sync" + "time" ) -/* -SecretKey 通信加密Key,不应当被修改 -*/ +//SecretKey 通信加密Key,不应当被修改 const SecretKey string = "1996victorique1127B612BTXL" -var header []byte = []byte{11, 27, 19, 96} -var Crypto *StarCrypto +// 识别头 +var header = []byte{11, 27, 19, 96, 12, 25, 02, 20} -func init() { - Crypto = new(StarCrypto) +// MsgQueue 为基本的信息单位 +type MsgQueue struct { + ID uint16 + Msg []byte + Conn interface{} } +// StarQueue 为流数据中的消息队列分发 type StarQueue struct { Encode bool + Reserve uint16 Msgid uint16 - MsgPool []MsgUsed - UnFinMsg []byte + MsgPool []MsgQueue + UnFinMsg sync.Map LastID int //= -1 + ctx context.Context + cancel context.CancelFunc + duration time.Duration } +// NewQueue 建立一个新消息队列 func NewQueue() *StarQueue { - que := new(StarQueue) - que.LastID = -1 + var que StarQueue que.Encode = true - return que + que.ctx, que.cancel = context.WithCancel(context.Background()) + que.duration = 0 + return &que } -func (this *StarQueue) BuildMessage(str string) []byte { - var msg []byte - var buffer bytes.Buffer - if this.Encode { - msg = Crypto.VicqueEncodeV1([]byte(str), SecretKey) - } else { - msg = []byte(str) +// Uint32ToByte 4位uint32转byte +func Uint32ToByte(src uint32) []byte { + res := make([]byte, 4) + res[3] = uint8(src) + res[2] = uint8(src >> 8) + res[1] = uint8(src >> 16) + res[0] = uint8(src >> 24) + return res +} + +// ByteToUint32 byte转4位uint32 +func ByteToUint32(src []byte) uint32 { + var res uint32 + buffer := bytes.NewBuffer(src) + binary.Read(buffer, binary.BigEndian, &res) + return res +} + +// Uint16ToByte 2位uint16转byte +func Uint16ToByte(src uint16) []byte { + res := make([]byte, 2) + res[1] = uint8(src) + res[0] = uint8(src >> 8) + return res +} + +// ByteToUint16 用于byte转uint16 +func ByteToUint16(src []byte) uint16 { + var res uint16 + buffer := bytes.NewBuffer(src) + binary.Read(buffer, binary.BigEndian, &res) + return res +} + +// BuildMessage 生成编码后的信息用于发送 +func (que *StarQueue) BuildMessage(src []byte) []byte { + var buff bytes.Buffer + que.Msgid++ + if que.Encode { + cryptos := new(StarCrypto) + src = cryptos.VicqueEncodeV1(src, SecretKey) + } + length := uint32(len(src)) + buff.Write(header) + buff.Write(Uint32ToByte(length)) + buff.Write(Uint16ToByte(que.Msgid)) + buff.Write(src) + return buff.Bytes() +} + +type unFinMsg struct { + ID uint16 + LengthRecv uint32 + // HeaderMsg 信息头,应当为14位:8位识别码+4位长度码+2位id + HeaderMsg []byte + RecvMsg []byte +} + +// ParseMessage 用于解析啊收到的msg信息 +func (que *StarQueue) ParseMessage(msg []byte, conn interface{}) error { + tmp, ok := que.UnFinMsg.Load(conn) + cryptos := new(StarCrypto) + if ok { //存在未完成的信息 + lastMsg := tmp.(*unFinMsg) + headerLen := len(lastMsg.HeaderMsg) + if headerLen < 14 { //未完成头标题 + //传输的数据不能填充header头 + if len(msg) < 14-headerLen { + //加入header头并退出 + lastMsg.HeaderMsg = bytesMerge(lastMsg.HeaderMsg, msg) + que.UnFinMsg.Store(conn, lastMsg) + return nil + } + //获取14字节完整的header + header := msg[0 : 14-headerLen] + lastMsg.HeaderMsg = bytesMerge(lastMsg.HeaderMsg, header) + //检查收到的header是否为认证header + //若不是,丢弃并重新来过 + if !checkHeader(lastMsg.HeaderMsg[0:8]) { + que.UnFinMsg.Delete(conn) + if len(msg) == 0 { + return nil + } + return que.ParseMessage(msg, conn) + } + //获得本数据包长度 + lastMsg.LengthRecv = ByteToUint32(lastMsg.HeaderMsg[8:12]) + //获得本数据包ID + lastMsg.ID = ByteToUint16(lastMsg.HeaderMsg[12:14]) + //存入列表 + que.UnFinMsg.Store(conn, lastMsg) + msg = msg[14-headerLen:] + if uint32(len(msg)) < lastMsg.LengthRecv { + lastMsg.RecvMsg = msg + que.UnFinMsg.Store(conn, lastMsg) + return nil + } + if uint32(len(msg)) >= lastMsg.LengthRecv { + lastMsg.RecvMsg = msg[0:lastMsg.LengthRecv] + if que.Encode { + lastMsg.RecvMsg = cryptos.VicqueDecodeV1(lastMsg.RecvMsg, SecretKey) + } + msg = msg[lastMsg.LengthRecv:] + stroeMsg := MsgQueue{ + ID: lastMsg.ID, + Msg: lastMsg.RecvMsg, + Conn: conn, + } + que.MsgPool = append(que.MsgPool, stroeMsg) + que.UnFinMsg.Delete(conn) + return que.ParseMessage(msg, conn) + } + } else { + lastID := int(lastMsg.LengthRecv) - len(lastMsg.RecvMsg) + if lastID < 0 { + que.UnFinMsg.Delete(conn) + return que.ParseMessage(msg, conn) + } + if len(msg) >= lastID { + lastMsg.RecvMsg = bytesMerge(lastMsg.RecvMsg, msg[0:lastID]) + if que.Encode { + lastMsg.RecvMsg = cryptos.VicqueDecodeV1(lastMsg.RecvMsg, SecretKey) + } + stroeMsg := MsgQueue{ + ID: lastMsg.ID, + Msg: lastMsg.RecvMsg, + Conn: conn, + } + que.MsgPool = append(que.MsgPool, stroeMsg) + que.UnFinMsg.Delete(conn) + if len(msg) == lastID { + return nil + } + msg = msg[lastID:] + return que.ParseMessage(msg, conn) + } + lastMsg.RecvMsg = bytesMerge(lastMsg.RecvMsg, msg) + que.UnFinMsg.Store(conn, lastMsg) + return nil + } } - buffer.Write([]byte(Crypto.CRC32(msg))) - buffer.Write([]byte{byte(this.Msgid >> 8), byte(this.Msgid)}) - buffer.Write(msg) - lens := len(buffer.Bytes()) - if lens > 65535 { + if len(msg) == 0 { return nil } - msg = make([]byte, lens) - copy(msg, buffer.Bytes()) - buffer.Reset() - ulens := uint16(lens) - buffer.Write(header) - buffer.Write([]byte{byte(ulens >> 8), byte(ulens)}) - buffer.Write(msg) - this.Msgid++ - return buffer.Bytes() -} - -type MsgUsed struct { - ID uint16 - Msg string - Crc32 string - Conn interface{} -} - -func (this *StarQueue) ParseMessage(msg []byte, conn interface{}) int { - var buffer bytes.Buffer - buffer.Write(this.UnFinMsg) - buffer.Write(msg) - msg = buffer.Bytes() - if len(msg) <= 6 { - this.UnFinMsg = msg - return -2 + var start int + if start = searchHeader(msg); start == -1 { + return errors.New("data format error") } - if msg[0] != byte(11) { - this.UnFinMsg = []byte{} - //resend last - return this.LastID + 1 + msg = msg[start:] + lastMsg := unFinMsg{} + que.UnFinMsg.Store(conn, &lastMsg) + return que.ParseMessage(msg, conn) +} + +func checkHeader(msg []byte) bool { + if len(msg) != 8 { + return false } - if msg[1] != byte(27) || msg[2] != byte(19) || msg[3] != byte(96) { - //resend last - this.UnFinMsg = []byte{} - return this.LastID + 1 + for k, v := range msg { + if v != header[k] { + return false + } } - length := uint16(uint(msg[4])< uint16(len(msg)) { - this.UnFinMsg = msg - return -2 - } else { - this.UnFinMsg = []byte{} - strmsg := msg[6 : length+6] - crc := strmsg[0:8] - id := strmsg[8:10] - strmsg = strmsg[10:] - if Crypto.CRC32([]byte(strmsg)) != string(crc) { - //resend last - this.UnFinMsg = []byte{} - return this.LastID + 1 - } else { - if this.Encode { - strmsg = Crypto.VicqueDecodeV1(strmsg, SecretKey) + return true +} + +func searchHeader(msg []byte) int { + if len(msg) < 8 { + return 0 + } + for k, v := range msg { + find := 0 + if v == header[0] { + for k2, v2 := range header { + if msg[k+k2] == v2 { + find++ + } else { + break + } + } + if find == 8 { + return k } - msgs := MsgUsed{uint16(uint(id[0])<<8 + uint(id[1])), string(strmsg), string(crc), conn} - this.LastID = int(msgs.ID) - this.MsgPool = append(this.MsgPool, msgs) - } - if 6+length == uint16(len(msg)) { - return -2 } - msg = msg[length+6:] - return this.ParseMessage(msg, conn) } - return -2 + return -1 } -func (this *StarQueue) Restore(n int) ([]MsgUsed, error) { - if n > len(this.MsgPool) { - return nil, errors.New("N is Too Large") +func bytesMerge(src ...[]byte) []byte { + var buff bytes.Buffer + for _, v := range src { + buff.Write(v) } - tmp := this.MsgPool[0:n] - if n != len(this.MsgPool) { - this.MsgPool = this.MsgPool[n:] - } else { - this.MsgPool = []MsgUsed{} - } - return tmp, nil + return buff.Bytes() } -func (this *StarQueue) RestoreOne() (MsgUsed, error) { - if len(this.MsgPool) == 0 { - return MsgUsed{}, errors.New("N is Too Large") +// Restore 获取收到的信息 +func (que *StarQueue) Restore(n int) ([]MsgQueue, error) { + var res []MsgQueue + dura := time.Duration(0) + for len(que.MsgPool) < n { + select { + case <-que.ctx.Done(): + return res, errors.New("Stoped By External Function Call") + default: + time.Sleep(time.Millisecond * 20) + dura = time.Millisecond*20 + dura + if que.duration != 0 && dura > que.duration { + return res, errors.New("Time Exceed") + } + } } - tmp := this.MsgPool[0] - if 1 != len(this.MsgPool) { - this.MsgPool = this.MsgPool[1:] - } else { - this.MsgPool = []MsgUsed{} + if len(que.MsgPool) < n { + return res, errors.New("Result Not Enough") + } + res = que.MsgPool[0:n] + que.MsgPool = que.MsgPool[n:] + return res, nil +} + +// RestoreOne 获取收到的一个信息 +func (que *StarQueue) RestoreOne() (MsgQueue, error) { + data, err := que.Restore(1) + if len(data) == 1 { + return data[0], err } - return tmp, nil + return MsgQueue{}, err +} + +// Stop 立即停止Restore +func (que *StarQueue) Stop() { + que.cancel() +} + +// RestoreDuration Restore最大超时时间 +func (que *StarQueue) RestoreDuration(tm time.Duration) { + que.duration = tm } diff --git a/net_test.go b/net_test.go new file mode 100644 index 0000000..5f6e6e7 --- /dev/null +++ b/net_test.go @@ -0,0 +1,184 @@ +package starainrt + +import ( + "fmt" + "testing" +) + +func Test_oldddd(t *testing.T) { + a := []int{} + a = append(a, 1) + a = append(a, 2) + a = append(a, 3) + fmt.Println(a) + a = a[3:] + fmt.Println(a) +} + +func Test_binary(t *testing.T) { + bytes := Uint16ToByte(65512) + fmt.Println(bytes) + fmt.Println(ByteToUint16(bytes)) +} + +func Test_test(t *testing.T) { + que := NewQueue() + okk := que.BuildMessage([]byte(` + with + all_values as ( + (select V.ID, + V.OBJID, + V.TITLE, + V.CONTENT, + V.URL, + V.URL_TYPE, + V.STATUS, + V.SEARCH_TIMES, + V.UPDATE_TIMES + from SPMS_SEARCH_VIEW V + ) + + ), + in_values as ( + select T1.* + from SPMS_SEARCH_DATASET T1, + (select V.ID, + V.OBJID, + V.TITLE, + V.CONTENT, + V.URL, + V.URL_TYPE, + V.STATUS, + V.SEARCH_TIMES, + V.UPDATE_TIMES + from SPMS_SEARCH_VIEW V + ) T + where T.OBJID = T1.OBJID + + ), + upsert as ( + update SPMS_SEARCH_DATASET as T1 + set + ID = T.ID, + TITLE = T.TITLE, + CONTENT = T.CONTENT, + URL = T.URL, + URL_TYPE = T.URL_TYPE, + STATUS = T.STATUS, + SEARCH_TIMES = T.SEARCH_TIMES, + UPDATE_TIMES = TO_CHAR(T.UPDATE_TIMES, 'yyyy-MM-dd hh24:mi:ss'), + SYNC_TIMES = V_CUR_TIME + from all_values T + where T.OBJID = T1.OBJID and TO_DATE(T1.UPDATE_TIMES, 'yyyy-MM-dd hh24:mi:ss') \u003c TO_DATE(TO_CHAR(T.UPDATE_TIMES, 'yyyy-MM-dd hh24:mi:ss'), 'yyyy-MM-dd hh24:mi:ss') + ) + insert into SPMS_SEARCH_DATASET(ID, OBJID, TITLE, CONTENT, URL, URL_TYPE, STATUS, SEARCH_TIMES, UPDATE_TIMES, SYNC_TIMES) + select T.ID, + T.OBJID, + T.TITLE, + T.CONTENT, + T.URL, + T.URL_TYPE, + T.STATUS, + T.SEARCH_TIMES, + TO_CHAR(T.UPDATE_TIMES, 'yyyy-MM-dd hh24:mi:ss'), + V_CUR_TIME + from (select V.ID, + V.OBJID, + V.TITLE, + V.CONTENT, + V.URL, + V.URL_TYPE, + V.STATUS, + V.SEARCH_TIMES, + V.UPDATE_TIMES + from SPMS_SEARCH_VIEW V + ) T + where not exists(select 1 + from in_values T1 + where T.OBJID = T1.OBJID + ) + with + all_values as ( + (select V.ID, + V.OBJID, + V.TITLE, + V.CONTENT, + V.URL, + V.URL_TYPE, + V.STATUS, + V.SEARCH_TIMES, + V.UPDATE_TIMES + from SPMS_SEARCH_VIEW V + ) + + ), + in_values as ( + select T1.* + from SPMS_SEARCH_DATASET T1, + (select V.ID, + V.OBJID, + V.TITLE, + V.CONTENT, + V.URL, + V.URL_TYPE, + V.STATUS, + V.SEARCH_TIMES, + V.UPDATE_TIMES + from SPMS_SEARCH_VIEW V + ) T + where T.OBJID = T1.OBJID + + ), + upsert as ( + update SPMS_SEARCH_DATASET as T1 + set + ID = T.ID, + TITLE = T.TITLE, + CONTENT = T.CONTENT, + URL = T.URL, + URL_TYPE = T.URL_TYPE, + STATUS = T.STATUS, + SEARCH_TIMES = T.SEARCH_TIMES, + UPDATE_TIMES = TO_CHAR(T.UPDATE_TIMES, 'yyyy-MM-dd hh24:mi:ss'), + SYNC_TIMES = V_CUR_TIME + from all_values T + where T.OBJID = T1.OBJID and TO_DATE(T1.UPDATE_TIMES, 'yyyy-MM-dd hh24:mi:ss') \u003c TO_DATE(TO_CHAR(T.UPDATE_TIMES, 'yyyy-MM-dd hh24:mi:ss'), 'yyyy-MM-dd hh24:mi:ss') + ) +insert into SPMS_SEARCH_DATASET(ID, OBJID, TITLE, CONTENT, URL, URL_TYPE, STATUS, SEARCH_TIMES, UPDATE_TIMES, SYNC_TIMES) +select T.ID, + T.OBJID, + T.TITLE, + T.CONTENT, + T.URL, + T.URL_TYPE, + T.STATUS, + T.SEARCH_TIMES, + TO_CHAR(T.UPDATE_TIMES, 'yyyy-MM-dd hh24:mi:ss'), + V_CUR_TIME +from (select V.ID, + V.OBJID, + V.TITLE, + V.CONTENT, + V.URL, + V.URL_TYPE, + V.STATUS, + V.SEARCH_TIMES, + V.UPDATE_TIMES +from SPMS_SEARCH_VIEW V +) T +where not exists(select 1 +from in_values T1 +where T.OBJID = T1.OBJID +) + `)) + fmt.Println(string(okk)) + que.ParseMessage([]byte{'n', 'm', 'b'}, "nbb") + // que.ParseMessage([]byte{'n', 23, 24, 4, 45, 6, 56, 56, 2, 3, 1, 2}, "nbb") + que.ParseMessage(okk[0:123], "nbb") + que.ParseMessage([]byte{}, "nbb") + que.ParseMessage([]byte{}, "nbb") + que.ParseMessage([]byte{}, "nbb") + que.ParseMessage(okk[123:135], "nbb") + que.ParseMessage(okk[135:], "nbb") + fmt.Println(string(que.MsgPool[0].Msg)) +}