1// +build future 2 3/* 4Copyright 2014 SAP SE 5 6Licensed under the Apache License, Version 2.0 (the "License"); 7you may not use this file except in compliance with the License. 8You may obtain a copy of the License at 9 10 http://www.apache.org/licenses/LICENSE-2.0 11 12Unless required by applicable law or agreed to in writing, software 13distributed under the License is distributed on an "AS IS" BASIS, 14WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15See the License for the specific language governing permissions and 16limitations under the License. 17*/ 18 19package driver 20 21import ( 22 "database/sql" 23 "fmt" 24 "testing" 25) 26 27const ( 28 bulkSamples = 10000 29) 30 31// TestBulkInsert 32func TestBulkInsert(t *testing.T) { 33 34 tmpTableName := Identifier("#tmpTable") 35 36 db, err := sql.Open(DriverName, TestDSN) 37 if err != nil { 38 t.Fatal(err) 39 } 40 defer db.Close() 41 42 //keep connection / hdb session for using local temporary tables 43 tx, err := db.Begin() 44 if err != nil { 45 t.Fatal(err) 46 } 47 defer tx.Rollback() //cleanup 48 49 if _, err := tx.Exec(fmt.Sprintf("create local temporary table %s (i integer)", tmpTableName)); err != nil { 50 t.Fatalf("create table failed: %s", err) 51 } 52 53 stmt, err := tx.Prepare(fmt.Sprintf("insert into %s values (?)", tmpTableName)) 54 if err != nil { 55 t.Fatalf("prepare bulk insert failed: %s", err) 56 } 57 defer stmt.Close() 58 59 prm := NoFlush 60 for i := 0; i < bulkSamples; i++ { 61 if i == (bulkSamples - 1) { 62 prm = Flush 63 } 64 if _, err := stmt.Exec(i, prm); err != nil { 65 t.Fatalf("insert failed: %s", err) 66 } 67 } 68 69 i := 0 70 err = tx.QueryRow(fmt.Sprintf("select count(*) from %s", tmpTableName)).Scan(&i) 71 if err != nil { 72 t.Fatalf("select count failed: %s", err) 73 } 74 75 if i != bulkSamples { 76 t.Fatalf("invalid number of records %d - %d expected", i, bulkSamples) 77 } 78 79 rows, err := tx.Query(fmt.Sprintf("select * from %s order by i", tmpTableName)) 80 if err != nil { 81 t.Fatal(err) 82 } 83 defer rows.Close() 84 85 i = 0 86 for rows.Next() { 87 88 var j int 89 90 if err := rows.Scan(&j); err != nil { 91 t.Fatal(err) 92 } 93 94 if j != i { 95 t.Fatalf("value %d - expected %d", j, i) 96 } 97 98 i++ 99 } 100 if err := rows.Err(); err != nil { 101 t.Fatal(err) 102 } 103} 104 105// TestBulkInsertDuplicates 106func TestBulkInsertDuplicates(t *testing.T) { 107 108 db, err := sql.Open(DriverName, TestDSN) 109 if err != nil { 110 t.Fatal(err) 111 } 112 defer db.Close() 113 114 table := RandomIdentifier("bulkInsertDuplicates") 115 116 if _, err := db.Exec(fmt.Sprintf("create table %s.%s (k integer primary key, v integer)", TestSchema, table)); err != nil { 117 t.Fatalf("create table failed: %s", err) 118 } 119 120 stmt, err := db.Prepare(fmt.Sprintf("insert into %s.%s values (?,?)", TestSchema, table)) 121 if err != nil { 122 t.Fatalf("prepare bulk insert failed: %s", err) 123 } 124 defer stmt.Close() 125 126 prm := NoFlush 127 for i := 1; i < 4; i++ { 128 if i == 3 { 129 prm = Flush 130 } 131 if _, err := stmt.Exec(i, i, prm); err != nil { 132 t.Fatalf("insert failed: %s", err) 133 } 134 } 135 136 for i := 0; i < 4; i++ { 137 if _, err := stmt.Exec(i, i, NoFlush); err != nil { 138 t.Fatalf("insert failed: %s", err) 139 } 140 } 141 _, err = stmt.Exec(5, 5) 142 if err == nil { 143 t.Fatal("error duplicate key expected") 144 } 145 146 dbError, ok := err.(Error) 147 if !ok { 148 t.Fatal("driver.Error expected") 149 } 150 151 // expect 3 errors for statement 1,2 and 3 152 if dbError.NumError() != 3 { 153 t.Fatalf("number of errors: %d - %d expected", dbError.NumError(), 3) 154 } 155 156 stmtNo := []int{1, 2, 3} 157 158 for i := 0; i < dbError.NumError(); i++ { 159 dbError.SetIdx(i) 160 if dbError.StmtNo() != stmtNo[i] { 161 t.Fatalf("statement number: %d - %d expected", dbError.StmtNo(), stmtNo[i]) 162 } 163 } 164} 165