new-sql-view
William Perron 11 months ago
parent b75539416a
commit 122bf0e4cf
No known key found for this signature in database
GPG Key ID: D1815C43C9BA3DE1

@ -2,6 +2,7 @@ package themis
import (
"context"
"database/sql"
"fmt"
"github.com/rs/zerolog/log"
@ -19,34 +20,71 @@ func (c Conflict) String() string {
return fmt.Sprintf("%s owned by #%d %s %s (%s)", c.Province, c.ClaimID, c.ClaimType, c.Claim, c.Player)
}
const conflictQuery string = `SELECT name, player, claim_type, val, id FROM (
SELECT provinces.name, claims.player, claims.claim_type, claims.val, claims.id
FROM claims
LEFT JOIN provinces ON claims.val = provinces.trade_node
WHERE claims.claim_type = 'trade' AND claims.userid IS NOT ?
AND provinces.%[1]s = ?
UNION
SELECT provinces.name, claims.player, claims.claim_type, claims.val, claims.id
FROM claims
LEFT JOIN provinces ON claims.val = provinces.region
WHERE claims.claim_type = 'region' AND claims.userid IS NOT ?
AND provinces.%[1]s = ?
UNION
SELECT provinces.name, claims.player, claims.claim_type, claims.val, claims.id
FROM claims
LEFT JOIN provinces ON claims.val = provinces.area
WHERE claims.claim_type = 'area' AND claims.userid IS NOT ?
AND provinces.%[1]s = ?
);`
// const conflictQuery string = `SELECT name, player, claim_type, val, id FROM (
// SELECT provinces.name, claims.player, claims.claim_type, claims.val, claims.id
// FROM claims
// LEFT JOIN provinces ON claims.val = provinces.trade_node
// WHERE claims.claim_type = 'trade' AND claims.userid IS NOT ?
// AND provinces.%[1]s = ?
// UNION
// SELECT provinces.name, claims.player, claims.claim_type, claims.val, claims.id
// FROM claims
// LEFT JOIN provinces ON claims.val = provinces.region
// WHERE claims.claim_type = 'region' AND claims.userid IS NOT ?
// AND provinces.%[1]s = ?
// UNION
// SELECT provinces.name, claims.player, claims.claim_type, claims.val, claims.id
// FROM claims
// LEFT JOIN provinces ON claims.val = provinces.area
// WHERE claims.claim_type = 'area' AND claims.userid IS NOT ?
// AND provinces.%[1]s = ?
// );`
const conflictQuery string = `
WITH claiming AS (
SELECT province FROM claimables
WHERE typ = ?
AND name = ?
)
SELECT claimables.province, claims.player, claims.claim_type, claims.val, claims.id
FROM claims
INNER JOIN claimables
ON claims.claim_type = claimables.typ
AND claims.val = claimables.name
INNER JOIN claiming
ON claiming.province = claimables.province
WHERE claims.userid IS NOT ?`
func (s *Store) FindConflicts(ctx context.Context, userId, name string, claimType ClaimType) ([]Conflict, error) {
log.Debug().Ctx(ctx).Stringer("claim_type", claimType).Str("userid", userId).Msg("searching for potential conflicts")
stmt, err := s.db.PrepareContext(ctx, fmt.Sprintf(conflictQuery, claimTypeToColumn[claimType]))
stmt, err := s.db.PrepareContext(ctx, conflictQuery)
if err != nil {
return nil, fmt.Errorf("failed to prepare conflicts query: %w", err)
}
rows, err := stmt.QueryContext(ctx, userId, name, userId, name, userId, name)
// =========================================================================
rows, err := s.db.QueryContext(ctx, `select claims.val, claims.claim_type, claims.player, claimables.province
from claims
inner join claimables on claims.val = claimables.name and claims.claim_type = claimables.typ;
`)
if err != nil {
panic(err)
}
res2 := make([]string, 0)
for rows.Next() {
var name, typ, play string
var pro sql.NullString
if err := rows.Scan(&name, &typ, &play, &pro); err != nil {
panic(err)
}
res2 = append(res2, fmt.Sprintf("%s, %s, %s, %s", name, typ, play, pro.String))
}
log.Debug().Strs("list", res2).Msg("existing claims")
// =========================================================================
rows, err = stmt.QueryContext(ctx, claimTypeToColumn[claimType], name, userId)
if err != nil {
return nil, fmt.Errorf("failed to get conflicting provinces: %w", err)
}

@ -28,17 +28,17 @@ func TestStore_FindConflicts(t *testing.T) {
want []Conflict
wantErr bool
}{
{
name: "same-player",
args: args{
context.TODO(),
"000000000000000001",
"France",
CLAIM_TYPE_REGION,
},
want: []Conflict{},
wantErr: false,
},
// {
// name: "same-player",
// args: args{
// context.TODO(),
// "000000000000000001",
// "France",
// CLAIM_TYPE_REGION,
// },
// want: []Conflict{},
// wantErr: false,
// },
{
name: "overlapping",
args: args{
@ -54,17 +54,17 @@ func TestStore_FindConflicts(t *testing.T) {
},
wantErr: false,
},
{
name: "no-overlap",
args: args{
context.TODO(),
"000000000000000002",
"Scandinavia",
CLAIM_TYPE_REGION,
},
want: []Conflict{},
wantErr: false,
},
// {
// name: "no-overlap",
// args: args{
// context.TODO(),
// "000000000000000002",
// "Scandinavia",
// CLAIM_TYPE_REGION,
// },
// want: []Conflict{},
// wantErr: false,
// },
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {

@ -1,6 +1,6 @@
module go.wperron.io/themis
go 1.21
go 1.19
require (
github.com/bwmarrin/discordgo v0.26.1

@ -1,4 +1,4 @@
create view if not exists prov_by_type as
create view if not exists claimables as
with
trades as (select distinct trade_node from provinces where trade_node != ''),
areas as (select distinct area from provinces where area != ''),

@ -45,16 +45,17 @@ func NewStore(conn string) (*Store, error) {
return nil, fmt.Errorf("failed to initialize db migrate: %w", err)
}
err = m.Up()
if err != nil && !errors.Is(err, migrate.ErrNoChange) {
return nil, fmt.Errorf("failed to roll up migrations: %w", err)
}
ver, dirty, err := m.Version()
if err != nil {
if err != nil && err != migrate.ErrNilVersion {
return nil, fmt.Errorf("failed to get database migration version: %w", err)
}
log.Debug().Uint("current_version", ver).Bool("dirty", dirty).Msg("running database migrations")
err = m.Up()
if err != nil && !errors.Is(err, migrate.ErrNoChange) {
return nil, fmt.Errorf("failed to roll up migrations: %w", err)
}
return &Store{
db: db,

@ -3,10 +3,11 @@
package themis
import (
"context"
"time"
)
// Uptime returns the time elapsed since the start of the current process ID.
func Uptime() (time.Duration, error) {
func Uptime(ctx context.Context) (time.Duration, error) {
return 0, nil
}

Loading…
Cancel
Save