...

Source file src/github.com/lib/pq/hstore/hstore_test.go

Documentation: github.com/lib/pq/hstore

     1  package hstore
     2  
     3  import (
     4  	"database/sql"
     5  	"os"
     6  	"testing"
     7  
     8  	_ "github.com/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  	// quietly 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": {String: "value1", Valid: true},
    91  		},
    92  	}
    93  
    94  	hsThreePairs := Hstore{
    95  		Map: map[string]sql.NullString{
    96  			"key1": {String: "value1", Valid: true},
    97  			"key2": {String: "value2", Valid: true},
    98  			"key3": {String: "value3", Valid: true},
    99  		},
   100  	}
   101  
   102  	hsSmorgasbord := Hstore{
   103  		Map: map[string]sql.NullString{
   104  			"nullstring":             {String: "NULL", Valid: true},
   105  			"actuallynull":           {String: "", Valid: false},
   106  			"NULL":                   {String: "NULL string key", Valid: true},
   107  			"withbracket":            {String: "value>42", Valid: true},
   108  			"withequal":              {String: "value=42", Valid: true},
   109  			`"withquotes1"`:          {String: `this "should" be fine`, Valid: true},
   110  			`"withquotes"2"`:         {String: `this "should\" also be fine`, Valid: true},
   111  			"embedded1":              {String: "value1=>x1", Valid: true},
   112  			"embedded2":              {String: `"value2"=>x2`, Valid: true},
   113  			"withnewlines":           {String: "\n\nvalue\t=>2", Valid: true},
   114  			"<<all sorts of crazy>>": {String: `this, "should,\" also, => be fine`, Valid: 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  }
   149  

View as plain text