annotate example/OnClientExample.java @ 970:f90d811e97eb default tip

Adjust getTableTypes() test for new table type: LOCAL TEMPORARY VIEW, added in 11.53.4 (Mar2025-SP1)
author Martin van Dinther <martin.van.dinther@monetdbsolutions.com>
date Thu, 03 Apr 2025 15:01:33 +0200 (3 days ago)
parents d416e9b6b3d0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
542
d462000fc410 Various changes suggested by Martin van Dinther
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 541
diff changeset
1 /*
833
e890195256ac Update copyright for the new year, move to MonetDB Foundation, add SPDX.
Sjoerd Mullender <sjoerd@acm.org>
parents: 716
diff changeset
2 * SPDX-License-Identifier: MPL-2.0
e890195256ac Update copyright for the new year, move to MonetDB Foundation, add SPDX.
Sjoerd Mullender <sjoerd@acm.org>
parents: 716
diff changeset
3 *
542
d462000fc410 Various changes suggested by Martin van Dinther
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 541
diff changeset
4 * This Source Code Form is subject to the terms of the Mozilla Public
d462000fc410 Various changes suggested by Martin van Dinther
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 541
diff changeset
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
d462000fc410 Various changes suggested by Martin van Dinther
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 541
diff changeset
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
d462000fc410 Various changes suggested by Martin van Dinther
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 541
diff changeset
7 *
937
d416e9b6b3d0 Update Copyright year.
Martin van Dinther <martin.van.dinther@monetdbsolutions.com>
parents: 833
diff changeset
8 * Copyright 2024, 2025 MonetDB Foundation;
833
e890195256ac Update copyright for the new year, move to MonetDB Foundation, add SPDX.
Sjoerd Mullender <sjoerd@acm.org>
parents: 716
diff changeset
9 * Copyright August 2008 - 2023 MonetDB B.V.;
e890195256ac Update copyright for the new year, move to MonetDB Foundation, add SPDX.
Sjoerd Mullender <sjoerd@acm.org>
parents: 716
diff changeset
10 * Copyright 1997 - July 2008 CWI.
542
d462000fc410 Various changes suggested by Martin van Dinther
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 541
diff changeset
11 */
d462000fc410 Various changes suggested by Martin van Dinther
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 541
diff changeset
12
517
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
13 import org.monetdb.jdbc.MonetConnection;
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
14
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
15 import java.io.BufferedReader;
608
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
16 import java.io.BufferedWriter;
517
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
17 import java.io.IOException;
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
18 import java.io.InputStream;
608
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
19 import java.io.InputStreamReader;
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
20 import java.io.OutputStream;
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
21 import java.io.OutputStreamWriter;
517
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
22 import java.io.PrintStream;
608
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
23 import java.nio.charset.Charset;
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
24 import java.nio.charset.StandardCharsets;
517
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
25 import java.nio.file.FileSystems;
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
26 import java.nio.file.Files;
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
27 import java.nio.file.Path;
609
6666a9c62460 Cosmetic changes
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 608
diff changeset
28 import java.sql.Connection;
6666a9c62460 Cosmetic changes
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 608
diff changeset
29 import java.sql.DriverManager;
6666a9c62460 Cosmetic changes
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 608
diff changeset
30 import java.sql.ResultSet;
6666a9c62460 Cosmetic changes
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 608
diff changeset
31 import java.sql.SQLException;
6666a9c62460 Cosmetic changes
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 608
diff changeset
32 import java.sql.SQLNonTransientException;
6666a9c62460 Cosmetic changes
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 608
diff changeset
33 import java.sql.Statement;
517
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
34
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
35 public class OnClientExample {
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
36
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
37 public static void main(String[] args) {
556
87feb93330a6 Misc. changes suggested by analysis tool
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 551
diff changeset
38 int status;
517
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
39 try {
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
40 // Ideally this would not be hardcoded..
558
ebf65f416da9 Many improvements to the example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 556
diff changeset
41 final String dbUrl = "jdbc:monetdb://localhost:50000/demo";
ebf65f416da9 Many improvements to the example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 556
diff changeset
42 final String userName = "monetdb";
ebf65f416da9 Many improvements to the example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 556
diff changeset
43 final String password = "monetdb";
517
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
44 final String uploadDir = "/home/jvr/mydata";
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
45 final boolean filesAreUtf8 = false;
558
ebf65f416da9 Many improvements to the example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 556
diff changeset
46 String[] queries = {
ebf65f416da9 Many improvements to the example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 556
diff changeset
47 "DROP TABLE IF EXISTS mytable",
ebf65f416da9 Many improvements to the example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 556
diff changeset
48 "CREATE TABLE mytable(i INT, t TEXT)",
608
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
49
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
50 // with this filename our handler will make up data by itself
558
ebf65f416da9 Many improvements to the example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 556
diff changeset
51 "COPY INTO mytable FROM 'generated.csv' ON CLIENT",
608
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
52
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
53 // with this filename our handler will access the file system
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
54 "COPY INTO mytable FROM 'data.csv' ON CLIENT",
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
55
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
56 // with this statement, the server will ask the handler to stop halfway
558
ebf65f416da9 Many improvements to the example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 556
diff changeset
57 "COPY 20 RECORDS OFFSET 5 INTO mytable FROM 'generated.csv' ON CLIENT",
608
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
58
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
59 // this demonstrates sending errors
558
ebf65f416da9 Many improvements to the example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 556
diff changeset
60 "COPY INTO mytable FROM 'nonexistentfilethatdoesnotexist.csv' ON CLIENT",
608
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
61
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
62 // downloads but does not write to file, only counts the lines
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
63 "COPY SELECT * FROM mytable INTO 'justcount.csv' ON CLIENT",
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
64
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
65 // downloads to actual file
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
66 "COPY SELECT * FROM mytable INTO 'download.csv' ON CLIENT",
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
67
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
68 // demonstrate that the connection is still alive
558
ebf65f416da9 Many improvements to the example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 556
diff changeset
69 "SELECT COUNT(*) FROM mytable",
ebf65f416da9 Many improvements to the example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 556
diff changeset
70 };
517
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
71
558
ebf65f416da9 Many improvements to the example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 556
diff changeset
72 status = run(dbUrl, userName, password, uploadDir, filesAreUtf8, queries);
517
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
73
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
74 } catch (Exception e) {
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
75 status = 1;
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
76 e.printStackTrace();
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
77 }
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
78 System.exit(status);
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
79 }
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
80
558
ebf65f416da9 Many improvements to the example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 556
diff changeset
81 private static int run(String dbUrl, String userName, String password, String uploadDir, boolean filesAreUtf8, String[] queries) throws ClassNotFoundException, SQLException {
517
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
82 int status = 0;
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
83
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
84 // Connect
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
85 Class.forName("org.monetdb.jdbc.MonetDriver");
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
86 Connection conn = DriverManager.getConnection(dbUrl, userName, password);
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
87
608
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
88 // Register upload- and download handler
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
89 MyHandler handler = new MyHandler(uploadDir, filesAreUtf8);
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
90 MonetConnection monetConnection = conn.unwrap(MonetConnection.class);
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
91 monetConnection.setUploadHandler(handler);
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
92 monetConnection.setDownloadHandler(handler);
517
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
93
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
94 Statement stmt = conn.createStatement();
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
95 for (String q : queries) {
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
96 System.out.println(q);
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
97 try {
558
ebf65f416da9 Many improvements to the example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 556
diff changeset
98 boolean hasResultSet = stmt.execute(q);
ebf65f416da9 Many improvements to the example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 556
diff changeset
99 if (hasResultSet) {
ebf65f416da9 Many improvements to the example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 556
diff changeset
100 ResultSet rs = stmt.getResultSet();
517
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
101 long count = 0;
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
102 while (rs.next()) {
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
103 count++;
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
104 }
610
6aa38e8c0f2d Updated Copyright year.
Martin van Dinther <martin.van.dinther@monetdbsolutions.com>
parents: 609
diff changeset
105 rs.close();
517
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
106 System.out.printf(" OK, returned %d rows%n", count);
558
ebf65f416da9 Many improvements to the example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 556
diff changeset
107 } else {
ebf65f416da9 Many improvements to the example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 556
diff changeset
108 System.out.printf(" OK, updated %d rows%n", stmt.getUpdateCount());
517
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
109 }
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
110 } catch (SQLNonTransientException e) {
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
111 throw e;
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
112 } catch (SQLException e) {
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
113 System.out.println(" => SQL ERROR " + e.getMessage());
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
114 status = 1;
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
115 }
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
116 }
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
117
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
118 return status;
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
119 }
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
120
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
121
608
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
122 private static class MyHandler implements MonetConnection.UploadHandler, MonetConnection.DownloadHandler {
517
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
123 private final Path uploadDir;
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
124 private final boolean filesAreUtf8;
558
ebf65f416da9 Many improvements to the example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 556
diff changeset
125 private boolean stopUploading = false;
517
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
126
608
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
127 public MyHandler(String uploadDir, boolean filesAreUtf8) {
517
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
128 this.uploadDir = FileSystems.getDefault().getPath(uploadDir).normalize();
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
129 this.filesAreUtf8 = filesAreUtf8;
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
130 }
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
131
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
132 @Override
558
ebf65f416da9 Many improvements to the example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 556
diff changeset
133 public void uploadCancelled() {
ebf65f416da9 Many improvements to the example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 556
diff changeset
134 System.out.println(" CANCELLATION CALLBACK: server cancelled the upload");
ebf65f416da9 Many improvements to the example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 556
diff changeset
135 stopUploading = true;
ebf65f416da9 Many improvements to the example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 556
diff changeset
136 }
517
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
137
558
ebf65f416da9 Many improvements to the example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 556
diff changeset
138 @Override
ebf65f416da9 Many improvements to the example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 556
diff changeset
139 public void handleUpload(MonetConnection.Upload handle, String name, boolean textMode, long linesToSkip) throws IOException {
517
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
140 // We can upload data read from the file system but also make up our own data
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
141 if (name.equals("generated.csv")) {
558
ebf65f416da9 Many improvements to the example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 556
diff changeset
142 uploadGeneratedData(handle, linesToSkip);
608
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
143 } else {
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
144 uploadFileData(handle, name, textMode, linesToSkip);
517
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
145 }
608
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
146 }
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
147
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
148 @Override
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
149 public void handleDownload(MonetConnection.Download handle, String name, boolean textMode) throws IOException {
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
150 if (name.equals("justcount.csv")) {
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
151 justCountLines(handle);
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
152 } else {
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
153 downloadFileData(handle, name, textMode);
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
154 }
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
155 }
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
156
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
157 private Path securelyResolvePath(String name) {
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
158 Path p = uploadDir.resolve(name).normalize();
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
159 if (p.startsWith(uploadDir)) {
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
160 return p;
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
161 } else {
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
162 return null;
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
163 }
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
164 }
517
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
165
608
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
166 private void uploadGeneratedData(MonetConnection.Upload handle, long toSkip) throws IOException {
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
167 // Set the chunk size to a tiny amount, so we can demonstrate
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
168 // cancellation handling. The default chunk size is one megabyte.
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
169 // DO NOT DO THIS IN PRODUCTION!
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
170 handle.setChunkSize(50);
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
171
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
172 // Make up some data and upload it.
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
173 PrintStream stream = handle.getStream();
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
174 long n = 100;
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
175 System.out.printf(" HANDLER: uploading %d generated lines, numbered %d to %d%n", n - toSkip, toSkip + 1, n);
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
176 long i;
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
177 for (i = toSkip + 1; i <= n; i++) {
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
178 if (stopUploading) {
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
179 System.out.printf(" HANDLER: at line %d we noticed the server asked us to stop sending%n", i);
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
180 break;
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
181 }
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
182 stream.printf("%d|the number is %d%n", i, i);
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
183 }
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
184 System.out.println(" HANDLER: done uploading");
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
185 stream.close();
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
186 }
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
187
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
188 private void uploadFileData(MonetConnection.Upload handle, String name, boolean textMode, long linesToSkip) throws IOException {
517
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
189 // Validate the path, demonstrating two ways of dealing with errors
608
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
190 Path path = securelyResolvePath(name);
609
6666a9c62460 Cosmetic changes
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 608
diff changeset
191 if (path == null || !Files.exists(path)) {
558
ebf65f416da9 Many improvements to the example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 556
diff changeset
192 // This makes the COPY command fail but keeps the connection
ebf65f416da9 Many improvements to the example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 556
diff changeset
193 // alive. Can only be used if we haven't sent any data yet
517
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
194 handle.sendError("Invalid path");
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
195 return;
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
196 }
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
197 if (!Files.isReadable(path)) {
558
ebf65f416da9 Many improvements to the example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 556
diff changeset
198 // As opposed to handle.sendError(), we can throw an IOException
ebf65f416da9 Many improvements to the example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 556
diff changeset
199 // at any time. Unfortunately, the file upload protocol does not
ebf65f416da9 Many improvements to the example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 556
diff changeset
200 // provide a way to indicate to the server that the data sent so
ebf65f416da9 Many improvements to the example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 556
diff changeset
201 // far is incomplete, so for the time being throwing an
ebf65f416da9 Many improvements to the example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 556
diff changeset
202 // IOException from {@handleUpload} terminates the connection.
517
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
203 throw new IOException("Unreadable: " + path);
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
204 }
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
205
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
206 boolean binary = !textMode;
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
207 if (binary) {
558
ebf65f416da9 Many improvements to the example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 556
diff changeset
208 uploadAsBinary(handle, path);
551
5ce6a942aff3 Last minute API fix: 'int offset' -> 'long linesToSkip'
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 542
diff changeset
209 } else if (linesToSkip == 0 && filesAreUtf8) {
558
ebf65f416da9 Many improvements to the example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 556
diff changeset
210 // Avoid unnecessary UTF-8 -> Java String -> UTF-8 conversions
ebf65f416da9 Many improvements to the example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 556
diff changeset
211 // by pretending the data is binary.
ebf65f416da9 Many improvements to the example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 556
diff changeset
212 uploadAsBinary(handle, path);
517
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
213 } else {
608
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
214 // Charset and skip handling are really necessary
558
ebf65f416da9 Many improvements to the example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 556
diff changeset
215 uploadAsText(handle, path, linesToSkip);
517
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
216 }
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
217 }
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
218
558
ebf65f416da9 Many improvements to the example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 556
diff changeset
219 private void uploadAsText(MonetConnection.Upload handle, Path path, long toSkip) throws IOException {
517
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
220 BufferedReader reader = Files.newBufferedReader(path);// Converts from system encoding to Java text
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
221 for (long i = 0; i < toSkip; i++) {
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
222 reader.readLine();
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
223 }
608
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
224 // This variant of uploadFrom takes a Reader
517
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
225 handle.uploadFrom(reader); // Converts from Java text to UTF-8 as required by MonetDB
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
226 }
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
227
558
ebf65f416da9 Many improvements to the example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 556
diff changeset
228 private void uploadAsBinary(MonetConnection.Upload handle, Path path) throws IOException {
517
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
229 // No charset conversion whatsoever..
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
230 // Use this for binary data or when you are certain the file is UTF-8 encoded.
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
231 InputStream stream = Files.newInputStream(path);
608
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
232 // This variant of uploadFrom takes a Stream
517
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
233 handle.uploadFrom(stream);
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
234 }
608
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
235
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
236 private void justCountLines(MonetConnection.Download handle) throws IOException {
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
237 System.out.println(" HANDLER: not writing the download to file, just counting the lines");
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
238 InputStream stream = handle.getStream();
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
239 InputStreamReader reader = new InputStreamReader(stream, StandardCharsets.UTF_8); // MonetDB always sends UTF-8
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
240 BufferedReader bufreader = new BufferedReader(reader);
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
241 long count = 0;
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
242 while (bufreader.readLine() != null) {
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
243 count++;
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
244 }
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
245 System.out.println(" HANDLER: file had " + count + " lines");
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
246 }
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
247
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
248 private void downloadFileData(MonetConnection.Download handle, String name, boolean textMode) throws IOException {
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
249 Path path = securelyResolvePath(name);
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
250 if (path == null) {
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
251 handle.sendError("Illegal path");
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
252 return;
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
253 }
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
254
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
255 OutputStream stream = Files.newOutputStream(path);
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
256 if (!textMode || filesAreUtf8) {
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
257 handle.downloadTo(stream);
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
258 stream.close(); // do not forget this
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
259 } else {
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
260 OutputStreamWriter writer = new OutputStreamWriter(stream, Charset.defaultCharset()); // let system decide the encoding
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
261 BufferedWriter bufwriter = new BufferedWriter(writer);
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
262 handle.downloadTo(bufwriter);
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
263 bufwriter.close(); // do not forget this
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
264 }
c462161504a3 Extend example with Download functionality
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents: 582
diff changeset
265 }
517
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
266 }
130bb2e18d3f Add example code
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff changeset
267 }