· 4 years ago · Mar 13, 2021, 08:04 PM
1package drivers;
2
3import java.util.ArrayList;
4import java.util.regex.Matcher;
5import java.util.regex.Pattern;
6
7import apps.Database;
8import types.Driver;
9import types.Response;
10import types.Status;
11import types.Table;
12
13
14
15
16
17
18public class InsertOrReplaceTable implements Driver {
19 static final Pattern pattern = Pattern.compile(
20 //\s*(INSERT|REPLACE)\s+INTO\s+([a-z0-9_]+)\s*\((\s*[a-z0-9_]*\s*(?:,\s*[a-z0-9_]+\s*)*)\)*\s*VALUES\s*\((\s*[^0][-+".?!\s\w]*\s*(?:\s*,\s*[^0][-+".?!\s\w]*)*\s*)\)+
21 "\\s*(INSERT|REPLACE)\\s+INTO\\s+([a-z0-9_]+)\\s*\\(?(\\s*[a-z0-9_]*\\s*(?:,\\s*[a-z0-9_]+\\s*)*)\\)*?\\s*VALUES\\s*\\((\\s*[^0][-+\".?!\\s\\w]*\\s*(?:\\s*,\\s*[^0][-+\".?!\\s\\w]*)*\\s*)\\)+",
22 Pattern.CASE_INSENSITIVE
23 );
24 //group 1 = INSERT or REPLACE ?maybe
25 //group 2 = table_name
26 //group 3 = column_name
27 //group 4 = Value String
28
29 @Override
30 public Response execute(String query, Database db) {
31 Matcher matcher = pattern.matcher(query.strip());
32 if (!matcher.matches())
33 return new Response(query, Status.UNRECOGNIZED, null, null);//user input is a syntax error.
34
35
36 ArrayList<String> column_name = new ArrayList<String>();
37 ArrayList<String> value_strings = new ArrayList<String>();
38 ArrayList<Integer> pointer_array = new ArrayList<Integer>();
39 ArrayList<Object> row = new ArrayList<>();
40 ArrayList<Object> real_types = new ArrayList<>();
41
42
43
44 //***************************USERS INPUTS ARE STORED INTO ARRAYLIST**********************
45 //table name input validation
46 String table_name = matcher.group(2);
47 if(table_name.length() > 15)
48 return new Response(query, Status.FAILED, "Table names must be between 1-15 charachter ", null);//semantic error
49 if(!db.tables().contains(table_name))//checks if table exist
50 return new Response(query, Status.FAILED, "Invalid entry: Table entered was not found in db please try again. ", null);//checks if name exist in Database
51
52 //SCHEMA COLUMN INPUT
53 Table table = db.tables().get(table_name);//retrives schema col names
54 @SuppressWarnings("unchecked")
55 ArrayList<String> schema_col_name = (ArrayList<String>) table.schema().get("column_names"); System.out.println("\n****************START HERE****************\n SCHEMA COLUMN NAMES ARRAY\nSize of column_names before inputs: " + schema_col_name.size() +"\nArray schema_col_types contains the following: " + schema_col_name + "\nSize of column_names after inputs: " + schema_col_name.size() + "\n****************FINSHED HERE****************\n" );
56 @SuppressWarnings("unchecked")
57 ArrayList<String> schema_col_types = (ArrayList<String>) table.schema().get("column_types"); System.out.println("\n****************START HERE****************\n SCHEMA COLUMN TYPES ARRAY\nSize of column_names before inputs: " + schema_col_types.size() +"\nArray schema_col_types contains the following: " + schema_col_types + "\nSize of column_names after inputs: " + schema_col_types.size() + "\n****************FINSHED HERE****************\n" );
58
59 //COLUMN NAME INPUT
60 String[] query_column_name = matcher.group(3).split("\\s*,\\s*");//splits the strings at the comma and stores it into an array
61 if(query_column_name.length > 15) //column length validation
62 return new Response(query, Status.FAILED, "Columms defined exceeds capacity, reduce the number of column inputs to 15. ", null);//checks the size of columns define is <= 15 //System.out.println("the size of query "+query_column_name.length);
63
64 //group one column_names placed into an ArrayList for easy modifications as needed
65 System.out.println("****************START HERE****************\n COLUMN NAMES ARRAY\nSize of column_names before inputs: " + column_name.size());
66 for(String temp: query_column_name) {
67 column_name.add(temp); System.out.print(temp + " "); //use this to check what the column_names being added
68 } System.out.println("Array column_names contains the following: " + column_name + "\nSize of column_names after inputs: " + column_name.size() + "\n****************FINSHED HERE****************\n" );
69
70 //VALUE STRING INPUT
71 String[] query_value_string = matcher.group(4).split("\\s*,\\s*");//splits the strings at the comma and stores it into an array
72
73 //from group 3 placed into an ArrayList for easy modifications as needed
74 System.out.println("****************START HERE****************\n VALUE STRINGS ARRAY\nSize of column_names before inputs: " + value_strings.size());
75 for(String temp: query_value_string) {
76 if(temp.length() >= 130)
77 return new Response(query, Status.FAILED, "Invalid entry: String length cant be longer than 128 characters. ", null);//checks the size of columns define is <= 15
78 value_strings.add(temp); System.out.print(temp + " ");
79 }System.out.println("\nArray value_strings contains the following: " + value_strings + "\nSize of column_names after inputs: " + value_strings.size() + "\n****************FINSHED HERE****************\n" );
80
81
82 //PRIMARY INPUT INDEX FROM SCHEMA IS FOUND
83 String schema_primary = table.schema().get("primary_index").toString();
84 int primary_converted_2int = Integer.parseInt(schema_primary); System.out.println("This should be the primary index number: " + table.schema().get("primary_index").toString());
85
86
87 //****************************************************SANITIZARTION STARTS HERE***************************************************//
88 //if column name is missing schema column name is used this sets the schema column name to be used
89 int helper = 0;
90 String countLength = matcher.group(3);
91 if(countLength.length() == 0) {System.out.println("This is my size of the column names before adding anything: " + countLength.length());
92 if(value_strings.size() != schema_col_name.size())
93 return new Response(query, Status.FAILED, "Invalid entry: The number of column names entered & values entered must match, try again. ", null);
94 column_name.clear();
95 while(value_strings.size() != column_name.size()) {
96 String foundWordAtIndex = schema_col_name.get(helper);
97 column_name.add(foundWordAtIndex);
98 helper++;
99 }
100 }
101 if(value_strings.size()!= column_name.size())
102 return new Response(query, Status.FAILED, "Invalid entry: The number of column names entered & values entered must match, try again. ", null);
103 if(column_name.size() > schema_col_name.size())
104 return new Response(query, Status.FAILED, "Invalid entry: The number of column names entered is larger then the schema, try again. ", null);
105
106 //*****************************************COMPARING ARRAYS MEET QUALIFICATIONS***************************************************//
107 //pointer array is setup here
108 for(String temp: column_name) {
109 if(schema_col_name.contains(temp)) {
110 int found = schema_col_name.indexOf(temp);
111 if(pointer_array.contains(found))
112 return new Response(query, Status.FAILED, "Invalid entry: duplicated column name entry. ", null);
113 pointer_array.add(found);
114 }
115 }System.out.println("\nHere are index numbers stored from the pointer_array: " + pointer_array);
116
117 //checks for missig primary
118 if(!pointer_array.contains(primary_converted_2int))
119 return new Response(query, Status.FAILED, "Invalid entry: Missing primary entry. ", null);
120
121 //create empty row array
122 while(row.size() < schema_col_name.size()) {
123 row.add(null);
124 }System.out.println("Here I am the rows array as nulls array: " + row);
125
126 //create empty real_types array
127 while(real_types.size() < schema_col_name.size()) {
128 real_types.add(null);
129 }System.out.println("Here I am the realy_types array as nulls array: " + real_types);
130
131 //pointer array is used to build the rows array
132 int counter = 0;
133 for(int i: pointer_array) {
134 int found = i;
135 String rowsWord = value_strings.get(counter);
136
137 row.set(found, rowsWord);
138 counter++;
139 }System.out.println("Here I am the ROW array with values inputted: " + row);
140
141 //****************************strings from query converted to there respective data type values matched from schema_col_types array**********************/
142 int counter2 = 0;
143 for(String temp: value_strings) {
144 int indexValue = pointer_array.get(counter2);
145 String typesString = schema_col_types.get(indexValue);
146 counter2++;
147 System.out.println("\nBefore converting me to the appropriate type I am a string before any converstion is made: " + typesString);
148 System.out.println("This is my string I am: " + temp + "\n");
149
150
151 //String validation check
152 if(typesString.equalsIgnoreCase("String")) {System.out.println("I am the type STRING I look like this before converstion: " + temp);
153 if(!temp.contains("\"") )
154 return new Response(query, Status.FAILED, "Invalid entry: this STRING is missing quoatation marks. ", null);
155
156 String result = temp.substring(1 , temp.length()-1);System.out.println("I am the type string I look like this after converstion: " + temp);
157 real_types.set(indexValue, result);
158 }
159 //boolean validation check
160 else if(typesString.equalsIgnoreCase("Boolean")) { System.out.println("I am the type BOOLEAN. I look like this before converstion: " + temp);
161 if(temp.contains("\"") )
162 return new Response(query, Status.FAILED, "Invalid entry: boolean columns cannot accept string literals ",null);
163
164 if(temp.equalsIgnoreCase("null")) {
165 real_types.set(indexValue, null);
166 break;
167 }
168 if(temp.matches("[0-9]"))
169 return new Response(query, Status.FAILED, "Invalid entry: boolean columns cannot accept integer literals ",null);
170
171 boolean result = Boolean.parseBoolean(temp);
172 real_types.set(indexValue, result);
173 System.out.println("I am the type BOOLEAN. I look like this after converstion: " + temp);
174 }
175
176 //Integer validation check
177 else if(typesString.equalsIgnoreCase("Integer")) { System.out.println("I am the type INTEGER. I look like this before converstion: " + temp);
178 if(temp.equalsIgnoreCase("null")) {
179 real_types.set(indexValue, null);
180
181 }
182 else
183 try {
184 int result=Integer.parseInt(temp);
185 if(temp.startsWith("0") && result != 0) {
186 return new Response(query, Status.FAILED, "Invalid entry: leading zeros not allowed. ", null);
187 }
188 real_types.set(indexValue, result);
189 }
190 catch (NumberFormatException e) {
191 return new Response(query, Status.FAILED, "The Number entered is not a valid 32 bit integer in java", null);
192 }//semantic error
193 }
194 }
195
196 System.out.println("I am the REAL_TYPES array I look like this: " + real_types );
197
198 //checks for null primary columns
199 if(real_types.get(primary_converted_2int) == null ) {
200 return new Response(query, Status.FAILED, "Invalid entry: Primary entries can not be null. ", null);
201 }
202
203 ////*****************************************INSERTING ROWS STARTS HERE***************************************************//
204 int rowsModed = 0;
205 String Insert_or_Replace = matcher.group(1);
206
207 //inserts rows
208 if(Insert_or_Replace.equalsIgnoreCase("insert")) {
209 if(table.state().contains(real_types.get(primary_converted_2int)))
210 return new Response(query, Status.FAILED, "Invliad entry: Primary key already exists", null);
211
212 else table.state().put(real_types.get(primary_converted_2int), real_types);
213 }
214
215 //replaces rows
216 if(Insert_or_Replace.equalsIgnoreCase("replace")) {
217 rowsModed++;
218 table.state().put(real_types.get(primary_converted_2int), real_types);
219 }
220 int size = table.state().size();
221
222 System.out.println("\n");
223 return new Response(query, Status.SUCCESSFUL, "Tables name is: " + table_name + ", This tables size is: " + size + " & the number of rows modified: " + rowsModed, table);
224 }
225}