github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/lib/pq/hstore/hstore_test.go (about) 1 package hstore 2 3 import ( 4 "database/sql" 5 "os" 6 "testing" 7 8 _ "github.com/insionng/yougam/libraries/lib/pq" 9 ) 10 11 type Fatalistic interface { 12 Fatal(args ...interface{}) 13 } 14 15 func openTestConn(t Fatalistic) *sql.DB { 16 datname := os.Getenv("PGDATABASE") 17 sslmode := os.Getenv("PGSSLMODE") 18 19 if datname == "" { 20 os.Setenv("PGDATABASE", "pqgotest") 21 } 22 23 if sslmode == "" { 24 os.Setenv("PGSSLMODE", "disable") 25 } 26 27 conn, err := sql.Open("postgres", "") 28 if err != nil { 29 t.Fatal(err) 30 } 31 32 return conn 33 } 34 35 func TestHstore(t *testing.T) { 36 db := openTestConn(t) 37 defer db.Close() 38 39 // quitely create hstore if it doesn't exist 40 _, err := db.Exec("CREATE EXTENSION IF NOT EXISTS hstore") 41 if err != nil { 42 t.Skipf("Skipping hstore tests - hstore extension create failed: %s", err.Error()) 43 } 44 45 hs := Hstore{} 46 47 // test for null-valued hstores 48 err = db.QueryRow("SELECT NULL::hstore").Scan(&hs) 49 if err != nil { 50 t.Fatal(err) 51 } 52 if hs.Map != nil { 53 t.Fatalf("expected null map") 54 } 55 56 err = db.QueryRow("SELECT $1::hstore", hs).Scan(&hs) 57 if err != nil { 58 t.Fatalf("re-query null map failed: %s", err.Error()) 59 } 60 if hs.Map != nil { 61 t.Fatalf("expected null map") 62 } 63 64 // test for empty hstores 65 err = db.QueryRow("SELECT ''::hstore").Scan(&hs) 66 if err != nil { 67 t.Fatal(err) 68 } 69 if hs.Map == nil { 70 t.Fatalf("expected empty map, got null map") 71 } 72 if len(hs.Map) != 0 { 73 t.Fatalf("expected empty map, got len(map)=%d", len(hs.Map)) 74 } 75 76 err = db.QueryRow("SELECT $1::hstore", hs).Scan(&hs) 77 if err != nil { 78 t.Fatalf("re-query empty map failed: %s", err.Error()) 79 } 80 if hs.Map == nil { 81 t.Fatalf("expected empty map, got null map") 82 } 83 if len(hs.Map) != 0 { 84 t.Fatalf("expected empty map, got len(map)=%d", len(hs.Map)) 85 } 86 87 // a few example maps to test out 88 hsOnePair := Hstore{ 89 Map: map[string]sql.NullString{ 90 "key1": {"value1", true}, 91 }, 92 } 93 94 hsThreePairs := Hstore{ 95 Map: map[string]sql.NullString{ 96 "key1": {"value1", true}, 97 "key2": {"value2", true}, 98 "key3": {"value3", true}, 99 }, 100 } 101 102 hsSmorgasbord := Hstore{ 103 Map: map[string]sql.NullString{ 104 "nullstring": {"NULL", true}, 105 "actuallynull": {"", false}, 106 "NULL": {"NULL string key", true}, 107 "withbracket": {"value>42", true}, 108 "withequal": {"value=42", true}, 109 `"withquotes1"`: {`this "should" be fine`, true}, 110 `"withquotes"2"`: {`this "should\" also be fine`, true}, 111 "embedded1": {"value1=>x1", true}, 112 "embedded2": {`"value2"=>x2`, true}, 113 "withnewlines": {"\n\nvalue\t=>2", true}, 114 "<<all sorts of crazy>>": {`this, "should,\" also, => be fine`, true}, 115 }, 116 } 117 118 // test encoding in query params, then decoding during Scan 119 testBidirectional := func(h Hstore) { 120 err = db.QueryRow("SELECT $1::hstore", h).Scan(&hs) 121 if err != nil { 122 t.Fatalf("re-query %d-pair map failed: %s", len(h.Map), err.Error()) 123 } 124 if hs.Map == nil { 125 t.Fatalf("expected %d-pair map, got null map", len(h.Map)) 126 } 127 if len(hs.Map) != len(h.Map) { 128 t.Fatalf("expected %d-pair map, got len(map)=%d", len(h.Map), len(hs.Map)) 129 } 130 131 for key, val := range hs.Map { 132 otherval, found := h.Map[key] 133 if !found { 134 t.Fatalf(" key '%v' not found in %d-pair map", key, len(h.Map)) 135 } 136 if otherval.Valid != val.Valid { 137 t.Fatalf(" value %v <> %v in %d-pair map", otherval, val, len(h.Map)) 138 } 139 if otherval.String != val.String { 140 t.Fatalf(" value '%v' <> '%v' in %d-pair map", otherval.String, val.String, len(h.Map)) 141 } 142 } 143 } 144 145 testBidirectional(hsOnePair) 146 testBidirectional(hsThreePairs) 147 testBidirectional(hsSmorgasbord) 148 }