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