1+ package com .baeldung ;
2+
3+ import org .junit .jupiter .api .AfterEach ;
4+ import org .junit .jupiter .api .BeforeAll ;
5+ import org .junit .jupiter .api .BeforeEach ;
6+ import org .junit .jupiter .api .Test ;
7+
8+ import java .io .File ;
9+ import java .io .IOException ;
10+ import java .sql .Connection ;
11+ import java .sql .DriverManager ;
12+ import java .sql .PreparedStatement ;
13+ import java .sql .ResultSet ;
14+ import java .sql .ResultSetMetaData ;
15+ import java .sql .SQLException ;
16+ import java .sql .Statement ;
17+ import java .util .ArrayList ;
18+ import java .util .Calendar ;
19+ import java .util .Date ;
20+ import java .util .List ;
21+
22+ import static org .assertj .core .api .AssertionsForClassTypes .assertThat ;
23+
24+
25+ class DuckDbAccessIntegrationTest {
26+
27+ private Connection conn = null ;
28+ private Statement stmt = null ;
29+
30+ @ BeforeAll
31+ static void setupOnce () throws Exception {
32+ Class .forName ("org.duckdb.DuckDBDriver" );
33+ }
34+
35+ @ BeforeEach
36+ void setup () throws SQLException {
37+ conn = DriverManager .getConnection ("jdbc:duckdb:" );
38+ stmt = conn .createStatement ();
39+ }
40+
41+ @ Test
42+ void whenQueryCurrentDate_thenReturnToday () throws SQLException {
43+ ResultSet rs = stmt .executeQuery ("SELECT current_date" );
44+ Date currentDate = rs .next () ? rs .getDate (1 ) : null ;
45+
46+ Calendar calendar = Calendar .getInstance ();
47+ calendar .set (Calendar .HOUR_OF_DAY , 0 );
48+ calendar .set (Calendar .MINUTE , 0 );
49+ calendar .set (Calendar .SECOND , 0 );
50+ calendar .set (Calendar .MILLISECOND , 0 );
51+ Date expectedDate = calendar .getTime ();
52+
53+ assertThat (currentDate ).isEqualTo (expectedDate );
54+ }
55+
56+ @ Test
57+ void whenReadCsv_thenReturnHeaderAndData () throws SQLException {
58+ String filePath = getResourceAbsolutePath ("/customer.csv" );
59+ String query = String .format ("SELECT * FROM read_csv('%s')" , filePath );
60+
61+ ResultSet rs = stmt .executeQuery (query );
62+ ResultSetMetaData metadata = rs .getMetaData ();
63+
64+ List <String > actualHeaderNames = new ArrayList <>();
65+ for (int n =1 ; n <=metadata .getColumnCount (); n ++) {
66+ actualHeaderNames .add (metadata .getColumnLabel (n ));
67+ }
68+
69+ // Then
70+ List <String > expectedHeaderNames = List .of ("CustomerId" , "FirstName" , "LastName" , "Gender" );
71+ assertThat (actualHeaderNames ).isEqualTo (expectedHeaderNames );
72+
73+ int rowCount = 0 ;
74+ while (rs .next ()) {
75+ rowCount ++;
76+ }
77+ assertThat (rowCount ).isEqualTo (10 );
78+ }
79+
80+ @ Test
81+ void whenImportByCsv_thenReturnCorrectRowCount () throws SQLException {
82+ // When
83+ String filePath = getResourceAbsolutePath ("/customer.csv" );
84+ String query = String .format ("CREATE TABLE customer AS SELECT * FROM read_csv('%s')" , filePath );
85+ stmt .executeUpdate (query );
86+
87+ // Then
88+ assertThat (getTableRowCount (conn , "customer" )).isEqualTo (10 );
89+ }
90+
91+ @ Test
92+ void whenImportByJson_thenReturnCorrectRowCount () throws SQLException {
93+ // When
94+ String filePath = getResourceAbsolutePath ("/product.json" );
95+ String query = String .format ("CREATE TABLE product AS SELECT * FROM read_json('%s')" , filePath );
96+ stmt .executeUpdate (query );
97+
98+ // Then
99+ assertThat (getTableRowCount (conn , "product" )).isEqualTo (3 );
100+ }
101+
102+ @ Test
103+ void whenImportByInsert_thenReturnCorrectRowCount () throws SQLException {
104+ // When
105+ stmt .executeUpdate ("CREATE TABLE purchase(customerId BIGINT, productId BIGINT)" );
106+
107+ String query = "INSERT INTO purchase(customerId, productId) VALUES (?,?)" ;
108+ try (PreparedStatement pStmt = conn .prepareStatement (query )) {
109+
110+ pStmt .setInt (1 , 101 );
111+ pStmt .setInt (2 , 1 );
112+ pStmt .addBatch ();
113+
114+ pStmt .setInt (1 , 101 );
115+ pStmt .setInt (2 , 2 );
116+ pStmt .addBatch ();
117+
118+ pStmt .setInt (1 , 102 );
119+ pStmt .setInt (2 , 2 );
120+ pStmt .addBatch ();
121+
122+ pStmt .executeBatch ();
123+ }
124+
125+ // Then
126+ assertThat (getTableRowCount (conn , "purchase" )).isEqualTo (3 );
127+ }
128+
129+ @ Test
130+ void whenQueryWithJoin_thenReturnCorrectCount () throws SQLException {
131+ String customerFilePath = getResourceAbsolutePath ("/customer.csv" );
132+ String productFilePath = getResourceAbsolutePath ("/product.json" );
133+ whenImportByInsert_thenReturnCorrectRowCount ();
134+
135+ String query = String .format ("SELECT C.firstName, C.lastName, P.productName " +
136+ "FROM read_csv('%s') AS C, read_json('%s') AS P, purchase S " +
137+ "WHERE S.customerId = C.customerId " +
138+ "AND S.productId = P.productId " ,
139+ customerFilePath , productFilePath );
140+
141+ int count = 0 ;
142+ ResultSet rs = stmt .executeQuery (query );
143+ while (rs .next ()) {
144+ count ++;
145+ }
146+
147+ assertThat (count ).isEqualTo (3 );
148+ }
149+
150+ @ Test
151+ void whenExportData_thenFileIsCreated () throws IOException , SQLException {
152+ createPurchaseView (conn );
153+
154+ File tempFile = File .createTempFile ("temp" , "" );
155+ String exportFilePath = tempFile .getAbsolutePath ();
156+ String query = String .format ("COPY purchase_view TO '%s'" , exportFilePath );
157+ stmt .executeUpdate (query );
158+
159+ assertThat (tempFile .length ()).isGreaterThan (0 );
160+ tempFile .delete ();
161+ }
162+
163+ @ AfterEach
164+ void tearDown () throws SQLException {
165+ stmt .close ();
166+ conn .close ();
167+ }
168+
169+ private String getResourceAbsolutePath (String name ) {
170+ return this .getClass ().getResource (name ).getPath ().replaceFirst ("/" , "" );
171+ }
172+
173+ private int getTableRowCount (Connection conn , String tableName ) throws SQLException {
174+ try (Statement stmt = conn .createStatement ()) {
175+ ResultSet rs = stmt .executeQuery (String .format ("SELECT COUNT(*) FROM %s" , tableName ));
176+ return (rs .next ()) ? rs .getInt (1 ) : 0 ;
177+ }
178+ }
179+
180+ private void createPurchaseView (Connection conn ) throws SQLException {
181+ whenImportByCsv_thenReturnCorrectRowCount ();
182+ whenImportByJson_thenReturnCorrectRowCount ();
183+ whenImportByInsert_thenReturnCorrectRowCount ();
184+
185+ String query = "CREATE VIEW purchase_view AS " +
186+ "SELECT P.productName, COUNT(*) AS purchaseCount " +
187+ "FROM customer C, product P, purchase S " +
188+ "WHERE S.customerId = C.customerId " +
189+ "AND S.productId = P.productId " +
190+ "GROUP BY P.productName " +
191+ "ORDER BY COUNT(*) DESC " ;
192+
193+ try (Statement stmt = conn .createStatement ()) {
194+ stmt .executeUpdate (query );
195+ }
196+ }
197+
198+ }
0 commit comments