github.com/CanonicalLtd/go-sqlite3@v1.6.0/error_test.go (about) 1 // Copyright (C) 2014 Yasuhiro Matsumoto <mattn.jp@gmail.com>. 2 // 3 // Use of this source code is governed by an MIT-style 4 // license that can be found in the LICENSE file. 5 6 package sqlite3 7 8 import ( 9 "database/sql" 10 "io/ioutil" 11 "os" 12 "path" 13 "testing" 14 ) 15 16 func TestSimpleError(t *testing.T) { 17 e := ErrError.Error() 18 if e != "SQL logic error or missing database" && e != "SQL logic error" { 19 t.Error("wrong error code: " + e) 20 } 21 } 22 23 func TestCorruptDbErrors(t *testing.T) { 24 dirName, err := ioutil.TempDir("", "sqlite3") 25 if err != nil { 26 t.Fatal(err) 27 } 28 defer os.RemoveAll(dirName) 29 30 dbFileName := path.Join(dirName, "test.db") 31 f, err := os.Create(dbFileName) 32 if err != nil { 33 t.Error(err) 34 } 35 f.Write([]byte{1, 2, 3, 4, 5}) 36 f.Close() 37 38 db, err := sql.Open("sqlite3", dbFileName) 39 if err == nil { 40 _, err = db.Exec("drop table foo") 41 } 42 43 sqliteErr := err.(Error) 44 if sqliteErr.Code != ErrNotADB { 45 t.Error("wrong error code for corrupted DB") 46 } 47 if err.Error() == "" { 48 t.Error("wrong error string for corrupted DB") 49 } 50 db.Close() 51 } 52 53 func TestSqlLogicErrors(t *testing.T) { 54 dirName, err := ioutil.TempDir("", "sqlite3") 55 if err != nil { 56 t.Fatal(err) 57 } 58 defer os.RemoveAll(dirName) 59 60 dbFileName := path.Join(dirName, "test.db") 61 db, err := sql.Open("sqlite3", dbFileName) 62 if err != nil { 63 t.Error(err) 64 } 65 defer db.Close() 66 67 _, err = db.Exec("CREATE TABLE Foo (id INTEGER PRIMARY KEY)") 68 if err != nil { 69 t.Error(err) 70 } 71 72 const expectedErr = "table Foo already exists" 73 _, err = db.Exec("CREATE TABLE Foo (id INTEGER PRIMARY KEY)") 74 if err.Error() != expectedErr { 75 t.Errorf("Unexpected error: %s, expected %s", err.Error(), expectedErr) 76 } 77 78 } 79 80 func TestExtendedErrorCodes_ForeignKey(t *testing.T) { 81 dirName, err := ioutil.TempDir("", "sqlite3-err") 82 if err != nil { 83 t.Fatal(err) 84 } 85 defer os.RemoveAll(dirName) 86 87 dbFileName := path.Join(dirName, "test.db") 88 db, err := sql.Open("sqlite3", dbFileName) 89 if err != nil { 90 t.Error(err) 91 } 92 defer db.Close() 93 94 _, err = db.Exec("PRAGMA foreign_keys=ON;") 95 if err != nil { 96 t.Errorf("PRAGMA foreign_keys=ON: %v", err) 97 } 98 99 _, err = db.Exec(`CREATE TABLE Foo ( 100 id INTEGER PRIMARY KEY AUTOINCREMENT, 101 value INTEGER NOT NULL, 102 ref INTEGER NULL REFERENCES Foo (id), 103 UNIQUE(value) 104 );`) 105 if err != nil { 106 t.Error(err) 107 } 108 109 _, err = db.Exec("INSERT INTO Foo (ref, value) VALUES (100, 100);") 110 if err == nil { 111 t.Error("No error!") 112 } else { 113 sqliteErr := err.(Error) 114 if sqliteErr.Code != ErrConstraint { 115 t.Errorf("Wrong basic error code: %d != %d", 116 sqliteErr.Code, ErrConstraint) 117 } 118 if sqliteErr.ExtendedCode != ErrConstraintForeignKey { 119 t.Errorf("Wrong extended error code: %d != %d", 120 sqliteErr.ExtendedCode, ErrConstraintForeignKey) 121 } 122 } 123 124 } 125 126 func TestExtendedErrorCodes_NotNull(t *testing.T) { 127 dirName, err := ioutil.TempDir("", "sqlite3-err") 128 if err != nil { 129 t.Fatal(err) 130 } 131 defer os.RemoveAll(dirName) 132 133 dbFileName := path.Join(dirName, "test.db") 134 db, err := sql.Open("sqlite3", dbFileName) 135 if err != nil { 136 t.Error(err) 137 } 138 defer db.Close() 139 140 _, err = db.Exec("PRAGMA foreign_keys=ON;") 141 if err != nil { 142 t.Errorf("PRAGMA foreign_keys=ON: %v", err) 143 } 144 145 _, err = db.Exec(`CREATE TABLE Foo ( 146 id INTEGER PRIMARY KEY AUTOINCREMENT, 147 value INTEGER NOT NULL, 148 ref INTEGER NULL REFERENCES Foo (id), 149 UNIQUE(value) 150 );`) 151 if err != nil { 152 t.Error(err) 153 } 154 155 res, err := db.Exec("INSERT INTO Foo (value) VALUES (100);") 156 if err != nil { 157 t.Fatalf("Creating first row: %v", err) 158 } 159 160 id, err := res.LastInsertId() 161 if err != nil { 162 t.Fatalf("Retrieving last insert id: %v", err) 163 } 164 165 _, err = db.Exec("INSERT INTO Foo (ref) VALUES (?);", id) 166 if err == nil { 167 t.Error("No error!") 168 } else { 169 sqliteErr := err.(Error) 170 if sqliteErr.Code != ErrConstraint { 171 t.Errorf("Wrong basic error code: %d != %d", 172 sqliteErr.Code, ErrConstraint) 173 } 174 if sqliteErr.ExtendedCode != ErrConstraintNotNull { 175 t.Errorf("Wrong extended error code: %d != %d", 176 sqliteErr.ExtendedCode, ErrConstraintNotNull) 177 } 178 } 179 180 } 181 182 func TestExtendedErrorCodes_Unique(t *testing.T) { 183 dirName, err := ioutil.TempDir("", "sqlite3-err") 184 if err != nil { 185 t.Fatal(err) 186 } 187 defer os.RemoveAll(dirName) 188 189 dbFileName := path.Join(dirName, "test.db") 190 db, err := sql.Open("sqlite3", dbFileName) 191 if err != nil { 192 t.Error(err) 193 } 194 defer db.Close() 195 196 _, err = db.Exec("PRAGMA foreign_keys=ON;") 197 if err != nil { 198 t.Errorf("PRAGMA foreign_keys=ON: %v", err) 199 } 200 201 _, err = db.Exec(`CREATE TABLE Foo ( 202 id INTEGER PRIMARY KEY AUTOINCREMENT, 203 value INTEGER NOT NULL, 204 ref INTEGER NULL REFERENCES Foo (id), 205 UNIQUE(value) 206 );`) 207 if err != nil { 208 t.Error(err) 209 } 210 211 res, err := db.Exec("INSERT INTO Foo (value) VALUES (100);") 212 if err != nil { 213 t.Fatalf("Creating first row: %v", err) 214 } 215 216 id, err := res.LastInsertId() 217 if err != nil { 218 t.Fatalf("Retrieving last insert id: %v", err) 219 } 220 221 _, err = db.Exec("INSERT INTO Foo (ref, value) VALUES (?, 100);", id) 222 if err == nil { 223 t.Error("No error!") 224 } else { 225 sqliteErr := err.(Error) 226 if sqliteErr.Code != ErrConstraint { 227 t.Errorf("Wrong basic error code: %d != %d", 228 sqliteErr.Code, ErrConstraint) 229 } 230 if sqliteErr.ExtendedCode != ErrConstraintUnique { 231 t.Errorf("Wrong extended error code: %d != %d", 232 sqliteErr.ExtendedCode, ErrConstraintUnique) 233 } 234 extended := sqliteErr.Code.Extend(3).Error() 235 expected := "constraint failed" 236 if extended != expected { 237 t.Errorf("Wrong basic error code: %q != %q", 238 extended, expected) 239 } 240 } 241 242 }