Merge branch 'x/sqlx' into x/sqlc

r/paopao-ce-pro
Michael Li 2 years ago
commit b2bf5bd3af
No known key found for this signature in database

@ -504,16 +504,28 @@ feature/followship
feature/mir
feature/localoss
jc/alimy
r/paopao-plus
r/paopao-pro
x/sqlc
x/sqlx
```
**分支说明**
* 分支`main`是主分支也是paopao-ce的稳定版本发布分支只有经过内部测试没有重大bug出现的稳定代码才会推进到这个分支该分支主要由`beta`分支代码演进而来,原则上**只接受bug修复PR**。`rc版本/稳定版本` 发布都应该在`main`主分支中进行。
* 分支`beta`是公测分支,代码推进到`main`主分支的候选分支;该分支主要由`dev`分支代码演进而来,**接受bug修复以及新功能优化的PR**原则上不接受新功能PR。`alpha/beta版本` 发布都应该在`beta`公测分支下进行。
* 分支`dev`是开发分支,**不定期频繁更新**,接受 *新功能PR、代码优化PR、bug修复PR***新功能PR** 都应该首先提交给`dev`分支进行合并bug修复/代码优化 后 **冻结新功能** 将代码演进合并到`beta`分支。
* `feature/*`是新功能子分支,一般新功能子分支都是 *从`dev`开发分支fork出来的*;子功能分支 **只专注于该新功能** 代码的开发/优化,待开发接近内测阶段 *提交新功能PR给`dev`分支进行review/merge*,待新功能代码演进到`beta`分支后,原则上是可以删除该分支,但也可以保留到稳定版本发布。**该分支专注于新功能的开发只接受新功能的bug修复/优化PR**。
* `jc/*`是代码库维护者的开发分支一般包含一些局部优化或者bug修复代码有时可以直接将代码merge到`dev/beta`分支原则上不允许直接merge代码到`main`主分支。
* `x/*`是技术实验分支某些技术的引入需要经过具体的代码实现与真实场景的测评考量评估后如果某项技术适合引入到paopao-ce就fork出一个`feature/*`分支作为新功能引入到paopao-ce。一般一些比较激进的技术从`dev`分支fork出一个新的`x/*`分支各种尝试、考量、评估后或丢弃、或引入到paopao-ce。
**分支说明**
| 名称 | 说明 | 备注|
| ----- | ----- | ----- |
| [`main`](https://github.com/rocboss/paopao-ce) | 主分支 |分支`main`是主分支也是paopao-ce的稳定版本发布分支只有经过内部测试没有重大bug出现的稳定代码才会推进到这个分支该分支主要由`beta`分支代码演进而来,原则上**只接受bug修复PR**。`rc版本/稳定版本` 发布都应该在`main`主分支中进行。|
| [`beta`](https://github.com/rocboss/paopao-ce/tree/beta) | 公测分支 |分支`beta`是公测分支,代码推进到`main`主分支的候选分支;该分支主要由`dev`分支代码演进而来,**接受bug修复以及新功能优化的PR**原则上不接受新功能PR。`alpha/beta版本` 发布都应该在`beta`公测分支下进行。|
| [`dev`](https://github.com/rocboss/paopao-ce/tree/dev) | 开发分支 | 分支`dev`是开发分支,**不定期频繁更新**,接受 *新功能PR、代码优化PR、bug修复PR***新功能PR** 都应该首先提交给`dev`分支进行合并bug修复/代码优化 后 **冻结新功能** 将代码演进合并到`beta`分支。
| `feature/*` | 子功能分支 |`feature/*`是新功能子分支,一般新功能子分支都是 *从`dev`开发分支fork出来的*;子功能分支 **只专注于该新功能** 代码的开发/优化,待开发接近内测阶段 *提交新功能PR给`dev`分支进行review/merge*,待新功能代码演进到`beta`分支后,原则上是可以删除该分支,但也可以保留到稳定版本发布。**该分支专注于新功能的开发只接受新功能的bug修复/优化PR**。|
| `jc/*` |维护者的开发分支|`jc/*`是代码库维护者的开发分支一般包含一些局部优化或者bug修复代码有时可以直接将代码merge到`dev/beta`分支原则上不允许直接merge代码到`main`主分支。|
| `x/*` |实验分支|`x/*`是技术实验分支某些技术的引入需要经过具体的代码实现与真实场景的测评考量评估后如果某项技术适合引入到paopao-ce就fork出一个`feature/*`分支作为新功能引入到paopao-ce。一般一些比较激进的技术从`dev`分支fork出一个新的`x/*`分支各种尝试、考量、评估后或丢弃、或引入到paopao-ce。|
| `r/*` |发行版本分支|`r/*`是不同发行版本分支,不同发行版本各有不同的侧重点,可以根据需要选择适合的发行版本。|
**发行版本分支说明**
| 名称 | 说明 | 维护者 | 备注 |
| ----- | ----- | ----- | ----- |
|[`paopao-ce`](https://github.com/rocboss/paopao-ce/tree/dev)|paopao-ce 主发行版本|[ROC](https://github.com/rocboss 'ROC')|该分支 [数据逻辑层](https://github.com/rocboss/paopao-ce/tree/dev/internal/dao/jinzhu) 使用[gorm](https://github.com/go-gorm/gorm)作为数据逻辑层的ORM框架适配MySQL/PostgreSQL/Sqlite3数据库。|
|[`r/paopao-plus`](https://github.com/rocboss/paopao-ce/tree/r/paopao-plus)|paopao-plus 发行版本|[北野](https://github.com/alimy 'Michael Li')|该分支 [数据逻辑层](https://github.com/rocboss/paopao-ce/tree/r/paopao-plus/internal/dao/sakila) 使用[sqlx](https://github.com/jmoiron/sqlx)作为数据逻辑层的ORM框架专注于为MySQL/PostgreSQL/Sqlite3使用更优化的查询语句以提升数据检索效率。建议熟悉[sqlx](https://github.com/jmoiron/sqlx)的开发人员可以基于此版本来做 二次开发。|
|[`r/paopao-pro`](https://github.com/rocboss/paopao-ce/tree/r/paopao-pro)|paopao-pro 发行版本|[北野](https://github.com/alimy 'Michael Li')|该分支 [数据逻辑层](https://github.com/rocboss/paopao-ce/tree/r/paopao-pro/internal/dao/slonik) 使用[sqlc](https://github.com/kyleconroy/sqlc)作为sql语句生成器自动生成ORM代码专门针对特定数据库MySQL/PostgreSQL进行查询优化熟悉[sqlc](https://github.com/kyleconroy/sqlc)的开发人员可以基于此版本来做 二次开发。(另:分支目前只使用[pgx-v5](https://github.com/jackc/pgx)适配了PostgreSQL数据库后续或许会适配MySQL/TiDB数据库。)|
**代码分支演进图**
![](docs/proposal/.assets/000-01.png)
@ -526,7 +538,7 @@ x/sqlx
| 昵称 | [@GitHub](https://github.com 'github.com') | [@PaoPao](https://www.paopao.info 'paopao.info') |
| ----- | ----- | ----- |
| ROC | [ROC](https://github.com/rocboss 'ROC')|[ROC](https://www.paopao.info/#/user?username=roc 'ROC @roc')|
| 北野 | [Michael Li](https://github.com/alimy 'Michael Li') | [alimy](https://www.paopao.info/#/user?username=alimy '北野 @alimy')|
| [北野](https://alimy.me '糊涂小栈') | [Michael Li](https://github.com/alimy 'Michael Li') | [alimy](https://www.paopao.info/#/user?username=alimy '北野 @alimy')|
| orzi!| [orzi!](https://github.com/orziz 'orzi!')||
### 其他说明

@ -1,6 +1,7 @@
## 部署站点
PaoPao部署站点信息。
| 名称 | 网址 | 备注 |
| ----- | ----- | ----- |
|泡泡|[www.paopao.info](https://www.paopao.info)|PaoPao官方站点|
| 名称 | 网址 | 站长 | 备注 |
| ----- | ----- | ----- | ----- |
|泡泡|[www.paopao.info](https://www.paopao.info)|[ROC](https://www.paopao.info/#/user?username=roc 'roc(@paopao.info)')|PaoPao官方站点|
|布里塔|[bulita.net](https://bulita.net)|[chendong](https://www.paopao.info/#/user?username=chendong 'chendong(@paopao.info)')|布里塔 - 招聘求职转发|

@ -0,0 +1,21 @@
| 编号 | 作者 | 发表时间 | 变更时间 | 版本 | 状态 |
| ----- | ----- | ----- | ----- | ----- | ----- |
| 014| 北野 | 2023-02-09 | 2023-02-09 | v0.0 | 提议 |
### 概述
TODO
### 需求
TODO
### 方案
TODO
### 疑问
1. 为什么要引入sqlx/sqlc
TODO
### 更新记录
#### v0.0(2023-02-09) - 北野
* 初始文档, 先占个位置

@ -19,6 +19,30 @@ var (
_onceSql, _onceRedis sync.Once
)
const (
TableAnouncement = "user"
TableAnouncementContent = "anouncement_content"
TableAttachment = "attachment"
TableCaptcha = "captcha"
TableComment = "comment"
TableCommentContent = "comment_content"
TableCommentReply = "comment_reply"
TableContact = "contact"
TableContactGroup = "contact_group"
TableMessage = "message"
TablePost = "post"
TablePostAttachmentBill = "post_attachment_bill"
TablePostCollection = "post_collection"
TablePostContent = "post_content"
TablePostStar = "post_star"
TableTag = "tag"
TableUser = "user"
TableWalletRecharge = "wallet_recharge"
TableWalletStatement = "wallet_statement"
)
type TableNameMap map[string]string
func MustSqlDB() *sql.DB {
_onceSql.Do(func() {
var err error

@ -381,6 +381,35 @@ func (s *MeiliSettingS) Endpoint() string {
return endpoint(s.Host, s.Secure)
}
func (s *DatabaseSetingS) TableNames() (res TableNameMap) {
tableNames := []string{
TableAnouncement,
TableAnouncementContent,
TableAttachment,
TableCaptcha,
TableComment,
TableCommentContent,
TableCommentReply,
TableContact,
TableContactGroup,
TableMessage,
TablePost,
TablePostAttachmentBill,
TablePostCollection,
TablePostContent,
TablePostStar,
TableTag,
TableUser,
TableWalletRecharge,
TableWalletStatement,
}
res = make(TableNameMap, len(tableNames))
for _, name := range tableNames {
res[name] = s.TablePrefix + name
}
return
}
func endpoint(host string, secure bool) string {
schema := "http"
if secure {

@ -0,0 +1,54 @@
// Copyright 2023 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package jinzhu
import (
"github.com/rocboss/paopao-ce/internal/conf"
)
var (
_anouncement string
_anouncementContent string
_attachment string
_captcha string
_comment string
_commentContent string
_commentReply string
_contact string
_contactGroup string
_message string
_post string
_postAttachmentBill string
_postCollection string
_postContent string
_postStar string
_tag string
_user string
_walletRecharge string
_walletStatement string
)
func initTableName() {
m := conf.DatabaseSetting.TableNames()
_anouncement = m[conf.TableAnouncement]
_anouncementContent = m[conf.TableAnouncementContent]
_attachment = m[conf.TableAttachment]
_captcha = m[conf.TableCaptcha]
_comment = m[conf.TableComment]
_commentContent = m[conf.TableCommentContent]
_commentReply = m[conf.TableCommentReply]
_contact = m[conf.TableContact]
_contactGroup = m[conf.TableContactGroup]
_message = m[conf.TableMessage]
_post = m[conf.TablePost]
_postAttachmentBill = m[conf.TablePostAttachmentBill]
_postCollection = m[conf.TablePostCollection]
_postContent = m[conf.TablePostContent]
_postStar = m[conf.TablePostStar]
_tag = m[conf.TableTag]
_user = m[conf.TableUser]
_walletRecharge = m[conf.TableWalletRecharge]
_walletStatement = m[conf.TableWalletStatement]
}

@ -9,6 +9,8 @@
package jinzhu
import (
"sync"
"github.com/Masterminds/semver/v3"
"github.com/alimy/cfg"
"github.com/rocboss/paopao-ce/internal/conf"
@ -21,6 +23,8 @@ import (
var (
_ core.DataService = (*dataServant)(nil)
_ core.VersionInfo = (*dataServant)(nil)
_onceInitial sync.Once
)
type dataServant struct {
@ -40,6 +44,8 @@ type dataServant struct {
}
func NewDataService() (core.DataService, core.VersionInfo) {
lazyInitial()
var (
v core.VersionInfo
cis core.CacheIndexService
@ -104,3 +110,10 @@ func (s *dataServant) Name() string {
func (s *dataServant) Version() *semver.Version {
return semver.MustParse("v0.2.0")
}
// lazyInitial do some package lazy initialize for performance
func lazyInitial() {
_onceInitial.Do(func() {
initTableName()
})
}

@ -5,6 +5,8 @@
package sakila
import (
"sync"
"github.com/Masterminds/semver/v3"
"github.com/alimy/cfg"
"github.com/rocboss/paopao-ce/internal/core"
@ -16,6 +18,8 @@ import (
var (
_ core.DataService = (*dataServant)(nil)
_ core.VersionInfo = (*dataServant)(nil)
_onceInitial sync.Once
)
type dataServant struct {
@ -35,32 +39,33 @@ type dataServant struct {
}
func NewDataService() (core.DataService, core.VersionInfo) {
lazyInitial()
var (
v core.VersionInfo
cis core.CacheIndexService
ips core.IndexPostsService
)
db := sqlxDB()
pvs := security.NewPhoneVerifyService()
ams := NewAuthorizationManageService()
ths := newTweetHelpService(db)
ths := newTweetHelpService(_db)
// initialize core.IndexPostsService
if cfg.If("Friendship") {
ips = newFriendIndexService(db, ams, ths)
ips = newFriendIndexService(_db, ams, ths)
} else if cfg.If("Followship") {
ips = newFollowIndexService(db, ths)
ips = newFollowIndexService(_db, ths)
} else if cfg.If("Lightship") {
ips = newLightIndexService(db, ths)
ips = newLightIndexService(_db, ths)
} else {
// default use lightship post index service
ips = newLightIndexService(db, ths)
ips = newLightIndexService(_db, ths)
}
// initialize core.CacheIndexService
if cfg.If("SimpleCacheIndex") {
// simpleCache use special post index service
ips = newSimpleIndexPostsService(db, ths)
ips = newSimpleIndexPostsService(_db, ths)
cis, v = cache.NewSimpleCacheIndexService(ips)
} else if cfg.If("BigCacheIndex") {
// TODO: make cache index post in different scence like friendship/followship/lightship
@ -72,24 +77,25 @@ func NewDataService() (core.DataService, core.VersionInfo) {
ds := &dataServant{
IndexPostsService: cis,
WalletService: newWalletService(db),
MessageService: newMessageService(db),
TopicService: newTopicService(db),
TweetService: newTweetService(db),
TweetManageService: newTweetManageService(db, cis),
TweetHelpService: newTweetHelpService(db),
CommentService: newCommentService(db),
CommentManageService: newCommentManageService(db),
UserManageService: newUserManageService(db),
ContactManageService: newContactManageService(db),
SecurityService: newSecurityService(db, pvs),
WalletService: newWalletService(_db),
MessageService: newMessageService(_db),
TopicService: newTopicService(_db),
TweetService: newTweetService(_db),
TweetManageService: newTweetManageService(_db, cis),
TweetHelpService: newTweetHelpService(_db),
CommentService: newCommentService(_db),
CommentManageService: newCommentManageService(_db),
UserManageService: newUserManageService(_db),
ContactManageService: newContactManageService(_db),
SecurityService: newSecurityService(_db, pvs),
AttachmentCheckService: security.NewAttachmentCheckService(),
}
return ds, ds
}
func NewAuthorizationManageService() core.AuthorizationManageService {
return newAuthorizationManageService(sqlxDB())
lazyInitial()
return newAuthorizationManageService(_db)
}
func (s *dataServant) Name() string {
@ -99,3 +105,10 @@ func (s *dataServant) Name() string {
func (s *dataServant) Version() *semver.Version {
return semver.MustParse("v0.1.0")
}
// lazyInitial do some package lazy initialize for performance
func lazyInitial() {
_onceInitial.Do(func() {
initSqlxDB()
})
}

@ -8,7 +8,6 @@ import (
"context"
"database/sql"
"strings"
"sync"
"github.com/jmoiron/sqlx"
"github.com/rocboss/paopao-ce/internal/conf"
@ -16,8 +15,7 @@ import (
)
var (
_db *sqlx.DB
_once sync.Once
_db *sqlx.DB
)
type sqlxServant struct {
@ -86,21 +84,12 @@ func newSqlxServant(db *sqlx.DB) *sqlxServant {
}
}
func sqlxDB() *sqlx.DB {
_once.Do(func() {
_db = conf.MustSqlxDB()
})
return _db
}
func r(query string) string {
db := sqlxDB()
return db.Rebind(t(query))
return _db.Rebind(t(query))
}
func c(query string) *sqlx.Stmt {
db := sqlxDB()
stmt, err := db.Preparex(db.Rebind(t(query)))
stmt, err := _db.Preparex(_db.Rebind(t(query)))
if err != nil {
logrus.Fatalf("prepare query(%s) error: %s", query, err)
}
@ -108,8 +97,7 @@ func c(query string) *sqlx.Stmt {
}
func n(query string) *sqlx.NamedStmt {
db := sqlxDB()
stmt, err := db.PrepareNamed(t(query))
stmt, err := _db.PrepareNamed(t(query))
if err != nil {
logrus.Fatalf("prepare named query(%s) error: %s", query, err)
}
@ -120,3 +108,7 @@ func n(query string) *sqlx.NamedStmt {
func t(query string) string {
return strings.Replace(query, "@", conf.DatabaseSetting.TablePrefix, -1)
}
func initSqlxDB() {
_db = conf.MustSqlxDB()
}

@ -2,8 +2,10 @@
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
//go:build !jsoniter && !go_json
// +build !jsoniter,!go_json
//go:build !jsoniter && !go_json && !(sonic && avx && (linux || windows || darwin) && amd64)
// +build !jsoniter
// +build !go_json
// +build !sonic !avx !linux,!windows,!darwin !amd64
package json

Loading…
Cancel
Save