mirror of https://github.com/perkeep/perkeep.git
165 lines
3.3 KiB
Go
165 lines
3.3 KiB
Go
|
package pq
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"testing"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
func TestScanTimestamp(t *testing.T) {
|
||
|
var nt NullTime
|
||
|
tn := time.Now()
|
||
|
(&nt).Scan(tn)
|
||
|
if !nt.Valid {
|
||
|
t.Errorf("Expected Valid=false")
|
||
|
}
|
||
|
if nt.Time != tn {
|
||
|
t.Errorf("Time value mismatch")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestScanNilTimestamp(t *testing.T) {
|
||
|
var nt NullTime
|
||
|
(&nt).Scan(nil)
|
||
|
if nt.Valid {
|
||
|
t.Errorf("Expected Valid=false")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestTimestampWithTimeZone(t *testing.T) {
|
||
|
db := openTestConn(t)
|
||
|
defer db.Close()
|
||
|
|
||
|
tx, err := db.Begin()
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
defer tx.Rollback()
|
||
|
|
||
|
_, err = tx.Exec("create temp table test (t timestamp with time zone)")
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
// try several different locations, all included in Go's zoneinfo.zip
|
||
|
for _, locName := range []string{
|
||
|
"UTC",
|
||
|
"America/Chicago",
|
||
|
"America/New_York",
|
||
|
"Australia/Darwin",
|
||
|
"Australia/Perth",
|
||
|
} {
|
||
|
loc, err := time.LoadLocation(locName)
|
||
|
if err != nil {
|
||
|
t.Logf("Could not load time zone %s - skipping", locName)
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
// Postgres timestamps have a resolution of 1 microsecond, so don't
|
||
|
// use the full range of the Nanosecond argument
|
||
|
refTime := time.Date(2012, 11, 6, 10, 23, 42, 123456000, loc)
|
||
|
_, err = tx.Exec("insert into test(t) values($1)", refTime)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
for _, pgTimeZone := range []string{"US/Eastern", "Australia/Darwin"} {
|
||
|
// Switch Postgres's timezone to test different output timestamp formats
|
||
|
_, err = tx.Exec(fmt.Sprintf("set time zone '%s'", pgTimeZone))
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
var gotTime time.Time
|
||
|
row := tx.QueryRow("select t from test")
|
||
|
err = row.Scan(&gotTime)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
if !refTime.Equal(gotTime) {
|
||
|
t.Errorf("timestamps not equal: %s != %s", refTime, gotTime)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
_, err = tx.Exec("delete from test")
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestTimestampWithOutTimezone(t *testing.T) {
|
||
|
db := openTestConn(t)
|
||
|
defer db.Close()
|
||
|
|
||
|
test := func(ts, pgts string) {
|
||
|
r, err := db.Query("SELECT $1::timestamp", pgts)
|
||
|
if err != nil {
|
||
|
t.Fatalf("Could not run query: %v", err)
|
||
|
}
|
||
|
|
||
|
n := r.Next()
|
||
|
|
||
|
if n != true {
|
||
|
t.Fatal("Expected at least one row")
|
||
|
}
|
||
|
|
||
|
var result time.Time
|
||
|
err = r.Scan(&result)
|
||
|
if err != nil {
|
||
|
t.Fatalf("Did not expect error scanning row: %v", err)
|
||
|
}
|
||
|
|
||
|
expected, err := time.Parse(time.RFC3339, ts)
|
||
|
if err != nil {
|
||
|
t.Fatalf("Could not parse test time literal: %v", err)
|
||
|
}
|
||
|
|
||
|
if !result.Equal(expected) {
|
||
|
t.Fatalf("Expected time to match %v: got mismatch %v",
|
||
|
expected, result)
|
||
|
}
|
||
|
|
||
|
n = r.Next()
|
||
|
if n != false {
|
||
|
t.Fatal("Expected only one row")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
test("2000-01-01T00:00:00Z", "2000-01-01T00:00:00")
|
||
|
|
||
|
// Test higher precision time
|
||
|
test("2013-01-04T20:14:58.80033Z", "2013-01-04 20:14:58.80033")
|
||
|
}
|
||
|
|
||
|
func TestStringWithNul(t *testing.T) {
|
||
|
db := openTestConn(t)
|
||
|
defer db.Close()
|
||
|
|
||
|
hello0world := string("hello\x00world")
|
||
|
_, err := db.Query("SELECT $1::text", &hello0world)
|
||
|
if err == nil {
|
||
|
t.Fatal("Postgres accepts a string with nul in it; " +
|
||
|
"injection attacks may be plausible")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestByteToText(t *testing.T) {
|
||
|
db := openTestConn(t)
|
||
|
defer db.Close()
|
||
|
|
||
|
b := []byte("hello world")
|
||
|
row := db.QueryRow("SELECT $1::text", b)
|
||
|
|
||
|
var result []byte
|
||
|
err := row.Scan(&result)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
if string(result) != string(b) {
|
||
|
t.Fatalf("expected %v but got %v", b, result)
|
||
|
}
|
||
|
}
|