升级go mod

This commit is contained in:
2020-04-29 23:14:06 +08:00
parent f22e059172
commit 09412ce519
123 changed files with 263126 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
/.idea/*
+455
View File
@@ -0,0 +1,455 @@
package hotime
import (
"bytes"
"database/sql"
"encoding/json"
"io/ioutil"
"net/http"
"net/url"
"os"
"path/filepath"
"strconv"
"strings"
)
type Application struct {
MethodRouter
Router
contextBase
Port string //端口号
TLSPort string //ssl访问端口号
connectListener []func(this *Context) bool //所有的访问监听,true按原计划继续使用,false表示有监听器处理
connectDbFunc func(err ...*Error) *sql.DB
configPath string
Config Map
Db HoTimeDB
Server *http.Server
CacheIns
sessionLong CacheIns
sessionShort CacheIns
http.Handler
}
func (this *Application) ServeHTTP(w http.ResponseWriter, req *http.Request) {
this.handler(w, req)
}
//启动实例
func (this *Application) Run(router Router) {
//如果没有设置配置自动生成配置
if this.configPath == "" || len(this.Config) == 0 {
this.SetConfig()
}
//防止手动设置缓存误伤
if this.CacheIns == nil {
this.SetCache(CacheIns(&CacheMemory{}))
}
//防止手动设置session误伤
if this.sessionShort == nil && this.sessionLong == nil {
if this.connectDbFunc == nil {
this.SetSession(CacheIns(&CacheMemory{}), nil)
} else {
this.SetSession(CacheIns(&CacheMemory{}), CacheIns(&CacheDb{Db: &this.Db, Time: this.Config.GetInt64("cacheLongTime")}))
}
}
this.Router = router
//重新设置MethodRouter//直达路由
this.MethodRouter = MethodRouter{}
modeRouterStrict := true
if this.Config.Get("modeRouterStrict").(bool) == false {
modeRouterStrict = false
}
if router != nil {
for pk, pv := range router {
if !modeRouterStrict {
pk = strings.ToLower(pk)
}
if pv != nil {
for ck, cv := range pv {
if !modeRouterStrict {
ck = strings.ToLower(ck)
}
if cv != nil {
for mk, mv := range cv {
if !modeRouterStrict {
mk = strings.ToLower(mk)
}
this.MethodRouter["/"+pk+"/"+ck+"/"+mk] = mv
}
}
}
}
}
}
//this.Port = port
this.Port = this.Config.GetString("port")
this.TLSPort = this.Config.GetString("tlsPort")
if this.connectDbFunc != nil && (this.Db.DB == nil || this.Db.DB.Ping() != nil) {
this.Db.SetConnect(this.connectDbFunc)
}
if this.CacheIns == nil {
this.CacheIns = CacheIns(&CacheMemory{Map: Map{}, Time: this.Config.GetInt64("cacheShortTime")})
}
//异常处理
defer func() {
if err := recover(); err != nil {
//this.SetError(errors.New(fmt.Sprint(err)), LOG_FMT)
logFmt(err, 2, LOG_ERROR)
this.Run(router)
}
}()
this.Server = &http.Server{}
if !IsRun {
IsRun = true
}
ch := make(chan int)
if ObjToCeilInt(this.Port) != 0 {
go func() {
App[this.Port] = this
this.Server.Handler = this
//启动服务
this.Server.Addr = ":" + this.Port
err := this.Server.ListenAndServe()
logFmt(err, 2)
ch <- 1
}()
} else if ObjToCeilInt(this.TLSPort) != 0 {
go func() {
App[this.TLSPort] = this
this.Server.Handler = this
//启动服务
this.Server.Addr = ":" + this.TLSPort
err := this.Server.ListenAndServeTLS(this.Config.GetString("tlsCert"), this.Config.GetString("tlsKey"))
logFmt(err, 2)
ch <- 2
}()
} else {
logFmt("没有端口启用", 2, LOG_INFO)
return
}
value := <-ch
logFmt("启动服务失败 : "+ObjToStr(value), 2, LOG_ERROR)
}
//启动实例
func (this *Application) SetConnectDB(connect func(err ...*Error) *sql.DB) {
//this.Db.DBCached=false
//if this.Config.GetCeilInt("dbCached")!=0{
// this.Db.DBCached=true
//}
this.connectDbFunc = connect
this.Db.SetConnect(this.connectDbFunc)
this.Db.DBCached = false
if this.Config.GetCeilInt("dbCached") != 0 {
this.Db.DBCached = true
}
this.Db.Type = this.Config.GetString("dbType")
}
//设置配置文件路径全路径或者相对路径
func (this *Application) SetSession(short CacheIns, Long CacheIns) {
this.sessionLong = Long
this.sessionShort = short
}
//默认配置缓存和session实现
func (this *Application) SetDefault(connect func(err ...*Error) *sql.DB) {
this.SetConfig()
if connect != nil {
this.connectDbFunc = connect
this.Db.SetConnect(this.connectDbFunc)
}
}
//设置配置文件路径全路径或者相对路径
func (this *Application) SetCache(cache CacheIns) {
this.CacheIns = cache
}
//设置配置文件路径全路径或者相对路径
func (this *Application) SetConfig(configPath ...string) {
if len(configPath) != 0 {
this.configPath = configPath[0]
}
if this.configPath == "" {
this.configPath = "config/config.json"
}
//加载配置文件
btes, err := ioutil.ReadFile(this.configPath)
this.Config = DeepCopyMap(Config).(Map)
if err == nil {
cmap := Map{}
//文件是否损坏
cmap.JsonToMap(string(btes), &this.Error)
for k, v := range cmap {
this.Config[k] = v //程序配置
Config[k] = v //系统配置
}
} else {
logFmt("配置文件不存在,或者配置出错,使用缺省默认配置", 2)
}
//文件如果损坏则不写入配置防止配置文件数据丢失
if this.Error.GetError() == nil {
var configByte bytes.Buffer
err = json.Indent(&configByte, []byte(this.Config.ToJsonString()), "", "\t")
//判断配置文件是否序列有变化有则修改配置,五则不变
//fmt.Println(len(btes))
if len(btes) != 0 && configByte.String() == string(btes) {
return
}
//写入配置说明
var configNoteByte bytes.Buffer
json.Indent(&configNoteByte, []byte(ConfigNote.ToJsonString()), "", "\t")
os.MkdirAll(filepath.Dir(this.configPath), os.ModeDir)
err = ioutil.WriteFile(this.configPath, configByte.Bytes(), os.ModeAppend)
if err != nil {
this.Error.SetError(err)
}
ioutil.WriteFile(filepath.Dir(this.configPath)+"/confignote.json", configNoteByte.Bytes(), os.ModeAppend)
}
}
//连接判断,返回true继续传输至控制层,false则停止传输
func (this *Application) SetConnectListener(lis func(this *Context) bool) {
this.connectListener = append(this.connectListener, lis)
}
//网络错误
//func (this *Application) session(w http.ResponseWriter, req *http.Request) {
//
//}
//序列化链接
func (this *Application) urlSer(url string) (string, []string) {
q := strings.Index(url, "?")
if q == -1 {
q = len(url)
}
o := Substr(url, 0, q)
r := strings.SplitN(o, "/", -1)
var s = make([]string, 0)
for i := 0; i < len(r); i++ {
if !strings.EqualFold("", r[i]) {
s = append(s, r[i])
}
}
return o, s
}
//访问
func (this *Application) handler(w http.ResponseWriter, req *http.Request) {
_, s := this.urlSer(req.RequestURI)
//获取cookie
// 如果cookie存在直接将sessionId赋值为cookie.Value
// 如果cookie不存在就查找传入的参数中是否有token
// 如果token不存在就生成随机的sessionId
// 如果token存在就判断token是否在Session中有保存
// 如果有取出token并复制给cookie
// 没有保存就生成随机的session
cookie, err := req.Cookie(this.Config.GetString("sessionName"))
sessionId := Md5(strconv.Itoa(Rand(10)))
token := req.FormValue("token")
//isFirst:=false
if err != nil || (len(token) == 32 && cookie.Value != token) {
if len(token) == 32 {
sessionId = token
}
//else{
// isFirst=true;
//}
http.SetCookie(w, &http.Cookie{Name: this.Config.GetString("sessionName"), Value: sessionId, Path: "/"})
} else {
sessionId = cookie.Value
}
unescapeUrl, err := url.QueryUnescape(req.RequestURI)
if err != nil {
unescapeUrl = req.RequestURI
}
//访问实例
context := Context{SessionIns: SessionIns{SessionId: sessionId,
LongCache: this.sessionLong,
ShortCache: this.sessionShort,
},
CacheIns: this.CacheIns,
Resp: w, Req: req, Application: this, RouterString: s, Config: this.Config, Db: &this.Db, HandlerStr: unescapeUrl}
//header默认设置
header := w.Header()
header.Set("Content-Type", "text/html; charset=utf-8")
//url去掉参数并序列化
context.HandlerStr, context.RouterString = this.urlSer(context.HandlerStr)
//跨域设置
this.crossDomain(&context)
//是否展示日志
if this.Config.GetInt("connectLogShow") != 0 {
logFmt(Substr(context.Req.RemoteAddr, 0, strings.Index(context.Req.RemoteAddr, ":"))+" "+context.HandlerStr, 0, LOG_INFO)
}
//访问拦截true继续false暂停
connectListenerLen := len(this.connectListener)
if connectListenerLen != 0 {
for i := 0; i < connectListenerLen; i++ {
if !this.connectListener[i](&context) {
context.View()
return
}
}
}
//接口服务
//if len(s) == 3 {
// //如果满足规则则路由到对应控制器去
// if this.Router[s[0]] != nil && this.Router[s[0]][s[1]] != nil && this.Router[s[0]][s[1]][s[2]] != nil {
// //控制层
// this.Router[s[0]][s[1]][s[2]](&context)
// //header.Set("Content-Type", "text/html; charset=utf-8")
// context.View()
// return
// }
//
//}
//验证接口严格模式
modeRouterStrict := this.Config.Get("modeRouterStrict").(bool)
tempHandlerStr := context.HandlerStr
if !modeRouterStrict {
tempHandlerStr = strings.ToLower(tempHandlerStr)
}
//执行接口
if this.MethodRouter[tempHandlerStr] != nil {
this.MethodRouter[tempHandlerStr](&context)
context.View()
return
}
//url赋值
path := this.Config.GetString("tpt") + tempHandlerStr
//判断是否为默认
if path[len(path)-1] == '/' {
defFile := this.Config.GetSlice("defFile")
for i := 0; i < len(defFile); i++ {
temp := path + defFile.GetString(i)
_, err := os.Stat(temp)
if err == nil {
path = temp
break
}
}
if path[len(path)-1] == '/' {
w.WriteHeader(404)
return
}
}
if strings.Contains(path, "/.") {
w.WriteHeader(404)
return
}
//设置header
delete(header, "Content-Type")
if this.Config.GetInt("debug") != 1 {
header.Set("Cache-Control", "public")
}
if strings.Index(path, ".m3u8") != -1 {
header.Add("Content-Type", "audio/mpegurl")
}
//w.Write(data)
http.ServeFile(w, req, path)
}
func (this *Application) crossDomain(context *Context) {
//没有跨域设置
if context.Config.GetString("crossDomain") == "" {
return
}
header := context.Resp.Header()
header.Set("Access-Control-Allow-Origin", "*")
header.Set("Access-Control-Allow-Methods", "*")
header.Set("Access-Control-Allow-Credentials", "true")
header.Set("Access-Control-Expose-Headers", "*")
header.Set("Access-Control-Allow-Headers", "X-Requested-With,Content-Type,Access-Token")
if context.Config.GetString("crossDomain") != "*" {
header.Set("Access-Control-Allow-Origin", this.Config.GetString("crossDomain"))
return
}
origin := context.Req.Header.Get("Origin")
if origin != "" {
header.Set("Access-Control-Allow-Origin", origin)
return
}
refer := context.Req.Header.Get("Referer")
if refer != "" {
tempInt := 0
lastInt := strings.IndexFunc(refer, func(r rune) bool {
if r == '/' && tempInt > 8 {
return true
}
tempInt++
return false
})
if lastInt < 0 {
lastInt = len(refer)
}
refer = Substr(refer, 0, lastInt)
header.Set("Access-Control-Allow-Origin", refer)
}
}
+146
View File
@@ -0,0 +1,146 @@
package hotime
import (
"encoding/json"
"strings"
"time"
)
type CacheDb struct {
Time int64
Db *HoTimeDB
contextBase
isInit bool
}
func (this *CacheDb) initDbTable() {
if this.isInit {
return
}
if this.Db.Type == "mysql" {
dbNames := this.Db.Query("SELECT DATABASE()")
if len(dbNames) == 0 {
return
}
dbName := dbNames[0].GetString("DATABASE()")
res := this.Db.Query("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='" + dbName + "' AND TABLE_NAME='cached'")
if len(res) != 0 {
this.isInit = true
return
}
_, e := this.Db.Exec("CREATE TABLE `cached` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `ckey` varchar(60) DEFAULT NULL, `cvalue` varchar(2000) DEFAULT NULL, `time` bigint(20) DEFAULT NULL, `endtime` bigint(20) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=198740 DEFAULT CHARSET=utf8")
if e.GetError() == nil {
this.isInit = true
}
}
if this.Db.Type == "sqlite" {
res := this.Db.Query(`select * from sqlite_master where type = 'table' and name = 'cached'`)
if len(res) != 0 {
this.isInit = true
return
}
_, e := this.Db.Exec(`CREATE TABLE "cached" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"ckey" TEXT(60),
"cvalue" TEXT(2000),
"time" integer,
"endtime" integer
);`)
if e.GetError() == nil {
this.isInit = true
}
}
}
//获取Cache键只能为string类型
func (this *CacheDb) get(key string) interface{} {
cached := this.Db.Get("cached", "*", Map{"ckey": key})
if cached == nil {
return nil
}
//data:=cacheMap[key];
if cached.GetInt64("endtime") <= time.Now().Unix() {
this.Db.Delete("cached", Map{"id": cached.GetString("id")})
return nil
}
data := Map{}
data.JsonToMap(cached.GetString("cvalue"))
return data.Get("data")
}
//key value ,时间为时间戳
func (this *CacheDb) set(key string, value interface{}, tim int64) {
bte, _ := json.Marshal(Map{"data": value})
num := this.Db.Update("cached", Map{"cvalue": string(bte), "time": time.Now().UnixNano(), "endtime": tim}, Map{"ckey": key})
if num == int64(0) {
this.Db.Insert("cached", Map{"cvalue": string(bte), "time": time.Now().UnixNano(), "endtime": tim, "ckey": key})
}
//随机执行删除命令
if Rand(1000) > 950 {
this.Db.Delete("cached", Map{"endtime[<]": time.Now().Unix()})
}
}
func (this *CacheDb) delete(key string) {
del := strings.Index(key, "*")
//如果通配删除
if del != -1 {
key = Substr(key, 0, del)
this.Db.Delete("cached", Map{"ckey": key + "%"})
} else {
this.Db.Delete("cached", Map{"ckey": key})
}
}
func (this *CacheDb) Cache(key string, data ...interface{}) *Obj {
this.initDbTable()
if len(data) == 0 {
return &Obj{Data: this.get(key)}
}
tim := time.Now().Unix()
if len(data) == 1 && data[0] == nil {
this.delete(key)
return &Obj{Data: nil}
}
if len(data) == 1 {
if this.Time == 0 {
this.Time = Config.GetInt64("cacheLongTime")
}
tim += this.Time
}
if len(data) == 2 {
this.SetError(nil)
tempt := ObjToInt64(data[1], &this.Error)
if tempt > tim {
tim = tempt
} else if this.GetError() == nil {
tim = tim + tempt
}
}
this.set(key, data[0], tim)
return &Obj{Data: nil}
}
+146
View File
@@ -0,0 +1,146 @@
package hotime
import (
"strings"
"sync"
"time"
)
type CacheMemory struct {
Time int64
Map
contextBase
mutex *sync.RWMutex
}
//获取Cache键只能为string类型
func (this *CacheMemory) get(key string) interface{} {
this.Error.SetError(nil)
if this.Map == nil {
this.Map = Map{}
}
if this.Map[key] == nil {
return nil
}
data := this.Map.Get(key, &this.Error).(cacheData)
if this.GetError() != nil {
return nil
}
if data.time < time.Now().Unix() {
delete(this.Map, key)
return nil
}
return data.data
}
func (this *CacheMemory) refreshMap() {
go func() {
this.mutex.Lock()
defer this.mutex.Unlock()
for key, v := range this.Map {
data := v.(cacheData)
if data.time <= time.Now().Unix() {
delete(this.Map, key)
}
}
}()
}
//key value ,时间为时间戳
func (this *CacheMemory) set(key string, value interface{}, time int64) {
this.Error.SetError(nil)
var data cacheData
if this.Map == nil {
this.Map = Map{}
}
dd := this.Map[key]
if dd == nil {
data = cacheData{}
} else {
data = dd.(cacheData)
}
data.time = time
data.data = value
this.Map.Put(key, data)
}
func (this *CacheMemory) delete(key string) {
del := strings.Index(key, "*")
//如果通配删除
if del != -1 {
key = Substr(key, 0, del)
for k, _ := range this.Map {
if strings.Index(k, key) != -1 {
delete(this.Map, key)
}
}
} else {
delete(this.Map, key)
}
}
func (this *CacheMemory) Cache(key string, data ...interface{}) *Obj {
x := RandX(1, 100000)
if x > 99950 {
this.refreshMap()
}
if this.mutex == nil {
this.mutex = &sync.RWMutex{}
}
reData := &Obj{Data: nil}
if len(data) == 0 {
this.mutex.RLock()
reData.Data = this.get(key)
this.mutex.RUnlock()
return reData
}
tim := time.Now().Unix()
if len(data) == 1 && data[0] == nil {
this.mutex.Lock()
this.delete(key)
this.mutex.Unlock()
return reData
}
if len(data) == 1 {
if this.Time == 0 {
this.Time = Config.GetInt64("cacheShortTime")
}
tim = tim + this.Time
}
if len(data) == 2 {
this.Error.SetError(nil)
tempt := ObjToInt64(data[1], &this.Error)
if tempt > tim {
tim = tempt
} else if this.GetError() == nil {
tim = tim + tempt
}
}
this.mutex.Lock()
this.set(key, data[0], tim)
this.mutex.Unlock()
return reData
}
+16
View File
@@ -0,0 +1,16 @@
package hotime
type LOG_MODE int
const (
LOG_NIL = 0
LOG_FMT = 1
//LOG_FILE = 2
LOG_INFO LOG_MODE = 0
LOG_WARN LOG_MODE = 1
LOG_ERROR LOG_MODE = 2
)
//session储存头
const HEAD_SESSION_ADD = "session#"
+65
View File
@@ -0,0 +1,65 @@
package hotime
import (
"encoding/json"
"errors"
"net/http"
)
type Context struct {
contextBase
Resp http.ResponseWriter
Req *http.Request
Application *Application
RouterString []string
Config Map
Db *HoTimeDB
RespData Map
CacheIns
SessionIns
HandlerStr string //复写请求url
}
//唯一标志
func (this *Context) Mtd(router [3]string) Map {
this.Application.Router[router[0]][router[1]][router[2]](this)
d := this.RespData
this.RespData = nil
return d
}
//打印
func (this *Context) Display(statu int, data interface{}) {
resp := Map{"statu": statu}
if statu != 0 {
temp := Map{}
tpe := this.Config.GetMap("error").GetString(ObjToStr(statu))
if tpe == "" {
logFmt(errors.New("找不到对应的错误码"), 2, LOG_WARN)
}
temp["type"] = tpe
temp["msg"] = data
resp["result"] = temp
} else {
resp["result"] = data
}
this.RespData = resp
//this.Data=d;
}
func (this *Context) View() {
if this.RespData == nil {
return
}
d, err := json.Marshal(this.RespData)
if err != nil {
return
}
this.RespData = nil
this.Resp.Write(d)
}
+17
View File
@@ -0,0 +1,17 @@
package hotime
import "time"
type contextBase struct {
Error
tag int64
}
//唯一标志
func (this *contextBase) GetTag() int64 {
if this.tag == int64(0) {
this.tag = time.Now().UnixNano()
}
return this.tag
}
+935
View File
@@ -0,0 +1,935 @@
package hotime
import (
"database/sql"
"encoding/json"
"errors"
"os"
"reflect"
"strings"
)
type HoTimeDB struct {
*sql.DB
contextBase
CacheIns
Type string
DBCached bool
LastQuery string
LastData []interface{}
ConnectFunc func(err ...*Error) *sql.DB
LastErr Error
limit Slice
Tx *sql.Tx //事务对象
}
//设置数据库配置连接
func (this *HoTimeDB) SetConnect(connect func(err ...*Error) *sql.DB, err ...*Error) {
this.ConnectFunc = connect
this.InitDb()
}
//事务,如果action返回true则执行成功;false则回滚
func (this *HoTimeDB) Action(action func(db HoTimeDB) bool) bool {
db := HoTimeDB{DB: this.DB, CacheIns: this.CacheIns, DBCached: this.DBCached}
tx, err := db.Begin()
if err != nil {
this.LastErr.SetError(err)
return false
}
db.Tx = tx
result := action(db)
if !result {
db.Tx.Rollback()
return result
}
db.Tx.Commit()
return result
}
func (this *HoTimeDB) InitDb(err ...*Error) Error {
if len(err) != 0 {
this.LastErr = *(err[0])
}
this.DB = this.ConnectFunc(&this.LastErr)
if this.DB == nil {
return this.LastErr
}
e := this.DB.Ping()
this.LastErr.SetError(e)
return this.LastErr
}
func (this *HoTimeDB) Page(page, pageRow int) *HoTimeDB {
page = (page - 1) * pageRow
if page < 0 {
page = 1
}
this.limit = Slice{page, pageRow}
return this
}
func (this *HoTimeDB) PageSelect(table string, qu ...interface{}) []Map {
if len(qu) == 1 {
qu = append(qu, Map{"LIMIT": this.limit})
}
if len(qu) == 2 {
temp := qu[1].(Map)
temp["LIMIT"] = this.limit
qu[1] = temp
}
if len(qu) == 3 {
temp := qu[2].(Map)
temp["LIMIT"] = this.limit
qu[2] = temp
}
//fmt.Println(qu)
data := this.Select(table, qu...)
return data
}
//数据库数据解析
func (this *HoTimeDB) Row(resl *sql.Rows) []Map {
dest := make([]Map, 0)
strs, _ := resl.Columns()
for i := 0; resl.Next(); i++ {
lis := make(Map, 0)
a := make([]interface{}, len(strs))
b := make([]interface{}, len(a))
for j := 0; j < len(a); j++ {
b[j] = &a[j]
}
resl.Scan(b...)
for j := 0; j < len(a); j++ {
if a[j] != nil && reflect.ValueOf(a[j]).Type().String() == "[]uint8" {
lis[strs[j]] = string(a[j].([]byte))
} else {
lis[strs[j]] = a[j]
}
}
//防止int被误读为float64
jlis, e := json.Marshal(lis)
if e != nil {
this.LastErr.SetError(e)
} else {
lis.JsonToMap(string(jlis), &this.LastErr)
}
dest = append(dest, lis)
}
return dest
}
//
////code=0,1,2 0 backup all,1 backup data,2 backup ddl
//func (this *HoTimeDB) Backup(path string, code int) {
// var cmd *exec.Cmd
// switch code {
// case 0:cmd= exec.Command("mysqldump","-h"+ObjToStr(Config["dbHost"]), "-P"+ObjToStr(Config["dbPort"]),"-u"+ObjToStr(Config["dbUser"]), "-p"+ObjToStr(Config["dbPwd"]),ObjToStr(Config["dbName"]))
// case 1:cmd= exec.Command("mysqldump","-h"+ObjToStr(Config["dbHost"]), "-P"+ObjToStr(Config["dbPort"]),"-u"+ObjToStr(Config["dbUser"]), "-p"+ObjToStr(Config["dbPwd"]), ObjToStr(Config["dbName"]))
// case 2:cmd= exec.Command("mysqldump","--no-data","-h"+ObjToStr(Config["dbHost"]), "-P"+ObjToStr(Config["dbPort"]),"-u"+ObjToStr(Config["dbUser"]), "-p"+ObjToStr(Config["dbPwd"]),ObjToStr(Config["dbName"]))
// }
//
//
//
// stdout, err := cmd.StdoutPipe()
// if err != nil {
// log.Println(err)
// }
//
// if err := cmd.Start(); err != nil {
// log.Println(err)
// }
//
// bytes, err := ioutil.ReadAll(stdout)
// if err != nil {
// log.Println(err)
// }
// err = ioutil.WriteFile(path, bytes, 0644)
// if err != nil {
// panic(err)
// }
// return ;
// //
// //db := ``
// //fmt.Println(db)
// //
// //tables := this.Query("show tables")
// //lth := len(tables)
// //if lth == 0 {
// // return
// //}
// //for k, _ := range tables[0] {
// // db = Substr(k, 10, len(k))
// //}
// //
// //fd, _ := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644)
// //fd.Write([]byte("/*datetime " + time.Now().Format("2006-01-02 15:04:05") + " */ \r\n"))
// //fd.Close()
// //
// //for i := 0; i < lth; i++ {
// // tt := tables[i]["Tables_in_"+db].(string)
// // this.backupSave(path, tt, code)
// // debug.FreeOSMemory()
// //}
//
//}
func (this *HoTimeDB) backupSave(path string, tt string, code int) {
fd, _ := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644)
defer fd.Close()
str := "\r\n"
if code == 0 || code == 2 {
str += this.backupDdl(tt)
}
if code == 0 || code == 1 {
str += "insert into `" + tt + "`\r\n\r\n("
str += this.backupCol(tt)
}
fd.Write([]byte(str))
}
func (this *HoTimeDB) backupDdl(tt string) string {
data := this.Query("show create table " + tt)
if len(data) == 0 {
return ""
}
return ObjToStr(data[0]["Create Table"]) + ";\r\n\r\n"
}
func (this *HoTimeDB) backupCol(tt string) string {
str := ""
data := this.Select(tt, "*")
lthData := len(data)
if lthData == 0 {
return str
}
lthCol := len(data[0])
col := make([]string, lthCol)
tempLthData := 0
for k, _ := range data[0] {
if tempLthData == lthCol-1 {
str += "`" + k + "`)"
} else {
str += "`" + k + "`,"
}
col[tempLthData] = k
tempLthData++
}
str += " values"
for j := 0; j < lthData; j++ {
for m := 0; m < lthCol; m++ {
if m == 0 {
str += "("
}
v := "NULL"
if data[j][col[m]] != nil {
v = "'" + strings.Replace(ObjToStr(data[j][col[m]]), "'", `\'`, -1) + "'"
}
if m == lthCol-1 {
str += v + ")"
} else {
str += v + ","
}
}
if j == lthData-1 {
str += ";\r\n\r\n"
} else {
str += ",\r\n\r\n"
}
}
return str
}
func (this *HoTimeDB) md5(query string, args ...interface{}) string {
strByte, _ := json.Marshal(args)
str := Md5(query + ":" + string(strByte))
return str
}
func (this *HoTimeDB) Query(query string, args ...interface{}) []Map {
//fmt.Println(query)
var err error
var resl *sql.Rows
this.LastQuery = query
this.LastData = args
if this.DB == nil {
err = errors.New("没有初始化数据库")
this.LastErr.SetError(err)
return nil
}
if this.Tx != nil {
resl, err = this.Tx.Query(query, args...)
} else {
resl, err = this.DB.Query(query, args...)
}
this.LastErr.SetError(err)
if err != nil {
if err = this.DB.Ping(); err != nil {
this.LastErr.SetError(err)
this.InitDb()
if this.LastErr.GetError() != nil {
return nil
}
return this.Query(query, args...)
}
return nil
}
return this.Row(resl)
}
func (this *HoTimeDB) Exec(query string, args ...interface{}) (sql.Result, Error) {
this.LastQuery = query
this.LastData = args
var e error
var resl sql.Result
if this.DB == nil {
err := errors.New("没有初始化数据库")
this.LastErr.SetError(err)
return nil, this.LastErr
}
if this.Tx != nil {
resl, e = this.Tx.Exec(query, args...)
} else {
resl, e = this.DB.Exec(query, args...)
}
this.LastErr.SetError(e)
//判断是否连接断开了
if e != nil {
if e = this.DB.Ping(); e != nil {
this.LastErr.SetError(e)
this.InitDb()
if this.LastErr.GetError() != nil {
return resl, this.LastErr
}
return this.Exec(query, args...)
}
}
return resl, this.LastErr
}
//func (this *HoTimeDB)copy(data []Map)[]Map{
// if data==nil{
// return nil
// }
//
// lth:=len(data)
//
// res:=make([]Map,lth)
//
//
// for i:=0;i<lth;i++{
//
// res[i]=DeepCopy(data[i]).(Map)
// }
//
// return res
//
//}
func (this *HoTimeDB) Select(table string, qu ...interface{}) []Map {
query := "SELECT"
where := Map{}
qs := make([]interface{}, 0)
intQs, intWhere := 0, 1
join := false
if len(qu) == 3 {
intQs = 1
intWhere = 2
join = true
}
if len(qu) > 0 {
if reflect.ValueOf(qu[intQs]).Type().String() == "string" {
query += " " + qu[intQs].(string)
} else {
for i := 0; i < len(qu[intQs].(Slice)); i++ {
k := qu[intQs].(Slice)[i].(string)
if strings.Contains(k, " AS ") {
query += " " + k + " "
} else {
query += " `" + k + "` "
}
if i+1 != len(qu[intQs].(Slice)) {
query = query + ", "
}
}
}
} else {
query += " *"
}
query += " FROM " + table
if join {
for k, v := range qu[0].(Map) {
switch Substr(k, 0, 3) {
case "[>]":
query += " LEFT JOIN " + Substr(k, 3, len(k)-3) + " ON " + v.(string)
case "[<]":
query += " RIGHT JOIN " + Substr(k, 3, len(k)-3) + " ON " + v.(string)
}
switch Substr(k, 0, 4) {
case "[<>]":
query += " FULL JOIN " + Substr(k, 4, len(k)-4) + " ON " + v.(string)
case "[><]":
query += " INNER JOIN " + Substr(k, 4, len(k)-4) + " ON " + v.(string)
}
}
}
if len(qu) > 1 {
where = qu[intWhere].(Map)
}
temp, resWhere := this.where(where)
query += temp
qs = append(qs, resWhere...)
md5 := this.md5(query, qs...)
if this.DBCached && this.CacheIns != nil {
//如果缓存有则从缓存取
cacheData := this.Cache(table + ":" + md5)
if cacheData.Data != nil {
return cacheData.ToMapArray()
}
}
//无缓存则数据库取
res := this.Query(query, qs...)
if res == nil {
res = []Map{}
}
//缓存
if this.DBCached && this.CacheIns != nil {
this.Cache(table+":"+md5, res)
}
return res
}
func (this *HoTimeDB) Get(table string, qu ...interface{}) Map {
//fmt.Println(qu)
if len(qu) == 1 {
qu = append(qu, Map{"LIMIT": 1})
}
if len(qu) == 2 {
temp := qu[1].(Map)
temp["LIMIT"] = 1
qu[1] = temp
}
if len(qu) == 3 {
temp := qu[2].(Map)
temp["LIMIT"] = 1
qu[2] = temp
}
//fmt.Println(qu)
data := this.Select(table, qu...)
if len(data) == 0 {
return nil
}
return data[0]
}
/**
** 计数
*/
func (this *HoTimeDB) Count(table string, qu ...interface{}) int {
req := []interface{}{}
if len(qu) == 2 {
req = append(req, qu[0])
req = append(req, "COUNT(*)")
req = append(req, qu[1])
} else {
req = append(req, "COUNT(*)")
req = append(req, qu...)
}
//req=append(req,qu...)
data := this.Select(table, req...)
//fmt.Println(data)
if len(data) == 0 {
return 0
}
//res,_:=StrToInt(data[0]["COUNT(*)"].(string))
res := ObjToStr(data[0]["COUNT(*)"])
count, _ := StrToInt(res)
return count
}
var condition = []string{"AND", "OR"}
var vcond = []string{"GROUP", "ORDER", "LIMIT"}
//where语句解析
func (this *HoTimeDB) where(data Map) (string, []interface{}) {
where := ""
res := make([]interface{}, 0)
//AND OR判断
for k, v := range data {
x := 0
for i := 0; i < len(condition); i++ {
if condition[i] == k {
tw, ts := this.cond(k, v.(Map))
where += tw
res = append(res, ts...)
break
}
x++
}
y := 0
for j := 0; j < len(vcond); j++ {
if vcond[j] == k {
break
}
y++
}
if x == len(condition) && y == len(vcond) {
tv, vv := this.varCond(k, v)
where += tv
res = append(res, vv...)
}
}
if len(where) != 0 {
where = " WHERE " + where
}
//特殊字符
for j := 0; j < len(vcond); j++ {
for k, v := range data {
if vcond[j] == k {
if k == "ORDER" {
where += " " + k + " BY "
//fmt.Println(reflect.ValueOf(v).Type())
//break
} else if k == "GROUP" {
where += " " + k + " BY "
} else {
where += " " + k
}
if reflect.ValueOf(v).Type().String() == "hotime.Slice" {
for i := 0; i < len(v.(Slice)); i++ {
where += " " + ObjToStr(v.(Slice)[i])
if len(v.(Slice)) != i+1 {
where += ","
}
}
} else {
//fmt.Println(v)
where += " " + ObjToStr(v)
}
break
}
}
}
return where, res
}
func (this *HoTimeDB) varCond(k string, v interface{}) (string, []interface{}) {
where := ""
res := make([]interface{}, 0)
length := len(k)
if length > 4 {
def := false
switch Substr(k, length-3, 3) {
case "[>]":
k = strings.Replace(k, "[>]", "", -1)
where += "`" + k + "`>? "
res = append(res, v)
case "[<]":
k = strings.Replace(k, "[<]", "", -1)
where += "`" + k + "`<? "
res = append(res, v)
case "[!]":
k = strings.Replace(k, "[!]", "", -1)
where, res = this.notIn(k, v, where, res)
case "[#]":
k = strings.Replace(k, "[#]", "", -1)
where += " " + k + "=" + ObjToStr(v)
case "[#!]":
k = strings.Replace(k, "[#!]", "", -1)
where += " " + k + "!=" + ObjToStr(v)
case "[!#]":
k = strings.Replace(k, "[!#]", "", -1)
where += " " + k + "!=" + ObjToStr(v)
case "[~]":
k = strings.Replace(k, "[~]", "", -1)
where += "`" + k + "` LIKE ? "
v = "%" + ObjToStr(v) + "%"
res = append(res, v)
case "[!~]": //左边任意
k = strings.Replace(k, "[~]", "", -1)
where += "`" + k + "` LIKE ? "
v = "%" + ObjToStr(v)
res = append(res, v)
case "[~!]": //右边任意
k = strings.Replace(k, "[~]", "", -1)
where += "`" + k + "` LIKE ? "
v = ObjToStr(v) + "%"
res = append(res, v)
case "[~~]": //手动任意
k = strings.Replace(k, "[~]", "", -1)
where += "`" + k + "` LIKE ? "
//v = ObjToStr(v)
res = append(res, v)
default:
def = true
}
if def {
switch Substr(k, length-4, 4) {
case "[>=]":
k = strings.Replace(k, "[>=]", "", -1)
where += "`" + k + "`>=? "
res = append(res, v)
case "[<=]":
k = strings.Replace(k, "[<=]", "", -1)
where += "`" + k + "`<=? "
res = append(res, v)
case "[><]":
k = strings.Replace(k, "[><]", "", -1)
where += "`" + k + "` NOT BETWEEN ? AND ? "
res = append(res, v.(Slice)[0])
res = append(res, v.(Slice)[1])
case "[<>]":
k = strings.Replace(k, "[<>]", "", -1)
where += "`" + k + "` BETWEEN ? AND ? "
res = append(res, v.(Slice)[0])
res = append(res, v.(Slice)[1])
default:
if reflect.ValueOf(v).Type().String() == "hotime.Slice" {
where += "`" + k + "` IN ("
res = append(res, (v.(Slice))...)
if len(v.(Slice)) == 0 {
where += ") "
} else {
for i := 0; i < len(v.(Slice)); i++ {
if i+1 != len(v.(Slice)) {
where += "?,"
} else {
where += "?) "
}
//res=append(res,(v.(Slice))[i])
}
}
} else {
where += "`" + k + "`=? "
res = append(res, v)
}
}
}
} else if k == "[#]" {
k = strings.Replace(k, "[#]", "", -1)
where += " " + ObjToStr(v) + " "
} else {
//fmt.Println(reflect.ValueOf(v).Type().String())
if v == nil {
where += "`" + k + "` IS NULL"
} else if reflect.ValueOf(v).Type().String() == "hotime.Slice" {
//fmt.Println(v)
where += "`" + k + "` IN ("
res = append(res, (v.(Slice))...)
for i := 0; i < len(v.(Slice)); i++ {
if i+1 != len(v.(Slice)) {
where += "?,"
} else {
where += "?) "
}
//res=append(res,(v.(Slice))[i])
}
} else if reflect.ValueOf(v).Type().String() == "[]interface {}" {
where += "`" + k + "` IN ("
res = append(res, (v.([]interface{}))...)
for i := 0; i < len(v.([]interface{})); i++ {
if i+1 != len(v.([]interface{})) {
where += "?,"
} else {
where += "?) "
}
//res=append(res,(v.(Slice))[i])
}
} else {
where += "`" + k + "`=? "
res = append(res, v)
}
}
return where, res
}
// this.Db.Update("user",hotime.Map{"ustate":"1"},hotime.Map{"AND":hotime.Map{"OR":hotime.Map{"uid":4,"uname":"dasda"}},"ustate":1})
func (this *HoTimeDB) notIn(k string, v interface{}, where string, res []interface{}) (string, []interface{}) {
//where:=""
//fmt.Println(reflect.ValueOf(v).Type().String())
if v == nil {
where += "`" + k + "` IS NOT NULL "
} else if reflect.ValueOf(v).Type().String() == "hotime.Slice" {
where += "`" + k + "` NOT IN ("
res = append(res, (v.(Slice))...)
for i := 0; i < len(v.(Slice)); i++ {
if i+1 != len(v.(Slice)) {
where += "?,"
} else {
where += "?) "
}
//res=append(res,(v.(Slice))[i])
}
} else if reflect.ValueOf(v).Type().String() == "[]interface {}" {
where += "`" + k + "` NOT IN ("
res = append(res, (v.([]interface{}))...)
for i := 0; i < len(v.([]interface{})); i++ {
if i+1 != len(v.([]interface{})) {
where += "?,"
} else {
where += "?) "
}
//res=append(res,(v.(Slice))[i])
}
} else {
where += "`" + k + "` !=? "
res = append(res, v)
}
return where, res
}
func (this *HoTimeDB) cond(tag string, data Map) (string, []interface{}) {
where := " "
res := make([]interface{}, 0)
lens := len(data)
//fmt.Println(lens)
for k, v := range data {
x := 0
for i := 0; i < len(condition); i++ {
if condition[i] == k {
tw, ts := this.cond(k, v.(Map))
if lens--; lens <= 0 {
//fmt.Println(lens)
where += "(" + tw + ") "
} else {
where += "(" + tw + ") " + tag + " "
}
res = append(res, ts...)
break
}
x++
}
if x == len(condition) {
tv, vv := this.varCond(k, v)
res = append(res, vv...)
if lens--; lens <= 0 {
where += tv + ""
} else {
where += tv + " " + tag + " "
}
}
}
return where, res
}
//更新数据
func (this *HoTimeDB) Update(table string, data Map, where Map) int64 {
query := "UPDATE " + table + " SET "
//UPDATE Person SET Address = 'Zhongshan 23', City = 'Nanjing' WHERE LastName = 'Wilson'
qs := make([]interface{}, 0)
tp := len(data)
for k, v := range data {
vstr := "?"
if Substr(k, len(k)-3, 3) == "[#]" {
k = strings.Replace(k, "[#]", "", -1)
vstr = ObjToStr(v)
} else {
qs = append(qs, v)
}
query += "`" + k + "`=" + vstr + ""
if tp--; tp != 0 {
query += ", "
}
}
temp, resWhere := this.where(where)
//fmt.Println(resWhere)
query += temp
qs = append(qs, resWhere...)
res, err := this.Exec(query, qs...)
rows := int64(0)
if err.GetError() == nil && res != nil {
rows, _ = res.RowsAffected()
}
//如果更新成功,则删除缓存
if rows != 0 {
if this.DBCached && this.CacheIns != nil {
this.Cache(table+"*", nil)
}
}
return rows
}
func (this *HoTimeDB) Delete(table string, data map[string]interface{}) int64 {
query := "DELETE FROM " + table + " "
temp, resWhere := this.where(data)
query += temp
res, err := this.Exec(query, resWhere...)
rows := int64(0)
if err.GetError() == nil && res != nil {
rows, _ = res.RowsAffected()
}
//如果删除成功,删除对应缓存
if rows != 0 {
if this.DBCached && this.CacheIns != nil {
this.Cache(table+"*", nil)
}
}
//return 0
return rows
}
//插入新数据
func (this *HoTimeDB) Insert(table string, data map[string]interface{}) int64 {
values := make([]interface{}, 0)
queryString := " ("
valueString := " ("
lens := len(data)
tempLen := 0
for k, v := range data {
tempLen++
values = append(values, v)
if tempLen < lens {
queryString += "`" + k + "`,"
valueString += "?,"
} else {
queryString += "`" + k + "`) "
valueString += "?);"
}
}
query := "INSERT INTO " + table + queryString + "VALUES" + valueString
res, err := this.Exec(query, values...)
id := int64(0)
if err.GetError() == nil && res != nil {
id, this.LastErr.err = res.LastInsertId()
}
//如果插入成功,删除缓存
if id != 0 {
if this.DBCached && this.CacheIns != nil {
this.Cache(table+"*", nil)
}
}
//fmt.Println(id)
return id
}
+25
View File
@@ -0,0 +1,25 @@
package hotime
//框架层处理错误
type Error struct {
error
err error
}
func (this *Error) GetError() error {
return this.error
}
func (this *Error) SetError(err error, loglevel ...int) {
this.error = nil
if err == nil {
this.error = err
this.err = err
return
}
this.error = err
return
}
+382
View File
@@ -0,0 +1,382 @@
package hotime
import (
"crypto/md5"
"encoding/hex"
"fmt"
"math"
"os"
"path/filepath"
"runtime"
"strings"
"time"
)
//安全锁
//func SafeMutex(tag int, f func() interface{}) interface{} {
//
// mutexer.Lock()
// if mutex[tag] == nil {
//
// mutex[tag] = &sync.RWMutex{}
//
// }
// mutexer.Unlock()
//
// mutex[tag].Lock()
// res := f()
// mutex[tag].Unlock()
// return res
//}
func LogError(logMsg interface{}) {
logFmt(fmt.Sprintln(logMsg), 2, LOG_ERROR)
}
func LogWarn(logMsg interface{}) {
logFmt(fmt.Sprintln(logMsg), 2, LOG_WARN)
}
func LogInfo(logMsg ...interface{}) {
logFmt(fmt.Sprintln(logMsg), 2, LOG_INFO)
}
//func LogFmt(logMsg interface{}, loglevel ...LOG_MODE) {
//
// logFmt(logMsg, 2, loglevel...)
//}
//日志打印以及存储到文件
func logFmt(logMsg interface{}, printLevel int, loglevel ...LOG_MODE) {
if Config.GetInt("logLevel") == int(LOG_NIL) {
return
}
lev := LOG_INFO
if len(loglevel) != 0 {
lev = loglevel[0]
}
gofile := ""
if Config.GetInt("debug") != 0 && printLevel != 0 {
_, file, line, ok := runtime.Caller(printLevel)
if ok {
gofile = " " + file + ":" + ObjToStr(line)
}
}
logStr := ""
if lev == LOG_INFO {
logStr = "info:"
}
if printLevel == 0 {
logStr = "connect:"
}
if lev == LOG_WARN {
logStr = "warn:"
}
if lev == LOG_ERROR {
logStr = "error:"
}
logStr = fmt.Sprintln(time.Now().Format("2006/01/02 15:04:05"), logStr, logMsg, gofile)
//打印日志
fmt.Print(logStr)
//不需要存储到文件
if Config.GetString("logFile") == "" {
return
}
//存储到文件
logFilePath := time.Now().Format(Config.GetString("logFile"))
os.MkdirAll(filepath.Dir(logFilePath), os.ModeAppend)
//os.Create(logFilePath)
f, err := os.OpenFile(logFilePath, os.O_APPEND|os.O_CREATE, 0644)
if err != nil {
return
}
f.Write([]byte(logStr))
f.Close()
}
//字符串首字符大写
func StrFirstToUpper(str string) string {
if len(str) == 0 {
return str
}
first := Substr(str, 0, 1)
other := Substr(str, 1, len(str)-1)
return strings.ToUpper(first) + other
}
//字符串截取
func Substr(str string, start int, length int) string {
rs := []rune(str)
rl := len(rs)
end := 0
if start < 0 {
start = rl - 1 + start
}
end = start + length
if start > end {
start, end = end, start
}
if start < 0 {
start = 0
}
if start > rl {
start = rl
}
if end < 0 {
end = 0
}
if end > rl {
end = rl
}
return string(rs[start:end])
}
//获取最后出现字符串的下标
//return 找不到返回 -1
func IndexLastStr(str, sep string) int {
sepSlice := []rune(sep)
strSlice := []rune(str)
if len(sepSlice) > len(strSlice) {
return -1
}
v := sepSlice[len(sepSlice)-1]
for i := len(strSlice) - 1; i >= 0; i-- {
vs := strSlice[i]
if v == vs {
j := len(sepSlice) - 2
for ; j >= 0; j-- {
vj := sepSlice[j]
vsj := strSlice[i-(len(sepSlice)-j-1)]
if vj != vsj {
break
}
}
if j < 0 {
return i - len(sepSlice) + 1
}
}
}
return -1
}
//md5
func Md5(req string) string {
md5Ctx := md5.New()
md5Ctx.Write([]byte(req))
cipherStr := md5Ctx.Sum(nil)
return hex.EncodeToString(cipherStr)
}
//随机数
func Rand(count int) int {
res := Random()
for i := 0; i < count; i++ {
res = res * 10
}
return ObjToInt(res)
}
func Random() float64 {
v := float64(0)
m := float64(0.1)
for i := 0; i < 15; i++ {
facter := map[int]int{4: 1, 9: 1, 2: 1, 3: 1, 1: 1, 7: 1, 0: 1, 5: 1, 6: 1, 8: 1}
for k, _ := range facter {
v = v + float64(k)*m
break
}
m = m * 0.1
}
return v
}
//随机数范围
func RandX(small int, max int) int {
res := 0
//随机对象
if small == max {
return small
}
for {
res = ObjToInt(Random() * float64(max+1))
if res >= small {
break
}
}
return res
}
//
////路由
//func Router(ctr CtrInterface) {
//
// str := reflect.ValueOf(ctr).Type().String()
// a := strings.IndexByte(str, '.')
//
// c := len(str) - len("Ctr") - 1
//
// app := Substr(str, 0, a) //属于哪个app
// ct := Substr(str, a+1, c-a) //属于哪个控制器
// var x = map[string]CtrInterface{}
// if _, ok := Proj[app]; ok {
// //存在APP
// x = Proj[app]
// } else {
// x = map[string]CtrInterface{}
// }
// x[ct] = ctr //将控制器存入APP
// // fmt.Println(c)
// Proj[app] = x //将APP存入测试
//}
//
//func RunMethodListener(test func(app []string)) {
// RunMethodListenerFunc = test
//}
//func SetDb(db *sql.DB) {
// db.SetMaxOpenConns(2000)
// db.SetMaxIdleConns(1000)
// db.Ping()
// SqlDB = &*db
// GetDb()
//}
//复制返回数组
func DeepCopyMap(value interface{}) interface{} {
if valueMap, ok := value.(Map); ok {
newMap := make(Map)
for k, v := range valueMap {
newMap[k] = DeepCopyMap(v)
}
return newMap
} else if valueSlice, ok := value.([]interface{}); ok {
newSlice := make([]interface{}, len(valueSlice))
for k, v := range valueSlice {
newSlice[k] = DeepCopyMap(v)
}
return newSlice
} else if valueMap, ok := value.(map[string]interface{}); ok {
newMap := make(map[string]interface{})
for k, v := range valueMap {
newMap[k] = DeepCopyMap(v)
}
return newMap
} else if valueSlice, ok := value.(Slice); ok {
newSlice := make(Slice, len(valueSlice))
for k, v := range valueSlice {
newSlice[k] = DeepCopyMap(v)
}
return newSlice
}
return value
}
////获取数据库
//func GetDb() (HoTimeDB, error) {
// Db.DB = &*SqlDB
// Db.Cached = true
// return Db, nil
//}
//初始化方法
//func Init() {
//
// http.HandleFunc("/", PublicCore.myHandler)
//
// InitCache()
// http.ListenAndServe(":"+Config["port"].(string), nil)
//}
////设置Config
//func SetCfg(tData Map) {
// for k, v := range tData {
// Config[k] = v
// }
//}
//浮点数四舍五入保留小数
func Round(f float64, n int) float64 {
pow10_n := math.Pow10(n)
return math.Trunc((f+0.5/pow10_n)*pow10_n) / pow10_n
}
//func InitDbCache(tim int64) {
// res := Db.Query("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='" + Config.GetString("dbName") + "' AND TABLE_NAME='cached'")
// if len(res) == 0 {
// Db.Exec("CREATE TABLE `cached` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `ckey` varchar(60) DEFAULT NULL, `cvalue` varchar(2000) DEFAULT NULL, `time` bigint(20) DEFAULT NULL, `endtime` int(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=198740 DEFAULT CHARSET=utf8")
// }
// cacheConfig := Config.GetMap("cacheConfig").GetObj("db").(CacheConfg)
// cacheConfig.Used = true
// if tim != 0 {
// cacheConfig.Time = tim
// }
// Config.GetMap("cacheConfig")["db"] = cacheConfig
//}
//
//func Cache(key interface{}, data ...interface{}) interface{} {
// cachePRI := Config["cachePRI"].([]string)
// var res interface{}
// for i := 0; i < len(cachePRI); i++ {
// if cachePRI[i] == "ridis" && Config["cacheConfig"].(Map)["ridis"].(CacheConfg).Used {
// res = CacheMemIns.Cache(ObjToStr(key), data...)
// }
// if cachePRI[i] == "db" && Config["cacheConfig"].(Map)["db"].(CacheConfg).Used {
// res = CacheDBIns.Cache(ObjToStr(key), data...)
// }
// if cachePRI[i] == "memory" && Config["cacheConfig"].(Map)["memory"].(CacheConfg).Used {
// res = CacheMemIns.Cache(ObjToStr(key), data...)
// }
// //将缓存送到前面的可缓存仓库去
// if res != nil {
// for j := 0; j < i; j++ {
// if cachePRI[j] == "ridis" && Config["cacheConfig"].(Map)["ridis"].(CacheConfg).Used {
// CacheMemIns.Cache(ObjToStr(key), res)
// }
// if cachePRI[j] == "db" && Config["cacheConfig"].(Map)["db"].(CacheConfg).Used {
// CacheDBIns.Cache(ObjToStr(key), res)
// }
// if cachePRI[j] == "memory" && Config["cacheConfig"].(Map)["memory"].(CacheConfg).Used {
// CacheMemIns.Cache(ObjToStr(key), res)
// }
//
// }
// break
// }
//
// }
// return res
//}
//func InitCache() {
// CacheMemIns.Init(Config["cacheConfig"].(Map)["memory"].(CacheConfg).Time)
// CacheDBIns.Init(Config["cacheConfig"].(Map)["db"].(CacheConfg).Time)
//}
+155
View File
@@ -0,0 +1,155 @@
package hotime
import (
"encoding/json"
"errors"
"reflect"
)
//hotime的常用map
type Map map[string]interface{}
//获取string
func (this Map) GetString(key string, err ...*Error) string {
if len(err) != 0 {
err[0].SetError(nil)
}
return ObjToStr((this)[key])
}
func (this *Map) Pointer() *Map {
return this
}
//增加接口
func (this Map) Put(key string, value interface{}) {
//if this==nil{
// this=Map{}
//}
this[key] = value
}
//删除接口
func (this Map) Delete(key string) {
delete(this, key)
}
//获取Int
func (this Map) GetInt(key string, err ...*Error) int {
v := ObjToInt((this)[key], err...)
return v
}
//获取Int
func (this Map) GetInt64(key string, err ...*Error) int64 {
v := ObjToInt64((this)[key], err...)
return v
}
//获取向上取整Int64
func (this Map) GetCeilInt64(key string, err ...*Error) int64 {
v := ObjToCeilInt64((this)[key], err...)
return v
}
//获取向上取整Int
func (this Map) GetCeilInt(key string, err ...*Error) int {
v := ObjToCeilInt((this)[key], err...)
return v
}
//获取向上取整float64
func (this Map) GetCeilFloat64(key string, err ...*Error) float64 {
v := ObjToCeilFloat64((this)[key], err...)
return v
}
//获取Float64
func (this Map) GetFloat64(key string, err ...*Error) float64 {
v := ObjToFloat64((this)[key], err...)
return v
}
func (this Map) GetSlice(key string, err ...*Error) Slice {
//var v Slice
v := ObjToSlice((this)[key], err...)
return v
}
func (this Map) GetMap(key string, err ...*Error) Map {
//var data Slice
v := ObjToMap((this)[key], err...)
return v
}
func (this Map) Get(key string, err ...*Error) interface{} {
if v, ok := (this)[key]; ok {
return v
}
e := errors.New("没有存储key及对应的数据")
if len(err) != 0 {
err[0].SetError(e)
}
return nil
}
//请传递指针过来
func (this Map) ToStruct(stct interface{}) {
data := reflect.ValueOf(stct).Elem()
for k, v := range this {
ks := StrFirstToUpper(k)
dkey := data.FieldByName(ks)
if !dkey.IsValid() {
continue
}
switch dkey.Type().String() {
case "int":
dkey.SetInt(this.GetInt64(k))
case "int64":
dkey.Set(reflect.ValueOf(this.GetInt64(k)))
case "float64":
dkey.Set(reflect.ValueOf(this.GetFloat64(k)))
case "string":
dkey.Set(reflect.ValueOf(this.GetString(k)))
case "interface{}":
dkey.Set(reflect.ValueOf(v))
}
}
}
func (this Map) ToJsonString() string {
return ObjToStr(this)
}
func (this Map) JsonToMap(jsonStr string, err ...*Error) {
e := json.Unmarshal([]byte(jsonStr), &this)
if e != nil && len(err) != 0 {
err[0].SetError(e)
}
}
+543
View File
@@ -0,0 +1,543 @@
package hotime
var MimeMaps = map[string]string{
".3dm": "x-world/x-3dmf",
".3dmf": "x-world/x-3dmf",
".7z": "application/x-7z-compressed",
".a": "application/octet-stream",
".aab": "application/x-authorware-bin",
".aam": "application/x-authorware-map",
".aas": "application/x-authorware-seg",
".abc": "text/vndabc",
".ace": "application/x-ace-compressed",
".acgi": "text/html",
".m3u8": "audio/mpegurl",
".afl": "video/animaflex",
".ai": "application/postscript",
".aif": "audio/aiff",
".aifc": "audio/aiff",
".aiff": "audio/aiff",
".aim": "application/x-aim",
".aip": "text/x-audiosoft-intra",
".alz": "application/x-alz-compressed",
".ani": "application/x-navi-animation",
".aos": "application/x-nokia-9000-communicator-add-on-software",
".aps": "application/mime",
".apk": "application/vnd.android.package-archive",
".arc": "application/x-arc-compressed",
".arj": "application/arj",
".art": "image/x-jg",
".asf": "video/x-ms-asf",
".asm": "text/x-asm",
".asp": "text/asp",
".asx": "application/x-mplayer2",
".au": "audio/basic",
".avi": "video/x-msvideo",
".avs": "video/avs-video",
".bcpio": "application/x-bcpio",
".bin": "application/mac-binary",
".bmp": "image/bmp",
".boo": "application/book",
".book": "application/book",
".boz": "application/x-bzip2",
".bsh": "application/x-bsh",
".bz2": "application/x-bzip2",
".bz": "application/x-bzip",
".c++": "text/plain",
".c": "text/x-c",
".cab": "application/vnd.ms-cab-compressed",
".cat": "application/vndms-pkiseccat",
".cc": "text/x-c",
".ccad": "application/clariscad",
".cco": "application/x-cocoa",
".cdf": "application/cdf",
".cer": "application/pkix-cert",
".cha": "application/x-chat",
".chat": "application/x-chat",
".chrt": "application/vnd.kde.kchart",
".class": "application/java",
".com": "text/plain",
".conf": "text/plain",
".cpio": "application/x-cpio",
".cpp": "text/x-c",
".cpt": "application/mac-compactpro",
".crl": "application/pkcs-crl",
".crt": "application/pkix-cert",
".crx": "application/x-chrome-extension",
".csh": "text/x-scriptcsh",
".css": "text/css;charset=utf-8",
".csv": "text/csv",
".cxx": "text/plain",
".dar": "application/x-dar",
".dcr": "application/x-director",
".deb": "application/x-debian-package",
".deepv": "application/x-deepv",
".def": "text/plain",
".der": "application/x-x509-ca-cert",
".dif": "video/x-dv",
".dir": "application/x-director",
".divx": "video/divx",
".dl": "video/dl",
".dmg": "application/x-apple-diskimage",
".doc": "application/msword",
".dot": "application/msword",
".dp": "application/commonground",
".drw": "application/drafting",
".dump": "application/octet-stream",
".dv": "video/x-dv",
".dvi": "application/x-dvi",
".dwf": "drawing/x-dwf=(old)",
".dwg": "application/acad",
".dxf": "application/dxf",
".dxr": "application/x-director",
".el": "text/x-scriptelisp",
".elc": "application/x-bytecodeelisp=(compiled=elisp)",
".eml": "message/rfc822",
".env": "application/x-envoy",
".eps": "application/postscript",
".es": "application/x-esrehber",
".etx": "text/x-setext",
".evy": "application/envoy",
".exe": "application/octet-stream",
".f77": "text/x-fortran",
".f90": "text/x-fortran",
".f": "text/x-fortran",
".fdf": "application/vndfdf",
".fif": "application/fractals",
".fli": "video/fli",
".flo": "image/florian",
".flv": "video/x-flv",
".flx": "text/vndfmiflexstor",
".fmf": "video/x-atomic3d-feature",
".for": "text/x-fortran",
".fpx": "image/vndfpx",
".frl": "application/freeloader",
".funk": "audio/make",
".g3": "image/g3fax",
".g": "text/plain",
".gif": "image/gif",
".gl": "video/gl",
".gsd": "audio/x-gsm",
".gsm": "audio/x-gsm",
".gsp": "application/x-gsp",
".gss": "application/x-gss",
".gtar": "application/x-gtar",
".gz": "application/x-compressed",
".gzip": "application/x-gzip",
".h": "text/x-h",
".hdf": "application/x-hdf",
".help": "application/x-helpfile",
".hgl": "application/vndhp-hpgl",
".hh": "text/x-h",
".hlb": "text/x-script",
".hlp": "application/hlp",
".hpg": "application/vndhp-hpgl",
".hpgl": "application/vndhp-hpgl",
".hqx": "application/binhex",
".hta": "application/hta",
".htc": "text/x-component",
".htm": "text/html;charset=utf-8",
".html": "text/html;charset=utf-8",
".htmls": "text/html",
".htt": "text/webviewhtml",
".htx": "text/html",
".ice": "x-conference/x-cooltalk",
".ico": "image/x-icon",
".ics": "text/calendar",
".icz": "text/calendar",
".idc": "text/plain",
".ief": "image/ief",
".iefs": "image/ief",
".iges": "application/iges",
".igs": "application/iges",
".ima": "application/x-ima",
".imap": "application/x-httpd-imap",
".inf": "application/inf",
".ins": "application/x-internett-signup",
".ip": "application/x-ip2",
".isu": "video/x-isvideo",
".it": "audio/it",
".iv": "application/x-inventor",
".ivr": "i-world/i-vrml",
".ivy": "application/x-livescreen",
".jam": "audio/x-jam",
".jav": "text/x-java-source",
".java": "text/x-java-source",
".jcm": "application/x-java-commerce",
".jfif-tbnl": "image/jpeg",
".jfif": "image/jpeg",
".jnlp": "application/x-java-jnlp-file",
".jpe": "image/jpeg",
".jpeg": "image/jpeg",
".jpg": "image/jpeg",
".jps": "image/x-jps",
".js": "application/javascript;charset=utf-8",
".json": "application/json",
".jut": "image/jutvision",
".kar": "audio/midi",
".karbon": "application/vnd.kde.karbon",
".kfo": "application/vnd.kde.kformula",
".flw": "application/vnd.kde.kivio",
".kml": "application/vnd.google-earth.kml+xml",
".kmz": "application/vnd.google-earth.kmz",
".kon": "application/vnd.kde.kontour",
".kpr": "application/vnd.kde.kpresenter",
".kpt": "application/vnd.kde.kpresenter",
".ksp": "application/vnd.kde.kspread",
".kwd": "application/vnd.kde.kword",
".kwt": "application/vnd.kde.kword",
".ksh": "text/x-scriptksh",
".la": "audio/nspaudio",
".lam": "audio/x-liveaudio",
".latex": "application/x-latex",
".lha": "application/lha",
".lhx": "application/octet-stream",
".list": "text/plain",
".lma": "audio/nspaudio",
".log": "text/plain",
".lsp": "text/x-scriptlisp",
".lst": "text/plain",
".lsx": "text/x-la-asf",
".ltx": "application/x-latex",
".lzh": "application/octet-stream",
".lzx": "application/lzx",
".m1v": "video/mpeg",
".m2a": "audio/mpeg",
".m2v": "video/mpeg",
".m3u": "audio/x-mpegurl",
".m": "text/x-m",
".man": "application/x-troff-man",
".manifest": "text/cache-manifest",
".map": "application/x-navimap",
".mar": "text/plain",
".mbd": "application/mbedlet",
".mc$": "application/x-magic-cap-package-10",
".mcd": "application/mcad",
".mcf": "text/mcf",
".mcp": "application/netmc",
".me": "application/x-troff-me",
".mht": "message/rfc822",
".mhtml": "message/rfc822",
".mid": "application/x-midi",
".midi": "application/x-midi",
".mif": "application/x-frame",
".mime": "message/rfc822",
".mjf": "audio/x-vndaudioexplosionmjuicemediafile",
".mjpg": "video/x-motion-jpeg",
".mm": "application/base64",
".mme": "application/base64",
".mod": "audio/mod",
".moov": "video/quicktime",
".mov": "video/quicktime",
".movie": "video/x-sgi-movie",
".mp2": "audio/mpeg",
".mp3": "audio/mpeg3",
".mp4": "video/mp4",
".mpa": "audio/mpeg",
".mpc": "application/x-project",
".mpe": "video/mpeg",
".mpeg": "video/mpeg",
".mpg": "video/mpeg",
".mpga": "audio/mpeg",
".mpp": "application/vndms-project",
".mpt": "application/x-project",
".mpv": "application/x-project",
".mpx": "application/x-project",
".mrc": "application/marc",
".ms": "application/x-troff-ms",
".mv": "video/x-sgi-movie",
".my": "audio/make",
".mzz": "application/x-vndaudioexplosionmzz",
".nap": "image/naplps",
".naplps": "image/naplps",
".nc": "application/x-netcdf",
".ncm": "application/vndnokiaconfiguration-message",
".nif": "image/x-niff",
".niff": "image/x-niff",
".nix": "application/x-mix-transfer",
".nsc": "application/x-conference",
".nvd": "application/x-navidoc",
".o": "application/octet-stream",
".oda": "application/oda",
".odb": "application/vnd.oasis.opendocument.database",
".odc": "application/vnd.oasis.opendocument.chart",
".odf": "application/vnd.oasis.opendocument.formula",
".odg": "application/vnd.oasis.opendocument.graphics",
".odi": "application/vnd.oasis.opendocument.image",
".odm": "application/vnd.oasis.opendocument.text-master",
".odp": "application/vnd.oasis.opendocument.presentation",
".ods": "application/vnd.oasis.opendocument.spreadsheet",
".odt": "application/vnd.oasis.opendocument.text",
".oga": "audio/ogg",
".ogg": "audio/ogg",
".ogv": "video/ogg",
".omc": "application/x-omc",
".omcd": "application/x-omcdatamaker",
".omcr": "application/x-omcregerator",
".otc": "application/vnd.oasis.opendocument.chart-template",
".otf": "application/vnd.oasis.opendocument.formula-template",
".otg": "application/vnd.oasis.opendocument.graphics-template",
".oth": "application/vnd.oasis.opendocument.text-web",
".oti": "application/vnd.oasis.opendocument.image-template",
".otm": "application/vnd.oasis.opendocument.text-master",
".otp": "application/vnd.oasis.opendocument.presentation-template",
".ots": "application/vnd.oasis.opendocument.spreadsheet-template",
".ott": "application/vnd.oasis.opendocument.text-template",
".p10": "application/pkcs10",
".p12": "application/pkcs-12",
".p7a": "application/x-pkcs7-signature",
".p7c": "application/pkcs7-mime",
".p7m": "application/pkcs7-mime",
".p7r": "application/x-pkcs7-certreqresp",
".p7s": "application/pkcs7-signature",
".p": "text/x-pascal",
".part": "application/pro_eng",
".pas": "text/pascal",
".pbm": "image/x-portable-bitmap",
".pcl": "application/vndhp-pcl",
".pct": "image/x-pict",
".pcx": "image/x-pcx",
".pdb": "chemical/x-pdb",
".pdf": "application/pdf",
".pfunk": "audio/make",
".pgm": "image/x-portable-graymap",
".pic": "image/pict",
".pict": "image/pict",
".pkg": "application/x-newton-compatible-pkg",
".pko": "application/vndms-pkipko",
".pl": "text/x-scriptperl",
".plx": "application/x-pixclscript",
".pm4": "application/x-pagemaker",
".pm5": "application/x-pagemaker",
".pm": "text/x-scriptperl-module",
".png": "image/png",
".pnm": "application/x-portable-anymap",
".pot": "application/mspowerpoint",
".pov": "model/x-pov",
".ppa": "application/vndms-powerpoint",
".ppm": "image/x-portable-pixmap",
".pps": "application/mspowerpoint",
".ppt": "application/mspowerpoint",
".ppz": "application/mspowerpoint",
".pre": "application/x-freelance",
".prt": "application/pro_eng",
".ps": "application/postscript",
".psd": "application/octet-stream",
".pvu": "paleovu/x-pv",
".pwz": "application/vndms-powerpoint",
".py": "text/x-scriptphyton",
".pyc": "applicaiton/x-bytecodepython",
".qcp": "audio/vndqcelp",
".qd3": "x-world/x-3dmf",
".qd3d": "x-world/x-3dmf",
".qif": "image/x-quicktime",
".qt": "video/quicktime",
".qtc": "video/x-qtc",
".qti": "image/x-quicktime",
".qtif": "image/x-quicktime",
".ra": "audio/x-pn-realaudio",
".ram": "audio/x-pn-realaudio",
".rar": "application/x-rar-compressed",
".ras": "application/x-cmu-raster",
".rast": "image/cmu-raster",
".rexx": "text/x-scriptrexx",
".rf": "image/vndrn-realflash",
".rgb": "image/x-rgb",
".rm": "application/vndrn-realmedia",
".rmi": "audio/mid",
".rmm": "audio/x-pn-realaudio",
".rmp": "audio/x-pn-realaudio",
".rng": "application/ringing-tones",
".rnx": "application/vndrn-realplayer",
".roff": "application/x-troff",
".rp": "image/vndrn-realpix",
".rpm": "audio/x-pn-realaudio-plugin",
".rt": "text/vndrn-realtext",
".rtf": "text/richtext",
".rtx": "text/richtext",
".rv": "video/vndrn-realvideo",
".s": "text/x-asm",
".s3m": "audio/s3m",
".s7z": "application/x-7z-compressed",
".saveme": "application/octet-stream",
".sbk": "application/x-tbook",
".scm": "text/x-scriptscheme",
".sdml": "text/plain",
".sdp": "application/sdp",
".sdr": "application/sounder",
".sea": "application/sea",
".set": "application/set",
".sgm": "text/x-sgml",
".sgml": "text/x-sgml",
".sh": "text/x-scriptsh",
".shar": "application/x-bsh",
".shtml": "text/x-server-parsed-html",
".sid": "audio/x-psid",
".skd": "application/x-koan",
".skm": "application/x-koan",
".skp": "application/x-koan",
".skt": "application/x-koan",
".sit": "application/x-stuffit",
".sitx": "application/x-stuffitx",
".sl": "application/x-seelogo",
".smi": "application/smil",
".smil": "application/smil",
".snd": "audio/basic",
".sol": "application/solids",
".spc": "text/x-speech",
".spl": "application/futuresplash",
".spr": "application/x-sprite",
".sprite": "application/x-sprite",
".spx": "audio/ogg",
".src": "application/x-wais-source",
".ssi": "text/x-server-parsed-html",
".ssm": "application/streamingmedia",
".sst": "application/vndms-pkicertstore",
".step": "application/step",
".stl": "application/sla",
".stp": "application/step",
".sv4cpio": "application/x-sv4cpio",
".sv4crc": "application/x-sv4crc",
".svf": "image/vnddwg",
".svg": "image/svg+xml",
".svr": "application/x-world",
".swf": "application/x-shockwave-flash",
".t": "application/x-troff",
".talk": "text/x-speech",
".tar": "application/x-tar",
".tbk": "application/toolbook",
".tcl": "text/x-scripttcl",
".tcsh": "text/x-scripttcsh",
".tex": "application/x-tex",
".texi": "application/x-texinfo",
".texinfo": "application/x-texinfo",
".text": "text/plain",
".tgz": "application/gnutar",
".tif": "image/tiff",
".tiff": "image/tiff",
".tr": "application/x-troff",
".tsi": "audio/tsp-audio",
".tsp": "application/dsptype",
".tsv": "text/tab-separated-values",
".turbot": "image/florian",
".txt": "text/plain",
".uil": "text/x-uil",
".uni": "text/uri-list",
".unis": "text/uri-list",
".unv": "application/i-deas",
".uri": "text/uri-list",
".uris": "text/uri-list",
".ustar": "application/x-ustar",
".uu": "text/x-uuencode",
".uue": "text/x-uuencode",
".vcd": "application/x-cdlink",
".vcf": "text/x-vcard",
".vcard": "text/x-vcard",
".vcs": "text/x-vcalendar",
".vda": "application/vda",
".vdo": "video/vdo",
".vew": "application/groupwise",
".viv": "video/vivo",
".vivo": "video/vivo",
".vmd": "application/vocaltec-media-desc",
".vmf": "application/vocaltec-media-file",
".voc": "audio/voc",
".vos": "video/vosaic",
".vox": "audio/voxware",
".vqe": "audio/x-twinvq-plugin",
".vqf": "audio/x-twinvq",
".vql": "audio/x-twinvq-plugin",
".vrml": "application/x-vrml",
".vrt": "x-world/x-vrt",
".vsd": "application/x-visio",
".vst": "application/x-visio",
".vsw": "application/x-visio",
".w60": "application/wordperfect60",
".w61": "application/wordperfect61",
".w6w": "application/msword",
".wav": "audio/wav",
".wb1": "application/x-qpro",
".wbmp": "image/vnd.wap.wbmp",
".web": "application/vndxara",
".wiz": "application/msword",
".wk1": "application/x-123",
".wmf": "windows/metafile",
".wml": "text/vnd.wap.wml",
".wmlc": "application/vnd.wap.wmlc",
".wmls": "text/vnd.wap.wmlscript",
".wmlsc": "application/vnd.wap.wmlscriptc",
".word": "application/msword",
".wp5": "application/wordperfect",
".wp6": "application/wordperfect",
".wp": "application/wordperfect",
".wpd": "application/wordperfect",
".wq1": "application/x-lotus",
".wri": "application/mswrite",
".wrl": "application/x-world",
".wrz": "model/vrml",
".wsc": "text/scriplet",
".wsrc": "application/x-wais-source",
".wtk": "application/x-wintalk",
".x-png": "image/png",
".xbm": "image/x-xbitmap",
".xdr": "video/x-amt-demorun",
".xgz": "xgl/drawing",
".xif": "image/vndxiff",
".xl": "application/excel",
".xla": "application/excel",
".xlb": "application/excel",
".xlc": "application/excel",
".xld": "application/excel",
".xlk": "application/excel",
".xll": "application/excel",
".xlm": "application/excel",
".xls": "application/excel",
".xlt": "application/excel",
".xlv": "application/excel",
".xlw": "application/excel",
".xm": "audio/xm",
".xml": "text/xml",
".xmz": "xgl/movie",
".xpix": "application/x-vndls-xpix",
".xpm": "image/x-xpixmap",
".xsr": "video/x-amt-showrun",
".xwd": "image/x-xwd",
".xyz": "chemical/x-pdb",
".z": "application/x-compress",
".zip": "application/zip",
".zoo": "application/octet-stream",
".zsh": "text/x-scriptzsh",
".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
".docm": "application/vnd.ms-word.document.macroEnabled.12",
".dotx": "application/vnd.openxmlformats-officedocument.wordprocessingml.template",
".dotm": "application/vnd.ms-word.template.macroEnabled.12",
".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
".xlsm": "application/vnd.ms-excel.sheet.macroEnabled.12",
".xltx": "application/vnd.openxmlformats-officedocument.spreadsheetml.template",
".xltm": "application/vnd.ms-excel.template.macroEnabled.12",
".xlsb": "application/vnd.ms-excel.sheet.binary.macroEnabled.12",
".xlam": "application/vnd.ms-excel.addin.macroEnabled.12",
".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
".pptm": "application/vnd.ms-powerpoint.presentation.macroEnabled.12",
".ppsx": "application/vnd.openxmlformats-officedocument.presentationml.slideshow",
".ppsm": "application/vnd.ms-powerpoint.slideshow.macroEnabled.12",
".potx": "application/vnd.openxmlformats-officedocument.presentationml.template",
".potm": "application/vnd.ms-powerpoint.template.macroEnabled.12",
".ppam": "application/vnd.ms-powerpoint.addin.macroEnabled.12",
".sldx": "application/vnd.openxmlformats-officedocument.presentationml.slide",
".sldm": "application/vnd.ms-powerpoint.slide.macroEnabled.12",
".thmx": "application/vnd.ms-officetheme",
".onetoc": "application/onenote",
".onetoc2": "application/onenote",
".onetmp": "application/onenote",
".onepkg": "application/onenote",
".key": "application/x-iwork-keynote-sffkey",
".kth": "application/x-iwork-keynote-sffkth",
".nmbtemplate": "application/x-iwork-numbers-sfftemplate",
".numbers": "application/x-iwork-numbers-sffnumbers",
".pages": "application/x-iwork-pages-sffpages",
".template": "application/x-iwork-pages-sfftemplate",
".xpi": "application/x-xpinstall",
".oex": "application/x-opera-extension",
".mustache": "text/html",
}
+93
View File
@@ -0,0 +1,93 @@
package hotime
//对象封装方便取用
type Obj struct {
Data interface{}
contextBase
}
func (this *Obj) Put(data interface{}) {
this.Data = data
}
func (this *Obj) ToInt(err ...Error) int {
if len(err) != 0 {
this.Error = err[0]
}
return ObjToInt(this.Data, &this.Error)
}
func (this *Obj) ToInt64(err ...Error) int64 {
if len(err) != 0 {
this.Error = err[0]
}
return ObjToInt64(this.Data, &this.Error)
}
func (this *Obj) ToFloat64(err ...Error) float64 {
if len(err) != 0 {
this.Error = err[0]
}
return ObjToFloat64(this.Data, &this.Error)
}
//获取向上取整float64
func (this *Obj) ToCeilFloat64(err ...*Error) float64 {
if len(err) != 0 {
this.Error = *err[0]
}
v := ObjToCeilFloat64(this.Data, err...)
return v
}
func (this *Obj) ToStr() string {
return ObjToStr(this.Data)
}
func (this *Obj) ToMap(err ...Error) Map {
if len(err) != 0 {
this.Error = err[0]
}
return ObjToMap(this.Data, &this.Error)
}
func (this *Obj) ToSlice(err ...Error) Slice {
if len(err) != 0 {
this.Error = err[0]
}
return ObjToSlice(this.Data, &this.Error)
}
func (this *Obj) ToMapArray(err ...Error) []Map {
if len(err) != 0 {
this.Error = err[0]
}
return ObjToMapArray(this.Data, &this.Error)
}
func (this *Obj) ToObj() interface{} {
return this.Data
}
//获取向上取整Int64
func (this *Obj) ToCeilInt64(err ...*Error) int64 {
if len(err) != 0 {
this.Error = *err[0]
}
v := ObjToCeilInt64(this.Data, err...)
return v
}
//获取向上取整Int
func (this *Obj) ToCeilInt(err ...*Error) int {
if len(err) != 0 {
this.Error = *err[0]
}
v := ObjToCeilInt(this.Data, err...)
return v
}
+294
View File
@@ -0,0 +1,294 @@
package hotime
import (
"encoding/json"
"errors"
"math"
"strconv"
)
//仅限于hotime.Slice
func ObjToMap(obj interface{}, e ...*Error) Map {
var err error
var v Map
if obj == nil {
v = nil
err = errors.New("没有合适的转换对象!")
} else {
switch obj.(type) {
case Map:
v = obj.(Map)
case map[string]interface{}:
v = obj.(map[string]interface{})
case string:
v = Map{}
e := json.Unmarshal([]byte(obj.(string)), &v)
if e != nil {
err = errors.New("没有合适的转换对象!" + e.Error())
v = nil
}
default:
data, err := json.Marshal(obj)
if err != nil {
err = errors.New("没有合适的转换对象!" + err.Error())
v = nil
}
v = Map{}
e := json.Unmarshal(data, &v)
if e != nil {
err = errors.New("没有合适的转换对象!" + e.Error())
v = nil
}
}
}
if len(e) != 0 {
e[0].SetError(err)
}
return v
}
func ObjToMapArray(obj interface{}, e ...*Error) []Map {
s := ObjToSlice(obj, e...)
res := []Map{}
for i := 0; i < len(s); i++ {
res = append(res, s.GetMap(i))
}
return res
}
//仅限于hotime.Slice
func ObjToSlice(obj interface{}, e ...*Error) Slice {
var err error
var v Slice
if obj == nil {
v = nil
err = errors.New("没有合适的转换对象!")
} else {
switch obj.(type) {
case Slice:
v = obj.(Slice)
case []interface{}:
v = obj.([]interface{})
case []string:
v = Slice{}
for i := 0; i < len(obj.([]string)); i++ {
v = append(v, obj.([]string)[i])
}
case string:
v = Slice{}
err = json.Unmarshal([]byte(obj.(string)), &v)
default:
v = Slice{}
var data []byte
data, err = json.Marshal(obj)
err = json.Unmarshal(data, &v)
}
}
if len(e) != 0 {
e[0].SetError(err)
}
return v
}
func ObjToFloat64(obj interface{}, e ...*Error) float64 {
var err error
v := float64(0)
if obj == nil {
err = errors.New("没有合适的转换对象!")
} else {
switch obj.(type) {
case int:
v = float64(obj.(int))
case int64:
v = float64(obj.(int64))
case string:
value, e := strconv.ParseFloat(obj.(string), 64)
if e != nil {
v = float64(0)
err = e
} else {
v = value
}
case float64:
v = obj.(float64)
case float32:
v = float64(obj.(float32))
case uint8:
value, e := strconv.ParseFloat(obj.(string), 64)
if e != nil {
v = float64(0)
err = e
} else {
v = value
}
default:
v = float64(0)
err = errors.New("没有合适的转换对象!")
}
}
if len(e) != 0 {
e[0].SetError(err)
}
return v
}
//向上取整
func ObjToCeilInt64(obj interface{}, e ...*Error) int64 {
f := ObjToCeilFloat64(obj, e...)
return ObjToInt64(math.Ceil(f))
}
//向上取整
func ObjToCeilFloat64(obj interface{}, e ...*Error) float64 {
f := ObjToFloat64(obj, e...)
return math.Ceil(f)
}
//向上取整
func ObjToCeilInt(obj interface{}, e ...*Error) int {
f := ObjToCeilFloat64(obj, e...)
return ObjToInt(f)
}
func ObjToInt64(obj interface{}, e ...*Error) int64 {
var err error
v := int64(0)
if obj == nil {
err = errors.New("没有合适的转换对象!")
} else {
switch obj.(type) {
case int:
v = int64(obj.(int))
case int64:
v = obj.(int64)
case string:
value, e := StrToInt(obj.(string))
if e != nil {
v = int64(0)
err = e
} else {
v = int64(value)
}
case uint8:
value, e := StrToInt(obj.(string))
if e != nil {
v = int64(0)
err = e
} else {
v = int64(value)
}
case float64:
v = int64(obj.(float64))
case float32:
v = int64(obj.(float32))
default:
v = int64(0)
err = errors.New("没有合适的转换对象!")
}
}
if len(e) != 0 {
e[0].SetError(err)
}
return v
}
func ObjToInt(obj interface{}, e ...*Error) int {
v := ObjToInt64(obj, e...)
return int(v)
}
func ObjToStr(obj interface{}) string {
// fmt.Println(reflect.ValueOf(obj).Type().String() )
str := ""
if obj == nil {
return str
}
switch obj.(type) {
case int:
str = strconv.Itoa(obj.(int))
case uint8:
str = obj.(string)
case int64:
str = strconv.FormatInt(obj.(int64), 10)
case []byte:
str = string(obj.([]byte))
case string:
str = obj.(string)
case float64:
str = strconv.FormatFloat(obj.(float64), 'f', -1, 64)
default:
strbte, err := json.Marshal(obj)
if err == nil {
str = string(strbte)
}
}
return str
}
//转换为Map
func StrToMap(string string) Map {
data := Map{}
data.JsonToMap(string)
return data
}
//转换为Slice
func StrToSlice(string string) Slice {
data := ObjToSlice(string)
return data
}
//字符串数组: a1,a2,a3转["a1","a2","a3"]
func StrArrayToJsonStr(a string) string {
if len(a) > 2 {
if a[0] == ',' {
a = Substr(a, 1, len(a)-1)
}
if a[len(a)-1] == ',' {
a = Substr(a, 0, len(a)-1)
}
//a = strings.Replace(a, ",", `,`, -1)
a = `[` + a + `]`
} else {
a = "[]"
}
return a
}
//字符串数组: a1,a2,a3转["a1","a2","a3"]
func JsonStrToStrArray(a string) string {
//a = strings.Replace(a, `"`, "", -1)
if len(a) != 0 {
a = Substr(a, 1, len(a)-2)
}
return "," + a + ","
}
//字符串转int
func StrToInt(s string) (int, error) {
i, err := strconv.Atoi(s)
return i, err
}
+71
View File
@@ -0,0 +1,71 @@
package hotime
//session对象
type SessionIns struct {
ShortCache CacheIns
LongCache CacheIns
SessionId string
Map
contextBase
}
func (this *SessionIns) set() {
if this.ShortCache != nil {
this.ShortCache.Cache(HEAD_SESSION_ADD+this.SessionId, this.Map)
}
if this.LongCache != nil {
this.LongCache.Cache(HEAD_SESSION_ADD+this.SessionId, this.Map)
}
}
func (this *SessionIns) Session(key string, data ...interface{}) *Obj {
if this.Map == nil {
this.get()
}
if len(data) != 0 {
if data[0] == nil {
delete(this.Map, key)
this.set()
} else {
this.Map[key] = data[0]
this.set()
}
return &Obj{Data: nil}
}
return &Obj{Data: this.Map.Get(key)}
}
func (this *SessionIns) get() {
if this.ShortCache != nil {
this.Map = this.ShortCache.Cache(HEAD_SESSION_ADD + this.SessionId).ToMap()
if this.Map != nil {
return
}
}
if this.LongCache != nil {
this.Map = this.LongCache.Cache(HEAD_SESSION_ADD + this.SessionId).ToMap()
if this.Map != nil {
if this.ShortCache != nil {
this.ShortCache.Cache(HEAD_SESSION_ADD+this.SessionId, this.Map)
}
return
}
}
this.Map = Map{}
this.ShortCache.Cache(HEAD_SESSION_ADD+this.SessionId, this.Map)
return
}
func (this *SessionIns) Init(short CacheIns, long CacheIns) {
this.ShortCache = short
this.LongCache = long
}
+87
View File
@@ -0,0 +1,87 @@
package hotime
import (
"errors"
)
type Slice []interface{}
//获取string
func (this Slice) GetString(key int, err ...*Error) string {
if len(err) != 0 {
err[0].SetError(nil)
}
return ObjToStr((this)[key])
}
//获取Int
func (this Slice) GetInt(key int, err ...*Error) int {
v := ObjToInt((this)[key], err...)
return v
}
//获取Int
func (this Slice) GetInt64(key int, err ...*Error) int64 {
v := ObjToInt64((this)[key], err...)
return v
}
//获取向上取整Int64
func (this Slice) GetCeilInt64(key int, err ...*Error) int64 {
v := ObjToCeilInt64((this)[key], err...)
return v
}
//获取向上取整Int
func (this Slice) GetCeilInt(key int, err ...*Error) int {
v := ObjToCeilInt((this)[key], err...)
return v
}
//获取向上取整float64
func (this Slice) GetCeilFloat64(key int, err ...*Error) float64 {
v := ObjToCeilFloat64((this)[key], err...)
return v
}
//获取Float64
func (this Slice) GetFloat64(key int, err ...*Error) float64 {
v := ObjToFloat64((this)[key], err...)
return v
}
func (this Slice) GetSlice(key int, err ...*Error) Slice {
v := ObjToSlice((this)[key], err...)
return v
}
func (this Slice) GetMap(key int, err ...*Error) Map {
//var v Map
v := ObjToMap((this)[key], err...)
return v
}
func (this Slice) Get(key int, err ...*Error) interface{} {
if key < len(this) {
return this[key]
}
e := errors.New("没有存储key及对应的数据")
if len(err) != 0 {
err[0].SetError(e)
}
return nil
}
func (this Slice) Put(key int, value interface{}) {
this[key] = value
}
func (this Slice) ToJsonString() string {
return ObjToStr(this)
}
+18
View File
@@ -0,0 +1,18 @@
package db
import (
"code.hoteas.com/golang/hotime"
"code.hoteas.com/golang/hotime/tools/mysql"
"code.hoteas.com/golang/hotime/tools/sqlite"
"strings"
)
func SetDB(appIns *hotime.Application) {
if appIns.Config.GetString("dbType") == "sqlite" || strings.Index(appIns.Config.GetString("dbName"), ".db") == len(appIns.Config.GetString("dbName"))-3 {
appIns.Config["dbType"] = "sqlite"
sqlite.SetDB(appIns)
} else {
appIns.Config["dbType"] = "mysql"
mysql.SetDB(appIns)
}
}
+19
View File
@@ -0,0 +1,19 @@
package mysql
import (
"code.hoteas.com/golang/hotime"
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
func SetDB(appIns *hotime.Application) {
appIns.SetConnectDB(func(err ...*hotime.Error) *sql.DB {
query := appIns.Config.GetString("dbUser") + ":" + appIns.Config.GetString("dbPwd") +
"@tcp(" + appIns.Config.GetString("dbHost") + ":" + appIns.Config.GetString("dbPort") + ")/" + appIns.Config.GetString("dbName") + "?charset=utf8"
DB, e := sql.Open("mysql", query)
if e != nil && len(err) != 0 {
err[0].SetError(e)
}
return DB
})
}
+17
View File
@@ -0,0 +1,17 @@
package sqlite
import (
"code.hoteas.com/golang/hotime"
"database/sql"
_ "github.com/mattn/go-sqlite3"
)
func SetDB(appIns *hotime.Application) {
appIns.SetConnectDB(func(err ...*hotime.Error) *sql.DB {
db, e := sql.Open("sqlite3", appIns.Config.GetString("dbName"))
if e != nil && len(err) != 0 {
err[0].SetError(e)
}
return db
})
}
+21
View File
@@ -0,0 +1,21 @@
package hotime
//控制器
type Ctr map[string]Method
type Proj map[string]Ctr
type Router map[string]Proj
type MethodRouter map[string]Method //直接字符串关联函数
type Method func(this *Context)
type CacheIns interface {
//set(key string, value interface{}, time int64)
//get(key string) interface{}
//delete(key string)
Cache(key string, data ...interface{}) *Obj
}
//单条缓存数据
type cacheData struct {
time int64
data interface{}
}
+70
View File
@@ -0,0 +1,70 @@
package hotime
var IsRun = false //当前状态
var App = map[string]*Application{} //整个项目
//var Db = HoTimeDB{} //数据库实例
var Config = Map{
"debug": 1, //debug 0关闭1开启
"logLevel": LOG_FMT,
"dbHost": "127.0.0.1",
"dbName": "test",
"dbUser": "root",
"dbPwd": "root",
"dbPort": "3306",
"dbCached": 0, //0不开启缓存
"cacheShortTime": 60 * 60 * 2,
"cacheLongTime": 60 * 60 * 24 * 30,
"error": Map{
"1": "内部系统异常",
"2": "访问权限异常",
"3": "请求参数异常",
"4": "数据处理异常",
"5": "数据结果异常",
},
"tpt": "tpt",
"defFile": []string{"index.html", "index.htm"},
"modeRouterStrict": false, //路由严格模式/a/b/c
"port": "80",
"sessionName": "HOTIME",
"tlsPort": "0",
"tlsKey": "",
"tlsCert": "",
}
var ConfigNote = Map{
"logLevel": "日志等级,0关闭,1打印",
"logFile": "如果需要存储日志文件时使用,保存格式为:a/b/c/20060102150405.txt,将生成:a/b/c/年月日时分秒.txt,按需设置",
"debug": "是否开启debug模式,0关闭,其他开启,debug模式下日志展示更全", //debug 0关闭1开启
"dbHost": "数据库ip地址默认127.0.0.1",
"dbName": "数据库名称,sqlite为文件路径比如a/x.db",
"dbUser": "数据库用户名",
"dbPwd": "数据库密码",
"dbPort": "数据库端口",
"dbType": "如果需要使用自动数据库配置,请设置此项,手动配置数据库不需要,目前支持mysql,sqlite",
"dbCached": "是否开启数据库缓存0为关闭,其他开启", //0不开启缓存
"redisHost": "如果需要使用redis服务时配置,默认服务ip127.0.0.1",
"redisPort": "如果需要使用redis服务时配置,默认服务端口:6379",
"redisPwd": "如果需要使用redis服务时配置,默认服务密码:123456",
"cacheShortTime": "两级缓存,短缓存存储时间60 * 60 * 2,一般为内存缓存",
"cacheLongTime": "两级缓存,长缓存存储时间60 * 60 * 24 * 30,一般为数据库或者redis缓存",
"error": Map{
"1": "内部系统异常,在环境配置,文件访问权限等基础运行环境条件不足造成严重错误时使用",
"2": "访问权限异常,没有登录或者登录异常等时候使用",
"3": "请求参数异常,request参数不满足要求,比如参数不足,参数类型错误,参数不满足要求等时候使用",
"4": "数据处理异常,数据库操作或者三方请求返回的结果非正常结果,比如数据库突然中断等时候使用",
"5": "数据结果异常,一般用于无法给出response要求的格式要求下使用,比如response需要的是string格式但你只能提供int数据时",
"注释": "web服务内置错误提示,自定义异常建议10开始",
},
"tpt": "静态文件目录,默认为程序目录下tpt目录",
"defFile": "默认访问文件,默认访问index.html或者index.htm文件",
"crossDomain": "如果需要跨域设置,空字符串为不开启,*为开启所有网站允许跨域,http://www.baidu.com为指定域允许跨域", //是否开启跨域
"modeRouterStrict": "路由严格模式false,为大小写忽略必须匹配,true必须大小写匹配", //路由严格模式/a/b/c
"connectLogShow": "如果需要web访问链接、访问ip、访问时间打印,0为关闭其他数字开启此功能",
"sessionName": "设置session的cookie名默认HOTIME",
"port": "web服务开启Http端口,0为不启用http服务,默认80",
"tlsPort": "web服务https端口,0为不启用https服务",
"tlsKey": "https密钥",
"tlsCert": "https证书",
}