func (this *simpleOrm) DeleteByPk(entity interface{}, primary interface{}) (err error) { var sql string t := reflect.TypeOf(entity) if t.Kind() == reflect.Ptr { t = t.Elem() } /* build sql */ meta := this.getTableMapMeta(t) sql = fmt.Sprintf("DELETE FROM %s WHERE %s=?", meta.TableName, meta.PkFieldName, ) if this.useTrace { log.Println(fmt.Sprintf("[ ORM][ SQL]:%s , [ Params]:%s", sql, primary)) } /* query */ stmt, err := this.DB.Prepare(sql) if err != nil { return this.err(errors.New(fmt.Sprintf("[ ORM][ ERROR]:%s \n [ SQL]:%s", err.Error(), sql))) } defer stmt.Close() _, err = stmt.Exec(primary) if err != nil { return this.err(errors.New(err.Error() + "\n[ SQL]" + sql)) } return nil }
// 强制序列化为可用于HTML的JSON func MustHtmlJson(v interface{}) template.JS { d, err := json.Marshal(v) if err != nil { log.Println("[ Go2o][ Json] - ", err.Error()) } return template.JS(d) }
func (this *simpleOrm) GetByQuery(entity interface{}, sql string, args ...interface{}) error { var fieldLen int t := reflect.TypeOf(entity) if t.Kind() == reflect.Ptr { t = t.Elem() } val := reflect.ValueOf(entity) if val.Kind() != reflect.Ptr { return this.err(errors.New("Unaddressable of entity ,it must be a ptr")) } val = val.Elem() /* build sql */ meta := this.getTableMapMeta(t) fieldLen = len(meta.FieldsIndex) fieldArr := make([]string, fieldLen) var scanVal []interface{} = make([]interface{}, fieldLen) var rawBytes [][]byte = make([][]byte, fieldLen) for i, v := range meta.FieldMapNames { fieldArr[i] = this.unionField(meta, v) scanVal[i] = &rawBytes[i] } if strings.Index(sql, "*") != -1 { sql = strings.Replace(sql, "*", strings.Join(fieldArr, ","), 1) } if this.useTrace { log.Println(fmt.Sprintf("[ ORM][ SQL]:%s", sql)) } /* query */ stmt, err := this.DB.Prepare(sql) if err != nil { return this.err(errors.New(err.Error() + "\n[ SQL]:" + sql)) } defer stmt.Close() row := stmt.QueryRow(args...) err = row.Scan(scanVal...) if err != nil { return this.err(err) } for i := 0; i < fieldLen; i++ { field := val.Field(i) SetField(field, rawBytes[i]) } return nil }
func (this *simpleOrm) Get(primaryVal interface{}, entity interface{}) error { var sql string var fieldLen int t := reflect.TypeOf(entity) if t.Kind() == reflect.Ptr { t = t.Elem() } val := reflect.ValueOf(entity) if val.Kind() != reflect.Ptr { return this.err(errors.New("Unaddressable of entity ,it must be a ptr")) } val = val.Elem() /* build sql */ meta := this.getTableMapMeta(t) fieldLen = len(meta.FieldsIndex) fieldArr := make([]string, fieldLen) var scanVal []interface{} = make([]interface{}, fieldLen) var rawBytes [][]byte = make([][]byte, fieldLen) for i, v := range meta.FieldMapNames { fieldArr[i] = v scanVal[i] = &rawBytes[i] } sql = fmt.Sprintf("SELECT %s FROM %s WHERE %s=?", strings.Join(fieldArr, ","), meta.TableName, meta.PkFieldName, ) if this.useTrace { log.Println(fmt.Sprintf("[ ORM][ SQL]:%s , [ Params]:%+v", sql, primaryVal)) } /* query */ stmt, err := this.DB.Prepare(sql) if err != nil { return this.err(errors.New(err.Error() + "\n[ SQL]:" + sql)) return err } defer stmt.Close() row := stmt.QueryRow(primaryVal) err = row.Scan(scanVal...) if err != nil { return this.err(err) } for i := 0; i < fieldLen; i++ { field := val.Field(i) SetField(field, rawBytes[i]) } return nil }
func main() { app := &HttpApp{} // MVC路由表 routes := mvc.NewRoute(nil) // 注册控制器,test与/test/index中的test对应 routes.NormalRegister("test", testControllerGenerator) // 注册单例控制器 routes.Register("test_all", &testController{}) // 除了控制器,可以添加自定义的路由规则(正则表达式) routes.Add("^/[0-9]$", func(ctx *web.Context) { // 直接输出内容 ctx.Response.Write([]byte("数字路径")) return }) // 默认页路由 routes.Add("/", func(ctx *web.Context) { // sysName := ctx.App.Config().GetString("SYS_NAME") // ctx.ResponseWriter.Write([]byte("Hello," + sysName + "!")) // return // 使用模板 data := gof.TemplateDataMap{ "变量名": "变量值", } ctx.App.Template().Execute(ctx.Response, data, "template.html") return // 使用会话 ctx.Session().Set("user", "jarrysix") ctx.Session().Save() // 使用DB和ORM db := ctx.App.Db() orm := db.GetOrm() _ = orm.Version() }) // 使用一个拦截器,来拦截请求。 // 拦截器里可以决定,访问对应的路由表。 // 一个系统通常有多个子系统,每个子系统对应一个路由表。 var in = getInterceptor(app, routes) go http.ListenAndServe(":8080", in) log.Println("[ OK] - web is listening on port :8080.") var ch = make(chan int, 1) <-ch }
// 根据商城编号获取商户编号 func GetMchIdByShopId(shopId int) (mchId int) { key := "go2o:cache:mch-by-shop:" + strconv.Itoa(shopId) sto := GetKVS() var err error if mchId, err = sto.GetInt(key); err != nil || mchId <= 0 { mchId = dps.ShopService.GetMerchantId(shopId) if mchId > 0 { sto.SetExpire(key, mchId, DefaultMaxSeconds) } else { log.Println("[ Shop][ Exception] - shop", shopId, " no merchant bind!") } } return mchId }
func (this *simpleOrm) getTableMapMeta(t reflect.Type) *TableMapMeta { m, exists := this.tableMap[t.String()] if exists { return m } m = GetTableMapMeta(t) this.tableMap[t.String()] = m if this.useTrace { log.Println("[ ORM][ META]:", m) } return m }
func (this *simpleOrm) Delete(entity interface{}, where string, args ...interface{}) (effect int64, err error) { var sql string t := reflect.TypeOf(entity) if t.Kind() == reflect.Ptr { t = t.Elem() } /* build sql */ meta := this.getTableMapMeta(t) if where == "" { return 0, errors.New("Unknown condition") } sql = fmt.Sprintf("DELETE FROM %s WHERE %s", meta.TableName, where, ) if this.useTrace { log.Println(fmt.Sprintf("[ ORM][ SQL]:%s , [ Params]:%s", sql, args)) } /* query */ stmt, err := this.DB.Prepare(sql) if err != nil { return 0, this.err(errors.New(fmt.Sprintf("[ ORM][ ERROR]:%s [ SQL]:%s", err.Error(), sql))) } defer stmt.Close() result, err := stmt.Exec(args...) var rowNum int64 = 0 if err == nil { rowNum, err = result.RowsAffected() } if err != nil { return rowNum, this.err(errors.New(err.Error() + "\n[ SQL]" + sql)) } return rowNum, nil }
// 转出 func (this *personFinanceService) RiseTransferOut(personId int, transferWith personfinance.TransferWith, amount float32) (err error) { pf := this._rep.GetPersonFinance(personId) r := pf.GetRiseInfo() m := this._accRep.GetMember(personId) if m == nil { return member.ErrNoSuchMember } acc := m.GetAccount() if transferWith == personfinance.TransferOutWithBalance { //转入余额 if err = r.TransferOut(amount, transferWith, personfinance.RiseStateOk); err == nil { err = acc.ChargeBalance(member.TypeBalanceServiceCharge, "理财转出", domain.NewTradeNo(10000), amount) if err != nil { log.Println("[ TransferOut][ Error]:", err.Error()) } err = pf.SyncToAccount() } return err } if transferWith == personfinance.TransferOutWithBank { if b := m.Profile().GetBank(); !b.Right() || !b.Locked() { return member.ErrNoSuchBankInfo } if err = r.TransferOut(amount, transferWith, personfinance.RiseStateOk); err == nil { err = pf.SyncToAccount() } return err } return errors.New("暂时无法提供服务") }
func (this *simpleOrm) Save(primaryKey interface{}, entity interface{}) (rows int64, lastInsertId int64, err error) { var sql string //var condition string //var fieldLen int t := reflect.TypeOf(entity) if t.Kind() == reflect.Ptr { t = t.Elem() } val := reflect.Indirect(reflect.ValueOf(entity)) /* build sql */ meta := this.getTableMapMeta(t) //fieldLen = len(meta.FieldNames) params, fieldArr := ItrFieldForSave(meta, &val, false) //insert if primaryKey == nil { var pArr = make([]string, len(fieldArr)) for i := range pArr { pArr[i] = "?" } sql = fmt.Sprintf("INSERT INTO %s (%s) VALUES (%s)", meta.TableName, strings.Join(fieldArr, ","), strings.Join(pArr, ","), ) if this.useTrace { log.Println(fmt.Sprintf("[ ORM][ SQL]:%s , [ Params]:%+v", sql, params)) } /* query */ stmt, err := this.DB.Prepare(sql) if err != nil { return 0, 0, this.err(errors.New("[ ORM][ ERROR]:" + err.Error() + "\n[ SQL]" + sql)) } defer stmt.Close() result, err := stmt.Exec(params...) var rowNum int64 = 0 var lastInsertId int64 = 0 if err == nil { rowNum, err = result.RowsAffected() lastInsertId, _ = result.LastInsertId() return rowNum, lastInsertId, err } return rowNum, lastInsertId, this.err(errors.New(err.Error() + "\n[ SQL]" + sql)) } else { //update model var setCond string for i, k := range fieldArr { if i == 0 { setCond = fmt.Sprintf("%s = ?", k) } else { setCond = fmt.Sprintf("%s,%s = ?", setCond, k) } } sql = fmt.Sprintf("UPDATE %s SET %s WHERE %s=?", meta.TableName, setCond, meta.PkFieldName, ) /* query */ stmt, err := this.DB.Prepare(sql) if err != nil { return 0, 0, this.err(errors.New("[ ORM][ ERROR]:" + err.Error() + " [ SQL]" + sql)) } defer stmt.Close() params = append(params, primaryKey) if this.useTrace { log.Println(fmt.Sprintf("[ ORM][ SQL]:%s , [ Params]:%+v", sql, params)) } result, err := stmt.Exec(params...) var rowNum int64 = 0 if err == nil { rowNum, err = result.RowsAffected() return rowNum, 0, err } return rowNum, 0, this.err(errors.New(err.Error() + "\n[ SQL]" + sql)) } }
func (this *simpleOrm) err(err error) error { if this.useTrace && err != nil { log.Println("[ ORM][ ERROR]:", err.Error()) } return err }
// query rows func (this *simpleOrm) selectBy(to interface{}, sql string, fullSql bool, args ...interface{}) error { var fieldLen int var eleIsPtr bool // 元素是否为指针 toVal := reflect.Indirect(reflect.ValueOf(to)) toTyp := reflect.TypeOf(to).Elem() if toTyp.Kind() == reflect.Ptr { toTyp = toTyp.Elem() } if toTyp.Kind() != reflect.Slice { return this.err(errors.New("to must be slice")) } baseType := toTyp.Elem() if baseType.Kind() == reflect.Ptr { eleIsPtr = true baseType = baseType.Elem() } /* build sql */ meta := this.getTableMapMeta(baseType) fieldLen = len(meta.FieldMapNames) fieldArr := make([]string, fieldLen) var scanVal []interface{} = make([]interface{}, fieldLen) var rawBytes [][]byte = make([][]byte, fieldLen) for i, v := range meta.FieldMapNames { fieldArr[i] = this.unionField(meta, v) scanVal[i] = &rawBytes[i] } if fullSql { if strings.Index(sql, "*") != -1 { sql = strings.Replace(sql, "*", strings.Join(fieldArr, ","), 1) } } else { where := sql if len(where) == 0 { sql = fmt.Sprintf("SELECT %s FROM %s", strings.Join(fieldArr, ","), meta.TableName) } else { // 此时,sql为查询条件 sql = fmt.Sprintf("SELECT %s FROM %s WHERE %s", strings.Join(fieldArr, ","), meta.TableName, where) } } if this.useTrace { log.Println(fmt.Sprintf("[ ORM][ SQL]:%s [ Params] - %+v", sql, args)) } /* query */ stmt, err := this.DB.Prepare(sql) if err != nil { return this.err(errors.New(fmt.Sprintf("%s - [ SQL]: %s- [Args]:%+v", err.Error(), sql, args))) } defer stmt.Close() rows, err := stmt.Query(args...) if err != nil { return this.err(errors.New(err.Error() + "\n[ SQL]:" + sql)) } defer rows.Close() /* 用反射来对输出结果复制 */ toArr := toVal for rows.Next() { e := reflect.New(baseType) v := e.Elem() if err = rows.Scan(scanVal...); err != nil { break } for i, fi := range meta.FieldsIndex { SetField(v.Field(fi), rawBytes[i]) } if eleIsPtr { toArr = reflect.Append(toArr, e) } else { toArr = reflect.Append(toArr, v) } } toVal.Set(toArr) return this.err(err) }
func (this *simpleOrm) GetBy(entity interface{}, where string, args ...interface{}) error { var sql string var fieldLen int t := reflect.TypeOf(entity) if t.Kind() == reflect.Ptr { t = t.Elem() } val := reflect.ValueOf(entity) if val.Kind() != reflect.Ptr { return this.err(errors.New("unaddressable of entity ,it must be a ptr")) } if strings.Trim(where, "") == "" { return this.err(errors.New("param where can't be empty ")) } val = val.Elem() if !val.IsValid() { return this.err(errors.New("not validate or not initialize.")) } /* build sql */ meta := this.getTableMapMeta(t) fieldLen = len(meta.FieldsIndex) fieldArr := make([]string, fieldLen) var scanVal []interface{} = make([]interface{}, fieldLen) var rawBytes [][]byte = make([][]byte, fieldLen) for i, v := range meta.FieldMapNames { fieldArr[i] = v scanVal[i] = &rawBytes[i] } sql = fmt.Sprintf("SELECT %s FROM %s WHERE %s", strings.Join(fieldArr, ","), meta.TableName, where, ) if this.useTrace { log.Println(fmt.Sprintf("[ ORM][ SQL]:%s , [ Params]:%s - %+v", sql, where, args)) } /* query */ stmt, err := this.DB.Prepare(sql) if err != nil { if this.useTrace { log.Println("[ ORM][ ERROR]:", err.Error(), " [ SQL]:", sql) } return this.err(errors.New(err.Error() + "\n[ SQL]:" + sql)) } defer stmt.Close() row := stmt.QueryRow(args...) err = row.Scan(scanVal...) if err != nil { return this.err(err) } for i := 0; i < fieldLen; i++ { field := val.Field(i) SetField(field, rawBytes[i]) } return nil }