diff options
Diffstat (limited to '_example/custom_func/main.go')
-rw-r--r-- | _example/custom_func/main.go | 133 |
1 files changed, 0 insertions, 133 deletions
diff --git a/_example/custom_func/main.go b/_example/custom_func/main.go deleted file mode 100644 index 85657e6..0000000 --- a/_example/custom_func/main.go +++ /dev/null @@ -1,133 +0,0 @@ -package main - -import ( - "database/sql" - "fmt" - "log" - "math" - "math/rand" - - sqlite "github.com/mattn/go-sqlite3" -) - -// Computes x^y -func pow(x, y int64) int64 { - return int64(math.Pow(float64(x), float64(y))) -} - -// Computes the bitwise exclusive-or of all its arguments -func xor(xs ...int64) int64 { - var ret int64 - for _, x := range xs { - ret ^= x - } - return ret -} - -// Returns a random number. It's actually deterministic here because -// we don't seed the RNG, but it's an example of a non-pure function -// from SQLite's POV. -func getrand() int64 { - return rand.Int63() -} - -// Computes the standard deviation of a GROUPed BY set of values -type stddev struct { - xs []int64 - // Running average calculation - sum int64 - n int64 -} - -func newStddev() *stddev { return &stddev{} } - -func (s *stddev) Step(x int64) { - s.xs = append(s.xs, x) - s.sum += x - s.n++ -} - -func (s *stddev) Done() float64 { - mean := float64(s.sum) / float64(s.n) - var sqDiff []float64 - for _, x := range s.xs { - sqDiff = append(sqDiff, math.Pow(float64(x)-mean, 2)) - } - var dev float64 - for _, x := range sqDiff { - dev += x - } - dev /= float64(len(sqDiff)) - return math.Sqrt(dev) -} - -func main() { - sql.Register("sqlite3_custom", &sqlite.SQLiteDriver{ - ConnectHook: func(conn *sqlite.SQLiteConn) error { - if err := conn.RegisterFunc("pow", pow, true); err != nil { - return err - } - if err := conn.RegisterFunc("xor", xor, true); err != nil { - return err - } - if err := conn.RegisterFunc("rand", getrand, false); err != nil { - return err - } - if err := conn.RegisterAggregator("stddev", newStddev, true); err != nil { - return err - } - return nil - }, - }) - - db, err := sql.Open("sqlite3_custom", ":memory:") - if err != nil { - log.Fatal("Failed to open database:", err) - } - defer db.Close() - - var i int64 - err = db.QueryRow("SELECT pow(2,3)").Scan(&i) - if err != nil { - log.Fatal("POW query error:", err) - } - fmt.Println("pow(2,3) =", i) // 8 - - err = db.QueryRow("SELECT xor(1,2,3,4,5,6)").Scan(&i) - if err != nil { - log.Fatal("XOR query error:", err) - } - fmt.Println("xor(1,2,3,4,5) =", i) // 7 - - err = db.QueryRow("SELECT rand()").Scan(&i) - if err != nil { - log.Fatal("RAND query error:", err) - } - fmt.Println("rand() =", i) // pseudorandom - - _, err = db.Exec("create table foo (department integer, profits integer)") - if err != nil { - log.Fatal("Failed to create table:", err) - } - _, err = db.Exec("insert into foo values (1, 10), (1, 20), (1, 45), (2, 42), (2, 115)") - if err != nil { - log.Fatal("Failed to insert records:", err) - } - - rows, err := db.Query("select department, stddev(profits) from foo group by department") - if err != nil { - log.Fatal("STDDEV query error:", err) - } - defer rows.Close() - for rows.Next() { - var dept int64 - var dev float64 - if err := rows.Scan(&dept, &dev); err != nil { - log.Fatal(err) - } - fmt.Printf("dept=%d stddev=%f\n", dept, dev) - } - if err := rows.Err(); err != nil { - log.Fatal(err) - } -} |