source: gs2-extensions/tipple-bridge/trunk/src/src/main/java/sqlCli.java@ 34889

Last change on this file since 34889 was 34889, checked in by davidb, 3 years ago

Adjustment of some --option defaults; Refinement of what gets printed to the screen

File size: 7.9 KB
Line 
1import com.google.gson.JsonArray;
2import picocli.CommandLine;
3import picocli.CommandLine.Command;
4import picocli.CommandLine.Option;
5
6import java.sql.*;
7import java.util.HashMap;
8import com.google.gson.Gson;
9import java.io.FileWriter;
10
11/*
12TODO:
13for the CLI:
14- Error handling
15- Subcommands?
16
17 */
18
19//-u su41Tipple -p --port 3306 --dbname tippleTest1
20//@/home/su41/configFileTest
21
22/*
23The mixinStandardHelpOptions = true adds in --help and --version options
24 */
25@Command (name="sqlCli", description = "Arguments for database connection", mixinStandardHelpOptions = true)
26public class sqlCli implements Runnable {
27 //our cli arguments
28
29 @Option(names = {"-u", "--user"}, description = "The user name")
30 String userName;
31
32 //interactive allows the user to omit the argument value and instead enter it as a prompt
33 /*
34 NOTE: if you are running an interactive option on an IDE, most likely will be using something
35 like the javaw.exe library which tries to mimic the terminal.
36 The point is that interactive option would usually make whatever you enter hidden (it doesn't
37 echo back) but on the IDE it will echo back.
38 */
39 @Option(names = {"-p", "--password"}, description = "User's password", interactive = true)
40 String password;
41
42 @Option(names = {"--port"}, description="Port number", defaultValue="3306")
43 int portNo;
44
45 @Option(names = {"--dbname"}, description="Name of the database", defaultValue="koicarp_test")
46 String dbName;
47
48 @Option(names = {"--projectID"}, description = "ID number of the project")
49 String projectID;
50
51 //defaultValue in case the user doesn't enter in an option for it
52 @Option(names = {"--fileName"}, description = "Name of output JSON file",
53 required = true, defaultValue = "myData.json")
54 String fileName;
55
56 @Option(names = {"--host"}, description = "Type of host e.g. localhost ",
57 required = true, defaultValue = "localhost")
58 String host;
59
60
61 public void run() {
62 databaseConnect(userName, password, portNo, dbName, projectID, fileName, host);
63 }
64
65 public static void main(String... args) {
66 int exitCode = new CommandLine(new sqlCli()).execute(args);
67 System.exit(exitCode);
68 }
69
70
71 private static void databaseConnect(String user, String pass, int port, String dbName,
72 String projectID, String filename, String host){
73 Connection conn;
74 Statement stmt;
75
76 // String dbUrl = "jdbc:mysql://localhost:" + port +"/"+ dbName;
77
78 //TODO: are we changing / putting the type of database into a variable too?
79 String dbUrl = "jdbc:mysql://" + host + ":" + port +"/"+ dbName;
80
81 //originally in the try ()
82 // FileWriter file = new FileWriter("tippleData.json")
83 System.out.println("Saving output to:");
84 System.out.println(" " + filename);
85
86 try (FileWriter file = new FileWriter(filename)){
87 //register the jdbc driver
88 Class.forName("com.mysql.cj.jdbc.Driver");
89 //opening the connection
90 System.out.println("Connecting to database:");
91 System.out.println(" " + dbUrl);
92
93 conn = DriverManager.getConnection(dbUrl, user, pass);
94
95 //create and execute query
96 stmt = conn.createStatement();
97 //remember to put in the projectId parameter instead of hardcoding it
98 String sql = "SELECT name, id, typeId, created from td_ContentItem where projectId="+projectID;
99/*
100 String sql = "select td_Document.id, td_Document.content " +
101 "from td_Document, td_ContentItem, td_ContentItem_Document " +
102 "where td_ContentItem.projectId=" + projectID + " and td_ContentItem.id =
103 td_ContentItem_Document.ContentItemId " +
104 "and td_ContentItem_Document.documentId = td_Document.id;";
105*/
106 ResultSet myResult = stmt.executeQuery(sql);
107 ResultSetMetaData resultMetaData = myResult.getMetaData();
108
109 int dbColumn = resultMetaData.getColumnCount();
110 System.out.println(" Number of columns in table retrieved: " + dbColumn);
111
112 Gson myGSon = new Gson();
113 file.write("[");
114
115 //does nothing, assuming the try catch picks up the error first,
116 if(!myResult.next()){
117 System.out.println("Access denied");
118 }
119
120 while(myResult.next()){
121 //string/object as key/value pair
122 HashMap<String, Object> dbRow = new HashMap<String, Object>(dbColumn);
123
124 //maybe use some kind of arrayList?
125 // ArrayList<Map<String, Object>> dbRowArray = new ArrayList<>(dbColumn);
126
127 for(int i = 1; i <= dbColumn; i++){
128 /*
129 doing checking this way would mean we have to have a case
130 for every data type,
131 if a data type changes in the database that's probably fine, but
132 if a new data type is sent in, the code may not handle it
133 */
134 /*
135 Without this kind of check though, the output would throw a pretty nasty
136 warning about illegal reflective access. Though it would still print the
137 date out fine. Think it switched to using some other java option?
138
139 WARNING: An illegal reflective access operation has occurred
140WARNING: Illegal reflective access by com.google.gson.internal.bind.ReflectiveTypeAdapterFactory (file:/home/su41/.gradle/caches/modules-2/files-2.1/com.google.code.gson/gson/2.7/751f548c85fa49f330cecbb1875893f971b33c4e/gson-2.7.jar) to field java.time.LocalDateTime.date
141WARNING: Please consider reporting this to the maintainers of com.google.gson.internal.bind.ReflectiveTypeAdapterFactory
142WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
143WARNING: All illegal access operations will be denied in a future release
144 */
145 if(resultMetaData.getColumnTypeName(i).equals("DATETIME")){
146 dbRow.put(resultMetaData.getColumnName(i), myResult.getDate(i));
147 //System.out.println("has a datetime");
148
149 }
150
151 else{
152 dbRow.put(resultMetaData.getColumnName(i), myResult.getObject(i));
153 // System.out.println("no datetime datetime");
154 }
155 }
156 //JsonObject jsonObject = myGSon.toJsonTree(dbRow).getAsJsonObject();
157
158 // using a hashmap wont work with this as its not an array
159 // JsonArray jsonArray = myGSon.toJsonTree(dbRow).getAsJsonArray();
160 String dbRowAsJson = myGSon.toJson(dbRow);
161
162 //printing statements for checking output
163 // System.out.println("As normal: " + dbRow);
164 // System.out.println("====");
165 //System.out.println("As JSON: " + anObject);
166
167 //saving to json file
168
169 file.write(dbRowAsJson);
170 //file.write(jsonArray.toString());
171 //Adding commas between each row that we write to our file, as we need it to be valid json
172 if(!myResult.isLast()){
173 file.write(",");
174 }
175 }
176 //write the closing bracket, and flush the writer
177 file.write("]");
178 file.flush();
179 file.close();
180 //System.out.println(myList);
181 System.out.println("Closing connection...");
182 myResult.close();
183 stmt.close();
184 conn.close();
185 }
186 catch(Exception e){
187 //catch for class.name
188 e.printStackTrace();
189 //print out wrong username or password instead of the stack trace?
190 System.out.println("encountered error");
191 }
192 }
193}
Note: See TracBrowser for help on using the repository browser.