package mdb import ( "context" _ "embed" "zombiezen.com/go/sqlite/sqlitex" "git.sunturtle.xyz/zephyr/horse" ) var ( //go:embed sql/spark.sql sparkSQL string //go:embed sql/spark-effect.sql sparkEffectSQL string ) func Sparks(ctx context.Context, db *sqlitex.Pool) ([]horse.Spark, error) { // We don't use func load here because we have multiple queries to run. conn, err := db.Take(ctx) defer db.Put(conn) if err != nil { return nil, err } var sp []horse.Spark { stmt := conn.Prep(sparkSQL) for { ok, err := stmt.Step() if err != nil { return nil, err } if !ok { break } sp = append(sp, horse.Spark{ ID: horse.SparkID(stmt.ColumnInt(0)), Name: stmt.ColumnText(1), Description: stmt.ColumnText(2), Group: horse.SparkGroupID(stmt.ColumnInt(3)), Rarity: horse.SparkRarity(stmt.ColumnInt(4)), Type: horse.SparkType(stmt.ColumnInt(5)), // Effects filled in later, but we can start with space. // The vast majority of sparks are skill sparks, // which have five rolls. Effects: make([][]horse.SparkEffect, 0, 5), }) } } stmt := conn.Prep(sparkEffectSQL) cur := sp last := 0 for { ok, err := stmt.Step() if err != nil { return nil, err } if !ok { break } // We sort sparks by group ID first, so we can add effects in a single pass. group := stmt.ColumnInt(0) for len(cur) > 0 && cur[0].Group != horse.SparkGroupID(group) { cur = cur[1:] last = 0 // reset whenever we change group IDs } effect := stmt.ColumnInt(1) if effect != last { // This effect is a separate roll from the previous one. // Create a new slot for the effects to go into. for i := range cur { if cur[i].Group != horse.SparkGroupID(group) { break } cur[i].Effects = append(cur[i].Effects, make([]horse.SparkEffect, 0, 1)) } last = effect } for i := range cur { if cur[i].Group != horse.SparkGroupID(group) { break } e := horse.SparkEffect{ Target: horse.SparkTarget(stmt.ColumnInt(2)), Value1: stmt.ColumnInt32(3), Value2: stmt.ColumnInt32(4), } cur[i].Effects[len(cur[i].Effects)-1] = append(cur[i].Effects[len(cur[i].Effects)-1], e) } } return sp, nil }