mirror of
https://gitee.com/johng/gf.git
synced 2024-11-30 03:07:45 +08:00
完成gmvc基本开发及测试
This commit is contained in:
parent
03109055c1
commit
aacb6abb9a
81
README.MD
81
README.MD
@ -20,7 +20,7 @@ import "gitee.com/johng/gf/g/xxx/xxx"
|
||||
│ │ └── gset 并发安全的集合
|
||||
│ │
|
||||
│ ├── database 【数据库操作】
|
||||
│ │ └── gdb MySQL、PostgreSQL的操作封装
|
||||
│ │ └── gdb 通用关系型数据库操作封装(目前仅支持MySQL、PostgreSQL)
|
||||
│ │
|
||||
│ ├── encoding 【数据编码】
|
||||
│ │ ├── gbase64 BASE64
|
||||
@ -34,10 +34,16 @@ import "gitee.com/johng/gf/g/xxx/xxx"
|
||||
│ │ ├── gsha1 SHA1
|
||||
│ │ └── gurl URL
|
||||
│ │
|
||||
│ ├── frame 【开发框架】
|
||||
│ │ ├── gconfig 通用配置管理
|
||||
│ │ ├── ginstance 单例对象管理
|
||||
│ │ └── gmvc MVC模式封装基类
|
||||
│ │
|
||||
│ ├── net 【网络通信】
|
||||
│ │ ├── ghttp HTTP客户端及服务端
|
||||
│ │ ├── gip IP操作
|
||||
│ │ ├── gipv4 IP操作
|
||||
│ │ ├── gscanner 端口扫描
|
||||
│ │ ├── gsession SESSION会话管理
|
||||
│ │ ├── gsmtp SMTP邮件管理
|
||||
│ │ ├── gtcp TCP服务端
|
||||
│ │ └── gudp UDP服务端
|
||||
@ -45,12 +51,14 @@ import "gitee.com/johng/gf/g/xxx/xxx"
|
||||
│ ├── os 【系统管理】
|
||||
│ │ ├── gcache 本地缓存管理
|
||||
│ │ ├── gconsole 命令行控制
|
||||
│ │ ├── genv 环境变量管理
|
||||
│ │ ├── gfile 文件管理
|
||||
│ │ ├── gfilepool 文件指针池
|
||||
│ │ ├── gfilespace 文件碎片管理
|
||||
│ │ ├── glog 日志管理
|
||||
│ │ ├── gmmap MMAP文件内存映射
|
||||
│ │ └── gtime 时间管理
|
||||
│ │ ├── gtime 时间管理
|
||||
│ │ └── gview 视图管理(通用的模板管理对象,独立于MVC模块)
|
||||
│ │
|
||||
│ └── util 【常用工具】
|
||||
│ ├── gpage 分页
|
||||
@ -65,3 +73,70 @@ import "gitee.com/johng/gf/g/xxx/xxx"
|
||||
## 配置
|
||||
1. 默认读取文件运行目录的config.json文件;
|
||||
1. 支持多配置文件管理,默认配置文件目录为当前运行目录;
|
||||
1. config.json配置文件说明:
|
||||
```json
|
||||
{
|
||||
"viewpath" : "视图文件存放路径",
|
||||
"database" : {
|
||||
"数据库分组名称" : [
|
||||
{
|
||||
"host" : "地址",
|
||||
"port" : "端口",
|
||||
"user" : "账号",
|
||||
"pass" : "密码",
|
||||
"name" : "数据库名称",
|
||||
"type" : "数据库类型(mysql|pgsql)",
|
||||
"role" : "数据库角色(master|slave)",
|
||||
"charset" : "字符编码",
|
||||
"priority" : "数据库优先级(负载均衡处理)"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
1. config.json示例文件:
|
||||
```json
|
||||
{
|
||||
"viewpath" : "/home/john/Workspace/Go/gitee.com/johng/gf/geg/frame/mvc/view",
|
||||
"database" : {
|
||||
"default" : [
|
||||
{
|
||||
"host" : "127.0.0.1",
|
||||
"port" : "3306",
|
||||
"user" : "root",
|
||||
"pass" : "123456",
|
||||
"name" : "test",
|
||||
"type" : "mysql",
|
||||
"role" : "master",
|
||||
"charset" : "utf8",
|
||||
"priority" : "100"
|
||||
},
|
||||
{
|
||||
"host" : "127.0.0.1",
|
||||
"port" : "3306",
|
||||
"user" : "root",
|
||||
"pass" : "123456",
|
||||
"name" : "test",
|
||||
"type" : "mysql",
|
||||
"role" : "slave",
|
||||
"charset" : "utf8",
|
||||
"priority" : "100"
|
||||
}
|
||||
],
|
||||
"ucenter" : [
|
||||
{
|
||||
"host" : "127.0.0.1",
|
||||
"port" : "3306",
|
||||
"user" : "root",
|
||||
"pass" : "123456",
|
||||
"name" : "ucenter",
|
||||
"type" : "mysql",
|
||||
"role" : "master",
|
||||
"charset" : "utf8",
|
||||
"priority" : "100"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -27,8 +27,8 @@ type Link interface {
|
||||
Exec(q string, args ...interface{}) (sql.Result, error)
|
||||
Prepare(q string) (*sql.Stmt, error)
|
||||
|
||||
GetAll(q string, args ...interface{}) (*List, error)
|
||||
GetOne(q string, args ...interface{}) (*Map, error)
|
||||
GetAll(q string, args ...interface{}) (List, error)
|
||||
GetOne(q string, args ...interface{}) (Map, error)
|
||||
GetValue(q string, args ...interface{}) (interface{}, error)
|
||||
|
||||
PingMaster() error
|
||||
@ -49,15 +49,15 @@ type Link interface {
|
||||
Commit() error
|
||||
Rollback() error
|
||||
|
||||
insert(table string, data *Map, option uint8) (sql.Result, error)
|
||||
Insert(table string, data *Map) (sql.Result, error)
|
||||
Replace(table string, data *Map) (sql.Result, error)
|
||||
Save(table string, data *Map) (sql.Result, error)
|
||||
insert(table string, data Map, option uint8) (sql.Result, error)
|
||||
Insert(table string, data Map) (sql.Result, error)
|
||||
Replace(table string, data Map) (sql.Result, error)
|
||||
Save(table string, data Map) (sql.Result, error)
|
||||
|
||||
batchInsert(table string, list *List, batch int, option uint8) error
|
||||
BatchInsert(table string, list *List, batch int) error
|
||||
BatchReplace(table string, list *List, batch int) error
|
||||
BatchSave(table string, list *List, batch int) error
|
||||
batchInsert(table string, list List, batch int, option uint8) error
|
||||
BatchInsert(table string, list List, batch int) error
|
||||
BatchReplace(table string, list List, batch int) error
|
||||
BatchSave(table string, list List, batch int) error
|
||||
|
||||
Update(table string, data interface{}, condition interface{}, args ...interface{}) (sql.Result, error)
|
||||
Delete(table string, condition interface{}, args ...interface{}) (sql.Result, error)
|
||||
@ -136,7 +136,6 @@ func NewByGroup(groupName string) (Link, error) {
|
||||
if len(masterList) < 1 {
|
||||
return nil, errors.New("at least one master node configuration's need to make sense")
|
||||
}
|
||||
fmt.Println(masterList)
|
||||
masterNode := getConfigNodeByPriority(&masterList)
|
||||
var slaveNode *ConfigNode
|
||||
if len(slaveList) > 0 {
|
||||
|
@ -67,7 +67,7 @@ func (l *dbLink) formatError(err error, q *string, args ...interface{}) error {
|
||||
|
||||
|
||||
// 数据库查询,获取查询结果集,以列表结构返回
|
||||
func (l *dbLink) GetAll(q string, args ...interface{}) (*List, error) {
|
||||
func (l *dbLink) GetAll(q string, args ...interface{}) (List, error) {
|
||||
// 执行sql
|
||||
rows, err := l.Query(q, args ...)
|
||||
if err != nil || rows == nil {
|
||||
@ -88,7 +88,7 @@ func (l *dbLink) GetAll(q string, args ...interface{}) (*List, error) {
|
||||
for rows.Next() {
|
||||
err = rows.Scan(scanArgs...)
|
||||
if err != nil {
|
||||
return &list, err
|
||||
return list, err
|
||||
}
|
||||
row := make(Map)
|
||||
for i, col := range values {
|
||||
@ -96,16 +96,16 @@ func (l *dbLink) GetAll(q string, args ...interface{}) (*List, error) {
|
||||
}
|
||||
list = append(list, row)
|
||||
}
|
||||
return &list, nil
|
||||
return list, nil
|
||||
}
|
||||
|
||||
// 数据库查询,获取查询结果集,以关联数组结构返回
|
||||
func (l *dbLink) GetOne(q string, args ...interface{}) (*Map, error) {
|
||||
func (l *dbLink) GetOne(q string, args ...interface{}) (Map, error) {
|
||||
list, err := l.GetAll(q, args ...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &(*list)[0], nil
|
||||
return list[0], nil
|
||||
}
|
||||
|
||||
// 数据库查询,获取查询字段值
|
||||
@ -114,7 +114,7 @@ func (l *dbLink) GetValue(q string, args ...interface{}) (interface{}, error) {
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
for _, v := range *one {
|
||||
for _, v := range one {
|
||||
return v, nil
|
||||
}
|
||||
return "", nil
|
||||
@ -194,11 +194,11 @@ func (l *dbLink) getInsertOperationByOption(option uint8) string {
|
||||
// 1: replace: 如果数据存在(主键或者唯一索引),那么删除后重新写入一条
|
||||
// 2: save: 如果数据存在(主键或者唯一索引),那么更新,否则写入一条新数据
|
||||
// 3: ignore: 如果数据存在(主键或者唯一索引),那么什么也不做
|
||||
func (l *dbLink) insert(table string, data *Map, option uint8) (sql.Result, error) {
|
||||
func (l *dbLink) insert(table string, data Map, option uint8) (sql.Result, error) {
|
||||
var keys []string
|
||||
var values []string
|
||||
var params []interface{}
|
||||
for k, v := range *data {
|
||||
for k, v := range data {
|
||||
keys = append(keys, l.charl + k + l.charr)
|
||||
values = append(values, "?")
|
||||
params = append(params, v)
|
||||
@ -207,7 +207,7 @@ func (l *dbLink) insert(table string, data *Map, option uint8) (sql.Result, erro
|
||||
updatestr := ""
|
||||
if option == OPTION_SAVE {
|
||||
var updates []string
|
||||
for k, _ := range *data {
|
||||
for k, _ := range data {
|
||||
updates = append(updates, fmt.Sprintf("%s%s%s=VALUES(%s)", l.charl, k, l.charr, k))
|
||||
}
|
||||
updatestr = fmt.Sprintf(" ON DUPLICATE KEY UPDATE %s", strings.Join(updates, ","))
|
||||
@ -219,33 +219,33 @@ func (l *dbLink) insert(table string, data *Map, option uint8) (sql.Result, erro
|
||||
}
|
||||
|
||||
// CURD操作:单条数据写入, 仅仅执行写入操作,如果存在冲突的主键或者唯一索引,那么报错返回
|
||||
func (l *dbLink) Insert(table string, data *Map) (sql.Result, error) {
|
||||
func (l *dbLink) Insert(table string, data Map) (sql.Result, error) {
|
||||
return l.link.insert(table, data, OPTION_INSERT)
|
||||
}
|
||||
|
||||
// CURD操作:单条数据写入, 如果数据存在(主键或者唯一索引),那么删除后重新写入一条
|
||||
func (l *dbLink) Replace(table string, data *Map) (sql.Result, error) {
|
||||
func (l *dbLink) Replace(table string, data Map) (sql.Result, error) {
|
||||
return l.link.insert(table, data, OPTION_REPLACE)
|
||||
}
|
||||
|
||||
// CURD操作:单条数据写入, 如果数据存在(主键或者唯一索引),那么更新,否则写入一条新数据
|
||||
func (l *dbLink) Save(table string, data *Map) (sql.Result, error) {
|
||||
func (l *dbLink) Save(table string, data Map) (sql.Result, error) {
|
||||
return l.link.insert(table, data, OPTION_SAVE)
|
||||
}
|
||||
|
||||
// 批量写入数据
|
||||
func (l *dbLink) batchInsert(table string, list *List, batch int, option uint8) error {
|
||||
func (l *dbLink) batchInsert(table string, list List, batch int, option uint8) error {
|
||||
var keys []string
|
||||
var values []string
|
||||
var bvalues []string
|
||||
var params []interface{}
|
||||
var size int = len(*list)
|
||||
var size int = len(list)
|
||||
// 判断长度
|
||||
if size < 1 {
|
||||
return errors.New("empty data list")
|
||||
}
|
||||
// 首先获取字段名称及记录长度
|
||||
for k, _ := range (*list)[0] {
|
||||
for k, _ := range list[0] {
|
||||
keys = append(keys, k)
|
||||
values = append(values, "?")
|
||||
}
|
||||
@ -263,7 +263,7 @@ func (l *dbLink) batchInsert(table string, list *List, batch int, option uint8)
|
||||
// 构造批量写入数据格式(注意map的遍历是无序的)
|
||||
for i := 0; i < size; i++ {
|
||||
for _, k := range keys {
|
||||
params = append(params, (*list)[i][k])
|
||||
params = append(params, list[i][k])
|
||||
}
|
||||
bvalues = append(bvalues, "(" + strings.Join(values, ",") + ")")
|
||||
if len(bvalues) == batch {
|
||||
@ -285,17 +285,17 @@ func (l *dbLink) batchInsert(table string, list *List, batch int, option uint8)
|
||||
}
|
||||
|
||||
// CURD操作:批量数据指定批次量写入
|
||||
func (l *dbLink) BatchInsert(table string, list *List, batch int) error {
|
||||
func (l *dbLink) BatchInsert(table string, list List, batch int) error {
|
||||
return l.link.batchInsert(table, list, batch, OPTION_INSERT)
|
||||
}
|
||||
|
||||
// CURD操作:批量数据指定批次量写入, 如果数据存在(主键或者唯一索引),那么删除后重新写入一条
|
||||
func (l *dbLink) BatchReplace(table string, list *List, batch int) error {
|
||||
func (l *dbLink) BatchReplace(table string, list List, batch int) error {
|
||||
return l.link.batchInsert(table, list, batch, OPTION_REPLACE)
|
||||
}
|
||||
|
||||
// CURD操作:批量数据指定批次量写入, 如果数据存在(主键或者唯一索引),那么更新,否则写入一条新数据
|
||||
func (l *dbLink) BatchSave(table string, list *List, batch int) error {
|
||||
func (l *dbLink) BatchSave(table string, list List, batch int) error {
|
||||
return l.link.batchInsert(table, list, batch, OPTION_SAVE)
|
||||
}
|
||||
|
||||
@ -307,16 +307,16 @@ func (l *dbLink) Update(table string, data interface{}, condition interface{}, a
|
||||
switch data.(type) {
|
||||
case string:
|
||||
updates = data.(string)
|
||||
case *Map:
|
||||
case Map:
|
||||
var keys []string
|
||||
for k, v := range *data.(*Map) {
|
||||
for k, v := range data.(Map) {
|
||||
keys = append(keys, fmt.Sprintf("%s%s%s=?", l.charl, k, l.charr))
|
||||
params = append(params, v)
|
||||
}
|
||||
updates = strings.Join(keys, ",")
|
||||
|
||||
default:
|
||||
return nil, errors.New("invalid data type for 'data' field, string or *Map expected")
|
||||
return nil, errors.New("invalid data type for 'data' field, string or Map expected")
|
||||
}
|
||||
for _, v := range args {
|
||||
if r, ok := v.(string); ok {
|
||||
|
@ -3,9 +3,6 @@ package gdb
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"regexp"
|
||||
"strings"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -99,42 +96,42 @@ func AddConfigNode (group string, node ConfigNode) {
|
||||
|
||||
// 添加一台数据库服务器配置,通过解析规范的字符串配置实现
|
||||
// 配置格式:账号@地址:端口,密码,数据库名称,数据库类型[,集群角色(master|slave),字符编码,负载均衡优先级,自定义链接]
|
||||
func AddConfigNodeByString (group string, nodestr string) {
|
||||
reg, _ := regexp.Compile(`(.+)@(.+):([^,]+),([^,]+),([^,]+),([^,]+)`)
|
||||
match := reg.FindStringSubmatch(nodestr)
|
||||
if match != nil {
|
||||
node := ConfigNode{
|
||||
User : strings.TrimSpace(match[1]),
|
||||
Host : strings.TrimSpace(match[2]),
|
||||
Port : strings.TrimSpace(match[3]),
|
||||
Pass : strings.TrimSpace(match[4]),
|
||||
Name : strings.TrimSpace(match[5]),
|
||||
Type : strings.TrimSpace(match[6]),
|
||||
}
|
||||
if len(match[0]) + 1 < len(nodestr) {
|
||||
extra := strings.Split(nodestr[len(match[0]) + 1:], ",")
|
||||
if len(extra) > 0 {
|
||||
node.Role = strings.TrimSpace(extra[0])
|
||||
}
|
||||
if len(extra) > 1 {
|
||||
node.Charset = strings.TrimSpace(extra[1])
|
||||
}
|
||||
if len(extra) > 2 {
|
||||
node.Priority, _ = strconv.Atoi(strings.TrimSpace(extra[2]))
|
||||
}
|
||||
if len(extra) > 3 {
|
||||
index := len(extra[0]) + len(extra[1]) + len(extra[2]) + 3
|
||||
node.Linkinfo = strings.TrimSpace(nodestr[len(match[0]) + 1 + index:])
|
||||
}
|
||||
}
|
||||
AddConfigNode(group, node)
|
||||
}
|
||||
}
|
||||
//func AddConfigNodeByString (group string, nodestr string) {
|
||||
// reg, _ := regexp.Compile(`(.+)@(.+):([^,]+),([^,]+),([^,]+),([^,]+)`)
|
||||
// match := reg.FindStringSubmatch(nodestr)
|
||||
// if match != nil {
|
||||
// node := ConfigNode{
|
||||
// User : strings.TrimSpace(match[1]),
|
||||
// Host : strings.TrimSpace(match[2]),
|
||||
// Port : strings.TrimSpace(match[3]),
|
||||
// Pass : strings.TrimSpace(match[4]),
|
||||
// Name : strings.TrimSpace(match[5]),
|
||||
// Type : strings.TrimSpace(match[6]),
|
||||
// }
|
||||
// if len(match[0]) + 1 < len(nodestr) {
|
||||
// extra := strings.Split(nodestr[len(match[0]) + 1:], ",")
|
||||
// if len(extra) > 0 {
|
||||
// node.Role = strings.TrimSpace(extra[0])
|
||||
// }
|
||||
// if len(extra) > 1 {
|
||||
// node.Charset = strings.TrimSpace(extra[1])
|
||||
// }
|
||||
// if len(extra) > 2 {
|
||||
// node.Priority, _ = strconv.Atoi(strings.TrimSpace(extra[2]))
|
||||
// }
|
||||
// if len(extra) > 3 {
|
||||
// index := len(extra[0]) + len(extra[1]) + len(extra[2]) + 3
|
||||
// node.Linkinfo = strings.TrimSpace(nodestr[len(match[0]) + 1 + index:])
|
||||
// }
|
||||
// }
|
||||
// AddConfigNode(group, node)
|
||||
// }
|
||||
//}
|
||||
|
||||
// 添加默认链接的一台数据库服务器配置,通过解析规范的字符串配置实现
|
||||
func AddDefaultConfigNodeByString (nodestr string) {
|
||||
AddConfigNodeByString(gDEFAULT_CONFIG_GROUP_NAME, nodestr)
|
||||
}
|
||||
//func AddDefaultConfigNodeByString (nodestr string) {
|
||||
// AddConfigNodeByString(gDEFAULT_CONFIG_GROUP_NAME, nodestr)
|
||||
//}
|
||||
|
||||
// 添加默认链接的一台数据库服务器配置
|
||||
func AddDefaultConfigNode (node ConfigNode) {
|
||||
|
@ -19,7 +19,7 @@ type gLinkOp struct {
|
||||
start int
|
||||
limit int
|
||||
data interface{}
|
||||
dataList *List
|
||||
dataList List
|
||||
batch int
|
||||
}
|
||||
|
||||
@ -88,7 +88,7 @@ func (op *gLinkOp) Data(data interface{}) (*gLinkOp) {
|
||||
}
|
||||
|
||||
// 链式操作,操作数据记录项列表
|
||||
func (op *gLinkOp) List(list *List) (*gLinkOp) {
|
||||
func (op *gLinkOp) List(list List) (*gLinkOp) {
|
||||
op.dataList = list
|
||||
return op
|
||||
}
|
||||
@ -98,7 +98,7 @@ func (op *gLinkOp) Insert() (sql.Result, error) {
|
||||
if op.data == nil {
|
||||
return nil, errors.New("inserting into table with empty data")
|
||||
}
|
||||
if d, ok := op.data.(*Map); ok {
|
||||
if d, ok := op.data.(Map); ok {
|
||||
return op.link.Insert(op.tables, d)
|
||||
}
|
||||
return nil, errors.New("inserting into table with invalid data type")
|
||||
@ -109,7 +109,7 @@ func (op *gLinkOp) Replace() (sql.Result, error) {
|
||||
if op.data == nil {
|
||||
return nil, errors.New("replacing into table with empty data")
|
||||
}
|
||||
if d, ok := op.data.(*Map); ok {
|
||||
if d, ok := op.data.(Map); ok {
|
||||
return op.link.Insert(op.tables, d)
|
||||
}
|
||||
return nil, errors.New("replacing into table with invalid data type")
|
||||
@ -120,7 +120,7 @@ func (op *gLinkOp) Save() (sql.Result, error) {
|
||||
if op.data == nil {
|
||||
return nil, errors.New("saving into table with empty data")
|
||||
}
|
||||
if d, ok := op.data.(*Map); ok {
|
||||
if d, ok := op.data.(Map); ok {
|
||||
return op.link.Insert(op.tables, d)
|
||||
}
|
||||
return nil, errors.New("saving into table with invalid data type")
|
||||
@ -134,7 +134,7 @@ func (op *gLinkOp) Batch(batch int) *gLinkOp {
|
||||
|
||||
// 链式操作, CURD - BatchInsert
|
||||
func (op *gLinkOp) BatchInsert() error {
|
||||
if op.dataList == nil || len(*op.dataList) < 1 {
|
||||
if op.dataList == nil || len(op.dataList) < 1 {
|
||||
return errors.New("batch inserting into table with empty data list")
|
||||
}
|
||||
batch := 10
|
||||
@ -146,7 +146,7 @@ func (op *gLinkOp) BatchInsert() error {
|
||||
|
||||
// 链式操作, CURD - BatchReplace
|
||||
func (op *gLinkOp) BatchReplace() error {
|
||||
if op.dataList == nil || len(*op.dataList) < 1 {
|
||||
if op.dataList == nil || len(op.dataList) < 1 {
|
||||
return errors.New("batch replacing into table with empty data list")
|
||||
}
|
||||
batch := 10
|
||||
@ -158,7 +158,7 @@ func (op *gLinkOp) BatchReplace() error {
|
||||
|
||||
// 链式操作, CURD - BatchSave
|
||||
func (op *gLinkOp) BatchSave() error {
|
||||
if op.dataList == nil || len(*op.dataList) < 1 {
|
||||
if op.dataList == nil || len(op.dataList) < 1 {
|
||||
return errors.New("batch saving into table with empty data list")
|
||||
}
|
||||
batch := 10
|
||||
@ -185,7 +185,7 @@ func (op *gLinkOp) Delete() (sql.Result, error) {
|
||||
}
|
||||
|
||||
// 链式操作,select
|
||||
func (op *gLinkOp) Select() (*List, error) {
|
||||
func (op *gLinkOp) Select() (List, error) {
|
||||
if op.fields == "" {
|
||||
op.fields = "*"
|
||||
}
|
||||
@ -206,17 +206,17 @@ func (op *gLinkOp) Select() (*List, error) {
|
||||
}
|
||||
|
||||
// 链式操作,查询所有记录
|
||||
func (op *gLinkOp) All() (*List, error) {
|
||||
func (op *gLinkOp) All() (List, error) {
|
||||
return op.Select()
|
||||
}
|
||||
|
||||
// 链式操作,查询单条记录
|
||||
func (op *gLinkOp) One() (*Map, error) {
|
||||
func (op *gLinkOp) One() (Map, error) {
|
||||
list, err := op.All()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &(*list)[0], nil
|
||||
return list[0], nil
|
||||
}
|
||||
|
||||
// 链式操作,查询字段值
|
||||
@ -225,7 +225,7 @@ func (op *gLinkOp) Value() (interface{}, error) {
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
for _, v := range *one {
|
||||
for _, v := range one {
|
||||
return v, nil
|
||||
}
|
||||
return "", nil
|
||||
|
@ -1,58 +0,0 @@
|
||||
// 基类
|
||||
package gbase
|
||||
|
||||
import (
|
||||
"gitee.com/johng/gf/g/os/gfile"
|
||||
"gitee.com/johng/gf/g/os/gconsole"
|
||||
"gitee.com/johng/gf/g/database/gdb"
|
||||
"gitee.com/johng/gf/g/frame/gconfig"
|
||||
"gitee.com/johng/gf/g/frame/ginstance"
|
||||
)
|
||||
|
||||
// 框架基类,所有的基于gf框架的类对象都继承于此,以便使用框架的一些封装的核心组件
|
||||
type Base struct {
|
||||
Db gdb.Link // 数据库操作对象
|
||||
Config *gconfig.Config // 配置管理对象
|
||||
}
|
||||
|
||||
// 基类初始化,如若需要自定义初始化内置核心对象组件,可在继承子类中覆盖此方法
|
||||
func (b *Base) Init() {
|
||||
// 配置文件目录查找依次为:启动参数cfgpath、当前程序运行目录
|
||||
if b.Config == nil {
|
||||
path := gconsole.Option.Get("cfgpath")
|
||||
if path == "" {
|
||||
path = gfile.SelfDir()
|
||||
}
|
||||
ckey := "gf_config_with_path_" + path
|
||||
result := ginstance.Get(ckey)
|
||||
if result != nil {
|
||||
b.Config = result.(*gconfig.Config)
|
||||
} else {
|
||||
b.Config = gconfig.New(path)
|
||||
ginstance.Set(ckey, b.Config)
|
||||
}
|
||||
}
|
||||
// 数据库操作对象初始化
|
||||
// 全局只有一个数据库单例对象,可以配置不同分组的配置进行使用
|
||||
if b.Db == nil {
|
||||
ckey := "gf_database"
|
||||
result := ginstance.Get(ckey)
|
||||
if result != nil {
|
||||
b.Db = result.(gdb.Link)
|
||||
} else {
|
||||
if m := b.Config.GetMap("database"); m != nil {
|
||||
for group, v := range m {
|
||||
if list, ok := v.([]interface{}); ok {
|
||||
for _, nodei := range list {
|
||||
gdb.AddConfigNodeByString(group, nodei.(string))
|
||||
}
|
||||
}
|
||||
}
|
||||
if link, err := gdb.Instance(); err != nil {
|
||||
b.Db = link
|
||||
ginstance.Set(ckey, b.Db)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,21 @@
|
||||
// 单例对象管理工具
|
||||
// 框架内置了一些核心对象,并且可以通过Set和Get方法实现IoC以及对内置核心对象的自定义替换
|
||||
package ginstance
|
||||
|
||||
import "gitee.com/johng/gf/g/container/gmap"
|
||||
import (
|
||||
"strconv"
|
||||
"gitee.com/johng/gf/g/os/gfile"
|
||||
"gitee.com/johng/gf/g/os/gconsole"
|
||||
"gitee.com/johng/gf/g/database/gdb"
|
||||
"gitee.com/johng/gf/g/frame/gconfig"
|
||||
"gitee.com/johng/gf/g/container/gmap"
|
||||
"gitee.com/johng/gf/g/os/glog"
|
||||
)
|
||||
|
||||
const (
|
||||
FRAME_CORE_COMPONENT_NAME_CONFIG = "gf.component.config"
|
||||
FRAME_CORE_COMPONENT_NAME_DATABASE = "gf.component.database"
|
||||
)
|
||||
|
||||
// 单例对象存储器
|
||||
var instances = gmap.NewStringInterfaceMap()
|
||||
@ -15,3 +29,92 @@ func Get(k string) interface{} {
|
||||
func Set(k string, v interface{}) {
|
||||
instances.Set(k, v)
|
||||
}
|
||||
|
||||
// 核心对象:Config
|
||||
// 配置文件目录查找依次为:启动参数cfgpath、当前程序运行目录
|
||||
func Config() *gconfig.Config {
|
||||
result := Get(FRAME_CORE_COMPONENT_NAME_CONFIG)
|
||||
if result != nil {
|
||||
return result.(*gconfig.Config)
|
||||
} else {
|
||||
path := gconsole.Option.Get("cfgpath")
|
||||
if path == "" {
|
||||
path = gfile.SelfDir()
|
||||
}
|
||||
config := gconfig.New(path)
|
||||
Set(FRAME_CORE_COMPONENT_NAME_CONFIG, config)
|
||||
return config
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 核心对象:Database
|
||||
func Database(names...string) gdb.Link {
|
||||
result := Get(FRAME_CORE_COMPONENT_NAME_DATABASE)
|
||||
if result != nil {
|
||||
return result.(gdb.Link)
|
||||
} else {
|
||||
config := Config()
|
||||
if config == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if m := config.GetMap("database"); m != nil {
|
||||
for group, v := range m {
|
||||
if list, ok := v.([]interface{}); ok {
|
||||
for _, nodev := range list {
|
||||
node := gdb.ConfigNode{}
|
||||
nodem := nodev.(map[string]interface{})
|
||||
if value, ok := nodem["host"]; ok {
|
||||
node.Host = value.(string)
|
||||
}
|
||||
if value, ok := nodem["port"]; ok {
|
||||
node.Port = value.(string)
|
||||
}
|
||||
if value, ok := nodem["user"]; ok {
|
||||
node.User = value.(string)
|
||||
}
|
||||
if value, ok := nodem["pass"]; ok {
|
||||
node.Pass = value.(string)
|
||||
}
|
||||
if value, ok := nodem["name"]; ok {
|
||||
node.Name = value.(string)
|
||||
}
|
||||
if value, ok := nodem["type"]; ok {
|
||||
node.Type = value.(string)
|
||||
}
|
||||
if value, ok := nodem["role"]; ok {
|
||||
node.Role = value.(string)
|
||||
}
|
||||
if value, ok := nodem["charset"]; ok {
|
||||
node.Charset = value.(string)
|
||||
}
|
||||
if value, ok := nodem["priority"]; ok {
|
||||
node.Priority, _ = strconv.Atoi(value.(string))
|
||||
}
|
||||
gdb.AddConfigNode(group, node)
|
||||
}
|
||||
}
|
||||
}
|
||||
var db gdb.Link = nil
|
||||
if len(names) == 0 {
|
||||
if link, err := gdb.Instance(); err == nil {
|
||||
db = link
|
||||
} else {
|
||||
glog.Error(err)
|
||||
}
|
||||
} else {
|
||||
if link, err := gdb.InstanceByGroup(names[0]); err == nil {
|
||||
db = link
|
||||
} else {
|
||||
glog.Error(err)
|
||||
}
|
||||
}
|
||||
if db != nil {
|
||||
Set(FRAME_CORE_COMPONENT_NAME_DATABASE, db)
|
||||
return db
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
@ -3,7 +3,6 @@ package gmvc
|
||||
|
||||
import (
|
||||
"gitee.com/johng/gf/g/net/ghttp"
|
||||
"gitee.com/johng/gf/g/frame/gbase"
|
||||
"gitee.com/johng/gf/g/net/gsession"
|
||||
)
|
||||
|
||||
@ -13,7 +12,6 @@ const (
|
||||
|
||||
// 控制器基类
|
||||
type Controller struct {
|
||||
gbase.Base
|
||||
Server *ghttp.Server // Web Server对象
|
||||
Request *ghttp.ClientRequest // 请求数据对象
|
||||
Response *ghttp.ServerResponse // 返回数据对象
|
||||
@ -24,7 +22,6 @@ type Controller struct {
|
||||
|
||||
// 控制器初始化接口方法
|
||||
func (c *Controller) Init(s *ghttp.Server, r *ghttp.ClientRequest, w *ghttp.ServerResponse) {
|
||||
c.Base.Init()
|
||||
c.Server = s
|
||||
c.Request = r
|
||||
c.Response = w
|
||||
|
@ -1,8 +1,6 @@
|
||||
// 模型基类
|
||||
package gmvc
|
||||
|
||||
import "gitee.com/johng/gf/g/frame/gbase"
|
||||
|
||||
type Model struct {
|
||||
gbase.Base
|
||||
|
||||
}
|
@ -4,14 +4,13 @@ import (
|
||||
"sync"
|
||||
"html/template"
|
||||
"gitee.com/johng/gf/g/os/gview"
|
||||
"gitee.com/johng/gf/g/frame/gbase"
|
||||
"gitee.com/johng/gf/g/os/gfile"
|
||||
"gitee.com/johng/gf/g/os/gconsole"
|
||||
"gitee.com/johng/gf/g/frame/ginstance"
|
||||
)
|
||||
|
||||
// 视图对象(一个请求一个视图对象,用完即销毁)
|
||||
type View struct {
|
||||
gbase.Base
|
||||
mu sync.RWMutex // 并发互斥锁
|
||||
ctl *Controller // 所属控制器
|
||||
view *gview.View // 底层视图对象
|
||||
@ -25,9 +24,11 @@ func NewView(c *Controller) *View {
|
||||
if path == "" {
|
||||
path = gfile.SelfDir()
|
||||
}
|
||||
if r := c.Config.Get("viewpath"); r != nil {
|
||||
if config := ginstance.Config(); config != nil {
|
||||
if r := config.Get("viewpath"); r != nil {
|
||||
path = r.(string)
|
||||
}
|
||||
}
|
||||
return &View{
|
||||
ctl : c,
|
||||
view : gview.GetView(path),
|
||||
@ -52,7 +53,11 @@ func (view *View) Assign(key string, value interface{}) {
|
||||
}
|
||||
|
||||
// 解析指定模板
|
||||
func (view *View) Display(file string) error {
|
||||
func (view *View) Display(files...string) error {
|
||||
file := "default"
|
||||
if len(files) > 0 {
|
||||
file = files[0]
|
||||
}
|
||||
// 查询模板
|
||||
tpl, err := view.view.Template(file)
|
||||
if err != nil {
|
||||
|
@ -6,7 +6,7 @@
|
||||
"host" : "127.0.0.1",
|
||||
"port" : "3306",
|
||||
"user" : "root",
|
||||
"pass" : "127456",
|
||||
"pass" : "123456",
|
||||
"name" : "test",
|
||||
"type" : "mysql",
|
||||
"role" : "master",
|
||||
@ -17,7 +17,7 @@
|
||||
"host" : "127.0.0.1",
|
||||
"port" : "3306",
|
||||
"user" : "root",
|
||||
"pass" : "127456",
|
||||
"pass" : "123456",
|
||||
"name" : "test",
|
||||
"type" : "mysql",
|
||||
"role" : "master",
|
||||
|
@ -1,18 +1,11 @@
|
||||
package main
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"gitee.com/johng/gf/g/frame/ginstance"
|
||||
)
|
||||
|
||||
func Add(path string, name ... string) {
|
||||
fmt.Println(name)
|
||||
}
|
||||
|
||||
func main() {
|
||||
for _, e := range os.Environ() {
|
||||
|
||||
fmt.Println(e)
|
||||
|
||||
}
|
||||
|
||||
db := ginstance.Database()
|
||||
list, _ := db.Table("test").Select()
|
||||
fmt.Println(list[0])
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
package gf
|
||||
|
||||
// 框架信息
|
||||
const VERSION = "0.60"
|
||||
const VERSION = "0.80"
|
||||
const AUTHORS = "john<john@johng.cn>"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user