Commit 4da6c484 authored by 张振华's avatar 张振华

table refactor

parent 55e2f303
...@@ -6,13 +6,12 @@ package commands ...@@ -6,13 +6,12 @@ package commands
import ( import (
"fmt" "fmt"
"strings"
jsonrpc "github.com/33cn/chain33/rpc/jsonclient" jsonrpc "github.com/33cn/chain33/rpc/jsonclient"
rpctypes "github.com/33cn/chain33/rpc/types" rpctypes "github.com/33cn/chain33/rpc/types"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
gty "github.com/33cn/plugin/plugin/dapp/guess/types" gty "github.com/33cn/plugin/plugin/dapp/guess/types"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"strings"
) )
//GuessCmd Guess合约命令行 //GuessCmd Guess合约命令行
...@@ -250,6 +249,8 @@ func addGuessQueryFlags(cmd *cobra.Command) { ...@@ -250,6 +249,8 @@ func addGuessQueryFlags(cmd *cobra.Command) {
cmd.Flags().Int32P("status", "s", 0, "status") cmd.Flags().Int32P("status", "s", 0, "status")
cmd.Flags().StringP("gameIDs", "d", "", "gameIDs") cmd.Flags().StringP("gameIDs", "d", "", "gameIDs")
cmd.Flags().StringP("category", "c", "default", "game category") cmd.Flags().StringP("category", "c", "default", "game category")
cmd.Flags().StringP("primary", "p", "", "the primary to query from")
} }
func guessQuery(cmd *cobra.Command, args []string) { func guessQuery(cmd *cobra.Command, args []string) {
...@@ -262,6 +263,12 @@ func guessQuery(cmd *cobra.Command, args []string) { ...@@ -262,6 +263,12 @@ func guessQuery(cmd *cobra.Command, args []string) {
index, _ := cmd.Flags().GetInt64("index") index, _ := cmd.Flags().GetInt64("index")
gameIDs, _ := cmd.Flags().GetString("gameIDs") gameIDs, _ := cmd.Flags().GetString("gameIDs")
category, _ := cmd.Flags().GetString("category") category, _ := cmd.Flags().GetString("category")
primary, _ := cmd.Flags().GetString("primary")
var primaryKey []byte
if len(primary) > 0 {
primaryKey = []byte(primary)
}
var params rpctypes.Query4Jrpc var params rpctypes.Query4Jrpc
params.Execer = gty.GuessX params.Execer = gty.GuessX
...@@ -301,6 +308,7 @@ func guessQuery(cmd *cobra.Command, args []string) { ...@@ -301,6 +308,7 @@ func guessQuery(cmd *cobra.Command, args []string) {
req := &gty.QueryGuessGameInfo{ req := &gty.QueryGuessGameInfo{
Addr: addr, Addr: addr,
Index: index, Index: index,
PrimaryKey: primaryKey,
} }
params.FuncName = gty.FuncNameQueryGameByAddr params.FuncName = gty.FuncNameQueryGameByAddr
params.Payload = types.MustPBToJSON(req) params.Payload = types.MustPBToJSON(req)
...@@ -312,6 +320,7 @@ func guessQuery(cmd *cobra.Command, args []string) { ...@@ -312,6 +320,7 @@ func guessQuery(cmd *cobra.Command, args []string) {
req := &gty.QueryGuessGameInfo{ req := &gty.QueryGuessGameInfo{
Status: status, Status: status,
Index: index, Index: index,
PrimaryKey: primaryKey,
} }
params.FuncName = gty.FuncNameQueryGameByStatus params.FuncName = gty.FuncNameQueryGameByStatus
params.Payload = types.MustPBToJSON(req) params.Payload = types.MustPBToJSON(req)
...@@ -323,6 +332,7 @@ func guessQuery(cmd *cobra.Command, args []string) { ...@@ -323,6 +332,7 @@ func guessQuery(cmd *cobra.Command, args []string) {
req := &gty.QueryGuessGameInfo{ req := &gty.QueryGuessGameInfo{
AdminAddr: adminAddr, AdminAddr: adminAddr,
Index: index, Index: index,
PrimaryKey: primaryKey,
} }
params.FuncName = gty.FuncNameQueryGameByAdminAddr params.FuncName = gty.FuncNameQueryGameByAdminAddr
params.Payload = types.MustPBToJSON(req) params.Payload = types.MustPBToJSON(req)
...@@ -335,6 +345,7 @@ func guessQuery(cmd *cobra.Command, args []string) { ...@@ -335,6 +345,7 @@ func guessQuery(cmd *cobra.Command, args []string) {
Addr: addr, Addr: addr,
Status: status, Status: status,
Index: index, Index: index,
PrimaryKey: primaryKey,
} }
params.FuncName = gty.FuncNameQueryGameByAddrStatus params.FuncName = gty.FuncNameQueryGameByAddrStatus
params.Payload = types.MustPBToJSON(req) params.Payload = types.MustPBToJSON(req)
...@@ -347,6 +358,7 @@ func guessQuery(cmd *cobra.Command, args []string) { ...@@ -347,6 +358,7 @@ func guessQuery(cmd *cobra.Command, args []string) {
AdminAddr: adminAddr, AdminAddr: adminAddr,
Status: status, Status: status,
Index: index, Index: index,
PrimaryKey: primaryKey,
} }
params.FuncName = gty.FuncNameQueryGameByAdminStatus params.FuncName = gty.FuncNameQueryGameByAdminStatus
params.Payload = types.MustPBToJSON(req) params.Payload = types.MustPBToJSON(req)
...@@ -359,6 +371,7 @@ func guessQuery(cmd *cobra.Command, args []string) { ...@@ -359,6 +371,7 @@ func guessQuery(cmd *cobra.Command, args []string) {
Category: category, Category: category,
Status: status, Status: status,
Index: index, Index: index,
PrimaryKey: primaryKey,
} }
params.FuncName = gty.FuncNameQueryGameByCategoryStatus params.FuncName = gty.FuncNameQueryGameByCategoryStatus
params.Payload = types.MustPBToJSON(req) params.Payload = types.MustPBToJSON(req)
......
...@@ -5,52 +5,104 @@ ...@@ -5,52 +5,104 @@
package executor package executor
import ( import (
"fmt"
"github.com/33cn/chain33/common/db/table"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
gty "github.com/33cn/plugin/plugin/dapp/guess/types" gty "github.com/33cn/plugin/plugin/dapp/guess/types"
) )
func (g *Guess) rollbackGame(game *gty.GuessGame, log *gty.ReceiptGuessGame){
if game == nil || log == nil {
return
}
//如果状态发生了变化,则需要将游戏状态恢复到前一状态
if log.StatusChange {
game.Status = log.PreStatus
game.Index = log.PreIndex
//玩家信息中的index回滚
for i := 0; i < len(game.Plays); i++ {
player := game.Plays[i]
player.Bet.Index = player.Bet.PreIndex
}
}
//如果下注了,则需要把下注回滚
if log.Bet {
//统计信息回滚
game.BetStat.TotalBetTimes--
game.BetStat.TotalBetsNumber -= log.BetsNumber
for i := 0; i < len(game.BetStat.Items); i++ {
item := game.BetStat.Items[i]
if item.Option == log.Option{
item.BetsTimes--
item.BetsNumber -= log.BetsNumber
break
}
}
//玩家下注信息回滚
for i := 0; i < len(game.Plays); i++ {
player := game.Plays[i]
if player.Addr == log.Addr && player.Bet.Index == log.Index {
game.Plays = append(game.Plays[:i], game.Plays[i+1:]...)
break
}
}
}
}
func (g *Guess) rollbackIndex(log *gty.ReceiptGuessGame) (kvs []*types.KeyValue) { func (g *Guess) rollbackIndex(log *gty.ReceiptGuessGame) (kvs []*types.KeyValue) {
//新创建游戏,将增加的记录都删除掉 userTable := gty.NewGuessUserTable(g.GetLocalDB())
gameTable := gty.NewGuessGameTable(g.GetLocalDB())
tablejoin, err := table.NewJoinTable(userTable, gameTable, []string{"addr#status"})
if err != nil {
return nil
}
if log.Status == gty.GuessGameStatusStart { if log.Status == gty.GuessGameStatusStart {
//kvs = append(kvs, addGuessGameAddrIndexKey(log.Status, log.Addr, log.GameId, log.Index)) //新创建游戏回滚,game表删除记录
kvs = append(kvs, delGuessGameStatusIndexKey(log.Status, log.Index)) err = tablejoin.MustGetTable("game").Del([]byte(fmt.Sprintf("%018d", log.StartIndex)))
kvs = append(kvs, delGuessGameAdminIndexKey(log.AdminAddr, log.Index)) if err != nil {
kvs = append(kvs, delGuessGameAdminStatusIndexKey(log.Status, log.AdminAddr, log.Index)) return nil
kvs = append(kvs, delGuessGameCategoryStatusIndexKey(log.Status, log.Category, log.Index)) }
kvs, _ = tablejoin.Save()
return kvs
} else if log.Status == gty.GuessGameStatusBet { } else if log.Status == gty.GuessGameStatusBet {
//如果是下注状态,则有用户进行了下注操作,对这些记录进行删除 //下注阶段,需要更新游戏信息,回滚下注信息
kvs = append(kvs, delGuessGameAddrIndexKey(log.Addr, log.Index)) game := log.Game
kvs = append(kvs, delGuessGameAddrStatusIndexKey(log.Status, log.Addr, log.Index)) log.Game = nil
//如果发生了状态变化,恢复老状态的记录,删除新添加的状态记录 //先回滚游戏信息,再进行更新
if log.StatusChange { g.rollbackGame(game, log)
kvs = append(kvs, addGuessGameStatusIndexKey(log.PreStatus, log.GameID, log.PreIndex))
kvs = append(kvs, addGuessGameAdminStatusIndexKey(log.PreStatus, log.AdminAddr, log.GameID, log.PreIndex)) err = tablejoin.MustGetTable("game").Replace(game)
kvs = append(kvs, addGuessGameCategoryStatusIndexKey(log.PreStatus, log.Category, log.GameID, log.PreIndex)) if err != nil {
return nil
kvs = append(kvs, delGuessGameStatusIndexKey(log.Status, log.Index)) }
kvs = append(kvs, delGuessGameAdminStatusIndexKey(log.Status, log.AdminAddr, log.Index))
kvs = append(kvs, delGuessGameCategoryStatusIndexKey(log.Status, log.Category, log.Index)) err = tablejoin.MustGetTable("user").Del([]byte(fmt.Sprintf("%018d", log.Index)))
if err != nil {
return nil
} }
kvs, _ = tablejoin.Save()
} else if log.StatusChange { } else if log.StatusChange {
//其他状态时的状态发生变化的情况,要将老状态对应的记录恢复,同时删除新加的状态记录;对于每个地址的下注记录也需要遍历处理。 //如果是其他状态下仅发生了状态变化,则需要恢复游戏状态,并更新游戏记录。
kvs = append(kvs, addGuessGameStatusIndexKey(log.PreStatus, log.GameID, log.PreIndex)) game := log.Game
kvs = append(kvs, addGuessGameAdminStatusIndexKey(log.PreStatus, log.AdminAddr, log.GameID, log.PreIndex)) log.Game = nil
kvs = append(kvs, addGuessGameCategoryStatusIndexKey(log.PreStatus, log.Category, log.GameID, log.PreIndex))
//先回滚游戏信息,再进行更新
kvs = append(kvs, delGuessGameStatusIndexKey(log.Status, log.Index)) g.rollbackGame(game, log)
kvs = append(kvs, delGuessGameAdminStatusIndexKey(log.Status, log.AdminAddr, log.Index))
kvs = append(kvs, delGuessGameCategoryStatusIndexKey(log.Status, log.Category, log.Index)) err = tablejoin.MustGetTable("game").Replace(game)
if err != nil {
//从game中遍历每个地址的记录进行删除新增记录,回复老记录 return nil
game, err := readGame(g.GetStateDB(), log.GameID)
if err == nil {
for i := 0; i < len(game.Plays); i++ {
player := game.Plays[i]
kvs = append(kvs, addGuessGameAddrStatusIndexKey(log.PreStatus, player.Addr, log.GameID, player.Bet.PreIndex))
kvs = append(kvs, delGuessGameAddrStatusIndexKey(log.Status, player.Addr, log.Index))
}
} }
kvs, _ = tablejoin.Save()
} }
return kvs return kvs
...@@ -62,8 +114,7 @@ func (g *Guess) execDelLocal(receipt *types.ReceiptData) (*types.LocalDBSet, err ...@@ -62,8 +114,7 @@ func (g *Guess) execDelLocal(receipt *types.ReceiptData) (*types.LocalDBSet, err
return dbSet, nil return dbSet, nil
} }
/* for _, log := range receipt.Logs {
for _, log := range receiptData.Logs {
switch log.GetTy() { switch log.GetTy() {
case gty.TyLogGuessGameStart, gty.TyLogGuessGameBet, gty.TyLogGuessGameStopBet, gty.TyLogGuessGameAbort, gty.TyLogGuessGamePublish, gty.TyLogGuessGameTimeout: case gty.TyLogGuessGameStart, gty.TyLogGuessGameBet, gty.TyLogGuessGameStopBet, gty.TyLogGuessGameAbort, gty.TyLogGuessGamePublish, gty.TyLogGuessGameTimeout:
receiptGame := &gty.ReceiptGuessGame{} receiptGame := &gty.ReceiptGuessGame{}
...@@ -73,28 +124,8 @@ func (g *Guess) execDelLocal(receipt *types.ReceiptData) (*types.LocalDBSet, err ...@@ -73,28 +124,8 @@ func (g *Guess) execDelLocal(receipt *types.ReceiptData) (*types.LocalDBSet, err
kv := g.rollbackIndex(receiptGame) kv := g.rollbackIndex(receiptGame)
dbSet.KV = append(dbSet.KV, kv...) dbSet.KV = append(dbSet.KV, kv...)
} }
}*/
table := gty.NewTable(g.GetLocalDB())
for _, item := range receipt.Logs {
var gameLog gty.ReceiptGuessGame
err := types.Decode(item.Log, &gameLog)
if err != nil {
return nil, err
}
gameLog.Status = gameLog.PreStatus
gameLog.Index = gameLog.PreIndex
err = table.Replace(&gameLog)
if err != nil {
return nil, err
}
kvs, err := table.Save()
if err != nil {
return nil, err
}
dbSet.KV = append(dbSet.KV, kvs...)
} }
return dbSet, nil return dbSet, nil
} }
......
...@@ -5,51 +5,75 @@ ...@@ -5,51 +5,75 @@
package executor package executor
import ( import (
"github.com/33cn/chain33/common/db/table"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
gty "github.com/33cn/plugin/plugin/dapp/guess/types" gty "github.com/33cn/plugin/plugin/dapp/guess/types"
) )
func (g *Guess) getUserBet(log *gty.ReceiptGuessGame) (userBet *gty.UserBet) {
userBet = &gty.UserBet{}
userBet.StartIndex = log.StartIndex
userBet.Index = log.Index
userBet.GameID = log.GameID
userBet.Addr = log.Addr
if log.Bet {
userBet.Option = log.Option
userBet.BetsNumber = log.BetsNumber
}
return userBet
}
func (g *Guess) updateIndex(log *gty.ReceiptGuessGame) (kvs []*types.KeyValue) { func (g *Guess) updateIndex(log *gty.ReceiptGuessGame) (kvs []*types.KeyValue) {
//新创建游戏 userTable := gty.NewGuessUserTable(g.GetLocalDB())
gameTable := gty.NewGuessGameTable(g.GetLocalDB())
tablejoin, err := table.NewJoinTable(userTable, gameTable, []string{"addr#status"})
if err != nil {
return nil
}
if log.Status == gty.GuessGameStatusStart { if log.Status == gty.GuessGameStatusStart {
//kvs = append(kvs, addGuessGameAddrIndexKey(log.Status, log.Addr, log.GameId, log.Index)) //新创建游戏,game表新增记录
kvs = append(kvs, addGuessGameStatusIndexKey(log.Status, log.GameID, log.Index)) game := log.Game
kvs = append(kvs, addGuessGameAdminIndexKey(log.Status, log.AdminAddr, log.GameID, log.Index)) log.Game = nil
kvs = append(kvs, addGuessGameAdminStatusIndexKey(log.Status, log.AdminAddr, log.GameID, log.Index))
kvs = append(kvs, addGuessGameCategoryStatusIndexKey(log.Status, log.Category, log.GameID, log.Index)) err = tablejoin.MustGetTable("game").Replace(game)
if err != nil {
return nil
}
kvs, _ = tablejoin.Save()
return kvs
} else if log.Status == gty.GuessGameStatusBet { } else if log.Status == gty.GuessGameStatusBet {
//如果是下注状态,则有用户进行了下注操作 //用户下注,game表发生更新(game中下注信息有更新),user表新增下注记录
kvs = append(kvs, addGuessGameAddrIndexKey(log.Status, log.Addr, log.GameID, log.Index)) game := log.Game
kvs = append(kvs, addGuessGameAddrStatusIndexKey(log.Status, log.Addr, log.GameID, log.Index)) log.Game = nil
//如果发生了状态变化,则是从start->bet,对于老状态的记录进行删除操作,并增加新状态记录 userBet := g.getUserBet(log)
if log.StatusChange {
kvs = append(kvs, addGuessGameStatusIndexKey(log.Status, log.GameID, log.Index)) err = tablejoin.MustGetTable("game").Replace(game)
kvs = append(kvs, addGuessGameAdminStatusIndexKey(log.Status, log.AdminAddr, log.GameID, log.Index)) if err != nil {
kvs = append(kvs, addGuessGameCategoryStatusIndexKey(log.Status, log.Category, log.GameID, log.Index)) return nil
}
kvs = append(kvs, delGuessGameStatusIndexKey(log.PreStatus, log.PreIndex))
kvs = append(kvs, delGuessGameAdminStatusIndexKey(log.PreStatus, log.AdminAddr, log.PreIndex)) err = tablejoin.MustGetTable("user").Replace(userBet)
kvs = append(kvs, delGuessGameCategoryStatusIndexKey(log.PreStatus, log.Category, log.PreIndex)) if err != nil {
return nil
} }
kvs, _ = tablejoin.Save()
return kvs
} else if log.StatusChange { } else if log.StatusChange {
//其他状态时的状态发生变化,要将老状态对应的记录删除,同时加入新状态记录;对于每个地址的下注记录也需要遍历处理。 //其他状态,游戏状态变化,只需要更新game表
kvs = append(kvs, addGuessGameStatusIndexKey(log.Status, log.GameID, log.Index)) game := log.Game
kvs = append(kvs, addGuessGameAdminStatusIndexKey(log.Status, log.AdminAddr, log.GameID, log.Index)) log.Game = nil
kvs = append(kvs, addGuessGameCategoryStatusIndexKey(log.Status, log.Category, log.GameID, log.Index))
err = tablejoin.MustGetTable("game").Replace(game)
kvs = append(kvs, delGuessGameStatusIndexKey(log.PreStatus, log.PreIndex)) if err != nil {
kvs = append(kvs, delGuessGameAdminStatusIndexKey(log.PreStatus, log.AdminAddr, log.PreIndex)) return nil
kvs = append(kvs, delGuessGameCategoryStatusIndexKey(log.PreStatus, log.Category, log.PreIndex))
//从game中遍历每个地址的记录进行新状态记录的增和老状态记录的删除
game, err := readGame(g.GetStateDB(), log.GameID)
if err == nil {
for i := 0; i < len(game.Plays); i++ {
player := game.Plays[i]
kvs = append(kvs, addGuessGameAddrStatusIndexKey(log.Status, player.Addr, log.GameID, log.Index))
kvs = append(kvs, delGuessGameAddrStatusIndexKey(log.PreStatus, player.Addr, player.Bet.PreIndex))
}
} }
kvs, _ = tablejoin.Save()
return kvs
} }
return kvs return kvs
...@@ -61,22 +85,6 @@ func (g *Guess) execLocal(receipt *types.ReceiptData) (*types.LocalDBSet, error) ...@@ -61,22 +85,6 @@ func (g *Guess) execLocal(receipt *types.ReceiptData) (*types.LocalDBSet, error)
return dbSet, nil return dbSet, nil
} }
/*
for i := 0; i < len(receipt.Logs); i++ {
item := receipt.Logs[i]
if item.Ty >= gty.TyLogGuessGameStart && item.Ty <= gty.TyLogGuessGameTimeout {
var Gamelog gty.ReceiptGuessGame
err := types.Decode(item.Log, &Gamelog)
if err != nil {
panic(err) //数据错误了,已经被修改了
}
kv := g.updateIndex(&Gamelog)
dbSet.KV = append(dbSet.KV, kv...)
}
}
*/
table := gty.NewTable(g.GetLocalDB())
for _, item := range receipt.Logs { for _, item := range receipt.Logs {
if item.Ty >= gty.TyLogGuessGameStart && item.Ty <= gty.TyLogGuessGameTimeout { if item.Ty >= gty.TyLogGuessGameStart && item.Ty <= gty.TyLogGuessGameTimeout {
var gameLog gty.ReceiptGuessGame var gameLog gty.ReceiptGuessGame
...@@ -84,14 +92,7 @@ func (g *Guess) execLocal(receipt *types.ReceiptData) (*types.LocalDBSet, error) ...@@ -84,14 +92,7 @@ func (g *Guess) execLocal(receipt *types.ReceiptData) (*types.LocalDBSet, error)
if err != nil { if err != nil {
return nil, err return nil, err
} }
err = table.Replace(&gameLog) kvs := g.updateIndex(&gameLog)
if err != nil {
return nil, err
}
kvs, err := table.Save()
if err != nil {
return nil, err
}
dbSet.KV = append(dbSet.KV, kvs...) dbSet.KV = append(dbSet.KV, kvs...)
} }
} }
......
This diff is collapsed.
package executor
import (
"fmt"
"github.com/33cn/chain33/types"
gty "github.com/33cn/plugin/plugin/dapp/guess/types"
)
//addr prefix
func calcGuessGameAddrPrefix(addr string) []byte {
key := fmt.Sprintf("LODB-guess-addr:%s:", addr)
return []byte(key)
}
//addr index
func calcGuessGameAddrKey(addr string, index int64) []byte {
key := fmt.Sprintf("LODB-guess-addr:%s:%018d", addr, index)
return []byte(key)
}
//status prefix
func calcGuessGameStatusPrefix(status int32) []byte {
key := fmt.Sprintf("LODB-guess-status-index:%d:", status)
return []byte(key)
}
//status index
func calcGuessGameStatusKey(status int32, index int64) []byte {
key := fmt.Sprintf("LODB-guess-status-index:%d:%018d", status, index)
return []byte(key)
}
//addr status prefix
func calcGuessGameAddrStatusPrefix(addr string, status int32) []byte {
key := fmt.Sprintf("LODB-guess-addr-status-index:%s:%d:", addr, status)
return []byte(key)
}
//addr status index
func calcGuessGameAddrStatusKey(addr string, status int32, index int64) []byte {
key := fmt.Sprintf("LODB-guess-addr-status-index:%s:%d:%018d", addr, status, index)
return []byte(key)
}
//admin prefix
func calcGuessGameAdminPrefix(addr string) []byte {
key := fmt.Sprintf("LODB-guess-admin:%s:", addr)
return []byte(key)
}
//admin index
func calcGuessGameAdminKey(addr string, index int64) []byte {
key := fmt.Sprintf("LODB-guess-admin:%s:%018d", addr, index)
return []byte(key)
}
//admin status prefix
func calcGuessGameAdminStatusPrefix(admin string, status int32) []byte {
key := fmt.Sprintf("LODB-guess-admin-status-index:%s:%d:", admin, status)
return []byte(key)
}
//admin status index
func calcGuessGameAdminStatusKey(admin string, status int32, index int64) []byte {
key := fmt.Sprintf("LODB-guess-admin-status-index:%s:%d:%018d", admin, status, index)
return []byte(key)
}
func calcGuessGameCategoryStatusPrefix(category string, status int32) []byte {
key := fmt.Sprintf("LODB-guess-category-status-index:%s:%d:", category, status)
return []byte(key)
}
func calcGuessGameCategoryStatusKey(category string, status int32, index int64) []byte {
key := fmt.Sprintf("LODB-guess-category-status-index:%s:%d:%018d", category, status, index)
return []byte(key)
}
func addGuessGameAddrIndexKey(status int32, addr, gameID string, index int64) *types.KeyValue {
kv := &types.KeyValue{}
kv.Key = calcGuessGameAddrKey(addr, index)
record := &gty.GuessGameRecord{
GameID: gameID,
Status: status,
Index: index,
}
kv.Value = types.Encode(record)
return kv
}
func delGuessGameAddrIndexKey(addr string, index int64) *types.KeyValue {
kv := &types.KeyValue{}
kv.Key = calcGuessGameAddrKey(addr, index)
kv.Value = nil
return kv
}
func addGuessGameStatusIndexKey(status int32, gameID string, index int64) *types.KeyValue {
kv := &types.KeyValue{}
kv.Key = calcGuessGameStatusKey(status, index)
record := &gty.GuessGameRecord{
GameID: gameID,
Status: status,
Index: index,
}
kv.Value = types.Encode(record)
return kv
}
func delGuessGameStatusIndexKey(status int32, index int64) *types.KeyValue {
kv := &types.KeyValue{}
kv.Key = calcGuessGameStatusKey(status, index)
kv.Value = nil
return kv
}
func addGuessGameAddrStatusIndexKey(status int32, addr, gameID string, index int64) *types.KeyValue {
kv := &types.KeyValue{}
kv.Key = calcGuessGameAddrStatusKey(addr, status, index)
record := &gty.GuessGameRecord{
GameID: gameID,
Status: status,
Index: index,
}
kv.Value = types.Encode(record)
return kv
}
func delGuessGameAddrStatusIndexKey(status int32, addr string, index int64) *types.KeyValue {
kv := &types.KeyValue{}
kv.Key = calcGuessGameAddrStatusKey(addr, status, index)
kv.Value = nil
return kv
}
func addGuessGameAdminIndexKey(status int32, addr, gameID string, index int64) *types.KeyValue {
kv := &types.KeyValue{}
kv.Key = calcGuessGameAdminKey(addr, index)
record := &gty.GuessGameRecord{
GameID: gameID,
Status: status,
Index: index,
}
kv.Value = types.Encode(record)
return kv
}
func delGuessGameAdminIndexKey(addr string, index int64) *types.KeyValue {
kv := &types.KeyValue{}
kv.Key = calcGuessGameAdminKey(addr, index)
kv.Value = nil
return kv
}
func addGuessGameAdminStatusIndexKey(status int32, addr, gameID string, index int64) *types.KeyValue {
kv := &types.KeyValue{}
kv.Key = calcGuessGameAdminStatusKey(addr, status, index)
record := &gty.GuessGameRecord{
GameID: gameID,
Status: status,
Index: index,
}
kv.Value = types.Encode(record)
return kv
}
func delGuessGameAdminStatusIndexKey(status int32, addr string, index int64) *types.KeyValue {
kv := &types.KeyValue{}
kv.Key = calcGuessGameAdminStatusKey(addr, status, index)
kv.Value = nil
return kv
}
func addGuessGameCategoryStatusIndexKey(status int32, category, gameID string, index int64) *types.KeyValue {
kv := &types.KeyValue{}
kv.Key = calcGuessGameCategoryStatusKey(category, status, index)
record := &gty.GuessGameRecord{
GameID: gameID,
Status: status,
Index: index,
}
kv.Value = types.Encode(record)
return kv
}
func delGuessGameCategoryStatusIndexKey(status int32, category string, index int64) *types.KeyValue {
kv := &types.KeyValue{}
kv.Key = calcGuessGameCategoryStatusKey(category, status, index)
kv.Value = nil
return kv
}
...@@ -5,80 +5,79 @@ ...@@ -5,80 +5,79 @@
package executor package executor
import ( import (
"fmt"
"github.com/33cn/chain33/common/db/table"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
gty "github.com/33cn/plugin/plugin/dapp/guess/types" gty "github.com/33cn/plugin/plugin/dapp/guess/types"
) )
//Query_QueryGamesByIDs method //Query_QueryGamesByIDs method
func (g *Guess) Query_QueryGamesByIDs(in *gty.QueryGuessGameInfos) (types.Message, error) { func (g *Guess) Query_QueryGamesByIDs(in *gty.QueryGuessGameInfos) (types.Message, error) {
return Infos(g.GetStateDB(), in) return QueryGameInfos(g.GetLocalDB(), in)
} }
//Query_QueryGameByID method //Query_QueryGameByID method
func (g *Guess) Query_QueryGameByID(in *gty.QueryGuessGameInfo) (types.Message, error) { func (g *Guess) Query_QueryGameByID(in *gty.QueryGuessGameInfo) (types.Message, error) {
game, err := readGame(g.GetStateDB(), in.GetGameID()) game, err := QueryGameInfo(g.GetLocalDB(), []byte(in.GetGameID()))
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &gty.ReplyGuessGameInfo{Game: game}, nil return &gty.ReplyGuessGameInfo{Game: game}, nil
} }
//Query_QueryGamesByAddr method //Query_QueryGamesByAddr method
func (g *Guess) Query_QueryGamesByAddr(in *gty.QueryGuessGameInfo) (types.Message, error) { func (g *Guess) Query_QueryGamesByAddr(in *gty.QueryGuessGameInfo) (types.Message, error) {
records, err := getGameListByAddr(g.GetLocalDB(), in.Addr, in.Index) gameTable := gty.NewGuessUserTable(g.GetLocalDB())
if err != nil { query := gameTable.GetQuery(g.GetLocalDB())
return nil, err
}
return records, nil return QueryUserTableData(query, "addr", []byte(in.Addr), in.PrimaryKey)
} }
//Query_QueryGamesByStatus method //Query_QueryGamesByStatus method
func (g *Guess) Query_QueryGamesByStatus(in *gty.QueryGuessGameInfo) (types.Message, error) { func (g *Guess) Query_QueryGamesByStatus(in *gty.QueryGuessGameInfo) (types.Message, error) {
records, err := getGameListByStatus(g.GetLocalDB(), in.Status, in.Index) gameTable := gty.NewGuessGameTable(g.GetLocalDB())
if err != nil { query := gameTable.GetQuery(g.GetLocalDB())
return nil, err
}
return records, nil return QueryGameTableData(query, "status", []byte(fmt.Sprintf("%2d", in.Status)), in.PrimaryKey)
} }
//Query_QueryGamesByAdminAddr method //Query_QueryGamesByAdminAddr method
func (g *Guess) Query_QueryGamesByAdminAddr(in *gty.QueryGuessGameInfo) (types.Message, error) { func (g *Guess) Query_QueryGamesByAdminAddr(in *gty.QueryGuessGameInfo) (types.Message, error) {
records, err := getGameListByAdminAddr(g.GetLocalDB(), in.AdminAddr, in.Index) gameTable := gty.NewGuessGameTable(g.GetLocalDB())
if err != nil { query := gameTable.GetQuery(g.GetLocalDB())
return nil, err prefix := []byte(in.AdminAddr)
} return QueryGameTableData(query, "admin", prefix, in.PrimaryKey)
return records, nil
} }
//Query_QueryGamesByAddrStatus method //Query_QueryGamesByAddrStatus method
func (g *Guess) Query_QueryGamesByAddrStatus(in *gty.QueryGuessGameInfo) (types.Message, error) { func (g *Guess) Query_QueryGamesByAddrStatus(in *gty.QueryGuessGameInfo) (types.Message, error) {
records, err := getGameListByAddrStatus(g.GetLocalDB(), in.Addr, in.Status, in.Index) userTable := gty.NewGuessUserTable(g.GetLocalDB())
gameTable := gty.NewGuessGameTable(g.GetLocalDB())
tableJoin, err := table.NewJoinTable(userTable, gameTable, []string{"addr#status"})
if err != nil { if err != nil {
return nil, err return nil, err
} }
return records, nil prefix := table.JoinKey([]byte(fmt.Sprintf("%s", in.Addr)), []byte(fmt.Sprintf("%2d", in.Status)))
return QueryJoinTableData(tableJoin, "addr#status", prefix, in.PrimaryKey)
} }
//Query_QueryGamesByAdminStatus method //Query_QueryGamesByAdminStatus method
func (g *Guess) Query_QueryGamesByAdminStatus(in *gty.QueryGuessGameInfo) (types.Message, error) { func (g *Guess) Query_QueryGamesByAdminStatus(in *gty.QueryGuessGameInfo) (types.Message, error) {
records, err := getGameListByAdminStatus(g.GetLocalDB(), in.AdminAddr, in.Status, in.Index) gameTable := gty.NewGuessGameTable(g.GetLocalDB())
if err != nil { query := gameTable.GetQuery(g.GetLocalDB())
return nil, err prefix := []byte(fmt.Sprintf("%s:%2d", in.AdminAddr, in.Status))
}
return records, nil return QueryGameTableData(query, "admin_status", prefix, in.PrimaryKey)
} }
//Query_QueryGamesByCategoryStatus method //Query_QueryGamesByCategoryStatus method
func (g *Guess) Query_QueryGamesByCategoryStatus(in *gty.QueryGuessGameInfo) (types.Message, error) { func (g *Guess) Query_QueryGamesByCategoryStatus(in *gty.QueryGuessGameInfo) (types.Message, error) {
records, err := getGameListByCategoryStatus(g.GetLocalDB(), in.Category, in.Status, in.Index) gameTable := gty.NewGuessGameTable(g.GetLocalDB())
if err != nil { query := gameTable.GetQuery(g.GetLocalDB())
return nil, err prefix := []byte(fmt.Sprintf("%s:%2d", in.Category, in.Status))
}
return records, nil return QueryGameTableData(query, "category_status", prefix, in.PrimaryKey)
} }
...@@ -12,25 +12,26 @@ message GuessGame { ...@@ -12,25 +12,26 @@ message GuessGame {
int64 startTime = 4; //创建游戏的时间 int64 startTime = 4; //创建游戏的时间
int64 startHeight = 5; //创建游戏的时间 int64 startHeight = 5; //创建游戏的时间
string startTxHash = 6; //创建游戏的交易hash string startTxHash = 6; //创建游戏的交易hash
string topic = 7; //主题 int64 startIndex = 7; //创建游戏的交易index
string category = 8; //分类 string topic = 8; //主题
string options = 9; //选项 string category = 9; //分类
int64 maxBetHeight = 10; //截止下注的块高 string options = 10; //选项
int64 maxBetsOneTime = 11; //单次可以下多少注,默认100 int64 maxBetHeight = 11; //截止下注的块高
int64 maxBetsNumber = 12; //最多可以下多少注 int64 maxBetsOneTime = 12; //单次可以下多少注,默认100
int64 devFeeFactor = 13; //开发者抽成比例 int64 maxBetsNumber = 13; //最多可以下多少注
string devFeeAddr = 14; //开发者地址 int64 devFeeFactor = 14; //开发者抽成比例
int64 platFeeFactor = 15; //平台抽成比例 string devFeeAddr = 15; //开发者地址
string platFeeAddr = 16; //平台地址 int64 platFeeFactor = 16; //平台抽成比例
int64 expireHeight = 17; //游戏过期区块高度 string platFeeAddr = 17; //平台地址
string adminAddr = 18; //游戏创建者地址,只有该地址可以开奖 int64 expireHeight = 18; //游戏过期区块高度
int64 betsNumber = 19; //已下注数,如果数量达到maxBetsNumber,则不允许再下注 string adminAddr = 19; //游戏创建者地址,只有该地址可以开奖
repeated GuessPlayer plays = 20; //参与游戏下注的玩家投注信息 int64 betsNumber = 20; //已下注数,如果数量达到maxBetsNumber,则不允许再下注
string result = 21; //公布的中奖结果 repeated GuessPlayer plays = 21; //参与游戏下注的玩家投注信息
GuessBetStat betStat = 22; string result = 22; //公布的中奖结果
int64 index = 23; GuessBetStat betStat = 23;
int64 preIndex = 24; int64 index = 24;
bool drivenByAdmin = 25; int64 preIndex = 25;
bool drivenByAdmin = 26;
} }
//GuessPlayer 竞猜玩家信息 //GuessPlayer 竞猜玩家信息
...@@ -129,6 +130,7 @@ message QueryGuessGameInfo { ...@@ -129,6 +130,7 @@ message QueryGuessGameInfo {
int64 index = 4; int64 index = 4;
string adminAddr = 5; string adminAddr = 5;
string category = 6; string category = 6;
bytes primaryKey = 7;
} }
//ReplyGuessGameInfo 游戏信息查询响应消息 //ReplyGuessGameInfo 游戏信息查询响应消息
...@@ -148,15 +150,30 @@ message ReplyGuessGameInfos { ...@@ -148,15 +150,30 @@ message ReplyGuessGameInfos {
//ReceiptGuessGame 竞猜游戏收据信息 //ReceiptGuessGame 竞猜游戏收据信息
message ReceiptGuessGame { message ReceiptGuessGame {
string gameID = 1; int64 startIndex = 1;
int32 preStatus = 2; string gameID = 2;
int32 status = 3; int32 preStatus = 3;
int32 status = 4;
string addr = 5;
string adminAddr = 6;
int64 preIndex = 7;
int64 index = 8;
string category = 9;
bool statusChange = 10;
bool bet = 11;
string option = 12;
int64 betsNumber = 13;
GuessGame game = 14;
}
//UserBet 用户下注信息
message UserBet {
int64 startIndex = 1;
int64 index = 2;
string gameID = 3;
string addr = 4; string addr = 4;
string adminAddr = 5; string option = 5;
int64 preIndex = 6; int64 betsNumber = 6;
int64 index = 7;
string category = 8;
bool statusChange = 9;
} }
//GuessStartTxReq 构造start交易的请求 //GuessStartTxReq 构造start交易的请求
...@@ -206,13 +223,13 @@ message GuessPublishTxReq { ...@@ -206,13 +223,13 @@ message GuessPublishTxReq {
// GuessGameRecord game信息查询记录 // GuessGameRecord game信息查询记录
message GuessGameRecord { message GuessGameRecord {
string gameID = 1; string gameID = 1;
int32 status = 2; int64 startIndex = 2;
int64 index = 3;
} }
// GuessGameRecords game信息查询记录集 // GuessGameRecords game信息查询记录集
message GuessGameRecords { message GuessGameRecords {
repeated GuessGameRecord records = 1; repeated GuessGameRecord records = 1;
bytes primaryKey = 2;
} }
......
...@@ -11,4 +11,8 @@ var ( ...@@ -11,4 +11,8 @@ var (
ErrNoPrivilege = errors.New("ErrNoPrivilege") ErrNoPrivilege = errors.New("ErrNoPrivilege")
ErrGuessStatus = errors.New("ErrGuessStatus") ErrGuessStatus = errors.New("ErrGuessStatus")
ErrOverBetsLimit = errors.New("ErrOverBetsLimit") ErrOverBetsLimit = errors.New("ErrOverBetsLimit")
ErrParamStatusInvalid = errors.New("ErrParamStatusInvalid")
ErrParamAddressMustnotEmpty = errors.New("ErrParamAddressMustnotEmpty")
ErrGameNotExist = errors.New("ErrGameNotExist")
ErrSaveTable = errors.New("ErrSaveTable")
) )
This diff is collapsed.
...@@ -15,17 +15,17 @@ data: guess ...@@ -15,17 +15,17 @@ data: guess
index: addr,status,addr_status,admin,admin_status,category_status index: addr,status,addr_status,admin,admin_status,category_status
*/ */
var opt = &table.Option{ var opt_guess_user = &table.Option{
Prefix: "LODB", Prefix: "LODB_guess",
Name: "guess", Name: "user",
Primary: "gameid", Primary: "index",
Index: []string{"addr", "status", "addr_status", "admin", "admin_status", "category_status"}, Index: []string{"addr", "startindex"},
} }
//NewTable 新建表 //NewTable 新建表
func NewTable(kvdb db.KV) *table.Table { func NewGuessUserTable(kvdb db.KV) *table.Table {
rowmeta := NewGuessRow() rowmeta := NewGuessUserRow()
table, err := table.NewTable(rowmeta, kvdb, opt) table, err := table.NewTable(rowmeta, kvdb, opt_guess_user)
if err != nil { if err != nil {
panic(err) panic(err)
} }
...@@ -33,39 +33,91 @@ func NewTable(kvdb db.KV) *table.Table { ...@@ -33,39 +33,91 @@ func NewTable(kvdb db.KV) *table.Table {
} }
//OracleRow table meta 结构 //OracleRow table meta 结构
type GuessRow struct { type GuessUserRow struct {
*ReceiptGuessGame *UserBet
} }
//NewOracleRow 新建一个meta 结构 //NewOracleRow 新建一个meta 结构
func NewGuessRow() *GuessRow { func NewGuessUserRow() *GuessUserRow {
return &GuessRow{ReceiptGuessGame: &ReceiptGuessGame{}} return &GuessUserRow{UserBet: &UserBet{}}
} }
//CreateRow 新建数据行(注意index 数据一定也要保存到数据中,不能就保存eventid) //CreateRow 新建数据行(注意index 数据一定也要保存到数据中,不能就保存eventid)
func (tx *GuessRow) CreateRow() *table.Row { func (tx *GuessUserRow) CreateRow() *table.Row {
return &table.Row{Data: &ReceiptGuessGame{}} return &table.Row{Data: &ReceiptGuessGame{}}
} }
//SetPayload 设置数据 //SetPayload 设置数据
func (tx *GuessRow) SetPayload(data types.Message) error { func (tx *GuessUserRow) SetPayload(data types.Message) error {
if txdata, ok := data.(*ReceiptGuessGame); ok { if txdata, ok := data.(*UserBet); ok {
tx.ReceiptGuessGame = txdata tx.UserBet = txdata
return nil return nil
} }
return types.ErrTypeAsset return types.ErrTypeAsset
} }
//Get 按照indexName 查询 indexValue //Get 按照indexName 查询 indexValue
func (tx *GuessRow) Get(key string) ([]byte, error) { func (tx *GuessUserRow) Get(key string) ([]byte, error) {
if key == "gameid" { if key == "index" {
return []byte(tx.GameID), nil return []byte(fmt.Sprintf("%018d", tx.Index)), nil
} else if key == "addr" {
return []byte(fmt.Sprintf("%s", tx.Addr)), nil
} else if key == "startindex" {
return []byte(fmt.Sprintf("%018d", tx.StartIndex)), nil
}
return nil, types.ErrNotFound
}
var opt_guess_game = &table.Option{
Prefix: "LODB_guess",
Name: "game",
Primary: "startindex",
Index: []string{"gameid", "status","admin","admin_status", "category_status"},
}
//NewTable 新建表
func NewGuessGameTable(kvdb db.KV) *table.Table {
rowmeta := NewGuessGameRow()
table, err := table.NewTable(rowmeta, kvdb, opt_guess_game)
if err != nil {
panic(err)
}
return table
}
//OracleRow table meta 结构
type GuessGameRow struct {
*GuessGame
}
//NewOracleRow 新建一个meta 结构
func NewGuessGameRow() *GuessGameRow {
return &GuessGameRow{GuessGame: &GuessGame{}}
}
//CreateRow 新建数据行(注意index 数据一定也要保存到数据中,不能就保存eventid)
func (tx *GuessGameRow) CreateRow() *table.Row {
return &table.Row{Data: &GuessGame{}}
}
//SetPayload 设置数据
func (tx *GuessGameRow) SetPayload(data types.Message) error {
if txdata, ok := data.(*GuessGame); ok {
tx.GuessGame = txdata
return nil
}
return types.ErrTypeAsset
}
//Get 按照indexName 查询 indexValue
func (tx *GuessGameRow) Get(key string) ([]byte, error) {
if key == "startindex"{
return []byte(fmt.Sprintf("%018d", tx.StartIndex)), nil
}else if key == "gameid" {
return []byte(fmt.Sprintf("%s", tx.GameID)), nil
} else if key == "status" { } else if key == "status" {
return []byte(fmt.Sprintf("%2d", tx.Status)), nil return []byte(fmt.Sprintf("%2d", tx.Status)), nil
} else if key == "addr" {
return []byte(tx.Addr), nil
} else if key == "addr_status" {
return []byte(fmt.Sprintf("%s:%2d", tx.Addr, tx.Status)), nil
} else if key == "admin" { } else if key == "admin" {
return []byte(tx.AdminAddr), nil return []byte(tx.AdminAddr), nil
}else if key == "admin_status" { }else if key == "admin_status" {
...@@ -73,5 +125,6 @@ func (tx *GuessRow) Get(key string) ([]byte, error) { ...@@ -73,5 +125,6 @@ func (tx *GuessRow) Get(key string) ([]byte, error) {
} else if key == "category_status" { } else if key == "category_status" {
return []byte(fmt.Sprintf("%s:%2d", tx.Category, tx.Status)), nil return []byte(fmt.Sprintf("%s:%2d", tx.Category, tx.Status)), nil
} }
return nil, types.ErrNotFound return nil, types.ErrNotFound
} }
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment