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  }