diff --git a/common/database/conn.go b/common/database/conn.go index 1a57a29acfcd22741fd82782c1f9a493169ddf80..1847d991056f52b5c9bf070573d399f3873575b8 100644 --- a/common/database/conn.go +++ b/common/database/conn.go @@ -18,10 +18,8 @@ var ( ) //InitConnection 初始化数据库连接 -func InitConnection(config Config) error { - db, e := getConnection(config) - defaultDB = db - return e +func InitConnection(config Config) (*sql.DB, error) { + return getConnection(config) } func getConnection(config Config) (*sql.DB, error) { diff --git a/common/database/database.go b/common/database/database.go index 2cb4da111131060d810b13f6654619dffa522d41..05ff3680d11233dcc3e0acaa67dbb89bb329fe8a 100644 --- a/common/database/database.go +++ b/common/database/database.go @@ -1,5 +1,10 @@ package database - +const ( + //MysqlDriver mysql驱动器 + MysqlDriver = "mysql" + //Sqlite3Driver Sqlite3Driver驱动 + Sqlite3Driver = "sqlite3" +) //Config 数据库配置结构体 type Config interface { GetDriver() string diff --git a/common/listener/intercept.go b/common/listener/intercept.go new file mode 100644 index 0000000000000000000000000000000000000000..dbf5f5093cc994d35816fc6a8947116e999f8f16 --- /dev/null +++ b/common/listener/intercept.go @@ -0,0 +1,43 @@ +package listener + +import "sync" + +//InterceptFunc 拦截函数 +type InterceptFunc func(event interface{}) error + +//Intercept 拦截器 +type Intercept struct { + callbacks []InterceptFunc + locker sync.RWMutex +} + +//NewIntercept 创建拦截器 +func NewIntercept() *Intercept { + return &Intercept{ + callbacks: nil, + locker: sync.RWMutex{}, + } +} + +//Add add +func (i *Intercept) Add(f func(v interface{}) error) { + i.locker.Lock() + i.callbacks = append(i.callbacks, InterceptFunc(f)) + i.locker.Unlock() +} + +//Call call +func (i *Intercept) Call(v interface{}) error { + i.locker.RLock() + fs := i.callbacks + i.locker.RUnlock() + + for _, f := range fs { + err := f(v) + if err != nil { + + return err + } + } + return nil +} diff --git a/common/pdao/demo/demo.go b/common/pdao/demo/demo.go new file mode 100644 index 0000000000000000000000000000000000000000..6f9cc409ee1ca8551f94429842e228d579d289d6 --- /dev/null +++ b/common/pdao/demo/demo.go @@ -0,0 +1,62 @@ +package main + +import ( + "fmt" + "github.com/eolinker/goku-api-gateway/common/pdao" +) + +type DemoGetDao interface { + GetNameById(id int) string + GetIdByName(name string) int +} +type DemoSetDao interface { + Set(id int,name string) + +} + +type Demo struct { + names map[string]int + ids map[int]string +} + +func NewDemo() *Demo { + return &Demo{ + names: make(map[string]int), + ids: make(map[int]string), + }} + +func (d *Demo) Set(id int, name string) { + d.names[name]=id + d.ids[id]=name +} + +func (d *Demo) GetNameById(id int) string { + return d.ids[id] +} + +func (d *Demo) GetIdByName(name string) int { + return d.names[name] +} +var ( + getDao DemoGetDao + setDao DemoSetDao +) + +func init() { + pdao.Need(&getDao) + pdao.Need(&setDao) +} +func main() { + + demo:=NewDemo() + var seter DemoSetDao = demo + pdao.Set(&seter) + var getter DemoGetDao = demo + pdao.Set(&getter) + + pdao.Check() + + setDao.Set(1,"test") + fmt.Println(getDao.GetNameById(1)) + fmt.Println(getDao.GetIdByName("test")) +} \ No newline at end of file diff --git a/common/pdao/factory.go b/common/pdao/factory.go new file mode 100644 index 0000000000000000000000000000000000000000..5b0ad7962b257f08d2d6da9f022860867a3fa353 --- /dev/null +++ b/common/pdao/factory.go @@ -0,0 +1,21 @@ +package pdao + +import "database/sql" + +//FactoryFunc factoryFunc +type FactoryFunc func(db *sql.DB) (interface{}, error) + +//Create create +func (f FactoryFunc) Create(db *sql.DB) (interface{}, error) { + return f(db) +} + +//Factory factory +type Factory interface { + Create(db *sql.DB) (interface{}, error) +} + +//DBBuilder dbBuilder +type DBBuilder interface { + Build(db *sql.DB) error +} diff --git a/common/pdao/needs.go b/common/pdao/needs.go new file mode 100644 index 0000000000000000000000000000000000000000..d84f7df222a09541259b7c26d637d83d8d4cb4c7 --- /dev/null +++ b/common/pdao/needs.go @@ -0,0 +1,93 @@ +package pdao + +import ( + "fmt" + "reflect" + "sync" +) + +//NeedsManager needsManager +type NeedsManager struct { + daoInterfaces map[string][]*reflect.Value + lock sync.Mutex +} + +//NewNeedsManager 创建新的needsManager +func NewNeedsManager() *NeedsManager { + return &NeedsManager{ + daoInterfaces: make(map[string][]*reflect.Value), + lock: sync.Mutex{}, + } +} + +func (m *NeedsManager) add(key string, v *reflect.Value) { + m.lock.Lock() + m.daoInterfaces[key] = append(m.daoInterfaces[key], v) + m.lock.Unlock() +} + +func (m *NeedsManager) set(key string, v reflect.Value) { + m.lock.Lock() + for _, e := range m.daoInterfaces[key] { + e.Set(v) + } + delete(m.daoInterfaces, key) + m.lock.Unlock() +} +func (m *NeedsManager) check() []string { + m.lock.Lock() + r := make([]string, 0, len(m.daoInterfaces)) + for pkg := range m.daoInterfaces { + + r = append(r, pkg) + } + m.lock.Unlock() + return r +} + +//Need 声明 +func (m *NeedsManager) Need(p interface{}) { + + v := reflect.ValueOf(p) + + if v.Kind() != reflect.Ptr { + panic("must ptr") + } + e := v.Elem() + pkg := key(e.Type()) + if pkg == "" { + panic("invalid interface") + } + + if !e.CanSet() { + panic("invalid interface") + } + m.add(pkg, &e) +} + +//Set 注入 +func (m *NeedsManager) Set(i interface{}) { + v := reflect.ValueOf(i) + if v.Kind() != reflect.Ptr { + panic("must ptr") + } + e := v.Elem() + pkg := key(e.Type()) + + if pkg == "" { + panic("invalid interface") + } + m.set(pkg, e) +} +func key(t reflect.Type) string { + return fmt.Sprintf("%s.%s", t.PkgPath(), t.String()) +} + +//Check 检查是否实现相关dao类 +func (m *NeedsManager) Check() error { + rs := m.check() + if len(rs) > 0 { + return fmt.Errorf("need:%v", rs) + } + return nil +} diff --git a/common/pdao/needs_test.go b/common/pdao/needs_test.go new file mode 100644 index 0000000000000000000000000000000000000000..1388a2dc912b500707751636347164822f77ac2b --- /dev/null +++ b/common/pdao/needs_test.go @@ -0,0 +1,66 @@ +package pdao + +import ( + "fmt" + "testing" + + test1 "github.com/eolinker/goku-api-gateway/common/pdao/test/test/test/test" +) + +type T1 struct { +} + +func (t *T1) Test4() { + fmt.Println("implement me") +} + +type T2 struct { +} + +func (t *T2) Test3() { + fmt.Println("implement me") +} + +type T3 struct { +} + +func (t *T3) Test2() { + + fmt.Println("implement me") +} + +type T4 struct { +} + +func (t *T4) Test1() { + fmt.Println("implement me") +} + +func Test(t *testing.T) { + + t.Run("all", func(t *testing.T) { + var t1 test1.Test + //var t2 test2.Test = nil + //var t3 test3.Test = nil + //var t4 test4.Test = nil + Need(&t1) + //Need(&t2) + //Need(&t3) + //Need(&t4) + + var t1v test1.Test = new(T4) + Set(&t1v) + //Set(test2.Test(new(T3))) + // + //Set(test3.Test(new(T2))) + //Set(test4.Test(new(T1))) + + t1.Test1() + //t2.Test2() + //t3.Test3() + //t4.Test4() + Check() + + }) + +} diff --git a/common/pdao/pdao.go b/common/pdao/pdao.go new file mode 100644 index 0000000000000000000000000000000000000000..b8aa7a35a5afed58f403b6e20d2227f7c0aa8116 --- /dev/null +++ b/common/pdao/pdao.go @@ -0,0 +1,116 @@ +package pdao + +import ( + "database/sql" + "sync" +) + +var ( + needsManager = NewNeedsManager() + factoryManage = NewFactoryManager() +) + +//Need need +func Need(is ...interface{}) { + for _, i := range is { + needsManager.Need(i) + } +} + +//Check check +func Check() error { + return needsManager.Check() +} + +//RegisterDao 注册dao类 +func RegisterDao(driver string, factories ...Factory) { + for _, factory := range factories { + factoryManage.RegisterDao(driver, factory) + } + +} + +//RegisterDBBuilder 注册dbBuilder +func RegisterDBBuilder(driver string, builders ...DBBuilder) { + for _, builder := range builders { + factoryManage.RegisterDBBuilder(driver, builder) + + } +} + +//Build build +func Build(driver string, db *sql.DB) error { + return factoryManage.Build(driver, db, needsManager) +} + +//FactoryManager 工厂管理者 +type FactoryManager struct { + factories map[string][]Factory + builders map[string][]DBBuilder + locker sync.Mutex +} + +//NewFactoryManager new工厂管理者 +func NewFactoryManager() *FactoryManager { + return &FactoryManager{ + factories: make(map[string][]Factory), + builders: make(map[string][]DBBuilder), + locker: sync.Mutex{}, + } +} + +//RegisterDBBuilder dbBuilder注册器 +func (f *FactoryManager) RegisterDBBuilder(driver string, builder DBBuilder) { + f.locker.Lock() + f.builders[driver] = append(f.builders[driver], builder) + f.locker.Unlock() +} + +//RegisterDao dao类注册器 +func (f *FactoryManager) RegisterDao(driver string, factory Factory) { + f.locker.Lock() + f.factories[driver] = append(f.factories[driver], factory) + f.locker.Unlock() +} + +func (f *FactoryManager) get(driver string) []Factory { + f.locker.Lock() + fs := f.factories[driver] + delete(f.factories, driver) + f.locker.Unlock() + return fs +} + +func (f *FactoryManager) callBuild(driver string, db *sql.DB) error { + f.locker.Lock() + + bs := f.builders[driver] + for _, b := range bs { + err := b.Build(db) + if err != nil { + f.locker.Unlock() + return err + } + } + f.locker.Unlock() + return nil +} + +//Build build +func (f *FactoryManager) Build(driver string, db *sql.DB, m *NeedsManager) error { + err := f.callBuild(driver, db) + if err != nil { + return err + } + fs := f.get(driver) + for _, factory := range fs { + + i, err := factory.Create(db) + if err != nil { + return err + } + m.Set(i) + } + return nil + +} diff --git a/common/pdao/test/t.go b/common/pdao/test/t.go new file mode 100644 index 0000000000000000000000000000000000000000..532bcfaf6a304ce72470312a3c76ad483896f569 --- /dev/null +++ b/common/pdao/test/t.go @@ -0,0 +1,6 @@ +package test + + +type Test interface { + Test4() +} \ No newline at end of file diff --git a/common/pdao/test/test/t.go b/common/pdao/test/test/t.go new file mode 100644 index 0000000000000000000000000000000000000000..2aa08133485c6db31f4e6c0fe6285df6a3a09ce6 --- /dev/null +++ b/common/pdao/test/test/t.go @@ -0,0 +1,6 @@ +package test + + +type Test interface { + Test3() +} \ No newline at end of file diff --git a/common/pdao/test/test/test/t.go b/common/pdao/test/test/test/t.go new file mode 100644 index 0000000000000000000000000000000000000000..6508d58eee17b2bdbc25e9c1a457ece2b8a18805 --- /dev/null +++ b/common/pdao/test/test/test/t.go @@ -0,0 +1,6 @@ +package test + + +type Test interface { + Test2() +} \ No newline at end of file diff --git a/common/pdao/test/test/test/test/t.go b/common/pdao/test/test/test/test/t.go new file mode 100644 index 0000000000000000000000000000000000000000..036cbee6213da3e1e2a426b982becc549e37e1a0 --- /dev/null +++ b/common/pdao/test/test/test/test/t.go @@ -0,0 +1,6 @@ +package test + + +type Test interface { + Test1() +} \ No newline at end of file