├── .classpath ├── .gitignore ├── .project ├── .settings └── org.eclipse.jdt.core.prefs ├── DBMS.iml ├── README.md ├── lib ├── gson-2.3.1.jar ├── log4j-api-2.6.2.jar ├── log4j-core-2.6.2.jar ├── protobuf-java-3.1.0.jar └── protobuf-java-util-3.1.0.jar ├── screenshots ├── ScreenShot_1.png └── ScreenShot_2.png └── src ├── dbms ├── backend │ ├── BackendController.java │ ├── BackendParser.java │ ├── BackendParserFactory.java │ └── parsers │ │ ├── json │ │ ├── ClassTypeAdapter.java │ │ ├── ClassTypeAdapterFactory.java │ │ ├── ColumnAdapter.java │ │ ├── Constants.properties │ │ ├── JSONParser.java │ │ └── test.java │ │ ├── protobuf │ │ ├── ColumnsAdapterProtoBuf.java │ │ ├── Constants.properties │ │ ├── ProtocolBufferParser.java │ │ └── TableProtoBuf.java │ │ └── xml │ │ ├── Constants.properties │ │ ├── XMLParser.java │ │ └── schema │ │ ├── dtd │ │ ├── DTDAttributeCreator.java │ │ ├── DTDElementCreator.java │ │ └── DTDSchemaParser.java │ │ └── xsd │ │ └── XSDParser.java ├── datatypes │ ├── DBDatatype.java │ ├── DBDate.java │ ├── DBFloat.java │ ├── DBInteger.java │ ├── DBString.java │ └── DatatypeFactory.java ├── exception │ ├── DataTypeNotSupportedException.java │ ├── DatabaseAlreadyCreatedException.java │ ├── DatabaseNotFoundException.java │ ├── IncorrectDataEntryException.java │ ├── ReservedKeyWordException.java │ ├── SyntaxErrorException.java │ ├── TableAlreadyCreatedException.java │ ├── TableNotFoundException.java │ └── TypeNotSupportedException.java ├── sqlparser │ ├── PatternsHolder.java │ ├── SQLParser.java │ ├── SQLRegex.properties │ ├── sqlInterpreter │ │ ├── BooleanExpression.java │ │ ├── BooleanExpressionEvaluator.java │ │ ├── BooleanOperator.java │ │ ├── Condition.java │ │ ├── SQLPredicate.java │ │ ├── Where.java │ │ └── rules │ │ │ ├── AlterAdd.java │ │ │ ├── AlterDrop.java │ │ │ ├── CreateDatabase.java │ │ │ ├── CreateTable.java │ │ │ ├── DDLStatement.java │ │ │ ├── DMLStatement.java │ │ │ ├── Delete.java │ │ │ ├── DropDatabase.java │ │ │ ├── DropTable.java │ │ │ ├── Expression.java │ │ │ ├── InsertIntoTable.java │ │ │ ├── Select.java │ │ │ ├── Union.java │ │ │ ├── Update.java │ │ │ └── UseDatabase.java │ └── syntax │ │ ├── AlterSyntax.java │ │ ├── CreateSyntax.java │ │ ├── DeleteSyntax.java │ │ ├── DropSyntax.java │ │ ├── InsertSyntax.java │ │ ├── SQLSyntax.java │ │ ├── SelectSyntax.java │ │ ├── SyntaxUtil.java │ │ ├── UpdateSyntax.java │ │ ├── UseSyntax.java │ │ └── WhereSyntax.java ├── test │ ├── JSONParserTesting │ │ ├── JSONTestingDelete.java │ │ ├── JSONTestingSelect.java │ │ └── JSONTestingUpdate.java │ ├── OrderbyTesting.java │ ├── ProtoBufParserTesting │ │ ├── ProtoBufTestingDelete.java │ │ ├── ProtoBufTestingSelect.java │ │ └── ProtoBufTestingUpdate.java │ ├── SQLParserTesting │ │ ├── AlterTest.java │ │ ├── CreateTest.java │ │ ├── DeleteTest.java │ │ ├── DropTest.java │ │ ├── InsertTest.java │ │ ├── SelectTest.java │ │ ├── SqlParserRef.java │ │ └── UpdateTest.java │ ├── Test.java │ └── XMLParserTesting │ │ ├── XMLTestingDelete.java │ │ ├── XMLTestingSelect.java │ │ └── XMLTestingUpdate.java ├── ui │ ├── Formatter.java │ └── Main.java └── util │ ├── Column.java │ ├── DBComparatorChain.java │ ├── Database.java │ ├── Evaluator.java │ ├── Operation.java │ ├── Operator.java │ ├── Record.java │ ├── RecordSet.java │ └── Table.java ├── jdbc └── imp │ ├── connection │ ├── ConnectionAdapter.java │ └── DBConnection.java │ ├── driver │ └── DBDriver.java │ ├── resultSet │ ├── DBResultSet.java │ └── DBResultSetImpl.java │ ├── resultSetMetaData │ ├── DBResultSetMetaData.java │ └── DBResultSetMetaDataImpl.java │ ├── statement │ ├── DBStatement.java │ └── StatementAdapter.java │ ├── test │ ├── jdbcTesting │ │ └── JDBCTest.java │ └── onlineTester │ │ ├── IntegrationTest.java │ │ ├── SmokeTest.java │ │ └── TestRunner.java │ └── ui │ └── Main.java └── log4j2.properties /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | \bin 2 | .DS_Store 3 | .idea 4 | \JDBCLogs -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | DBMS 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.sirius.nature.modelingproject 16 | org.eclipse.jdt.core.javanature 17 | 18 | 19 | -------------------------------------------------------------------------------- /.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate 4 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 5 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 6 | org.eclipse.jdt.core.compiler.compliance=1.7 7 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 8 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 9 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 10 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 11 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 12 | org.eclipse.jdt.core.compiler.source=1.7 13 | -------------------------------------------------------------------------------- /DBMS.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Java DBMS 2 | [![Codacy Badge](https://api.codacy.com/project/badge/Grade/db90bf05197e4a8dbd537b5b2e081e62)](https://www.codacy.com/app/yakout/DBMS?utm_source=github.com&utm_medium=referral&utm_content=yakout/DBMS&utm_campaign=badger) 3 | 4 | > XML, JSON and [Protocol Buffers](https://developers.google.com/protocol-buffers/) based [RDBMS](https://en.wikipedia.org/wiki/Relational_database_management_system) that supports [SQL](https://en.wikipedia.org/wiki/SQL) syntax with [JDBC](https://en.wikipedia.org/wiki/Java_Database_Connectivity) API implementation. 5 | 6 | ## Supported SQL statements ## 7 | > ### CREATE 8 | >> - ``` CREATE DATABASE dbname; ``` 9 | >> - ``` CREATE TABLE table_name (column_name1 data_type, column_name2 data_type); ``` 10 | 11 | > ### DROP 12 | >> - ``` DROP TABLE table_name; ``` 13 | >> - ``` DROP DATABASE database_name; ``` 14 | 15 | > ### INSERT 16 | >> - ``` INSERT INTO table_name (ID,Name) VALUES (1,'Ahmed'); ``` 17 | >> - ``` INSERT INTO table_name VALUES (1,'Ahmed', ...); ``` 18 | 19 | > ### SELECT 20 | >> - ``` SELECT col1, col2, col3 FROM table_name WHERE col1!='value'; ``` 21 | >> - ```SELECT * FROM table_name WHERE TRUE; ``` 22 | >> - ```SELECT * FROM table_name where col1 <= col2;``` 23 | >> - ```SELECT * FROM table_name where ID == 6;``` 24 | >> - ```SELECT * FROM table_name order by col1 ASC;``` 25 | >> - ```SELECT * FROM table_name order by col2 DESC;``` 26 | >> - ```SELECT * FROM table_name order by Name DESC where Name < 'S';``` 27 | >> - ```SELECT DISTINCT City FROM Customers;``` 28 | 29 | > ### DELETE 30 | >> - ```DELETE FROM table_name WHERE some_column=some_value;``` 31 | >> - ```DELETE FROM table_name; // delete all rows but keeps the table``` 32 | >> - ```DELETE * FROM table_name; // same as above``` 33 | 34 | > ### UPDATE 35 | >> - ```UPDATE table_name SET column1='value1',column2='value2' WHERE some_column='some_value'; // with condition``` 36 | >> - ```UPDATE tableName SET columnName='someValue', columnName='someValue'; // with no condition``` 37 | 38 | > ### ALTER 39 | >> - ```ALTER TABLE table_name ADD column_name datatype``` 40 | >> - ```ALTER TABLE table_name DROP COLUMN column_name``` 41 | 42 | > ### Union 43 | >> - ```SELECT column_name(s) FROM table1 UNION SELECT column_name(s) FROM table2;``` 44 | >> - ```SELECT column_name(s) FROM table1 UNION ALL SELECT column_name(s) FROM table2;``` 45 | >> - ```SELECT city FROM Customers UNION all SELECT city FROM Suppliers union select city from City ORDER BY City;``` 46 | 47 | 48 | ## Supported Data Types 49 | ##### int, varchar, date, float. 50 | 51 | ## Contribution Guidelines 52 | This project is public, feel free to create pull requests or open issues. 53 | 54 | ## Screen Shots 55 | ![picture alt](https://github.com/yakout/DBMS/blob/master/screenshots/ScreenShot_1.png) 56 | ![picture alt](https://github.com/yakout/DBMS/blob/master/screenshots/ScreenShot_2.png) 57 | -------------------------------------------------------------------------------- /lib/gson-2.3.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yakout/DBMS/2c028ee73aac520f7cdc634f6792701ddcdd71b1/lib/gson-2.3.1.jar -------------------------------------------------------------------------------- /lib/log4j-api-2.6.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yakout/DBMS/2c028ee73aac520f7cdc634f6792701ddcdd71b1/lib/log4j-api-2.6.2.jar -------------------------------------------------------------------------------- /lib/log4j-core-2.6.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yakout/DBMS/2c028ee73aac520f7cdc634f6792701ddcdd71b1/lib/log4j-core-2.6.2.jar -------------------------------------------------------------------------------- /lib/protobuf-java-3.1.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yakout/DBMS/2c028ee73aac520f7cdc634f6792701ddcdd71b1/lib/protobuf-java-3.1.0.jar -------------------------------------------------------------------------------- /lib/protobuf-java-util-3.1.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yakout/DBMS/2c028ee73aac520f7cdc634f6792701ddcdd71b1/lib/protobuf-java-util-3.1.0.jar -------------------------------------------------------------------------------- /screenshots/ScreenShot_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yakout/DBMS/2c028ee73aac520f7cdc634f6792701ddcdd71b1/screenshots/ScreenShot_1.png -------------------------------------------------------------------------------- /screenshots/ScreenShot_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yakout/DBMS/2c028ee73aac520f7cdc634f6792701ddcdd71b1/screenshots/ScreenShot_2.png -------------------------------------------------------------------------------- /src/dbms/backend/BackendParser.java: -------------------------------------------------------------------------------- 1 | package dbms.backend; 2 | 3 | import java.io.File; 4 | 5 | import dbms.exception.DatabaseAlreadyCreatedException; 6 | import dbms.exception.DatabaseNotFoundException; 7 | import dbms.exception.TableAlreadyCreatedException; 8 | import dbms.exception.TableNotFoundException; 9 | import dbms.util.Database; 10 | import dbms.util.Table; 11 | 12 | public abstract class BackendParser { 13 | public static void createDatabase(Database database) 14 | throws DatabaseAlreadyCreatedException { 15 | File workspace = new File(BackendController.getInstance() 16 | .getCurrentDatabaseDir()); 17 | if (!workspace.exists()) { 18 | workspace.mkdirs(); 19 | } 20 | File databaseDir = new File(workspace, 21 | database.getName()); 22 | if (!databaseDir.exists()) { 23 | databaseDir.mkdirs(); 24 | } else { 25 | throw new DatabaseAlreadyCreatedException(); 26 | } 27 | } 28 | 29 | public static void dropDatabase(Database database) 30 | throws DatabaseNotFoundException { 31 | File databaseDir = new File(BackendController.getInstance() 32 | .getCurrentDatabaseDir() 33 | + File.separator + database.getName()); 34 | if (databaseDir.exists()) { 35 | String[] files = databaseDir.list(); 36 | for (String fileName : files) { 37 | new File(databaseDir.getPath(), fileName).delete(); 38 | } 39 | databaseDir.delete(); 40 | } else { 41 | throw new DatabaseNotFoundException(); 42 | } 43 | } 44 | 45 | public abstract BackendParser getParser(); 46 | 47 | public abstract void loadTable(Table table) 48 | throws TableNotFoundException, DatabaseNotFoundException; 49 | 50 | public abstract void writeToFile(Table table) 51 | throws TableNotFoundException, DatabaseNotFoundException; 52 | 53 | public abstract void createTable(Table table) 54 | throws DatabaseNotFoundException, TableAlreadyCreatedException; 55 | 56 | public abstract void dropTable(Table table) 57 | throws DatabaseNotFoundException; 58 | } 59 | -------------------------------------------------------------------------------- /src/dbms/backend/BackendParserFactory.java: -------------------------------------------------------------------------------- 1 | package dbms.backend; 2 | 3 | import dbms.backend.parsers.json.JSONParser; 4 | 5 | import java.util.HashMap; 6 | 7 | public class BackendParserFactory { 8 | private static HashMap registeredParsers = null; 9 | private static BackendParserFactory instance = null; 10 | private String currentKey = JSONParser.KEY; 11 | 12 | private BackendParserFactory() { 13 | registeredParsers = new HashMap<>(); 14 | loadParsers(); 15 | } 16 | /** 17 | * 18 | * @return {@link BackendParserFactory} return static instance of 19 | * factory by singleton. 20 | */ 21 | public static BackendParserFactory getFactory() { 22 | if (instance == null) { 23 | instance = new BackendParserFactory(); 24 | } 25 | return instance; 26 | } 27 | 28 | /** 29 | * Registers the invoker class to the factory. 30 | * @param key defines the key of the parser required to be registered. 31 | * @param parser {@link BackendParser} shows value of the 32 | * registered class type. 33 | */ 34 | public void register(final String key, final BackendParser parser) { 35 | registeredParsers.put(key, parser); 36 | } 37 | 38 | /** 39 | * Links the invoker class to its instance 40 | * @param key defines the the key of the required parser. 41 | * @return {@link BackendParser} reference to the instance of 42 | * the required parser. 43 | */ 44 | public BackendParser getRegisteredParser(final String key) { 45 | return registeredParsers.get(key).getParser(); 46 | } 47 | 48 | public BackendParser getCurrentParser() { 49 | return registeredParsers.get(currentKey).getParser(); 50 | } 51 | 52 | public void setCurrentParser(final String key) { 53 | if (registeredParsers.get(key) == null) { 54 | throw new UnsupportedOperationException(); 55 | } 56 | currentKey = key; 57 | } 58 | 59 | public static void loadParsers() { 60 | try { 61 | Class.forName("dbms.backend.parsers.xml.XMLParser"); 62 | Class.forName("dbms.backend.parsers.json.JSONParser"); 63 | Class.forName("dbms.backend.parsers.protobuf.ProtocolBufferParser"); 64 | } catch (ClassNotFoundException e) { 65 | e.printStackTrace(); 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /src/dbms/backend/parsers/json/ClassTypeAdapter.java: -------------------------------------------------------------------------------- 1 | package dbms.backend.parsers.json; 2 | 3 | import java.io.IOException; 4 | 5 | import com.google.gson.TypeAdapter; 6 | import com.google.gson.stream.JsonReader; 7 | import com.google.gson.stream.JsonToken; 8 | import com.google.gson.stream.JsonWriter; 9 | 10 | public class ClassTypeAdapter extends TypeAdapter> { 11 | 12 | @Override 13 | public Class read(JsonReader jsonReader) throws IOException { 14 | if (jsonReader.peek() == JsonToken.NULL) { 15 | jsonReader.nextNull(); 16 | return null; 17 | } 18 | Class clazz = null; 19 | try { 20 | clazz = Class.forName(jsonReader.nextString()); 21 | } catch (ClassNotFoundException exception) { 22 | throw new IOException(exception); 23 | } 24 | return clazz; 25 | } 26 | 27 | 28 | @Override 29 | public void write(JsonWriter jsonWriter, Class clazz) throws 30 | IOException { 31 | if (clazz == null) { 32 | jsonWriter.nullValue(); 33 | return; 34 | } 35 | jsonWriter.value(clazz.getName()); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/dbms/backend/parsers/json/ClassTypeAdapterFactory.java: -------------------------------------------------------------------------------- 1 | package dbms.backend.parsers.json; 2 | 3 | import com.google.gson.Gson; 4 | import com.google.gson.TypeAdapter; 5 | import com.google.gson.TypeAdapterFactory; 6 | import com.google.gson.reflect.TypeToken; 7 | 8 | public class ClassTypeAdapterFactory implements TypeAdapterFactory { 9 | @Override 10 | public TypeAdapter create(final Gson gson, 11 | final TypeToken typeToken) { 12 | if (!Class.class.isAssignableFrom(typeToken.getRawType())) { 13 | return null; 14 | } 15 | return (TypeAdapter) new ClassTypeAdapter(); 16 | } 17 | } -------------------------------------------------------------------------------- /src/dbms/backend/parsers/json/ColumnAdapter.java: -------------------------------------------------------------------------------- 1 | package dbms.backend.parsers.json; 2 | 3 | import java.lang.reflect.InvocationTargetException; 4 | import java.lang.reflect.Type; 5 | import java.sql.Date; 6 | import java.text.DateFormat; 7 | import java.text.ParseException; 8 | import java.text.SimpleDateFormat; 9 | 10 | import com.google.gson.JsonArray; 11 | import com.google.gson.JsonDeserializationContext; 12 | import com.google.gson.JsonDeserializer; 13 | import com.google.gson.JsonElement; 14 | import com.google.gson.JsonObject; 15 | import com.google.gson.JsonParseException; 16 | import com.google.gson.JsonPrimitive; 17 | import com.google.gson.JsonSerializationContext; 18 | import com.google.gson.JsonSerializer; 19 | 20 | import dbms.datatypes.DBDatatype; 21 | import dbms.datatypes.DBDate; 22 | import dbms.datatypes.DBFloat; 23 | import dbms.datatypes.DBInteger; 24 | import dbms.datatypes.DBString; 25 | import dbms.datatypes.DatatypeFactory; 26 | import dbms.util.Column; 27 | 28 | /** 29 | * Serializes/Deserializes a column to .JSON format. 30 | */ 31 | public class ColumnAdapter implements JsonSerializer, 32 | JsonDeserializer { 33 | 34 | @Override 35 | public JsonElement serialize(final Column column, final Type type, 36 | final JsonSerializationContext jsc) { 37 | JsonObject columnObject = new JsonObject(); 38 | columnObject.addProperty("name", column.getName()); 39 | String typeProperty = null; 40 | try { 41 | typeProperty = (String) column.getType().getMethod( 42 | "getKey").invoke(column.getType().newInstance()); 43 | } catch (IllegalAccessException | InvocationTargetException 44 | | NoSuchMethodException | InstantiationException e) { 45 | e.printStackTrace(); 46 | } 47 | columnObject.addProperty("type", typeProperty); 48 | columnObject.add("entries", addSerializedEntries( 49 | column, typeProperty)); 50 | return columnObject; 51 | } 52 | 53 | @Override 54 | public Column deserialize(final JsonElement jsonElement, final Type type, 55 | final JsonDeserializationContext jsc) 56 | throws JsonParseException { 57 | Column column = new Column(); 58 | String nameProp = jsonElement.getAsJsonObject().getAsJsonPrimitive( 59 | "name").getAsString(); 60 | String typeProp = jsonElement.getAsJsonObject().getAsJsonPrimitive( 61 | "type").getAsString(); 62 | Class typeClass = DatatypeFactory.getFactory() 63 | .getRegisteredDatatype(typeProp); 64 | column.setName(nameProp); 65 | column.setType(typeClass); 66 | JsonArray entries = jsonElement.getAsJsonObject().getAsJsonArray( 67 | "entries"); 68 | for (JsonElement entry : entries) { 69 | if (typeProp.equals(DBInteger.KEY)) { 70 | try { 71 | Integer x = entry.getAsJsonPrimitive().getAsInt(); 72 | column.addEntry(new DBInteger(x)); 73 | } catch (NumberFormatException e) { 74 | column.addEntry(null); 75 | } 76 | } else if (typeProp.equals(DBString.KEY)) { 77 | String x = entry.getAsJsonPrimitive().getAsString(); 78 | column.addEntry(new DBString(x)); 79 | } else if (typeProp.equals(DBFloat.KEY)) { 80 | try { 81 | Float x = entry.getAsJsonPrimitive().getAsFloat(); 82 | column.addEntry(new DBFloat(x)); 83 | } catch (NumberFormatException e) { 84 | column.addEntry(null); 85 | } 86 | } else if (typeProp.equals(DBDate.KEY)) { 87 | String dateString = entry.getAsJsonPrimitive().getAsString(); 88 | DateFormat format = new SimpleDateFormat("yyyy-MM-dd"); 89 | try { 90 | Date x = new Date(format.parse(dateString).getTime()); 91 | column.addEntry(new DBDate(x)); 92 | } catch (ParseException e) { 93 | column.addEntry(null); 94 | } 95 | } 96 | } 97 | return column; 98 | } 99 | 100 | private JsonArray addSerializedEntries(final Column column, 101 | final String typeProperty) { 102 | JsonArray entries = new JsonArray(); 103 | for (DBDatatype entry : column.getEntries()) { 104 | JsonPrimitive obj = null; 105 | if (typeProperty.equals(DBInteger.KEY)) { 106 | if (entry == null) { 107 | obj = new JsonPrimitive(""); 108 | } else { 109 | obj = new JsonPrimitive((Integer) entry.getValue()); 110 | } 111 | } else if (typeProperty.equals(DBString.KEY)) { 112 | if (entry == null || entry.getValue().equals("")) { 113 | obj = new JsonPrimitive(""); 114 | } else { 115 | obj = new JsonPrimitive((String) entry.getValue()); 116 | } 117 | } else if (typeProperty.equals(DBFloat.KEY)) { 118 | if (entry == null) { 119 | obj = new JsonPrimitive(""); 120 | } else { 121 | obj = new JsonPrimitive((Float) entry.getValue()); 122 | } 123 | } else if (typeProperty.equals(DBDate.KEY)) { 124 | if (entry == null) { 125 | obj = new JsonPrimitive(""); 126 | } else { 127 | DBDate date = (DBDate) entry; 128 | obj = new JsonPrimitive(date.toString()); 129 | } 130 | } 131 | entries.add(obj); 132 | } 133 | return entries; 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/dbms/backend/parsers/json/Constants.properties: -------------------------------------------------------------------------------- 1 | extension.json=.json -------------------------------------------------------------------------------- /src/dbms/backend/parsers/json/JSONParser.java: -------------------------------------------------------------------------------- 1 | package dbms.backend.parsers.json; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.File; 5 | import java.io.FileNotFoundException; 6 | import java.io.FileReader; 7 | import java.io.FileWriter; 8 | import java.io.IOException; 9 | import java.util.ResourceBundle; 10 | 11 | import org.apache.logging.log4j.LogManager; 12 | import org.apache.logging.log4j.Logger; 13 | 14 | import com.google.gson.ExclusionStrategy; 15 | import com.google.gson.FieldAttributes; 16 | import com.google.gson.Gson; 17 | import com.google.gson.GsonBuilder; 18 | 19 | import dbms.backend.BackendController; 20 | import dbms.backend.BackendParser; 21 | import dbms.backend.BackendParserFactory; 22 | import dbms.exception.DatabaseNotFoundException; 23 | import dbms.exception.TableAlreadyCreatedException; 24 | import dbms.exception.TableNotFoundException; 25 | import dbms.util.Column; 26 | import dbms.util.Database; 27 | import dbms.util.Table; 28 | 29 | /** 30 | * Table parser to .JSON format. 31 | */ 32 | public class JSONParser extends BackendParser { 33 | 34 | /** 35 | * Key to JSON parser that is used to register to factory. 36 | */ 37 | public static final String KEY = "alt"; 38 | 39 | /** 40 | * Resource bundle to constants. 41 | */ 42 | private static final ResourceBundle CONSTANTS = ResourceBundle.getBundle( 43 | "dbms.backend.parsers.json.Constants"); 44 | 45 | /** 46 | * Logger. 47 | */ 48 | private Logger log = LogManager.getFormatterLogger(); 49 | 50 | /** 51 | * {@link GsonBuilder} Builds GSON objects. 52 | */ 53 | private GsonBuilder builder; 54 | 55 | /** 56 | * {@link Gson} Google Gson object that is used to parse tables. 57 | */ 58 | private Gson gson; 59 | 60 | /** 61 | * Static singleton instance. 62 | */ 63 | private static JSONParser instance = null; 64 | 65 | static { 66 | BackendParserFactory.getFactory().register(KEY, getInstance()); 67 | } 68 | 69 | private JSONParser() { 70 | enhanceBuilder(); 71 | } 72 | 73 | /** 74 | * Gets static instance. 75 | * @return static instance. 76 | */ 77 | public static JSONParser getInstance() { 78 | if (instance == null) { 79 | instance = new JSONParser(); 80 | } 81 | return instance; 82 | } 83 | 84 | private static File openTable(final String dbName, final String tableName) 85 | throws TableNotFoundException, 86 | DatabaseNotFoundException { 87 | File tableFile = new File(openDB(dbName), tableName + CONSTANTS 88 | .getString("extension.json")); 89 | if (!tableFile.exists()) { 90 | // log.error("Error occured: " + tableName + " file is not found!"); 91 | throw new TableNotFoundException(); 92 | } 93 | return tableFile; 94 | } 95 | 96 | private static File openDB(final String dbName) 97 | throws DatabaseNotFoundException { 98 | File database = new File(BackendController.getInstance() 99 | .getCurrentDatabaseDir() 100 | + File.separator + dbName); 101 | if (!database.exists()) { 102 | // log.error("Error occured: Database is not found."); 103 | throw new DatabaseNotFoundException(); 104 | } 105 | return database; 106 | } 107 | 108 | private void enhanceBuilder() { 109 | builder = new GsonBuilder().setExclusionStrategies( 110 | new ExclusionStrategy() { 111 | @Override 112 | public boolean shouldSkipField(final 113 | FieldAttributes 114 | fieldAttributes) { 115 | if (fieldAttributes.getDeclaringClass().equals( 116 | Database.class)) { 117 | if (fieldAttributes.getName().equals("tables")) { 118 | return true; 119 | } 120 | } 121 | return false; 122 | } 123 | 124 | @Override 125 | public boolean shouldSkipClass(Class arg0) { 126 | return false; 127 | } 128 | }); 129 | gson = builder.serializeNulls().disableHtmlEscaping() 130 | .registerTypeAdapterFactory(new ClassTypeAdapterFactory()) 131 | .registerTypeAdapter(Column.class, new ColumnAdapter()) 132 | .setPrettyPrinting().create(); 133 | } 134 | 135 | @Override 136 | public BackendParser getParser() { 137 | return instance; 138 | } 139 | 140 | @Override 141 | public void loadTable(final Table table) throws TableNotFoundException, 142 | DatabaseNotFoundException { 143 | BufferedReader bufferedReader; 144 | try { 145 | bufferedReader = new BufferedReader(new FileReader(openTable( 146 | table.getDatabase().getName(), table.getName()))); 147 | } catch (FileNotFoundException e) { 148 | log.error("Error occured while loading the table at: " + e.toString()); 149 | throw new TableNotFoundException(); 150 | } 151 | log.debug("\'" + table.getName() + "\' is loaded successfully."); 152 | table.setTable(gson.fromJson(bufferedReader, Table.class)); 153 | } 154 | 155 | @Override 156 | public void writeToFile(final Table table) throws TableNotFoundException, 157 | DatabaseNotFoundException { 158 | File tableFile = openTable(table.getDatabase().getName(), 159 | table.getName()); 160 | try { 161 | write(table, tableFile); 162 | } catch (IOException e) { 163 | log.error("Error occured while saving in JSON file at: " + e.toString()); 164 | e.printStackTrace(); 165 | } 166 | log.debug("Saved into JSON file successfully."); 167 | } 168 | 169 | @Override 170 | public void createTable(final Table table) throws DatabaseNotFoundException, 171 | TableAlreadyCreatedException { 172 | File tableFile = new File(openDB(table.getDatabase().getName()), 173 | table.getName() + CONSTANTS.getString("extension.json")); 174 | if (tableFile.exists()) { 175 | log.error("Can't create table with name" + table.getName() 176 | + " this nameDatabase already created"); 177 | throw new TableAlreadyCreatedException(); 178 | } 179 | try { 180 | write(table, tableFile); 181 | } catch (IOException e) { 182 | log.error("Error ocurred while parsing at: " + e.toString()); 183 | e.printStackTrace(); 184 | } 185 | log.debug("\'" + table.getName() + "\' is created successfully."); 186 | 187 | } 188 | 189 | private void write(final Table table, final File tableFile) 190 | throws IOException { 191 | FileWriter writer = new FileWriter(tableFile); 192 | writer.write(gson.toJson(table)); 193 | writer.close(); 194 | } 195 | 196 | @Override 197 | public void dropTable(final Table table) throws DatabaseNotFoundException { 198 | File tableFile = new File(openDB(table.getDatabase().getName()), 199 | table.getName() 200 | + CONSTANTS.getString("extension.json")); 201 | if (tableFile.exists()) { 202 | tableFile.delete(); 203 | log.debug(table.getName() + " file is successfully deleted."); 204 | } else { 205 | log.error("Error occured: " + table.getName() + " file is not" 206 | + " found!"); 207 | } 208 | } 209 | } -------------------------------------------------------------------------------- /src/dbms/backend/parsers/json/test.java: -------------------------------------------------------------------------------- 1 | package dbms.backend.parsers.json; 2 | 3 | import java.util.LinkedHashMap; 4 | import java.util.Map; 5 | 6 | import dbms.backend.BackendController; 7 | import dbms.backend.parsers.xml.XMLParser; 8 | import dbms.datatypes.DBDatatype; 9 | import dbms.datatypes.DBInteger; 10 | import dbms.datatypes.DBString; 11 | import dbms.datatypes.DatatypeFactory; 12 | import dbms.exception.DatabaseAlreadyCreatedException; 13 | import dbms.exception.DatabaseNotFoundException; 14 | import dbms.exception.IncorrectDataEntryException; 15 | import dbms.exception.SyntaxErrorException; 16 | import dbms.exception.TableAlreadyCreatedException; 17 | import dbms.exception.TableNotFoundException; 18 | import dbms.util.RecordSet; 19 | 20 | 21 | public class test { 22 | 23 | private final static BackendController JSONParserConc 24 | = BackendController.getInstance(); 25 | 26 | public static void main(String[] args) { 27 | try { 28 | JSONParserConc.createDatabase("mine"); 29 | } catch (DatabaseAlreadyCreatedException e) { 30 | e.printStackTrace(); 31 | } 32 | LinkedHashMap> passMap = new LinkedHashMap<>(); 33 | passMap.put("column_1", DBInteger.class); 34 | passMap.put("column_2", DBString.class); 35 | try { 36 | JSONParserConc.createTable("table11", passMap); 37 | } catch (DatabaseNotFoundException | TableAlreadyCreatedException 38 | | IncorrectDataEntryException e) { 39 | e.printStackTrace(); 40 | } 41 | Map entriesMap = new LinkedHashMap(); 42 | entriesMap.put("column_1", DatatypeFactory.convertToDataType(550)); 43 | entriesMap.put("column_2", DatatypeFactory.convertToDataType("KHalED")); 44 | try { 45 | JSONParserConc.insertIntoTable("table11", entriesMap); 46 | RecordSet rs = JSONParserConc.select("table11", null, null); 47 | } catch (DatabaseNotFoundException | TableNotFoundException 48 | | IncorrectDataEntryException e) { 49 | e.printStackTrace(); 50 | } catch (SyntaxErrorException e) { 51 | e.printStackTrace(); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/dbms/backend/parsers/protobuf/ColumnsAdapterProtoBuf.java: -------------------------------------------------------------------------------- 1 | package dbms.backend.parsers.protobuf; 2 | 3 | import java.lang.reflect.InvocationTargetException; 4 | import java.sql.Date; 5 | import java.text.DateFormat; 6 | import java.text.ParseException; 7 | import java.text.SimpleDateFormat; 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | import com.google.protobuf.InvalidProtocolBufferException; 12 | 13 | import dbms.datatypes.DBDatatype; 14 | import dbms.datatypes.DBDate; 15 | import dbms.datatypes.DBFloat; 16 | import dbms.datatypes.DBInteger; 17 | import dbms.datatypes.DBString; 18 | import dbms.datatypes.DatatypeFactory; 19 | import dbms.util.Column; 20 | import dbms.util.Table; 21 | 22 | public class ColumnsAdapterProtoBuf { 23 | 24 | public ColumnsAdapterProtoBuf() { 25 | } 26 | 27 | 28 | public void deserializeColumns(final byte[] deserialzedData, 29 | final Table table) 30 | throws InvalidProtocolBufferException { 31 | TableProtoBuf.TableModule tableModule = TableProtoBuf 32 | .TableModule.parseFrom(deserialzedData); 33 | List columnsModule 34 | = tableModule.getColumnsList(); 35 | List cloneColumns = new ArrayList<>(); 36 | for (TableProtoBuf.TableModule.ColumnModule col : columnsModule) { 37 | String columnName = col.getColumnName(); 38 | String typeProp = col.getColumnDataType(); 39 | Class typeClass = DatatypeFactory.getFactory() 40 | .getRegisteredDatatype(col.getColumnDataType()); 41 | Column newColumn = new Column(); 42 | newColumn.setName(columnName); 43 | newColumn.setType(typeClass); 44 | List columnValues = col.getEntriesList(); 45 | 46 | for (String stringValue : columnValues) { 47 | if (typeProp.equals(DBInteger.KEY)) { 48 | try { 49 | Integer x = Integer.parseInt(stringValue); 50 | newColumn.addEntry(new DBInteger(x)); 51 | } catch (NumberFormatException e) { 52 | newColumn.addEntry(null); 53 | } 54 | } else if (typeProp.equals(DBString.KEY)) { 55 | if (stringValue.compareTo("") == 0) { 56 | newColumn.addEntry(null); 57 | } else { 58 | newColumn.addEntry(new DBString(stringValue)); 59 | } 60 | } else if (typeProp.equals(DBFloat.KEY)) { 61 | try { 62 | Float x = Float.parseFloat(stringValue); 63 | newColumn.addEntry(new DBFloat(x)); 64 | } catch (NumberFormatException e) { 65 | newColumn.addEntry(null); 66 | } 67 | } else if (typeProp.equals(DBDate.KEY)) { 68 | DateFormat format = new SimpleDateFormat("yyyy-MM-dd"); 69 | try { 70 | Date x = new Date(format.parse(stringValue).getTime()); 71 | newColumn.addEntry(new DBDate(x)); 72 | } catch (ParseException e) { 73 | newColumn.addEntry(null); 74 | } 75 | } 76 | } 77 | cloneColumns.add(newColumn); 78 | } 79 | table.setColumns(cloneColumns); 80 | table.setSize(cloneColumns.get(0).getEntries().size()); 81 | } 82 | 83 | 84 | public byte[] serializeTable(Table table) throws IllegalAccessException, 85 | InstantiationException, NoSuchMethodException, 86 | InvocationTargetException { 87 | List columnsModule = new 88 | ArrayList<>(); 89 | List columns = table.getColumns(); 90 | for (Column col : columns) { 91 | 92 | List toProtoEntries = new ArrayList<>(); 93 | List entries = col.getEntries(); 94 | 95 | for (DBDatatype en : entries) { 96 | try { 97 | toProtoEntries.add(en.toString()); 98 | } catch (NullPointerException e) { 99 | toProtoEntries.add(""); 100 | } 101 | 102 | } 103 | 104 | TableProtoBuf.TableModule.ColumnModule columnMod 105 | = TableProtoBuf.TableModule.ColumnModule.newBuilder() 106 | .setColumnName(col.getName()) 107 | .setColumnDataType((String) col.getType().getMethod( 108 | "getKey").invoke(col.getType().newInstance())) 109 | .addAllEntries(toProtoEntries) 110 | .build(); 111 | 112 | columnsModule.add(columnMod); 113 | } 114 | 115 | TableProtoBuf.TableModule tableProtoBuf = TableProtoBuf.TableModule 116 | .newBuilder() 117 | .setTableName(table.getName()) 118 | .setDatabaseName(table.getDatabase().getName()) 119 | .addAllColumns(columnsModule) 120 | .build(); 121 | 122 | return tableProtoBuf.toByteArray(); 123 | } 124 | 125 | //TODO 126 | // check null or empty entries and how I will check them. 127 | // the extension of the output file. 128 | 129 | } -------------------------------------------------------------------------------- /src/dbms/backend/parsers/protobuf/Constants.properties: -------------------------------------------------------------------------------- 1 | extension.protoBuf=.protobuf -------------------------------------------------------------------------------- /src/dbms/backend/parsers/protobuf/ProtocolBufferParser.java: -------------------------------------------------------------------------------- 1 | package dbms.backend.parsers.protobuf; 2 | 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.io.FileOutputStream; 6 | import java.io.IOException; 7 | import java.lang.reflect.InvocationTargetException; 8 | import java.util.ResourceBundle; 9 | 10 | import org.apache.logging.log4j.LogManager; 11 | import org.apache.logging.log4j.Logger; 12 | 13 | import dbms.backend.BackendController; 14 | import dbms.backend.BackendParser; 15 | import dbms.backend.BackendParserFactory; 16 | import dbms.exception.DatabaseNotFoundException; 17 | import dbms.exception.TableAlreadyCreatedException; 18 | import dbms.exception.TableNotFoundException; 19 | import dbms.util.Table; 20 | 21 | public class ProtocolBufferParser extends BackendParser { 22 | private static Logger log = LogManager.getFormatterLogger(); 23 | public static final String KEY = "pb"; 24 | private static final ResourceBundle CONSTANTS 25 | = ResourceBundle.getBundle("dbms.backend.parsers.protobuf" 26 | + ".Constants"); 27 | private static ProtocolBufferParser instance = null; 28 | 29 | static { 30 | BackendParserFactory.getFactory().register(KEY, getInstance()); 31 | } 32 | 33 | private ProtocolBufferParser() { 34 | } 35 | 36 | public static ProtocolBufferParser getInstance() { 37 | if (instance == null) { 38 | instance = new ProtocolBufferParser(); 39 | } 40 | return instance; 41 | } 42 | 43 | @Override 44 | public BackendParser getParser() { 45 | return instance; 46 | } 47 | 48 | @Override 49 | public void loadTable(Table table) 50 | throws TableNotFoundException, DatabaseNotFoundException { 51 | File tableFile = openTable(table.getDatabase().getName(), 52 | table.getName()); 53 | try { 54 | load(table, tableFile); 55 | } catch (IOException e) { 56 | log.error("Error occured while loading the table at: " + e.toString()); 57 | e.printStackTrace(); 58 | } 59 | log.debug("Table is loaded successfully."); 60 | 61 | } 62 | 63 | @Override 64 | public void writeToFile(Table table) 65 | throws TableNotFoundException, DatabaseNotFoundException { 66 | File tableFile = openTable(table.getDatabase().getName(), 67 | table.getName()); 68 | try { 69 | write(table, tableFile); 70 | } catch (IOException | NoSuchMethodException 71 | | InstantiationException | IllegalAccessException 72 | | InvocationTargetException e) { 73 | log.error("Error occured while parsing at: " + e.toString()); 74 | e.printStackTrace(); 75 | } 76 | log.debug("Data is saved successfully."); 77 | } 78 | 79 | @Override 80 | public void createTable(Table table) 81 | throws DatabaseNotFoundException, TableAlreadyCreatedException { 82 | File tableFile = new File(openDB(table.getDatabase().getName()), 83 | table.getName() 84 | + CONSTANTS.getString("extension.protoBuf")); 85 | if (tableFile.exists()) { 86 | log.error("Error occured: table is already created!"); 87 | throw new TableAlreadyCreatedException(); 88 | } 89 | try { 90 | write(table, tableFile); 91 | } catch (IOException | NoSuchMethodException 92 | | InstantiationException | IllegalAccessException 93 | | InvocationTargetException e) { 94 | log.error("Error occured while creating table at: " + e.toString()); 95 | e.printStackTrace(); 96 | } 97 | log.debug("Table data is created successfully."); 98 | } 99 | 100 | @Override 101 | public void dropTable(Table table) throws DatabaseNotFoundException { 102 | File tableFile = new File(openDB(table.getDatabase().getName()), 103 | table.getName() 104 | + CONSTANTS.getString("extension.protoBuf") ); 105 | 106 | 107 | if (tableFile.exists()) { 108 | tableFile.delete(); 109 | log.debug("Table data is droped successfully."); 110 | } 111 | } 112 | 113 | private void write(Table table, File tableFile) 114 | throws InvocationTargetException, NoSuchMethodException, 115 | InstantiationException, IllegalAccessException, IOException { 116 | ColumnsAdapterProtoBuf columnAdapter = new ColumnsAdapterProtoBuf(); 117 | byte[] serializedData = columnAdapter.serializeTable(table); 118 | FileOutputStream fileOutputStream = new FileOutputStream(tableFile); 119 | fileOutputStream.write(serializedData); 120 | fileOutputStream.close(); 121 | 122 | } 123 | 124 | private void load(Table table, File tableFile) 125 | throws DatabaseNotFoundException, 126 | TableNotFoundException, IOException { 127 | ColumnsAdapterProtoBuf columnAdapter = new ColumnsAdapterProtoBuf(); 128 | FileInputStream fileInputStream = new FileInputStream(tableFile); 129 | byte[] deSerializedData = new byte[(int) tableFile.length()]; 130 | fileInputStream.read(deSerializedData); 131 | columnAdapter.deserializeColumns(deSerializedData, table); 132 | } 133 | 134 | private static File openDB(String dbName) 135 | throws DatabaseNotFoundException { 136 | File database = new File(BackendController 137 | .getInstance().getCurrentDatabaseDir() 138 | + File.separator + dbName); 139 | if (!database.exists()) { 140 | log.error("Error occured: " + dbName + " database is not found!"); 141 | throw new DatabaseNotFoundException(); 142 | } 143 | return database; 144 | } 145 | 146 | private static File openTable(String dbName, String tableName) 147 | throws TableNotFoundException, 148 | DatabaseNotFoundException { 149 | File tableFile = new File(openDB(dbName), tableName 150 | + CONSTANTS.getString("extension.protoBuf")); 151 | if (!tableFile.exists()) { 152 | log.error("Error occured: " + tableName + " is not found!"); 153 | throw new TableNotFoundException(); 154 | } 155 | return tableFile; 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /src/dbms/backend/parsers/xml/Constants.properties: -------------------------------------------------------------------------------- 1 | extension.schema=.xsd 2 | extension.xml=.xml 3 | extensionDTD.schema=.dtd 4 | xs.schema=xs:schema 5 | xs.element=xs:element 6 | xs.extension=xs:extension 7 | xs.complex=xs:complexType 8 | xs.sequence=xs:sequence 9 | xs.simple=xs:simpleContent 10 | xs.attr=xs:attribute 11 | nothing=0 12 | string.type=xs:string 13 | int.type=xs:integer 14 | table.element=table 15 | column.element=col 16 | optional.col=col* 17 | optional.row=row* 18 | pc.data=#PCDATA 19 | c.data=#CDATA 20 | row.element=row 21 | formDefault.attr=attributeFormDefault 22 | elementFormDefault.attr=elementFormDefault 23 | xmlns.attr=xmlns:xs 24 | name.attr=name 25 | db.attr=database 26 | rows.attr=rows 27 | type.attr=type 28 | use.attr=use 29 | maxOccurs.attr=maxOccurs 30 | minOccurs.attr=minOccurs 31 | base.attr=base 32 | formDefault.val=unqualified 33 | elementFormDefault.val=qualified 34 | xmlns.val=http://www.w3.org/2001/XMLSchema 35 | unbounded.val=unbounded 36 | optional.val=optional 37 | index.val=index 38 | default.attr=default 39 | indentation.val=4 40 | indentation={http://xml.apache.org/xslt}indent-amount 41 | req.type=#REQUIRED 42 | publicId.dtd=-//DBMS//XML DBMS 1.0//EN -------------------------------------------------------------------------------- /src/dbms/backend/parsers/xml/schema/dtd/DTDAttributeCreator.java: -------------------------------------------------------------------------------- 1 | package dbms.backend.parsers.xml.schema.dtd; 2 | 3 | import java.io.FileNotFoundException; 4 | import java.io.PrintWriter; 5 | import java.util.ResourceBundle; 6 | 7 | class DTDAttributeCreator { 8 | private static final ResourceBundle CONSTANTS = 9 | ResourceBundle.getBundle("dbms.backend.parsers.xml.Constants"); 10 | 11 | /** 12 | * Creates an attribute element in the DTD file. 13 | * @param elName element name. 14 | * @param attName attribute name. 15 | * @param state behaviour of DTD element. 16 | * @param out {@link PrintWriter} Reference on the file. 17 | * @throws FileNotFoundException if there is not file with that name. 18 | */ 19 | protected static void createElement(String elName, String attName, 20 | String state, PrintWriter out) throws 21 | FileNotFoundException { 22 | out.println(""); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/dbms/backend/parsers/xml/schema/dtd/DTDElementCreator.java: -------------------------------------------------------------------------------- 1 | package dbms.backend.parsers.xml.schema.dtd; 2 | 3 | import java.io.FileNotFoundException; 4 | import java.io.PrintWriter; 5 | 6 | class DTDElementCreator { 7 | static PrintWriter out; 8 | 9 | private DTDElementCreator() { 10 | } 11 | 12 | /** 13 | * Creates DTD element in DTD file. 14 | * @param elName defines element name. 15 | * @param property defines the behaviour of the DTD element. 16 | * @param out {@link PrintWriter} Reference on the file. 17 | * @throws FileNotFoundException if the named file is no found. 18 | */ 19 | protected static void createElement(String elName, String property, 20 | PrintWriter out) 21 | throws FileNotFoundException { 22 | out.println(""); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/dbms/backend/parsers/xml/schema/dtd/DTDSchemaParser.java: -------------------------------------------------------------------------------- 1 | package dbms.backend.parsers.xml.schema.dtd; 2 | 3 | import dbms.backend.BackendController; 4 | import dbms.exception.DatabaseNotFoundException; 5 | 6 | import java.io.File; 7 | import java.io.FileNotFoundException; 8 | import java.io.PrintWriter; 9 | import java.util.ResourceBundle; 10 | 11 | /** 12 | * Generates a DTD schema file for XML database. 13 | */ 14 | public class DTDSchemaParser { 15 | 16 | /** 17 | * Resource bundle to constants. 18 | */ 19 | private static final ResourceBundle CONSTANTS = 20 | ResourceBundle.getBundle("dbms.backend.parsers.xml.Constants"); 21 | 22 | /** 23 | * Static singleton instance. 24 | */ 25 | private static DTDSchemaParser instance = null; 26 | 27 | /** 28 | * TODO 29 | */ 30 | private PrintWriter out; 31 | 32 | private DTDSchemaParser() { 33 | } 34 | 35 | /** 36 | * Gets static singleton instance. 37 | * @return static singleton instance. 38 | */ 39 | public static DTDSchemaParser getInstance() { 40 | if (instance == null) { 41 | instance = new DTDSchemaParser(); 42 | } 43 | return instance; 44 | } 45 | 46 | /** 47 | * Creates the main flow to DTD file. 48 | * Writes element and attributes to DTD file. 49 | * @param dbName holds the name of the current database. 50 | * @param tableName holds the name of the table. 51 | * @throws DatabaseNotFoundException if no such database with the given 52 | * name is found. 53 | */ 54 | public void createDTDSchema(String dbName, String tableName) 55 | throws DatabaseNotFoundException { 56 | // File database = new File(WORKSPACE_DIR + File.separator + dbName); 57 | File database = new File(BackendController.getInstance() 58 | .getCurrentDatabaseDir() + File.separator + dbName); 59 | if (!database.exists()) { 60 | throw new DatabaseNotFoundException(); 61 | } 62 | File schema = new File(database, tableName 63 | + CONSTANTS.getString("extensionDTD.schema")); 64 | if (schema.exists()) { 65 | return; 66 | } 67 | try { 68 | out = new PrintWriter(schema); 69 | writeElements(schema, out); 70 | writeAttributes(schema, out); 71 | out.close(); 72 | } catch (FileNotFoundException e) { 73 | e.printStackTrace(); 74 | } 75 | } 76 | 77 | private void writeElements(File schema, PrintWriter pWriter) throws 78 | FileNotFoundException { 79 | 80 | DTDElementCreator.createElement( 81 | CONSTANTS.getString("table.element"), 82 | CONSTANTS.getString("optional.col"), pWriter); 83 | DTDElementCreator.createElement( 84 | CONSTANTS.getString("column.element"), 85 | CONSTANTS.getString("optional.row"), pWriter); 86 | DTDElementCreator.createElement( 87 | CONSTANTS.getString("row.element"), 88 | CONSTANTS.getString("pc.data"), pWriter); 89 | } 90 | 91 | private void writeAttributes(File schema, PrintWriter pWriter) throws 92 | FileNotFoundException { 93 | DTDAttributeCreator.createElement(CONSTANTS.getString("table.element"), 94 | CONSTANTS.getString("db.attr"), CONSTANTS.getString("req" 95 | + ".type"), pWriter); 96 | DTDAttributeCreator.createElement(CONSTANTS.getString("table.element"), 97 | CONSTANTS.getString("name.attr"), CONSTANTS.getString("req" 98 | + ".type"), pWriter); 99 | DTDAttributeCreator.createElement(CONSTANTS.getString("table.element"), 100 | CONSTANTS.getString("rows.attr"), "\"0\"", pWriter); 101 | DTDAttributeCreator.createElement(CONSTANTS.getString("column.element"), 102 | CONSTANTS.getString("name.attr"), CONSTANTS.getString("req" 103 | + ".type"), pWriter); 104 | DTDAttributeCreator.createElement(CONSTANTS.getString("column.element"), 105 | CONSTANTS.getString("type.attr"), CONSTANTS.getString("req" 106 | + ".type"), pWriter); 107 | DTDAttributeCreator.createElement(CONSTANTS.getString("row.element"), 108 | CONSTANTS.getString("index.val"), CONSTANTS.getString("req" 109 | + ".type"), pWriter); 110 | 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/dbms/datatypes/DBDatatype.java: -------------------------------------------------------------------------------- 1 | package dbms.datatypes; 2 | 3 | public interface DBDatatype extends Comparable { 4 | 5 | /** 6 | * Gets an equivalent primitive java object of a string value. 7 | * @param s String value. 8 | * @return Equivalent object. 9 | */ 10 | Object toObj(String s); 11 | 12 | /** 13 | * Gets the java primitive equivalent to the {@link DBDatatype}. 14 | * @return equivalent primitive java object. 15 | */ 16 | Object getValue(); 17 | 18 | /** 19 | * Gets String key that is used as an id of a data type. 20 | * @return KEY. 21 | */ 22 | String getKey(); 23 | } 24 | -------------------------------------------------------------------------------- /src/dbms/datatypes/DBDate.java: -------------------------------------------------------------------------------- 1 | package dbms.datatypes; 2 | 3 | import java.sql.Date; 4 | 5 | public class DBDate implements DBDatatype { 6 | 7 | /** 8 | * Key identifier to DBDate. 9 | */ 10 | public static final String KEY = "Date"; 11 | 12 | static { 13 | DatatypeFactory.getFactory().register(KEY, DBDate.class); 14 | } 15 | 16 | private Date value; 17 | 18 | public DBDate() { 19 | 20 | } 21 | 22 | /** 23 | * @param value {@link Date} sets the the local date to the fiven value. 24 | */ 25 | public DBDate(final Date value) { 26 | this.value = value; 27 | } 28 | 29 | @Override 30 | public Object toObj(final String s) { 31 | try { 32 | return Date.valueOf(s); 33 | } catch (Exception e) { 34 | return null; 35 | } 36 | } 37 | 38 | @Override 39 | public int compareTo(final DBDatatype data) { 40 | return value.compareTo((Date) data.getValue()); 41 | } 42 | 43 | @Override 44 | public Date getValue() { 45 | return value; 46 | } 47 | 48 | @Override 49 | public String toString() { 50 | return value.toString(); 51 | } 52 | 53 | @Override 54 | public String getKey() { 55 | return KEY; 56 | } 57 | 58 | @Override 59 | public boolean equals(final Object o) { 60 | if (this == o) return true; 61 | if (o == null || getClass() != o.getClass()) return false; 62 | 63 | DBDate dbDate = (DBDate) o; 64 | return value != null ? value.equals(dbDate.value) 65 | : dbDate.value == null; 66 | } 67 | 68 | @Override 69 | public int hashCode() { 70 | return value != null ? value.hashCode() : 0; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/dbms/datatypes/DBFloat.java: -------------------------------------------------------------------------------- 1 | package dbms.datatypes; 2 | 3 | public class DBFloat implements DBDatatype { 4 | 5 | /** 6 | * Key identifier to DBString. 7 | */ 8 | public static final String KEY = "Float"; 9 | 10 | static { 11 | DatatypeFactory.getFactory().register(KEY, DBFloat.class); 12 | } 13 | 14 | private Float value; 15 | 16 | public DBFloat() { 17 | 18 | } 19 | 20 | /** 21 | * @param value {@link Float} sets the local value to the given value. 22 | */ 23 | public DBFloat(final Float value) { 24 | this.value = value; 25 | } 26 | 27 | @Override 28 | public Object toObj(final String s) { 29 | try { 30 | return Float.parseFloat(s); 31 | } catch (Exception e) { 32 | return null; 33 | } 34 | } 35 | 36 | @Override 37 | public int compareTo(final DBDatatype data) { 38 | return value.compareTo((Float) data.getValue()); 39 | } 40 | 41 | @Override 42 | public Float getValue() { 43 | return value; 44 | } 45 | 46 | @Override 47 | public String toString() { 48 | return value.toString(); 49 | } 50 | 51 | @Override 52 | public String getKey() { 53 | return KEY; 54 | } 55 | 56 | @Override 57 | public boolean equals(final Object o) { 58 | if (this == o) return true; 59 | if (o == null || getClass() != o.getClass()) return false; 60 | 61 | DBFloat dbFloat = (DBFloat) o; 62 | 63 | return value != null ? value.equals(dbFloat.value) 64 | : dbFloat.value == null; 65 | } 66 | 67 | @Override 68 | public int hashCode() { 69 | return value != null ? value.hashCode() : 0; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/dbms/datatypes/DBInteger.java: -------------------------------------------------------------------------------- 1 | package dbms.datatypes; 2 | 3 | 4 | public class DBInteger implements DBDatatype { 5 | 6 | /** 7 | * Key identifier to DBInteger. 8 | */ 9 | public static final String KEY = "Integer"; 10 | 11 | static { 12 | DatatypeFactory.getFactory().register(KEY, DBInteger.class); 13 | } 14 | 15 | private Integer value; 16 | 17 | public DBInteger() { 18 | } 19 | 20 | public DBInteger(final Integer value) { 21 | this.value = value; 22 | } 23 | 24 | @Override 25 | public Object toObj(final String s) { 26 | try { 27 | return Integer.parseInt(s); 28 | } catch (Exception e) { 29 | return null; 30 | } 31 | } 32 | 33 | @Override 34 | public int compareTo(final DBDatatype data) { 35 | return value.compareTo((Integer) data.getValue()); 36 | } 37 | 38 | @Override 39 | public Integer getValue() { 40 | return value; 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return value.toString(); 46 | } 47 | 48 | @Override 49 | public String getKey() { 50 | return KEY; 51 | } 52 | 53 | @Override 54 | public boolean equals(final Object o) { 55 | if (this == o) return true; 56 | if (o == null || getClass() != o.getClass()) return false; 57 | 58 | DBInteger dbInteger = (DBInteger) o; 59 | 60 | return value != null ? value.equals(dbInteger.value) 61 | : dbInteger.value == null; 62 | } 63 | 64 | @Override 65 | public int hashCode() { 66 | return value != null ? value.hashCode() : 0; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/dbms/datatypes/DBString.java: -------------------------------------------------------------------------------- 1 | package dbms.datatypes; 2 | 3 | public class DBString implements DBDatatype { 4 | 5 | /** 6 | * Key identifier to DBString. 7 | */ 8 | public static final String KEY = "String"; 9 | 10 | static { 11 | DatatypeFactory.getFactory().register(KEY, DBString.class); 12 | } 13 | 14 | private String value = null; 15 | 16 | public DBString() { 17 | } 18 | 19 | public DBString(String value) { 20 | this.value = value; 21 | } 22 | 23 | @Override 24 | public Object toObj(String s) { 25 | return s; 26 | } 27 | 28 | @Override 29 | public int compareTo(DBDatatype data) { 30 | return value.compareTo((String) data.getValue()); 31 | } 32 | 33 | @Override 34 | public String getValue() { 35 | return value; 36 | } 37 | 38 | @Override 39 | public String toString() { 40 | return value; 41 | } 42 | 43 | @Override 44 | 45 | public String getKey() { 46 | return KEY; 47 | } 48 | 49 | @Override 50 | public boolean equals(Object o) { 51 | if (this == o) return true; 52 | if (o == null || getClass() != o.getClass()) return false; 53 | 54 | DBString dbString = (DBString) o; 55 | return value != null ? value.equals(dbString.value) : 56 | dbString.value == null; 57 | } 58 | 59 | @Override 60 | public int hashCode() { 61 | return value != null ? value.hashCode() : 0; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/dbms/datatypes/DatatypeFactory.java: -------------------------------------------------------------------------------- 1 | package dbms.datatypes; 2 | 3 | import dbms.sqlparser.syntax.SyntaxUtil; 4 | 5 | import java.lang.reflect.InvocationTargetException; 6 | import java.lang.reflect.Method; 7 | import java.sql.Date; 8 | import java.text.DateFormat; 9 | import java.text.ParseException; 10 | import java.text.SimpleDateFormat; 11 | import java.util.HashMap; 12 | 13 | /** 14 | * Registers and grants access to any of the supported datatypes 15 | * in DBMS. 16 | */ 17 | public class DatatypeFactory { 18 | /** 19 | * Holds all registered data types in factory. 20 | */ 21 | private static HashMap> registeredDataTypes = null; 23 | 24 | /** 25 | * Singleton static instance. 26 | */ 27 | private static DatatypeFactory instance = null; 28 | 29 | private DatatypeFactory() { 30 | registeredDataTypes = new HashMap<>(); 31 | loadDatatypes(); 32 | } 33 | 34 | /** 35 | * Gets static instance to factory. 36 | * @return static instance. 37 | */ 38 | public static DatatypeFactory getFactory() { 39 | if (instance == null) { 40 | instance = new DatatypeFactory(); 41 | } 42 | return instance; 43 | } 44 | 45 | /** 46 | * Converts a primitive java object to its equivalent 47 | * {@link DBDatatype}. 48 | * @param o Object to get converted. 49 | * @return {@link DBDatatype} object to get converted to. 50 | */ 51 | public static DBDatatype convertToDataType(Object o) { 52 | if (o == null) { 53 | return null; 54 | } 55 | Class classType = o.getClass(); 56 | if (classType == Integer.class) { 57 | return new DBInteger((Integer) o); 58 | } else if (classType == Date.class) { 59 | return new DBDate((Date) o); 60 | } else if (classType == Float.class) { 61 | return new DBFloat((Float) o); 62 | } else if (classType == String.class) { 63 | return new DBString((String) o); 64 | } 65 | return null; 66 | } 67 | 68 | /** 69 | * Converts a string value to its equivalent 70 | * {@link DBDatatype} object. 71 | * @param value String value. 72 | * @return {@link DBDatatype} object. 73 | */ 74 | public static Object convertToObject(String value) { 75 | if (value.matches(SyntaxUtil.DATE_FORMAT)) { 76 | value = value.replaceAll("'", ""); 77 | DateFormat format = new SimpleDateFormat("yyyy-MM-dd"); 78 | Date date = null; 79 | try { 80 | date = new Date(format.parse(value).getTime()); 81 | } catch (ParseException e) { 82 | e.printStackTrace(); 83 | } 84 | return date; 85 | } else if (value.matches(SyntaxUtil.NUMBER_FORMAT)) { 86 | try { 87 | return Integer.parseInt(value); 88 | } catch (Exception e) { 89 | try { 90 | return Float.parseFloat(value); 91 | } catch (Exception e2) { 92 | 93 | } 94 | } 95 | } 96 | return value.replaceAll("('|\")", ""); 97 | } 98 | 99 | /** 100 | * Registers a new datatype to factory. 101 | * @param key datatype key. 102 | * @param datatype Class of the datatype. 103 | */ 104 | public void register(final String key, 105 | final Class datatype) { 106 | registeredDataTypes.put(key, datatype); 107 | } 108 | 109 | /** 110 | * Gets registered datatype 111 | * @param name 112 | * @return 113 | */ 114 | public Class getRegisteredDatatype( 115 | final String name) { 116 | return registeredDataTypes.get(name); 117 | } 118 | 119 | /** 120 | * Converts a string value to an object given 121 | * key to {@link DBDatatype}. 122 | * @param s string value. 123 | * @param key {@link DBDatatype} key. 124 | * @return Object. 125 | */ 126 | public Object toObj(String s, String key) { 127 | Class datatype = registeredDataTypes 128 | .get(key); 129 | if (datatype == null) { 130 | return null; 131 | } 132 | Object ret = null; 133 | try { 134 | Method toObj = datatype.getMethod("toObj", String.class); 135 | ret = toObj.invoke(datatype.newInstance(), s); 136 | } catch (NoSuchMethodException | SecurityException 137 | | IllegalAccessException | IllegalArgumentException 138 | | InvocationTargetException | InstantiationException e) { 139 | e.printStackTrace(); 140 | } 141 | return ret; 142 | } 143 | 144 | /* 145 | * An alternate strategy to extensively load all datatypes 146 | * is to walk through directories in .classpath and registers any 147 | * class it finds that implements DBDatatype. 148 | */ 149 | private void loadDatatypes() { 150 | try { 151 | Class.forName("dbms.datatypes.DBInteger"); 152 | Class.forName("dbms.datatypes.DBString"); 153 | Class.forName("dbms.datatypes.DBFloat"); 154 | Class.forName("dbms.datatypes.DBDate"); 155 | } catch (ClassNotFoundException e) { 156 | e.printStackTrace(); 157 | } 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /src/dbms/exception/DataTypeNotSupportedException.java: -------------------------------------------------------------------------------- 1 | package dbms.exception; 2 | 3 | public class DataTypeNotSupportedException extends Exception { 4 | public DataTypeNotSupportedException() { 5 | super(); 6 | } 7 | 8 | public DataTypeNotSupportedException(final String message) { 9 | super(message); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/dbms/exception/DatabaseAlreadyCreatedException.java: -------------------------------------------------------------------------------- 1 | package dbms.exception; 2 | 3 | /** 4 | * Signals an attempt to create a database when it has 5 | * already been created. 6 | */ 7 | public class DatabaseAlreadyCreatedException extends Exception { 8 | private String message; 9 | 10 | public DatabaseAlreadyCreatedException() { 11 | super(); 12 | } 13 | 14 | public DatabaseAlreadyCreatedException(final String message) { 15 | super(message); 16 | this.message = message; 17 | } 18 | 19 | @Override 20 | public String toString() { 21 | return "DatabaseAlreadyCreatedException{" + 22 | "message='" + message + '\'' + 23 | '}'; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/dbms/exception/DatabaseNotFoundException.java: -------------------------------------------------------------------------------- 1 | package dbms.exception; 2 | 3 | /** 4 | * Signals an attempt to open a database that doesn't exist. 5 | */ 6 | public class DatabaseNotFoundException extends Exception { 7 | private String message; 8 | 9 | public DatabaseNotFoundException() { 10 | super(); 11 | } 12 | 13 | public DatabaseNotFoundException(final String message) { 14 | super(message); 15 | this.message = message; 16 | } 17 | 18 | @Override 19 | public String toString() { 20 | return "DatabaseNotFoundException{" + 21 | "message='" + message + '\'' + 22 | '}'; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/dbms/exception/IncorrectDataEntryException.java: -------------------------------------------------------------------------------- 1 | package dbms.exception; 2 | 3 | /** 4 | * Signals an incorrect data entry. 5 | */ 6 | public class IncorrectDataEntryException extends Exception { 7 | private String message; 8 | 9 | public IncorrectDataEntryException() { 10 | super(); 11 | } 12 | 13 | public IncorrectDataEntryException(final String message) { 14 | super(message); 15 | this.message = message; 16 | } 17 | 18 | @Override 19 | public String toString() { 20 | return "IncorrectDataEntryException{" + 21 | "message='" + message + '\'' + 22 | '}'; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/dbms/exception/ReservedKeyWordException.java: -------------------------------------------------------------------------------- 1 | package dbms.exception; 2 | 3 | public class ReservedKeyWordException extends Exception { 4 | private String message; 5 | 6 | public ReservedKeyWordException() { 7 | super(); 8 | } 9 | 10 | public ReservedKeyWordException(final String message) { 11 | super(message); 12 | this.message = message; 13 | } 14 | 15 | @Override 16 | public String toString() { 17 | return "ReservedKeyWordException{" + 18 | "message='" + message + '\'' + 19 | '}'; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/dbms/exception/SyntaxErrorException.java: -------------------------------------------------------------------------------- 1 | package dbms.exception; 2 | 3 | /** 4 | * Signals a syntax error in statement. 5 | */ 6 | public class SyntaxErrorException extends Exception { 7 | private String message; 8 | 9 | public SyntaxErrorException() { 10 | super(); 11 | } 12 | 13 | public SyntaxErrorException(final String message) { 14 | super(message); 15 | this.message = message; 16 | } 17 | 18 | @Override 19 | public String toString() { 20 | return "Syntax Error " + message; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/dbms/exception/TableAlreadyCreatedException.java: -------------------------------------------------------------------------------- 1 | package dbms.exception; 2 | 3 | /** 4 | * Signals an attempt to open a table that has already 5 | * been created. 6 | */ 7 | public class TableAlreadyCreatedException extends Exception { 8 | private String message; 9 | 10 | public TableAlreadyCreatedException() { 11 | super(); 12 | } 13 | 14 | public TableAlreadyCreatedException(final String message) { 15 | super(message); 16 | this.message = message; 17 | } 18 | 19 | @Override 20 | public String toString() { 21 | return "TableAlreadyCreatedException{" + 22 | "message='" + message + '\'' + 23 | '}'; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/dbms/exception/TableNotFoundException.java: -------------------------------------------------------------------------------- 1 | package dbms.exception; 2 | 3 | /** 4 | * Signals an attempt to open a table that doesn't exist. 5 | */ 6 | public class TableNotFoundException extends Exception { 7 | private String message; 8 | 9 | public TableNotFoundException() { 10 | super(); 11 | } 12 | 13 | public TableNotFoundException(final String message) { 14 | super(message); 15 | this.message = message; 16 | } 17 | 18 | @Override 19 | public String toString() { 20 | return "TableNotFoundException{" + 21 | "message='" + message + '\'' + 22 | '}'; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/dbms/exception/TypeNotSupportedException.java: -------------------------------------------------------------------------------- 1 | package dbms.exception; 2 | 3 | /** 4 | * Signals an attempt to add a non-supported type to table. 5 | */ 6 | public class TypeNotSupportedException extends Exception { 7 | private String message; 8 | 9 | public TypeNotSupportedException() { 10 | super(); 11 | } 12 | 13 | public TypeNotSupportedException(final String message) { 14 | super(message); 15 | this.message = message; 16 | } 17 | 18 | @Override 19 | public String toString() { 20 | return "TypeNotSupportedException{" + 21 | "message='" + message + '\'' + 22 | '}'; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/dbms/sqlparser/PatternsHolder.java: -------------------------------------------------------------------------------- 1 | package dbms.sqlparser; 2 | 3 | import java.util.ResourceBundle; 4 | import java.util.regex.Pattern; 5 | 6 | public class PatternsHolder { 7 | /** 8 | * name of the properties file that stores all regex pattern for sql 9 | * statements. 10 | */ 11 | private static final String propFileName = "dbms.sqlparser.SQLRegex"; 12 | /** 13 | * reference to SQLRegex.properties file. 14 | */ 15 | private static ResourceBundle SQLRegexProperties = ResourceBundle. 16 | getBundle(propFileName); 17 | private static Pattern rulePattern; 18 | private static Pattern selectPattern; 19 | private static Pattern updatePattern; 20 | private static Pattern usePattern; 21 | private static Pattern deletePattern; 22 | private static Pattern insertIntoPattern; 23 | private static Pattern dropPattern; 24 | private static Pattern alterPattern; 25 | private static Pattern createPattern; 26 | 27 | 28 | static synchronized Pattern getSelectPattern() { 29 | if (selectPattern == null) { 30 | selectPattern = Pattern.compile( 31 | SQLRegexProperties.getString("select.regex") 32 | + SQLRegexProperties.getString("orderby.regex") 33 | + SQLRegexProperties.getString("where.regex")); 34 | } 35 | return selectPattern; 36 | } 37 | 38 | static synchronized Pattern getAlterPattern() { 39 | if (alterPattern == null) { 40 | alterPattern = Pattern.compile(SQLRegexProperties.getString( 41 | "alter.regex")); 42 | } 43 | return alterPattern; 44 | } 45 | 46 | static synchronized Pattern getCreatePattern() { 47 | if (createPattern == null) { 48 | createPattern = Pattern.compile(SQLRegexProperties.getString( 49 | "create.regex")); 50 | } 51 | return createPattern; 52 | } 53 | 54 | 55 | static synchronized Pattern getRulePattern() { 56 | if (rulePattern == null) { 57 | rulePattern = Pattern.compile(SQLRegexProperties.getString( 58 | "rule.regex")); 59 | } 60 | return rulePattern; 61 | } 62 | 63 | static synchronized Pattern getUpdatePattern() { 64 | if (updatePattern == null) { 65 | updatePattern = Pattern.compile( 66 | SQLRegexProperties.getString("update.regex") 67 | + SQLRegexProperties.getString("where.regex")); 68 | } 69 | return updatePattern; 70 | } 71 | 72 | static synchronized Pattern getUsePattern() { 73 | if (usePattern == null) { 74 | usePattern = Pattern.compile(SQLRegexProperties.getString( 75 | "use.database.regex")); 76 | } 77 | return usePattern; 78 | } 79 | 80 | 81 | static synchronized Pattern getDeletePattern() { 82 | if (dropPattern == null) { 83 | deletePattern = Pattern.compile( 84 | SQLRegexProperties.getString("delete.regex") 85 | + SQLRegexProperties.getString("where.regex")); 86 | } 87 | return deletePattern; 88 | } 89 | 90 | static synchronized Pattern getInsertIntoPattern() { 91 | if (insertIntoPattern == null) { 92 | insertIntoPattern = Pattern.compile(SQLRegexProperties.getString( 93 | "insert.regex")); 94 | } 95 | return insertIntoPattern; 96 | } 97 | 98 | static synchronized Pattern getDropPattern() { 99 | if (dropPattern == null) { 100 | dropPattern = Pattern.compile(SQLRegexProperties.getString( 101 | "drop.regex")); 102 | } 103 | return dropPattern; 104 | } 105 | 106 | 107 | } 108 | -------------------------------------------------------------------------------- /src/dbms/sqlparser/SQLRegex.properties: -------------------------------------------------------------------------------- 1 | rule.regex=(?i)^\\s*(select|drop|insert|update|delete|create|where|use|alter).* 2 | where.regex=(\\s+where\\s+(TRUE|([(]\\s*)*\\s*(\\w+)\\s*(>|<|>=|<=|=|!=){1}\\s*('\\w+'|\\w+|"\\w+")\\s*(\\s*[)])*\\s*(\\s+(and|or)(\\s*([(]\\s*)*\\s*(\\w+)\\s*(>|<|>=|<=|=|!=){1}\\s*(\\w+|'\\w+'|"\\w+")\\s*(\\s*[)])*\\s*))*))?\\s*;\\s*$ 3 | select.regex=(?i)^\\s*select\\s+(?:distinct\\s+)?((\\w+\\s*(\\s*,\\s*\\w+)*)|(\\*))\\s+from\\s+(\\w+) 4 | drop.regex=(?i)^\\s*drop\\s+(table|database){1}\\s+(\\w+){1}\\s*;\\s*$ 5 | insert.regex=(?i)^\\s*insert\\s+into\\s+(\\w+){1}\\s+(?:[(]\\s*(\\w+\\s*(\\s*,\\s*\\w+)*)\\s*[)])?\\s*values\\s*[(]\\s*(('(?:\\s*\\w+\\s*)*'|\\d+|"(?:\\s*\\w+\\s*)*"){1}\\s*(\\s*,\\s*('(?:\\s*\\w+\\s*)*'|\\d+|"(?:\\s*\\w+\\s*)*"){1})*)\\s*[)]\\s*;\\s*$ 6 | create.regex=(?i)^\\s*create\\s+((database\\s+(\\w+)){1}|(table\\s+(\\w+)\\s*[(]\\s*(\\s*\\w+\\s+(int|varchar|date|float){1}\\s*(\\s*,\\s*\\w+\\s+(int|varchar|date|float){1}\\s*)*)\\s*[)]){1})\\s*;\\s*$ 7 | update.regex=(?i)^\\s*update\\s+(\\w+){1}\\s+set\\s+(\\w+\\s*=\\s*('\\w+'|\\w+|"\\w+"){1}\\s*(\\s*,\\s*\\w+\\s*=\\s*('\\w+'|\\w+|"\\w+"){1})*) 8 | delete.regex=(?i)^\\s*delete\\s+([*]{1}\\s+)?from\\s+(\\w+) 9 | alter.regex=(?i)^\\s*alter\\s+table\\s+(\\w+){1}\\s+(((drop\\s+column){1}\\s+(\\w+){1}\\s*)|((add){1}\\s+(\\w+){1}\\s+(int|varchar|date|float){1}))\\s*;\\s*$ 10 | use.database.regex=(?i)^\\s*use\\s+(\\w+)\\s*;\\s* 11 | orderby.regex=(\\s+(?i)(?:order\\s+by)(?-i)\\s+(\\w+\\s*(\\s+ASC|\\s+DESC)?\\s*(\\s*,\\s*\\w+\\s*(?:\\s+ASC|\\s+DESC)?\\s*)*))? -------------------------------------------------------------------------------- /src/dbms/sqlparser/sqlInterpreter/BooleanExpression.java: -------------------------------------------------------------------------------- 1 | package dbms.sqlparser.sqlInterpreter; 2 | 3 | import dbms.datatypes.DatatypeFactory; 4 | import dbms.exception.SyntaxErrorException; 5 | import dbms.sqlparser.syntax.SyntaxUtil; 6 | import dbms.sqlparser.syntax.WhereSyntax; 7 | 8 | import java.util.*; 9 | import java.util.regex.Matcher; 10 | import java.util.regex.Pattern; 11 | 12 | /** 13 | * Converting infix representation of boolean expression to postfix. 14 | */ 15 | public class BooleanExpression { 16 | /** 17 | * regex for predicate syntax used in {@link #getPredicates(String)}. 18 | */ 19 | // TODO: move this to syntax package 20 | private final String predicateRegex = "(TRUE|(" 21 | + SyntaxUtil.COLUMN_NAME + ")\\s*" 22 | + WhereSyntax.SUPPORTED_OPERATORS + "\\s*" 23 | + WhereSyntax.VALUE_FORMAT + ")"; 24 | /** 25 | * error message that will be sent with {@link SyntaxErrorException}. 26 | */ 27 | private final String errorMessage = "invalid condition syntax"; 28 | 29 | /** 30 | * main for testing toPostfix converter 31 | * @param args cmd arguments 32 | */ 33 | public static void main(String[] args) { 34 | //System.out.println(new BooleanExpression().predicateRegex); 35 | Queue postfix = new LinkedList<>(); 36 | try { 37 | postfix = new BooleanExpression().toPostfix("" 38 | + "( ( col != '1996-08-17' )" 39 | + " and ( col2 = 6.255 ) )"); 40 | } catch (SyntaxErrorException e) { 41 | e.printStackTrace(); 42 | } 43 | int size = postfix.size(); 44 | for (int i = 0; i < size; i++) { 45 | System.out.println(postfix.poll()); 46 | } 47 | } 48 | 49 | /** 50 | * infix to postfix converter. 51 | * @param infix 52 | * @return a queue of (SQLPredicates and/or BooleanOperator) contains 53 | * the postfix representation of boolean expression. 54 | * @throws SyntaxErrorException if the boolean expression 55 | * is badly constructed. 56 | */ 57 | public Queue toPostfix(final String infix) throws 58 | SyntaxErrorException { 59 | List sqlPredicates = getPredicates(infix); 60 | Queue postfix = new LinkedList(); 61 | Stack helperStack = new Stack<>(); 62 | 63 | // in case if one predicate just return it in the postfix queue. 64 | if (sqlPredicates.size() == 1) { 65 | postfix.add(sqlPredicates.get(0)); 66 | return postfix; 67 | } 68 | 69 | int predicateNumber = 0; 70 | for (int i = 0; i < infix.length(); i++) { 71 | char currentChar = infix.charAt(i); 72 | if (currentChar == '(') { 73 | helperStack.push(currentChar); 74 | } else if (currentChar == ')') { 75 | try { 76 | while (!(helperStack.peek() instanceof Character)) { 77 | postfix.add(helperStack.pop()); 78 | } 79 | } catch (EmptyStackException e) { 80 | throw new SyntaxErrorException(errorMessage); 81 | } 82 | helperStack.pop(); 83 | } else if (i + 3 < infix.length() && infix.substring(i, i + 3) 84 | .toLowerCase().equals("and")) { 85 | pushAndToPostfix(postfix, helperStack); 86 | i += 2; 87 | } else if (i + 2 < infix.length() && infix.substring(i, i + 2) 88 | .toLowerCase().equals("or")) { 89 | pushOrToPostfix(postfix, helperStack); 90 | i++; 91 | } else if (currentChar == ' ') { 92 | continue; 93 | } else { 94 | try { 95 | postfix.add(sqlPredicates.get(predicateNumber++)); 96 | while (infix.charAt(++i) != ')') { 97 | if (i + 3 < infix.length() && infix.substring(i, i + 3) 98 | .equals(" or") || i + 4 < infix.length() 99 | && infix.substring(i, i + 4).equals(" and")) { 100 | throw new SyntaxErrorException(errorMessage); 101 | } 102 | } 103 | i--; 104 | } catch (IndexOutOfBoundsException e) { 105 | throw new SyntaxErrorException(errorMessage); 106 | } 107 | } 108 | } 109 | if (!helperStack.isEmpty()) { 110 | if (helperStack.peek() instanceof Character) { 111 | throw new SyntaxErrorException(errorMessage); 112 | } else { // in case the user didn't put parenthesis 113 | // around the whole expression some operator 114 | //will remain in helper stack 115 | while (!helperStack.isEmpty()) { 116 | postfix.add(helperStack.pop()); 117 | } 118 | } 119 | } 120 | return postfix; 121 | } 122 | 123 | /** 124 | * helper method for toPostfix() that adds BooleanOperator 125 | * (AND) to postfix queue. 126 | * @param postfix 127 | * @param helperStack 128 | */ 129 | private void pushAndToPostfix(final Queue postfix, 130 | final Stack helperStack) { 131 | if (helperStack.isEmpty() || helperStack.peek() instanceof Character) { 132 | helperStack.push(new BooleanOperator(BooleanOperator.Operator.And)); 133 | } else if (((BooleanOperator) helperStack.peek()).getOperator() 134 | == BooleanOperator.Operator.And) { 135 | postfix.add(new BooleanOperator(BooleanOperator.Operator.And)); 136 | } else { 137 | helperStack.push(new BooleanOperator(BooleanOperator.Operator.And)); 138 | } 139 | } 140 | 141 | /** 142 | * helper method for toPostfix() that adds BooleanOperator 143 | * (OR) to postfix queue. 144 | * @param postfix 145 | * @param helperStack 146 | */ 147 | private void pushOrToPostfix(final Queue postfix, 148 | final Stack helperStack) { 149 | if (helperStack.isEmpty() || helperStack.peek() instanceof Character) { 150 | helperStack.push(new BooleanOperator(BooleanOperator.Operator.Or)); 151 | } else { 152 | if (((BooleanOperator) helperStack.peek()).getOperator() 153 | == BooleanOperator.Operator.And) { 154 | postfix.add(helperStack.pop()); 155 | helperStack.push(new BooleanOperator(BooleanOperator 156 | .Operator.Or)); 157 | } else { // or in helper stack 158 | postfix.add(new BooleanOperator(BooleanOperator.Operator.Or)); 159 | } 160 | } 161 | } 162 | 163 | /** 164 | * this helper function used to to extract predicates from 165 | * infix representation 166 | * of boolean expression. 167 | * @param infix infix representation for boolean expression. 168 | * @return list of SQLPredicates extracted from infix. 169 | */ 170 | private List getPredicates(final String infix) { 171 | /** 172 | * TODO: move pattern to {@link dbms.sqlparser.syntax} 173 | */ 174 | Matcher matcher = Pattern.compile(predicateRegex).matcher(infix); 175 | List sqlPredicates = new ArrayList<>(); 176 | while (matcher.find()) { 177 | if (matcher.group(1).equals("TRUE")) { 178 | sqlPredicates.add(new SQLPredicate(true)); 179 | return sqlPredicates; 180 | } 181 | 182 | SQLPredicate sqlPredicate; 183 | if (matcher.group(4).startsWith("'") || matcher.group(4) 184 | .startsWith("\"") 185 | || matcher.group(4).matches(SyntaxUtil.NUMBER_FORMAT)) { 186 | // TODO: remove lower case and let the backend handles the logic 187 | sqlPredicate = new SQLPredicate(matcher.group(2).toLowerCase(), 188 | matcher.group(3), DatatypeFactory.convertToDataType( 189 | DatatypeFactory.convertToObject(matcher.group(4)))); 190 | } else { 191 | sqlPredicate = new SQLPredicate(matcher.group(2).toLowerCase(), 192 | matcher.group(3), matcher.group(4)); 193 | } 194 | 195 | sqlPredicates.add(sqlPredicate); 196 | } 197 | return sqlPredicates; 198 | } 199 | } 200 | -------------------------------------------------------------------------------- /src/dbms/sqlparser/sqlInterpreter/BooleanExpressionEvaluator.java: -------------------------------------------------------------------------------- 1 | package dbms.sqlparser.sqlInterpreter; 2 | 3 | import dbms.datatypes.DBDatatype; 4 | import dbms.exception.IncorrectDataEntryException; 5 | 6 | import java.util.Map; 7 | import java.util.Queue; 8 | 9 | public abstract class BooleanExpressionEvaluator { 10 | private Queue postfix; 11 | 12 | public BooleanExpressionEvaluator(Queue postfix) { 13 | this.postfix = postfix; 14 | } 15 | 16 | public BooleanExpressionEvaluator() { 17 | } 18 | 19 | public void setPostfix(Queue postfix) { 20 | this.postfix = postfix; 21 | } 22 | 23 | private Object fetchFromColumn(String columnName) { 24 | return null; 25 | } 26 | 27 | protected abstract boolean evaluate(Map row, 28 | Queue postfix, Map columns) 30 | throws IncorrectDataEntryException; 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/dbms/sqlparser/sqlInterpreter/BooleanOperator.java: -------------------------------------------------------------------------------- 1 | package dbms.sqlparser.sqlInterpreter; 2 | 3 | 4 | public class BooleanOperator { 5 | private Operator operator; 6 | 7 | public BooleanOperator(Operator operator) { 8 | this.operator = operator; 9 | } 10 | 11 | public Operator getOperator() { 12 | return operator; 13 | } 14 | 15 | @Override 16 | public String toString() { 17 | return "BooleanOperator{" + 18 | "operator=" + operator + 19 | '}'; 20 | } 21 | 22 | public enum Operator { 23 | And, 24 | Or 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/dbms/sqlparser/sqlInterpreter/Condition.java: -------------------------------------------------------------------------------- 1 | package dbms.sqlparser.sqlInterpreter; 2 | 3 | import dbms.exception.SyntaxErrorException; 4 | 5 | import java.util.Queue; 6 | 7 | public interface Condition { 8 | public Queue getPostfix() throws SyntaxErrorException; 9 | } -------------------------------------------------------------------------------- /src/dbms/sqlparser/sqlInterpreter/SQLPredicate.java: -------------------------------------------------------------------------------- 1 | package dbms.sqlparser.sqlInterpreter; 2 | 3 | import dbms.datatypes.DBDatatype; 4 | import dbms.util.Operator; 5 | 6 | public class SQLPredicate { 7 | private String columnName; 8 | private String columnName2; 9 | private Operator operator; 10 | private DBDatatype value; 11 | private boolean isAlwaysTrue = false; 12 | private boolean isAlwaysFalse = false; 13 | 14 | public SQLPredicate(String columnName, String operator, 15 | DBDatatype value) { 16 | this.columnName = columnName; 17 | this.operator = toOperator(operator); 18 | this.value = value; 19 | } 20 | 21 | public SQLPredicate(String columnName, String operator, 22 | String columnName2) { 23 | this.columnName = columnName; 24 | this.operator = toOperator(operator); 25 | this.columnName2 = columnName2; 26 | } 27 | 28 | public SQLPredicate(boolean predicateValue) { 29 | if (predicateValue) { 30 | isAlwaysTrue = true; 31 | } else { 32 | isAlwaysFalse = true; 33 | } 34 | } 35 | 36 | public boolean isAlwaysTrue() { 37 | return isAlwaysTrue; 38 | } 39 | 40 | public boolean isAlwaysFalse() { 41 | return isAlwaysFalse; 42 | } 43 | 44 | /** 45 | * @param o DBDatatype for left-side column of this predicate 46 | * @return 47 | */ 48 | public boolean test(DBDatatype o) { 49 | return operator.apply(o, value); 50 | } 51 | 52 | /** 53 | * @param o1 DBDatatype for left-side column of this predicate 54 | * @param o2 DBDatatype for right-side column of this predicate. 55 | * @return 56 | */ 57 | public boolean test(DBDatatype o1, DBDatatype o2) { 58 | return operator.apply(o1, o2); 59 | } 60 | 61 | /** 62 | * @param sqlPredicate 63 | * @param o1 DBDatatype for left-side column of this predicate 64 | * @param o2 DBDatatype for right-side column of this predicate 65 | * @param o3 DBDatatype for left-side column of predicate argument 66 | * @param o4 DBDatatype for right-side column of predicate argument 67 | * @return boolean value true/false 68 | */ 69 | public boolean or(SQLPredicate sqlPredicate, DBDatatype o1, DBDatatype 70 | o2, DBDatatype o3, DBDatatype o4) { 71 | if (o4 == null && o3 == null && o2 == null) { 72 | return test(o1) || sqlPredicate.isAlwaysTrue(); 73 | } else if (o1 == null && o2 == null && o4 == null) { 74 | return isAlwaysTrue() || sqlPredicate.test(o3); 75 | } else if (o1 == null && o2 == null) { 76 | return isAlwaysTrue || sqlPredicate.test(o3, o4); 77 | } else if (o2 == null && o4 == null) { 78 | return test(o1) || sqlPredicate.test(o3); 79 | } else if (o3 == null && o4 == null) { 80 | return test(o1, o2) || sqlPredicate.isAlwaysTrue(); 81 | } else if (o2 == null) { 82 | return test(o1) || sqlPredicate.test(o3, o4); 83 | } else if (o4 == null) { 84 | return test(o1, o2) || sqlPredicate.test(o3); 85 | } else { 86 | return test(o1, o2) || sqlPredicate.test(o3, o4); 87 | } 88 | } 89 | 90 | /** 91 | * @param sqlPredicate 92 | * @param o1 DBDatatype for left-side column of this predicate 93 | * @param o2 DBDatatype for right-side column of this predicate 94 | * @param o3 DBDatatype for left-side column of predicate argument 95 | * @param o4 DBDatatype for right-side column of predicate argument 96 | * @return boolean value true/false 97 | */ 98 | public boolean and(SQLPredicate sqlPredicate, DBDatatype o1, DBDatatype 99 | o2, DBDatatype o3, DBDatatype o4) { 100 | if (o4 == null && o3 == null && o2 == null) { 101 | return test(o1) && sqlPredicate.isAlwaysTrue(); 102 | } else if (o1 == null && o2 == null && o4 == null) { 103 | return isAlwaysTrue() && sqlPredicate.test(o3); 104 | } else if (o1 == null && o2 == null) { 105 | return isAlwaysTrue && sqlPredicate.test(o3, o4); 106 | } else if (o2 == null && o4 == null) { 107 | return test(o1) && sqlPredicate.test(o3); 108 | } else if (o3 == null && o4 == null) { 109 | return test(o1, o2) && sqlPredicate.isAlwaysTrue(); 110 | } else if (o2 == null) { 111 | return test(o1) && sqlPredicate.test(o3, o4); 112 | } else if (o4 == null) { 113 | return test(o1, o2) && sqlPredicate.test(o3); 114 | } else { 115 | return test(o1, o2) && sqlPredicate.test(o3, o4); 116 | } 117 | } 118 | 119 | public String getColumnName() { 120 | return columnName; 121 | } 122 | 123 | public DBDatatype getValue() { 124 | return value; 125 | } 126 | 127 | public Operator getOperator() { 128 | return operator; 129 | } 130 | 131 | public String getColumnName2() { 132 | return columnName2; 133 | } 134 | 135 | public boolean compareWithValue() { 136 | return (getColumnName2() == null); 137 | } 138 | 139 | private Operator toOperator(String operator) { 140 | switch (operator) { 141 | case "<": 142 | return Operator.SmallerThan; 143 | case ">": 144 | return Operator.GreaterThan; 145 | case "=": 146 | return Operator.Equal; 147 | case "<=": 148 | return Operator.SmallerThanOrEqual; 149 | case ">=": 150 | return Operator.GreaterThanOrEqual; 151 | case "!=": 152 | return Operator.NotEqual; 153 | default: 154 | return null; 155 | } 156 | } 157 | 158 | @Override 159 | public String toString() { 160 | return "SQLPredicate{" + 161 | "columnName='" + columnName + '\'' + 162 | ", columnName2='" + columnName2 + '\'' + 163 | ", operator=" + operator + 164 | ", value=" + value + 165 | ", isAlwaysTrue=" + isAlwaysTrue + 166 | ", isAlwaysFalse=" + isAlwaysFalse + 167 | '}'; 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /src/dbms/sqlparser/sqlInterpreter/Where.java: -------------------------------------------------------------------------------- 1 | package dbms.sqlparser.sqlInterpreter; 2 | 3 | import dbms.exception.SyntaxErrorException; 4 | 5 | import java.util.Queue; 6 | 7 | public class Where implements Condition { 8 | private String infix; 9 | 10 | public Where(String infix) { 11 | this.infix = infix; 12 | } 13 | 14 | @Override 15 | public Queue getPostfix() throws SyntaxErrorException { 16 | return new BooleanExpression().toPostfix(infix); 17 | } 18 | 19 | @Override 20 | public String toString() { 21 | return "infix: " + infix; 22 | } 23 | } -------------------------------------------------------------------------------- /src/dbms/sqlparser/sqlInterpreter/rules/AlterAdd.java: -------------------------------------------------------------------------------- 1 | package dbms.sqlparser.sqlInterpreter.rules; 2 | 3 | import dbms.backend.BackendController; 4 | import dbms.datatypes.DBDatatype; 5 | import dbms.exception.DataTypeNotSupportedException; 6 | import dbms.exception.DatabaseAlreadyCreatedException; 7 | import dbms.exception.DatabaseNotFoundException; 8 | import dbms.exception.IncorrectDataEntryException; 9 | import dbms.exception.SyntaxErrorException; 10 | import dbms.exception.TableAlreadyCreatedException; 11 | import dbms.exception.TableNotFoundException; 12 | 13 | public class AlterAdd implements DDLStatement { 14 | private String tableName; 15 | private String columnName; 16 | private Class dataType; 17 | 18 | public AlterAdd(final String tableName, final String columnName, 19 | Class dataType) { 20 | this.tableName = tableName; 21 | this.columnName = columnName; 22 | this.dataType = dataType; 23 | } 24 | 25 | public String getTableName() { 26 | return tableName; 27 | } 28 | 29 | public String getColumnName() { 30 | return columnName; 31 | } 32 | 33 | public Class getDataType() { 34 | return dataType; 35 | } 36 | 37 | @Override 38 | public void execute() throws DatabaseNotFoundException, 39 | TableNotFoundException, SyntaxErrorException, 40 | DataTypeNotSupportedException, TableAlreadyCreatedException, 41 | DatabaseAlreadyCreatedException, IncorrectDataEntryException { 42 | BackendController.getInstance().alterAdd(tableName, columnName, 43 | dataType); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/dbms/sqlparser/sqlInterpreter/rules/AlterDrop.java: -------------------------------------------------------------------------------- 1 | package dbms.sqlparser.sqlInterpreter.rules; 2 | 3 | import dbms.backend.BackendController; 4 | import dbms.exception.*; 5 | 6 | public class AlterDrop implements DDLStatement { 7 | private String tableName; 8 | private String columnName; 9 | 10 | public AlterDrop(String tableName, String columnName) { 11 | this.tableName = tableName; 12 | this.columnName = columnName; 13 | } 14 | 15 | public String getTableName() { 16 | return tableName; 17 | } 18 | 19 | public String getColumnName() { 20 | return columnName; 21 | } 22 | 23 | @Override 24 | public void execute() throws DatabaseNotFoundException, 25 | TableNotFoundException, SyntaxErrorException, 26 | DataTypeNotSupportedException, 27 | TableAlreadyCreatedException, DatabaseAlreadyCreatedException, 28 | IncorrectDataEntryException { 29 | BackendController.getInstance().alterDrop(tableName, columnName); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/dbms/sqlparser/sqlInterpreter/rules/CreateDatabase.java: -------------------------------------------------------------------------------- 1 | package dbms.sqlparser.sqlInterpreter.rules; 2 | 3 | import dbms.backend.BackendController; 4 | import dbms.exception.DatabaseAlreadyCreatedException; 5 | 6 | public class CreateDatabase implements DDLStatement { 7 | private String dbName; 8 | 9 | public CreateDatabase(final String dbName) { 10 | this.dbName = dbName; 11 | } 12 | 13 | public String getDbName() { 14 | return dbName; 15 | } 16 | 17 | @Override 18 | public void execute() throws DatabaseAlreadyCreatedException { 19 | BackendController.getInstance().createDatabase(dbName); 20 | } 21 | } -------------------------------------------------------------------------------- /src/dbms/sqlparser/sqlInterpreter/rules/CreateTable.java: -------------------------------------------------------------------------------- 1 | package dbms.sqlparser.sqlInterpreter.rules; 2 | 3 | import dbms.backend.BackendController; 4 | import dbms.datatypes.DBDatatype; 5 | import dbms.exception.DatabaseNotFoundException; 6 | import dbms.exception.IncorrectDataEntryException; 7 | import dbms.exception.TableAlreadyCreatedException; 8 | 9 | import java.util.Map; 10 | 11 | public class CreateTable implements DDLStatement { 12 | private String tableName; 13 | private Map> columns; 14 | 15 | public CreateTable(final String tableName, final Map> columns) { 17 | this.tableName = tableName; 18 | this.columns = columns; 19 | } 20 | 21 | public String getTableName() { 22 | return tableName; 23 | } 24 | 25 | public Map> getColumns() { 26 | return columns; 27 | } 28 | 29 | @Override 30 | public void execute() throws DatabaseNotFoundException, 31 | TableAlreadyCreatedException, IncorrectDataEntryException { 32 | BackendController.getInstance().createTable(tableName, columns); 33 | } 34 | } -------------------------------------------------------------------------------- /src/dbms/sqlparser/sqlInterpreter/rules/DDLStatement.java: -------------------------------------------------------------------------------- 1 | package dbms.sqlparser.sqlInterpreter.rules; 2 | 3 | public interface DDLStatement extends Expression { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /src/dbms/sqlparser/sqlInterpreter/rules/DMLStatement.java: -------------------------------------------------------------------------------- 1 | package dbms.sqlparser.sqlInterpreter.rules; 2 | 3 | public interface DMLStatement extends Expression { 4 | int getUpdateCount(); 5 | } 6 | -------------------------------------------------------------------------------- /src/dbms/sqlparser/sqlInterpreter/rules/Delete.java: -------------------------------------------------------------------------------- 1 | package dbms.sqlparser.sqlInterpreter.rules; 2 | 3 | import dbms.backend.BackendController; 4 | import dbms.exception.DatabaseNotFoundException; 5 | import dbms.exception.IncorrectDataEntryException; 6 | import dbms.exception.SyntaxErrorException; 7 | import dbms.exception.TableNotFoundException; 8 | import dbms.sqlparser.sqlInterpreter.Where; 9 | 10 | public class Delete implements DMLStatement { 11 | private String tableName; 12 | private Where where; 13 | private int updateCount; 14 | 15 | public Delete(String tableName) { 16 | this.tableName = tableName; 17 | } 18 | 19 | public String getTableName() { 20 | return tableName; 21 | } 22 | 23 | public Where getWhere() { 24 | return where; 25 | } 26 | 27 | public void setWhere(Where where) { 28 | this.where = where; 29 | } 30 | 31 | @Override 32 | public int getUpdateCount() { 33 | return updateCount; 34 | } 35 | 36 | @Override 37 | public void execute() throws DatabaseNotFoundException, 38 | TableNotFoundException, SyntaxErrorException, IncorrectDataEntryException { 39 | updateCount = BackendController.getInstance().delete(tableName, where); 40 | } 41 | } -------------------------------------------------------------------------------- /src/dbms/sqlparser/sqlInterpreter/rules/DropDatabase.java: -------------------------------------------------------------------------------- 1 | package dbms.sqlparser.sqlInterpreter.rules; 2 | 3 | import dbms.backend.BackendController; 4 | import dbms.exception.DatabaseNotFoundException; 5 | 6 | public class DropDatabase implements DDLStatement { 7 | private String dbName; 8 | 9 | public DropDatabase(final String dbName) { 10 | this.dbName = dbName; 11 | } 12 | 13 | public String getDbName() { 14 | return dbName; 15 | } 16 | 17 | @Override 18 | public void execute() throws DatabaseNotFoundException { 19 | BackendController.getInstance().dropDatabase(dbName); 20 | } 21 | } -------------------------------------------------------------------------------- /src/dbms/sqlparser/sqlInterpreter/rules/DropTable.java: -------------------------------------------------------------------------------- 1 | package dbms.sqlparser.sqlInterpreter.rules; 2 | 3 | import dbms.backend.BackendController; 4 | import dbms.exception.DatabaseNotFoundException; 5 | 6 | public class DropTable implements DDLStatement { 7 | private String tableName; 8 | 9 | public DropTable(final String tableName) { 10 | this.tableName = tableName; 11 | } 12 | 13 | public String getTableName() { 14 | return tableName; 15 | } 16 | 17 | @Override 18 | public void execute() throws DatabaseNotFoundException { 19 | BackendController.getInstance().dropTable(tableName); 20 | } 21 | } -------------------------------------------------------------------------------- /src/dbms/sqlparser/sqlInterpreter/rules/Expression.java: -------------------------------------------------------------------------------- 1 | package dbms.sqlparser.sqlInterpreter.rules; 2 | 3 | import dbms.exception.*; 4 | 5 | public interface Expression { 6 | void execute() throws DatabaseNotFoundException, 7 | TableNotFoundException, 8 | SyntaxErrorException, 9 | DataTypeNotSupportedException, 10 | TableAlreadyCreatedException, 11 | DatabaseAlreadyCreatedException, 12 | IncorrectDataEntryException; 13 | } -------------------------------------------------------------------------------- /src/dbms/sqlparser/sqlInterpreter/rules/InsertIntoTable.java: -------------------------------------------------------------------------------- 1 | package dbms.sqlparser.sqlInterpreter.rules; 2 | 3 | import dbms.backend.BackendController; 4 | import dbms.datatypes.DBDatatype; 5 | import dbms.exception.DatabaseNotFoundException; 6 | import dbms.exception.IncorrectDataEntryException; 7 | import dbms.exception.TableNotFoundException; 8 | 9 | import java.util.ArrayList; 10 | import java.util.Collection; 11 | import java.util.Iterator; 12 | import java.util.Map; 13 | 14 | public class InsertIntoTable implements DMLStatement { 15 | private String tableName; 16 | private Map entryMap; 17 | private int updateCount; 18 | private boolean insertWithNoColumns = false; 19 | 20 | public InsertIntoTable(final String tableName, 21 | final Map entryMap) { 22 | this.tableName = tableName; 23 | this.entryMap = entryMap; 24 | } 25 | 26 | public void insertWithNoColumns(final boolean insertWithNoColumns) { 27 | this.insertWithNoColumns = insertWithNoColumns; 28 | } 29 | 30 | public String getTableName() { 31 | return tableName; 32 | } 33 | 34 | public Map getEntryMap() { 35 | return entryMap; 36 | } 37 | 38 | @Override 39 | public int getUpdateCount() { 40 | return updateCount; 41 | } 42 | 43 | @Override 44 | public void execute() throws DatabaseNotFoundException, 45 | TableNotFoundException, IncorrectDataEntryException { 46 | if (insertWithNoColumns) { 47 | Collection entries = new ArrayList<>(); 48 | Iterator> it 49 | = entryMap.entrySet().iterator(); 50 | while (it.hasNext()) { 51 | Map.Entry pair = (Map.Entry) it.next(); 52 | entries.add((DBDatatype) pair.getValue()); 53 | } 54 | updateCount = BackendController.getInstance() 55 | .insertIntoTable(tableName, entries); 56 | return; 57 | } 58 | updateCount = BackendController.getInstance() 59 | .insertIntoTable(tableName, entryMap); 60 | } 61 | } -------------------------------------------------------------------------------- /src/dbms/sqlparser/sqlInterpreter/rules/Select.java: -------------------------------------------------------------------------------- 1 | package dbms.sqlparser.sqlInterpreter.rules; 2 | 3 | import dbms.backend.BackendController; 4 | import dbms.exception.DatabaseNotFoundException; 5 | import dbms.exception.IncorrectDataEntryException; 6 | import dbms.exception.SyntaxErrorException; 7 | import dbms.exception.TableNotFoundException; 8 | import dbms.sqlparser.sqlInterpreter.Where; 9 | import dbms.ui.Formatter; 10 | import dbms.util.RecordSet; 11 | import javafx.util.Pair; 12 | 13 | import java.util.*; 14 | 15 | public class Select implements DMLStatement { 16 | private String tableName; 17 | private Collection columns; 18 | private List> orderBy; 19 | private boolean isDistinct = false; 20 | private int updateCount = 0; 21 | private RecordSet recordSet; 22 | 23 | private Where where; 24 | 25 | /** 26 | * Sets the name of the local table name. 27 | * @param tableName the name of current table. 28 | */ 29 | public Select(String tableName) { 30 | this.tableName = tableName; 31 | } 32 | 33 | /** 34 | * @return {@link Where} the local where statement. 35 | */ 36 | public Where getWhere() { 37 | return where; 38 | } 39 | 40 | /** 41 | * @return {@link Where} the local where statement. 42 | */ 43 | public void setWhere(final Where where) { 44 | this.where = where; 45 | } 46 | 47 | /** 48 | * @return {@link Collection} collection of columns. 49 | */ 50 | public Collection getColumns() { 51 | return columns; 52 | } 53 | 54 | /** 55 | * Sets the local Collection of columns. 56 | * @param columns {@link Collection} columns of current table. 57 | */ 58 | public void setColumns(final Collection columns) { 59 | this.columns = columns; 60 | } 61 | 62 | /** 63 | * @return the name of the table. 64 | */ 65 | public String getTableName() { 66 | return tableName; 67 | } 68 | 69 | /** 70 | * @return {@link List} list of columns orders. 71 | */ 72 | public List> getOrderBy() { 73 | return orderBy; 74 | } 75 | 76 | /** 77 | * @param orderBy {@link List} list of columns orders. 78 | */ 79 | public void setOrderBy(final List> orderBy) { 80 | this.orderBy = orderBy; 81 | } 82 | 83 | public boolean isDistinct() { 84 | return isDistinct; 85 | } 86 | 87 | public RecordSet getRecordSet() { 88 | return recordSet; 89 | } 90 | 91 | public void distinct() { 92 | isDistinct = true; 93 | } 94 | 95 | @Override 96 | public int getUpdateCount() { 97 | return updateCount; 98 | } 99 | 100 | 101 | private Collection getOrderByColumnsName() { 102 | Collection orderbyColumnsName = new ArrayList<>(); 103 | for (Pair pair : orderBy) { 104 | orderbyColumnsName.add(pair.getKey()); 105 | } 106 | return orderbyColumnsName; 107 | } 108 | 109 | @Override 110 | public void execute() throws DatabaseNotFoundException, 111 | TableNotFoundException, SyntaxErrorException, 112 | IncorrectDataEntryException { 113 | if (orderBy != null) { 114 | if (columns == null) { 115 | recordSet = BackendController.getInstance().select( 116 | tableName, null, where); 117 | } else { 118 | Collection necessaryColumns = new LinkedHashSet<>(columns); 119 | necessaryColumns.addAll(getOrderByColumnsName()); 120 | recordSet = BackendController.getInstance().select( 121 | tableName, necessaryColumns, where); 122 | } 123 | recordSet.orderBy(orderBy, columns); 124 | } else { 125 | recordSet = BackendController.getInstance().select( 126 | tableName, columns, where); 127 | } 128 | if (isDistinct) recordSet.distinct(); 129 | Formatter.getInstance().printTable(recordSet); 130 | recordSet.reset(); 131 | } 132 | } -------------------------------------------------------------------------------- /src/dbms/sqlparser/sqlInterpreter/rules/Union.java: -------------------------------------------------------------------------------- 1 | package dbms.sqlparser.sqlInterpreter.rules; 2 | 3 | import dbms.exception.*; 4 | import dbms.ui.Formatter; 5 | import dbms.util.RecordSet; 6 | 7 | import java.util.Iterator; 8 | import java.util.List; 9 | 10 | public class Union implements DMLStatement { 11 | private List selects, final boolean removeDuplicates) { 17 | this.selects = selects; 18 | this.removeDuplicates = removeDuplicates; 19 | } 20 | 21 | @Override 22 | public int getUpdateCount() { 23 | return updateCount; 24 | } 25 | 26 | public RecordSet getRecordSet() { 27 | return recordSet; 28 | } 29 | 30 | @Override 31 | public void execute() throws DatabaseNotFoundException, 32 | TableNotFoundException, 33 | SyntaxErrorException, DataTypeNotSupportedException, 34 | TableAlreadyCreatedException, DatabaseAlreadyCreatedException, 35 | IncorrectDataEntryException { 36 | 37 | Iterator