├── .gitignore ├── .gitmodules ├── LICENSE └── database ├── Makefile ├── README ├── docs └── Doxyfile ├── include ├── data │ ├── accessor.h │ ├── data_store.h │ ├── hash_functor.h │ ├── table.h │ └── types.h ├── sql │ ├── common.h │ ├── omdb_parser.h │ ├── parser │ │ ├── parse.h │ │ ├── parse.y │ │ ├── sqlite_parse.y │ │ └── token.h │ ├── predicate.h │ ├── statements │ │ ├── builder.h │ │ ├── common.h │ │ ├── data_definition.h │ │ ├── data_manipulation.h │ │ └── expression.h │ └── types │ │ ├── boolean.h │ │ ├── character.h │ │ ├── common.h │ │ ├── datetime.h │ │ └── exact_numeric.h ├── util │ ├── common.h │ ├── network │ │ ├── common.h │ │ └── connection.h │ ├── omdb_stdlib.h │ ├── packets.h │ ├── result.h │ └── types.h └── workmanager │ ├── types.h │ ├── work_manager.h │ └── work_thread.h ├── libomdb ├── ConsoleDemo │ ├── Makefile │ └── main.cc ├── Makefile ├── Tests │ ├── TestSerialization │ │ ├── Makefile │ │ └── testSerialization.cc │ └── Test_libomdb │ │ ├── Makefile │ │ ├── log.txt │ │ ├── main.cc │ │ ├── serialization_helper.cc │ │ ├── serialization_helper.h │ │ └── temp_server.cc ├── connection.cc ├── libomdb_result.cc ├── omdb_lib.cc ├── omdb_lib.h ├── serialization_helper.cc └── serialization_helper.h ├── source ├── data │ └── data_store.cc ├── main.cc ├── sql │ ├── common.cc │ ├── parser │ │ └── omdb_parser.cc │ ├── predicate.cc │ ├── statements │ │ ├── builder.cc │ │ ├── data_manipulation.cc │ │ └── expression.cc │ └── types │ │ ├── boolean.cc │ │ └── datetime.cc ├── util │ ├── common.cc │ ├── network │ │ ├── common.cc │ │ └── connection.cc │ └── omdb_stdlib.cc └── workmanager │ ├── work_manager.cc │ └── work_thread.cc ├── tests ├── DataStoreTest.cc ├── DataStoreTest.h ├── GraphTest.cc ├── GraphTest.h ├── Makefile ├── Modes.h ├── README.md ├── Randomizer.cc ├── Randomizer.h ├── SQLGenerator.cc ├── SQLGenerator.h ├── Test.cc ├── Test.h ├── TestConstants.h ├── TestResult.cc ├── TestResult.h ├── db_testing │ ├── README.md │ ├── maria_test │ │ ├── connector.java │ │ ├── main.java │ │ ├── makefile │ │ └── thread.java │ ├── memsql_test │ │ ├── Makefile │ │ ├── README │ │ ├── main.c │ │ ├── src │ │ │ ├── Commands.java │ │ │ ├── Constants.java │ │ │ ├── META-INF │ │ │ │ └── MANIFEST.MF │ │ │ ├── Sample.java │ │ │ └── Worker.java │ │ ├── test_file_parser.c │ │ ├── test_file_parser.h │ │ ├── test_runner.c │ │ └── test_runner.h │ └── volt_test │ │ ├── Connector.java │ │ ├── Insert.java │ │ ├── README │ │ ├── Run.java │ │ ├── Select.java │ │ ├── SelectB.java │ │ ├── Worker.java │ │ ├── create.txt │ │ ├── deployment.xml │ │ ├── makefile │ │ ├── parseSQL.sh │ │ ├── prep.sh │ │ ├── run.sh │ │ ├── start.sh │ │ └── stop.sh ├── graph_test.py ├── main.cc ├── performance_test.sh └── voltdb.sh └── tools └── lemon ├── Makefile ├── addopcodes.awk ├── lemon.c └── lempar.c /.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | *.ko 4 | *.obj 5 | *.elf 6 | 7 | # Executable 8 | openmemdb 9 | lemon 10 | test_libomdb 11 | temp_server 12 | omdb_console 13 | 14 | # Precompiled Headers 15 | *.gch 16 | *.pch 17 | 18 | # Libraries 19 | *.lib 20 | *.a 21 | *.la 22 | *.lo 23 | *.out 24 | 25 | # Shared objects (inc. Windows DLLs) 26 | *.dll 27 | *.so 28 | *.so.* 29 | *.dylib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | *.i*86 36 | *.x86_64 37 | *.hex 38 | 39 | # Debug files 40 | *.dSYM/ 41 | 42 | # Document intermediaries 43 | *.aux 44 | *.log 45 | *.pdf 46 | *.backup 47 | database/docs/doxygen 48 | 49 | # Gedit backup file 50 | .*~ 51 | 52 | # VIM temp files 53 | *.swp 54 | 55 | # generic temp file 56 | *.tmp 57 | *.temp 58 | 59 | # Project files (Eclipse) 60 | *.cproject 61 | *.project 62 | 63 | # GTAGS 64 | GPATH 65 | GRTAGS 66 | GTAGS 67 | 68 | # Generated data 69 | *.omdbt 70 | 71 | # Latex files 72 | *.bbl 73 | *.dvi 74 | *.blg 75 | 76 | # Graphics files 77 | *.png 78 | *.jpg 79 | *.gif 80 | *.pdf 81 | graphics 82 | 83 | #Latex intermidiate and compilation files 84 | *.toc 85 | *.gz 86 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "Tervel"] 2 | path = Tervel 3 | url = https://github.com/Dar13/Tervel 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Neil Moore 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /database/Makefile: -------------------------------------------------------------------------------- 1 | # Compiler to use 2 | CC=g++ 3 | 4 | # NAWK-compatible AWK 5 | NAWK=gawk 6 | 7 | TERVEL_DIR=../Tervel 8 | INC_DIR=./include 9 | SRC_DIR=./source 10 | EXEC=openmemdb 11 | 12 | TOOLS_DIR=./tools 13 | 14 | LEMON_GRAM_LOC=$(realpath ./include/sql/parser/parse.y) 15 | 16 | # Basic flags that will be shared between debug and release configurations 17 | CFLAGS=-Wall -Wextra -g -std=c++11 -I$(INC_DIR) -I$(TERVEL_DIR) 18 | 19 | LDFLAGS=-L$(TERVEL_DIR) -rdynamic -pthread -std=c++11 20 | 21 | SOURCES=$(shell find $(SRC_DIR) -name *.cc) 22 | 23 | SOURCES += $(shell find $(TERVEL_DIR)/tervel/util/ -name *.cc) 24 | OBJECTS=$(SOURCES:.cc=.o) 25 | 26 | all: $(SOURCES) $(EXEC) 27 | 28 | release: CFLAGS += -O2 29 | release: $(EXEC) 30 | 31 | $(EXEC): $(OBJECTS) 32 | $(CC) $(LDFLAGS) $(OBJECTS) -o $@ 33 | 34 | %.o : %.cc 35 | $(CC) $(CFLAGS) -c $< -o $@ 36 | 37 | clean: 38 | rm -f $(EXEC) 39 | rm -f $(OBJECTS) 40 | 41 | lemon: 42 | make -C $(TOOLS_DIR)/lemon 43 | cd $(TOOLS_DIR)/lemon && ./lemon -p $(LEMON_GRAM_LOC) 44 | mv $(INC_DIR)/sql/parser/parse.h $(INC_DIR)/sql/parser/parse.h.tmp 45 | mv $(INC_DIR)/sql/parser/parse.c $(SRC_DIR)/sql/parser/parse.c 46 | $(NAWK) -f $(TOOLS_DIR)/lemon/addopcodes.awk $(INC_DIR)/sql/parser/parse.h.tmp >$(INC_DIR)/sql/parser/parse.h 47 | rm $(INC_DIR)/sql/parser/parse.h.tmp 48 | -------------------------------------------------------------------------------- /database/README: -------------------------------------------------------------------------------- 1 | To build: 2 | 1) "make lemon" 3 | 2) "make" / "make release" 4 | -------------------------------------------------------------------------------- /database/include/data/accessor.h: -------------------------------------------------------------------------------- 1 | #ifndef DATA_ACCESSOR_H 2 | #define DATA_ACCESSOR_H 3 | 4 | // STL includes 5 | #include 6 | #include 7 | 8 | // Tervel includes 9 | #include "tervel/util/memory/hp/hp_element.h" 10 | #include "tervel/containers/wf/vector/vector.hpp" 11 | 12 | // Gets rid of long namespaces 13 | using namespace tervel::util::memory::hp; 14 | 15 | template 16 | class ValuePointer : public tervel::util::memory::hp::Element 17 | { 18 | public: 19 | S* ptr; 20 | std::atomic counter; 21 | 22 | ValuePointer(S* value) : ptr(value), counter(0) {} 23 | 24 | bool on_is_watched() { 25 | return (counter.load() > 0); 26 | } 27 | 28 | ~ValuePointer() { 29 | counter.store(std::numeric_limits::min()); 30 | delete ptr; 31 | } 32 | }; 33 | 34 | template 35 | class VectorAccessor { 36 | public: 37 | using Value = ValuePointer; 38 | 39 | Value* value; 40 | 41 | VectorAccessor() : value(nullptr) {} 42 | 43 | bool init(tervel::containers::wf::vector::Vector& vector, uint32_t index) { 44 | /////////////////////// 45 | // MAGIC DON'T TOUCH // 46 | /////////////////////// 47 | Value* retrieved_value; 48 | Value* value_ptr; 49 | if(vector.at(index, retrieved_value)) 50 | { 51 | // hp_watch 52 | HazardPointer::watch(HazardPointer::SlotID::SHORTUSE, retrieved_value); 53 | 54 | Value* test_value; 55 | if(!vector.at(index, test_value) || retrieved_value != test_value) 56 | { 57 | HazardPointer::unwatch(HazardPointer::SlotID::SHORTUSE, retrieved_value); 58 | return false; 59 | } 60 | 61 | uintptr_t clean_ptr = reinterpret_cast(retrieved_value) & (~0x7); 62 | value_ptr = reinterpret_cast(clean_ptr); 63 | 64 | int64_t res = value_ptr->counter.fetch_add(1); 65 | 66 | // hp_unwatch 67 | HazardPointer::unwatch(HazardPointer::SlotID::SHORTUSE, retrieved_value); 68 | 69 | Value* check_2 = nullptr; 70 | if(!vector.at(index, check_2)) 71 | { 72 | HazardPointer::unwatch(HazardPointer::SlotID::SHORTUSE, retrieved_value); 73 | return false; 74 | } 75 | 76 | if(res < 0 || retrieved_value != check_2) 77 | { 78 | retrieved_value->counter.fetch_sub(1); 79 | return false; 80 | } 81 | 82 | // Store the clean pointer and return true, the access is successful. 83 | this->value = value_ptr; 84 | return true; 85 | } 86 | else 87 | { 88 | return false; 89 | } 90 | } 91 | 92 | ~VectorAccessor() { 93 | if(value) 94 | { 95 | value->counter.fetch_sub(1); 96 | } 97 | } 98 | }; 99 | 100 | #endif 101 | -------------------------------------------------------------------------------- /database/include/data/data_store.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016 Neil Moore, Jason Stavrinaky, Micheal McGee, Robert Medina 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 4 | * software and associated documentation files (the "Software"), to deal in the Software 5 | * without restriction, including without limitation the rights to use, copy, modify, 6 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | * 9 | * The above copyright notice and this permission notice shall be included in all copies 10 | * or substantial portions of the Software. 11 | * 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 14 | * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 15 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 16 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 17 | * USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | */ 19 | 20 | #ifndef DATA_STORE_H 21 | #define DATA_STORE_H 22 | 23 | // STL includes 24 | #include 25 | #include 26 | #include 27 | 28 | // Tervel includes 29 | #include 30 | #include 31 | 32 | // Project includes 33 | #include "data/types.h" 34 | #include "data/table.h" 35 | #include "accessor.h" 36 | #include "util/types.h" 37 | #include "util/result.h" 38 | #include "sql/types/common.h" 39 | #include "sql/predicate.h" 40 | #include "sql/statements/data_definition.h" 41 | #include "sql/statements/data_manipulation.h" 42 | #include "sql/common.h" 43 | 44 | // The mack-daddy, the mapping of table names to tables/schemas. 45 | using TableMap = tervel::containers::wf::HashMap>; 48 | 49 | // Some common Result types for this module 50 | using DataResult = Result; 51 | using RecordResult = Result; 52 | using MultiRecordResult = Result; 53 | using ManipResult = Result; 54 | using ConstraintResult = Result; 55 | 56 | /** 57 | * @brief The interface into the data that is shared between all worker threads. 58 | */ 59 | class DataStore 60 | { 61 | public: 62 | DataStore() 63 | : table_name_mapping(63) 64 | {} 65 | 66 | TervelVector*> test; 67 | 68 | ManipResult createTable(CreateTableCommand table_info); 69 | 70 | ManipResult deleteTable(const std::string& table_name); 71 | 72 | UintResult getColumnIndex(const std::string& table_name, const std::string& column_name); 73 | 74 | SchemaResult getTableSchema(const std::string& table_name); 75 | 76 | ManipResult insertRecord(const std::string& table_name, 77 | RecordData record); 78 | 79 | ManipResult updateRecords(Predicate* predicates, 80 | const std::string& table_name, 81 | RecordData record); 82 | 83 | ManipResult deleteRecords(Predicate* predicates, 84 | const std::string& table_name); 85 | 86 | MultiRecordResult getRecords(Predicate* predicates, 87 | const std::string& table_name); 88 | 89 | private: 90 | bool getTablePair(std::string table_name, SchemaTablePair& pair); 91 | 92 | RecordCopy copyRecord(RecordVector& table, int64_t row_idx); 93 | RecordCopy copyRecord(Record* record); 94 | 95 | Record* updateRecord(const RecordCopy& old_record, RecordData& new_record); 96 | 97 | MultiRecordCopies searchTable(std::shared_ptr& table, ValuePredicate* value_pred); 98 | /* 99 | MultiTableRecordData searchTable(std::string table_first, std::string table_second, 100 | ColumnPredicate* col_pred); 101 | */ 102 | 103 | MultiTableRecordCopies searchTables(NestedPredicate* pred); 104 | 105 | RecordReferences searchTableForRefs(std::shared_ptr& table, 106 | ValuePredicate* value_pred); 107 | RecordReferences searchTablesForRefs(NestedPredicate* pred); 108 | 109 | ConstraintResult schemaChecker(SchemaTablePair& table_pair, RecordData *record); 110 | 111 | TableMap table_name_mapping; 112 | }; 113 | 114 | 115 | #endif 116 | -------------------------------------------------------------------------------- /database/include/data/hash_functor.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016 Neil Moore, Jason Stavrinaky, Micheal McGee, Robert Medina 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 4 | * software and associated documentation files (the "Software"), to deal in the Software 5 | * without restriction, including without limitation the rights to use, copy, modify, 6 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | * 9 | * The above copyright notice and this permission notice shall be included in all copies 10 | * or substantial portions of the Software. 11 | * 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 14 | * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 15 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 16 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 17 | * USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | */ 19 | 20 | #ifndef DATA_HASH_FUNCTOR_H 21 | #define DATA_HASH_FUNCTOR_H 22 | 23 | #include 24 | 25 | /** 26 | * \brief An object that implements various helper functions needed by Tervel's 27 | * hash map implementation. 28 | */ 29 | template 30 | struct TableHashFunctor 31 | { 32 | Key hash(Key k) 33 | { 34 | // Using a proper hashing algorithm is useless 35 | // It's a waste of cycles due to the compare of most types being so expensive. 36 | // If Tervel used an integral-type internal storage of keys, this would be 37 | // worthy of a hashing algorithm. 38 | return k; 39 | } 40 | 41 | bool key_equals(Key a, Key b) 42 | { 43 | return (a == b); 44 | } 45 | }; 46 | 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /database/include/data/table.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016 Neil Moore, Jason Stavrinaky, Micheal McGee, Robert Medina 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 4 | * software and associated documentation files (the "Software"), to deal in the Software 5 | * without restriction, including without limitation the rights to use, copy, modify, 6 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | * 9 | * The above copyright notice and this permission notice shall be included in all copies 10 | * or substantial portions of the Software. 11 | * 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 14 | * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 15 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 16 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 17 | * USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | */ 19 | 20 | #ifndef DATA_TABLE_H 21 | #define DATA_TABLE_H 22 | 23 | #include 24 | 25 | #include "accessor.h" 26 | #include "data/types.h" 27 | 28 | #include "sql/common.h" 29 | #include "sql/types/common.h" 30 | 31 | #include "util/result.h" 32 | 33 | /** 34 | * \brief The schema that a table must adhere to. 35 | * 36 | * \detail Table constraints are currently not supported by OpenMemDB 37 | */ 38 | struct TableSchema 39 | { 40 | //! A vector of column definitions according to the SQL standard 41 | std::vector columns; 42 | }; 43 | 44 | using SchemaResult = Result; 45 | 46 | /** 47 | * \brief A struct defining a table stored in the data store. 48 | * 49 | * \detail Holds a wait-free vector of pointers to data records as well as a record counter 50 | * to be used for row identification. 51 | */ 52 | struct DataTable 53 | { 54 | //! The constructor that initializes the record counter to a sane value 55 | DataTable() : records(10000), record_counter(0) {} 56 | ~DataTable() 57 | { 58 | // Remove table contents 59 | int64_t table_len = records.size(0); 60 | if(table_len != 0) 61 | { 62 | for(int64_t i = 0; i < table_len; i++) 63 | { 64 | // Get the current row pointer 65 | ValuePointer* row_ptr; 66 | if(!records.pop_back_w_ra(row_ptr)) 67 | { 68 | delete row_ptr->ptr; 69 | } 70 | else 71 | { 72 | printf("Unable to pop record off of table! Potential memory leak!\n"); 73 | } 74 | } 75 | } 76 | } 77 | 78 | //! The wait-free vector of pointers to the records stored in this table 79 | RecordVector records; 80 | 81 | //! An atomic counter that allows for the database to distinguish between 82 | //! two duplicate records 83 | std::atomic record_counter; 84 | }; 85 | 86 | /** 87 | * \brief A struct that binds a table's schema to its data. 88 | */ 89 | struct SchemaTablePair 90 | { 91 | SchemaTablePair() : table(nullptr), schema(nullptr) {} 92 | SchemaTablePair(DataTable* t, TableSchema* s) 93 | : table(t), schema(s) 94 | {} 95 | 96 | SchemaTablePair(const SchemaTablePair& pair) 97 | : table(pair.table), schema(pair.schema) 98 | {} 99 | 100 | //! The data that adheres to the schema 101 | std::shared_ptr table; 102 | 103 | //! The table's schema 104 | TableSchema* schema; 105 | }; 106 | 107 | #endif 108 | -------------------------------------------------------------------------------- /database/include/data/types.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016 Neil Moore, Jason Stavrinaky, Micheal McGee, Robert Medina 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 4 | * software and associated documentation files (the "Software"), to deal in the Software 5 | * without restriction, including without limitation the rights to use, copy, modify, 6 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | * 9 | * The above copyright notice and this permission notice shall be included in all copies 10 | * or substantial portions of the Software. 11 | * 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 14 | * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 15 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 16 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 17 | * USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | */ 19 | 20 | #ifndef DATA_TYPES_H 21 | #define DATA_TYPES_H 22 | 23 | // STL includes 24 | #include 25 | #include 26 | 27 | // Tervel includes 28 | #include 29 | #include 30 | 31 | // Project includes 32 | #include "accessor.h" 33 | #include "hash_functor.h" 34 | #include "util/types.h" 35 | #include "util/result.h" 36 | 37 | // Some typedefs(C++11-style) so that we don't have all that meaningless 38 | // namespace and template junk pop up everywhere. 39 | 40 | template 41 | using TervelVector = tervel::containers::wf::vector::Vector; 42 | 43 | // Table data definitions 44 | using Record = TervelVector; 45 | 46 | using RecordVector = TervelVector*>; 47 | 48 | using KeyHashFunctor = std::hash; 49 | 50 | // This is just a copy of a record 51 | using RecordData = std::vector; 52 | 53 | /** 54 | * \brief A struct that is a processed copy of a \refer Record object 55 | * 56 | * \detail The processing that's done compared to a raw \refer RecordData is 57 | * that the record ID is popped off the back and stored explicitly. 58 | * 59 | * \note THIS IS FOR INTERNAL USE ONLY! 60 | */ 61 | struct RecordCopy 62 | { 63 | RecordCopy() : id(0) {} 64 | RecordCopy(RecordData&& data) 65 | { 66 | id = data.back().data_value; 67 | data.pop_back(); 68 | this->data = std::move(data); 69 | } 70 | 71 | uint64_t id; 72 | RecordData data; 73 | }; 74 | 75 | struct RecordReference 76 | { 77 | RecordReference() : id(0), ptr(nullptr) {} 78 | RecordReference(uint64_t i, ValuePointer* p) : id(i), ptr(p) {} 79 | 80 | uint64_t id; 81 | ValuePointer* ptr; 82 | }; 83 | 84 | // TODO: Is there a more efficient way? 85 | using MultiRecordData = std::vector; 86 | 87 | /** 88 | * \brief A vector that holds multiple \refer RecordCopy objects 89 | * 90 | * \detail THIS IS FOR INTERNAL USE ONLY! 91 | */ 92 | using MultiRecordCopies = std::vector; 93 | 94 | /** 95 | * \brief A mapping from a table name to a set of \refer RecordCopy objects 96 | * 97 | * \detail THIS IS FOR INTERNAL USE ONLY 98 | */ 99 | using MultiTableRecordCopies = std::map; 100 | 101 | /** 102 | * \brief A vector that holds record ID and references instead of full records 103 | * 104 | * \detail THIS IS FOR INTERNAL USE ONLY 105 | */ 106 | using RecordReferences = std::vector; 107 | 108 | //! A typedef that allows returning multiple sets of records from multiple tables 109 | using MultiTableRecordData = std::map; 110 | 111 | // Some helper typedefs 112 | using ManipResult = Result; 113 | using MultiRecordResult = Result; 114 | using ConstraintResult = Result; 115 | 116 | template<> 117 | struct Result : public ResultBase 118 | { 119 | Result(ResultStatus s, ManipStatus res) 120 | : ResultBase(s, ResultType::COMMAND), result(res), rows_affected(0) 121 | {} 122 | 123 | Result() 124 | : ResultBase(ResultStatus::SUCCESS, ResultType::COMMAND), 125 | result(ManipStatus::SUCCESS), rows_affected(0) 126 | {} 127 | 128 | ManipStatus result; 129 | uint32_t rows_affected; 130 | }; 131 | 132 | template<> 133 | struct Result : public ResultBase 134 | { 135 | Result(ResultStatus s, const RecordData& res) : 136 | ResultBase(s, ResultType::QUERY), result(res) 137 | {} 138 | 139 | RecordData result; 140 | }; 141 | 142 | template<> 143 | struct Result : public ResultBase 144 | { 145 | Result(ResultStatus s, MultiRecordData res) : 146 | ResultBase(s, ResultType::QUERY), result(res) 147 | {} 148 | 149 | Result() 150 | : ResultBase(ResultStatus::SUCCESS, ResultType::QUERY) 151 | {} 152 | 153 | MultiRecordData result; 154 | }; 155 | 156 | #endif 157 | -------------------------------------------------------------------------------- /database/include/sql/common.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016 Neil Moore, Jason Stavrinaky, Micheal McGee, Robert Medina 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 4 | * software and associated documentation files (the "Software"), to deal in the Software 5 | * without restriction, including without limitation the rights to use, copy, modify, 6 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | * 9 | * The above copyright notice and this permission notice shall be included in all copies 10 | * or substantial portions of the Software. 11 | * 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 14 | * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 15 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 16 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 17 | * USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | */ 19 | 20 | #ifndef OMDB_SQL_COMMON_H 21 | #define OMDB_SQL_COMMON_H 22 | 23 | // C standard library includes 24 | #include 25 | 26 | // C++ standard library includes 27 | #include 28 | #include 29 | 30 | // Project includes 31 | #include 32 | #include "statements/expression.h" 33 | 34 | typedef uint16_t SQLSmallIntType; 35 | typedef uint32_t SQLIntegerType; 36 | typedef uint64_t SQLBigIntType; 37 | 38 | // TODO: Redo this enum's naming 39 | enum class SQLConstraintType : uint32_t 40 | { 41 | NO_CONSTRAINT = 0, 42 | NOT_NULL, 43 | DEFAULT, 44 | AUTO_INCREMENT 45 | }; 46 | 47 | /** 48 | * \brief A representation of a SQL constraint. 49 | * 50 | * \detail This covers the following constraints: NOT NULL, DEFAULT, UNIQUE, 51 | * PRIMARY_KEY, FOREIGN_KEY, AUTO_INCREMENT 52 | */ 53 | struct SQLConstraint 54 | { 55 | SQLConstraintType type; 56 | uint16_t column_idx; 57 | TervelData value; 58 | const char* ref_table; 59 | uint16_t ref_column_idx; 60 | }; 61 | 62 | /** 63 | * \brief Representation of a SQL column in a table 64 | */ 65 | struct SQLColumn 66 | { 67 | //! Title of the column 68 | std::string name; 69 | 70 | //! Data type of the data contained in the column 71 | DataType type; 72 | 73 | //! The constraint(s) placed upon the column 74 | std::vector constraint; 75 | }; 76 | 77 | /** 78 | * \brief Representation of an update to a specific column with specific data 79 | */ 80 | struct ColumnUpdate 81 | { 82 | uint32_t column_idx; 83 | TervelData new_data; 84 | }; 85 | 86 | /** 87 | * \brief A reference to a specific column within a table 88 | */ 89 | struct ColumnReference 90 | { 91 | std::string table; 92 | uint32_t column_idx; 93 | }; 94 | 95 | /** 96 | * \brief An enumeration of the various types of SQL statements supported by OpenMemDB 97 | */ 98 | enum class SQLStatement : uint16_t 99 | { 100 | INVALID = 0, 101 | CREATE_TABLE, 102 | DROP_TABLE, 103 | SELECT, 104 | UPDATE, 105 | INSERT_INTO, 106 | DELETE 107 | }; 108 | 109 | enum SQLAsciiUsage 110 | { 111 | SQL_SPACE = 0x1, 112 | SQL_ALPHA = 0x2, 113 | SQL_DIGIT = 0x4, 114 | SQL_ALNUM = (SQL_DIGIT | SQL_ALPHA), 115 | SQL_XDIGIT = 0x8, 116 | SQL_UPPER_ALPHA = 0x20, 117 | SQL_IDENT = 0x40, 118 | SQL_SYMBOL = 0x80, 119 | SQL_NONE = 0x0 120 | }; 121 | 122 | extern const unsigned char sql_ascii_map[256]; 123 | 124 | inline bool isSQLIdentifierChar(unsigned char ch) 125 | { 126 | return (sql_ascii_map[ch] & (SQL_IDENT | SQL_ALNUM)) != 0; 127 | } 128 | 129 | inline bool isSQLAlphabeticChar(unsigned char ch) 130 | { 131 | return (sql_ascii_map[ch] & (SQL_ALPHA)) != 0; 132 | } 133 | 134 | inline bool isSQLSymbolChar(unsigned char ch) 135 | { 136 | return (sql_ascii_map[ch] & SQL_SYMBOL) != 0; 137 | } 138 | 139 | inline bool isSQLNumericChar(unsigned char ch) 140 | { 141 | return (sql_ascii_map[ch] & SQL_DIGIT) != 0; 142 | } 143 | 144 | int strnicmp(const char* left, const char* right, int n); 145 | 146 | void initializeOperationMap(); 147 | 148 | /** 149 | * \brief A base class that implements the nullable property in SQL. 150 | * 151 | * \detail This is core of all the nullable types in SQL and implements some 152 | * helper functions. 153 | */ 154 | class SQLNullable 155 | { 156 | public: 157 | SQLNullable(bool null, bool is_nullable = true) 158 | : m_is_null(null), m_is_nullable(is_nullable) 159 | {} 160 | 161 | bool IsNull() const { return m_is_null;} 162 | 163 | bool IsNullable() const { return m_is_nullable; } 164 | protected: 165 | bool m_is_null; 166 | bool m_is_nullable; 167 | }; 168 | 169 | #endif 170 | -------------------------------------------------------------------------------- /database/include/sql/omdb_parser.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016 Neil Moore, Jason Stavrinaky, Micheal McGee, Robert Medina 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 4 | * software and associated documentation files (the "Software"), to deal in the Software 5 | * without restriction, including without limitation the rights to use, copy, modify, 6 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | * 9 | * The above copyright notice and this permission notice shall be included in all copies 10 | * or substantial portions of the Software. 11 | * 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 14 | * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 15 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 16 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 17 | * USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | */ 19 | 20 | #ifndef SQL_OMDB_PARSER_H 21 | #define SQL_OMDB_PARSER_H 22 | 23 | // C standard library includes 24 | #include 25 | #include 26 | #include 27 | 28 | // C++ standard library includes 29 | #include 30 | 31 | // Project includes 32 | #include "parser/parse.h" 33 | #include "util/result.h" 34 | #include "util/common.h" 35 | #include "statements/common.h" 36 | #include "statements/builder.h" 37 | #include "statements/data_definition.h" 38 | 39 | // Needed for the parser generated by Lemon 40 | typedef uint64_t u64; 41 | 42 | /* TODO: Come back and rework this whole type system. */ 43 | /** 44 | * \brief All the information related to a token needed by the parser 45 | */ 46 | struct TokenPair 47 | { 48 | TokenPair() : token(nullptr), token_type(TK_ILLEGAL) {} 49 | //! The actual token 50 | Token token; 51 | 52 | //! The token type 53 | uint32_t token_type; 54 | }; 55 | 56 | using ParseResult = Result; 57 | 58 | void setupTokenMappings(); 59 | 60 | void token_print(Token token); 61 | 62 | std::vector tokenize(std::string input); 63 | 64 | struct Parse; 65 | 66 | class DataStore; 67 | 68 | ParseResult parse(std::string input, DataStore* data_store); 69 | 70 | #define NEVER(X) 0 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /database/include/sql/parser/parse.h: -------------------------------------------------------------------------------- 1 | #define TK_SEMICOLON 1 2 | #define TK_CREATE 2 3 | #define TK_TABLE 3 4 | #define TK_LPAREN 4 5 | #define TK_RPAREN 5 6 | #define TK_COMMA 6 7 | #define TK_ID 7 8 | #define TK_STRING 8 9 | #define TK_DEFAULT 9 10 | #define TK_NOT 10 11 | #define TK_NULL 11 12 | #define TK_AUTO_INCREMENT 12 13 | #define TK_OR 13 14 | #define TK_AND 14 15 | #define TK_BETWEEN 15 16 | #define TK_IN 16 17 | #define TK_ISNULL 17 18 | #define TK_NOTNULL 18 19 | #define TK_NE 19 20 | #define TK_EQ 20 21 | #define TK_GT 21 22 | #define TK_LE 22 23 | #define TK_LT 23 24 | #define TK_GE 24 25 | #define TK_DOT 25 26 | #define TK_INTEGER 26 27 | #define TK_FLOAT 27 28 | #define TK_DATE 28 29 | #define TK_TIME 29 30 | #define TK_DROP 30 31 | #define TK_SELECT 31 32 | #define TK_DISTINCT 32 33 | #define TK_ALL 33 34 | #define TK_ASTERISK 34 35 | #define TK_AS 35 36 | #define TK_FROM 36 37 | #define TK_WHERE 37 38 | #define TK_UPDATE 38 39 | #define TK_SET 39 40 | #define TK_INSERT 40 41 | #define TK_INTO 41 42 | #define TK_VALUES 42 43 | #define TK_DELETE 43 44 | #define TK_TO_TEXT 44 45 | #define TK_TO_BLOB 45 46 | #define TK_TO_NUMERIC 46 47 | #define TK_TO_INT 47 48 | #define TK_TO_REAL 48 49 | #define TK_ISNOT 49 50 | #define TK_END_OF_FILE 50 51 | #define TK_ILLEGAL 51 52 | #define TK_SPACE 52 53 | #define TK_UNCLOSED_STRING 53 54 | #define TK_FUNCTION 54 55 | #define TK_COLUMN 55 56 | #define TK_AGG_FUNCTION 56 57 | #define TK_AGG_COLUMN 57 58 | #define TK_UMINUS 58 59 | #define TK_UPLUS 59 60 | #define TK_REGISTER 60 61 | -------------------------------------------------------------------------------- /database/include/sql/parser/token.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016 Neil Moore, Jason Stavrinaky, Micheal McGee, Robert Medina 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 4 | * software and associated documentation files (the "Software"), to deal in the Software 5 | * without restriction, including without limitation the rights to use, copy, modify, 6 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | * 9 | * The above copyright notice and this permission notice shall be included in all copies 10 | * or substantial portions of the Software. 11 | * 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 14 | * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 15 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 16 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 17 | * USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | */ 19 | 20 | #ifndef TOKEN_H 21 | #define TOKEN_H 22 | 23 | #include 24 | 25 | #include "util/types.h" 26 | 27 | // TODO: Document this 28 | /** 29 | * \brief A struct that represents a token in a SQL statement 30 | * 31 | * \detail Used by the parser to determine if a SQL statement is valid and/or 32 | * supported by OpenMemDB. 33 | */ 34 | struct TokenData 35 | { 36 | TokenData() 37 | : text(""), is_value(false), is_operation(false), is_column(false) 38 | {} 39 | 40 | TokenData(std::string str) 41 | : text(std::move(str)), is_value(false), is_operation(false), is_column(false) 42 | { 43 | // Special case, the NULL represents a typeless NULL value 44 | value.value = 0; // Initialize the struct to be all 0's 45 | if(text == "NULL") 46 | { 47 | is_value = true; 48 | value = TervelData { .value = 0 }; 49 | value.null = 1; 50 | } 51 | } 52 | 53 | TokenData(std::string str, bool val) 54 | : text(std::move(str)), is_value(true), is_operation(false), is_column(false) 55 | { 56 | value.value = 0; // Initialize the struct to be all 0's 57 | value.type = BOOLEAN; 58 | if(val) 59 | { 60 | value.data_value = 1; 61 | } 62 | else 63 | { 64 | value.data_value = 0; 65 | } 66 | } 67 | 68 | TokenData(std::string str, int16_t val) 69 | : text(std::move(str)), is_value(true), is_operation(false), is_column(false) 70 | { 71 | value.value = 0; // Initialize the struct to be all 0's 72 | value.type = SMALL_INT; 73 | value.data_value = val; 74 | } 75 | 76 | TokenData(std::string str, int32_t val) 77 | : text(std::move(str)), is_value(true), is_operation(false), is_column(false) 78 | { 79 | value.value = 0; // Initialize the struct to be all 0's 80 | value.type = INTEGER; 81 | value.data_value = val; 82 | } 83 | 84 | TokenData(std::string str, int64_t val) 85 | : text(std::move(str)), is_value(true), is_operation(false), is_column(false) 86 | { 87 | value.value = 0; // Initialize the struct to be all 0's 88 | value.type = BIG_INT; 89 | value.data_value = val; 90 | } 91 | 92 | TokenData(std::string str, float val) 93 | : text(std::move(str)), is_value(true), is_operation(false), is_column(false) 94 | { 95 | value.value = 0; // Initialize the struct to be all 0's 96 | value.type = FLOAT; 97 | value.data_value = static_cast(val); 98 | } 99 | 100 | TokenData(std::string str, std::string table, std::string column) 101 | : text(std::move(str)), is_value(false), is_operation(false), is_column(true), 102 | table_name(std::move(table)), column_name(std::move(column)) 103 | {} 104 | 105 | std::string text; 106 | 107 | bool is_value; 108 | TervelData value; 109 | 110 | bool is_operation; 111 | uint16_t operation; 112 | 113 | bool is_column; 114 | std::string table_name; 115 | std::string column_name; 116 | }; 117 | 118 | /** 119 | * \brief The datatype passed into the parser from the tokenizer 120 | */ 121 | typedef TokenData* Token; 122 | 123 | #endif 124 | -------------------------------------------------------------------------------- /database/include/sql/predicate.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016 Neil Moore, Jason Stavrinaky, Micheal McGee, Robert Medina 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 4 | * software and associated documentation files (the "Software"), to deal in the Software 5 | * without restriction, including without limitation the rights to use, copy, modify, 6 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | * 9 | * The above copyright notice and this permission notice shall be included in all copies 10 | * or substantial portions of the Software. 11 | * 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 14 | * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 15 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 16 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 17 | * USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | */ 19 | 20 | #ifndef SQL_PREDICATE_H 21 | #define SQL_PREDICATE_H 22 | 23 | #include "statements/common.h" 24 | #include "statements/expression.h" 25 | 26 | class DataStore; 27 | 28 | /* TODO: Consider moving this to a static heap to prevent dealing with 29 | * dynamic memory allocation errors and their propagation. 30 | */ 31 | 32 | enum class PredicateType : uint8_t { 33 | NESTED = 0, 34 | VALUE, 35 | COLUMN 36 | }; 37 | 38 | // TODO: Document this 39 | class ExpressionValue 40 | { 41 | public: 42 | ExpressionValue() : is_range(false) {} 43 | ExpressionValue(TervelData value) : is_range(false), value(value) {} 44 | ExpressionValue(TervelData start, TervelData end) 45 | : is_range(true), range_start(start), range_end(end) 46 | {} 47 | 48 | bool is_range; 49 | 50 | TervelData getValue() { return value; } 51 | DataRange getRange() { return (DataRange){range_start, range_end}; } 52 | 53 | private: 54 | TervelData value; 55 | TervelData range_start; 56 | TervelData range_end; 57 | }; 58 | 59 | SQLBoolean operator==(ExpressionValue& lhs, ExpressionValue& rhs); 60 | SQLBoolean operator!=(ExpressionValue& lhs, ExpressionValue& rhs); 61 | 62 | // TODO: Document this 63 | struct Predicate 64 | { 65 | public: 66 | Predicate(PredicateType type) 67 | : type(type), op(ExpressionOperation::NO_OP) 68 | {} 69 | 70 | PredicateType type; 71 | ExpressionOperation op; 72 | }; 73 | 74 | // TODO: Document this 75 | struct NestedPredicate : public Predicate 76 | { 77 | public: 78 | NestedPredicate() 79 | : Predicate(PredicateType::NESTED), 80 | left_child(nullptr), right_child(nullptr) 81 | {} 82 | 83 | ~NestedPredicate() 84 | { 85 | delete left_child; 86 | delete right_child; 87 | } 88 | 89 | Predicate* left_child; 90 | Predicate* right_child; 91 | }; 92 | 93 | // TODO: Document this 94 | struct ValuePredicate : public Predicate 95 | { 96 | public: 97 | ValuePredicate() 98 | : Predicate(PredicateType::VALUE) 99 | {} 100 | 101 | ColumnReference column; 102 | ExpressionValue expected_value; 103 | }; 104 | 105 | // TODO: Document this 106 | struct ColumnPredicate : public Predicate 107 | { 108 | public: 109 | ColumnPredicate() 110 | : Predicate(PredicateType::COLUMN) 111 | {} 112 | 113 | ColumnReference left_column; 114 | ColumnReference right_column; 115 | }; 116 | 117 | Predicate* getPredicateFromExpression(Expression* expr, DataStore* data_store); 118 | 119 | void setupStatement(ParsedStatement* statement, Expression* expr, DataStore* data_store); 120 | 121 | SQLBoolean evaluateOperation(ExpressionOperation op, ExpressionValue lhs, ExpressionValue rhs); 122 | 123 | #endif 124 | -------------------------------------------------------------------------------- /database/include/sql/statements/builder.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016 Neil Moore, Jason Stavrinaky, Micheal McGee, Robert Medina 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 4 | * software and associated documentation files (the "Software"), to deal in the Software 5 | * without restriction, including without limitation the rights to use, copy, modify, 6 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | * 9 | * The above copyright notice and this permission notice shall be included in all copies 10 | * or substantial portions of the Software. 11 | * 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 14 | * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 15 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 16 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 17 | * USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | */ 19 | 20 | #ifndef SQL_BUILDER_H 21 | #define SQL_BUILDER_H 22 | 23 | // C++ standard library includes 24 | #include 25 | 26 | // C standard library includes 27 | #include 28 | 29 | // Project includes 30 | #include "../common.h" 31 | #include "data_definition.h" 32 | #include "data_manipulation.h" 33 | 34 | #include "util/types.h" 35 | 36 | // Forward declaration 37 | class DataStore; 38 | 39 | /** 40 | * \brief The object that assists the parser in converting SQL statements into an 41 | * internal representation suitable for execution by the database. 42 | */ 43 | struct StatementBuilder 44 | { 45 | StatementBuilder() 46 | : started(false), valid(false), statement(nullptr), 47 | expr(nullptr) 48 | {} 49 | 50 | //! If true then the builder is in the middle of building a statement 51 | bool started; 52 | 53 | //! If true, then the builder's parsed statement is valid SQL 54 | bool valid; 55 | 56 | //! Vector to temporarily hold a columns' constraints. 57 | std::vector temp_constraints; 58 | 59 | //! The internal representation of a SQL statement 60 | ParsedStatement* statement; 61 | 62 | //! The expression tree generated by the parser 63 | Expression* expr; 64 | 65 | //! A reference to the current \refer DataStore object 66 | DataStore* data_store; 67 | }; 68 | 69 | // Table management functions 70 | void builderStartCreateTable(StatementBuilder* builder, Token table_name); 71 | void builderStartDropTable(StatementBuilder* builder, Token table_name); 72 | void builderAddColumnConstraint(StatementBuilder* builder, SQLConstraintType type, 73 | Token value = nullptr); 74 | 75 | // Query management function 76 | void builderStartSelectQuery(StatementBuilder* builder); 77 | void builderAddSelectAllColumns(StatementBuilder* builder, Token table); 78 | void builderAddQualifiedSelectColumn(StatementBuilder* builder, 79 | Token table, Token source_column, 80 | Token output_column); 81 | void builderFinishSelectQuery(StatementBuilder* builder); 82 | 83 | // Insert command functions 84 | void builderStartInsertCommand(StatementBuilder* builder); 85 | void builderAddDataItem(StatementBuilder* builder, Token data); 86 | void builderFinishInsertcommand(StatementBuilder* builder); 87 | 88 | // Update command functions 89 | void builderStartUpdateCommand(StatementBuilder* builder); 90 | void builderAddUpdateExpr(StatementBuilder* builder, Token operation, 91 | Token left, Token right); 92 | void builderFinishUpdateCommand(StatementBuilder* builder); 93 | 94 | // Somewhat generic helper functions 95 | void builderAddColumn(StatementBuilder* builder, 96 | Token column_name, 97 | Token column_type, 98 | Token column_constraints); 99 | void builderAddColumnName(StatementBuilder* builder, Token column_name); 100 | void builderAddColumnType(StatementBuilder* builder, Token column_type); 101 | void builderAddTableName(StatementBuilder* builder, Token table_name); 102 | void builderStartNestedExpr(StatementBuilder* builder, Token operation); 103 | void builderAddValueExpr(StatementBuilder* builder, 104 | Token operation, Token left_term, Token right_term); 105 | 106 | // Overall builder management 107 | void builderClean(StatementBuilder* builder); 108 | 109 | #endif 110 | -------------------------------------------------------------------------------- /database/include/sql/statements/common.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016 Neil Moore, Jason Stavrinaky, Micheal McGee, Robert Medina 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 4 | * software and associated documentation files (the "Software"), to deal in the Software 5 | * without restriction, including without limitation the rights to use, copy, modify, 6 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | * 9 | * The above copyright notice and this permission notice shall be included in all copies 10 | * or substantial portions of the Software. 11 | * 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 14 | * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 15 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 16 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 17 | * USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | */ 19 | 20 | #ifndef SQL_STMT_COMMON_H 21 | #define SQL_STMT_COMMON_H 22 | 23 | #include "sql/types/common.h" 24 | 25 | /** 26 | * \brief Base type of all SQL statement types that defines the type 27 | * and some useful metadata. 28 | */ 29 | class ParsedStatement 30 | { 31 | public: 32 | ParsedStatement(SQLStatement type) : type(type) {} 33 | 34 | //! The type of SQL statement that this struct represents 35 | SQLStatement type; 36 | 37 | //! The amount of time that has elapsed in the processing of this statement. 38 | uint32_t time_elapsed; 39 | }; 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /database/include/sql/statements/data_definition.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016 Neil Moore, Jason Stavrinaky, Micheal McGee, Robert Medina 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 4 | * software and associated documentation files (the "Software"), to deal in the Software 5 | * without restriction, including without limitation the rights to use, copy, modify, 6 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | * 9 | * The above copyright notice and this permission notice shall be included in all copies 10 | * or substantial portions of the Software. 11 | * 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 14 | * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 15 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 16 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 17 | * USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | */ 19 | 20 | #ifndef DATA_DEF_H 21 | #define DATA_DEF_H 22 | 23 | // C++ standard library includes 24 | #include 25 | #include 26 | 27 | // Project includes 28 | #include "sql/common.h" 29 | #include "sql/statements/common.h" 30 | #include "util/types.h" 31 | 32 | /** 33 | * \brief A struct that holds internal data comprising a CREATE TABLE statement 34 | */ 35 | struct CreateTableCommand : public ParsedStatement 36 | { 37 | CreateTableCommand() : ParsedStatement(SQLStatement::CREATE_TABLE) {} 38 | std::string table_name; 39 | std::vector columns; 40 | }; 41 | 42 | /** 43 | * /brief A struct that holds internal data comprising a DROP TABLE statement 44 | */ 45 | struct DropTableCommand : public ParsedStatement 46 | { 47 | DropTableCommand() : ParsedStatement(SQLStatement::DROP_TABLE) {} 48 | std::string table_name; 49 | }; 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /database/include/sql/statements/data_manipulation.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016 Neil Moore, Jason Stavrinaky, Micheal McGee, Robert Medina 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 4 | * software and associated documentation files (the "Software"), to deal in the Software 5 | * without restriction, including without limitation the rights to use, copy, modify, 6 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | * 9 | * The above copyright notice and this permission notice shall be included in all copies 10 | * or substantial portions of the Software. 11 | * 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 14 | * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 15 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 16 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 17 | * USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | */ 19 | 20 | #ifndef DATA_MANIP_H 21 | #define DATA_MANIP_H 22 | 23 | // STL Includes 24 | #include 25 | #include 26 | 27 | // Project includes 28 | #include "data/table.h" 29 | 30 | #include "util/types.h" 31 | 32 | #include "sql/common.h" 33 | #include "sql/predicate.h" 34 | #include "sql/statements/common.h" 35 | 36 | /** 37 | * \brief A struct that holds internal data comprising a SELECT query 38 | */ 39 | struct SelectQuery : public ParsedStatement 40 | { 41 | SelectQuery() : ParsedStatement(SQLStatement::SELECT), predicate(nullptr) {} 42 | 43 | ~SelectQuery() 44 | { 45 | if(predicate) 46 | { 47 | switch (predicate->type) 48 | { 49 | case PredicateType::NESTED: 50 | delete reinterpret_cast(predicate); 51 | break; 52 | default: 53 | delete predicate; 54 | break; 55 | } 56 | } 57 | } 58 | 59 | //! Vector of columns in the source table that are targeted 60 | std::vector source_columns; 61 | 62 | //! Tables that are targeted in this query 63 | std::vector tables; 64 | 65 | //! Names of output columns 66 | std::vector output_columns; 67 | 68 | //! The binary expression tree that determines which rows are selected 69 | Predicate* predicate; 70 | }; 71 | 72 | /** 73 | * \brief A struct that holds internal data comprising a INSERT INTO statement 74 | */ 75 | struct InsertCommand : public ParsedStatement 76 | { 77 | InsertCommand() : ParsedStatement(SQLStatement::INSERT_INTO) {} 78 | 79 | //! The vector of data that represents the row being inserted 80 | std::vector data; 81 | 82 | //! The table that's being inserted into 83 | std::string table; 84 | }; 85 | 86 | /** 87 | * \brief A struct that holds internal data comprising a UPDATE statement 88 | */ 89 | struct UpdateCommand : public ParsedStatement 90 | { 91 | UpdateCommand() : ParsedStatement(SQLStatement::UPDATE) {} 92 | 93 | //! The name of the target table 94 | std::string table; 95 | 96 | //! The schema of the target table 97 | TableSchema table_schema; 98 | 99 | //! The columns to be updated and their data 100 | std::vector columns; 101 | 102 | //! A full record 103 | RecordData full_record; 104 | 105 | //! The binary expression that determines which records are operated on 106 | Predicate* predicate; 107 | 108 | //! Is actually executable by the SQL Engine 109 | bool runnable; 110 | }; 111 | 112 | /** 113 | * \brief A struct that holds internal data comprising a DELETE statement 114 | */ 115 | struct DeleteCommand : public ParsedStatement 116 | { 117 | DeleteCommand() : ParsedStatement(SQLStatement::DELETE) {} 118 | 119 | //! Name of the table to be operated on 120 | std::string table; 121 | 122 | //! The binary expression tree that determines which records are deleted 123 | Predicate* predicate; 124 | }; 125 | 126 | #endif 127 | -------------------------------------------------------------------------------- /database/include/sql/statements/expression.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016 Neil Moore, Jason Stavrinaky, Micheal McGee, Robert Medina 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 4 | * software and associated documentation files (the "Software"), to deal in the Software 5 | * without restriction, including without limitation the rights to use, copy, modify, 6 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | * 9 | * The above copyright notice and this permission notice shall be included in all copies 10 | * or substantial portions of the Software. 11 | * 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 14 | * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 15 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 16 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 17 | * USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | */ 19 | 20 | #ifndef EXPRESSION_H 21 | #define EXPRESSION_H 22 | 23 | #include 24 | 25 | #include "sql/parser/token.h" 26 | #include "util/types.h" 27 | 28 | enum class ExpressionFlags : uint32_t 29 | { 30 | EMPTY = 0x0, 31 | COLUMN = 0x1, 32 | VALUE = 0x2, 33 | OPERATION = 0x4, 34 | NESTED = 0x8 35 | }; 36 | 37 | ExpressionFlags operator|(ExpressionFlags a, ExpressionFlags b); 38 | ExpressionFlags operator&(ExpressionFlags a, ExpressionFlags b); 39 | 40 | bool isExprFlagContained(ExpressionFlags a, ExpressionFlags b); 41 | 42 | enum class ExpressionOperation : uint16_t 43 | { 44 | NO_OP = 0, 45 | EQUALS, 46 | NOT_EQUALS, 47 | LESSER, 48 | LESSER_EQUALS, 49 | GREATER, 50 | GREATER_EQUALS, 51 | IN, 52 | BETWEEN, 53 | AND, 54 | OR 55 | }; 56 | 57 | struct Expression 58 | { 59 | Expression(); 60 | Expression(Token tok); 61 | 62 | ~Expression(); 63 | 64 | Expression* left; 65 | Expression* right; 66 | ExpressionOperation op; 67 | 68 | ExpressionFlags flags; 69 | 70 | std::string table_name; 71 | std::string table_column; 72 | 73 | DataType value_type; 74 | TervelData value; 75 | }; 76 | 77 | ExpressionOperation getOperation(std::string op); 78 | 79 | std::string getOperationString(ExpressionOperation op); 80 | 81 | void printExpressionTree(Expression* expr, int indent = 0); 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /database/include/sql/types/boolean.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016 Neil Moore, Jason Stavrinaky, Micheal McGee, Robert Medina 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 4 | * software and associated documentation files (the "Software"), to deal in the Software 5 | * without restriction, including without limitation the rights to use, copy, modify, 6 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | * 9 | * The above copyright notice and this permission notice shall be included in all copies 10 | * or substantial portions of the Software. 11 | * 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 14 | * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 15 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 16 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 17 | * USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | */ 19 | 20 | #ifndef OMDB_BOOLEAN_H 21 | #define OMDB_BOOLEAN_H 22 | 23 | #include 24 | 25 | #include 26 | 27 | enum BooleanValue : uint8_t 28 | { 29 | SQL_FALSE = 0, 30 | SQL_TRUE = 1, 31 | SQL_UNKNOWN = 2 32 | }; 33 | 34 | class SQLBoolean : public SQLNullable 35 | { 36 | public: 37 | SQLBoolean(); 38 | SQLBoolean(const SQLBoolean& other); 39 | SQLBoolean(SQLBoolean& other); 40 | SQLBoolean(bool value); 41 | SQLBoolean(TervelData value); 42 | SQLBoolean(BooleanValue value); 43 | SQLBoolean(BooleanValue value, bool nullable); 44 | 45 | //! Stores the tri-state boolean value. 46 | BooleanValue m_value; 47 | 48 | SQLBoolean& operator=(SQLBoolean other); 49 | 50 | bool IsUnknown() const; 51 | bool IsTrue() const; 52 | private: 53 | }; 54 | 55 | SQLBoolean operator!(SQLBoolean value); 56 | SQLBoolean operator||(const SQLBoolean& lhs, const SQLBoolean& rhs); 57 | SQLBoolean operator&&(const SQLBoolean& lhs, const SQLBoolean& rhs); 58 | 59 | SQLBoolean operator==(const SQLBoolean& lhs, const SQLBoolean& rhs); 60 | SQLBoolean operator!=(const SQLBoolean& lhs, const SQLBoolean& rhs); 61 | 62 | SQLBoolean operator>(const SQLBoolean& lhs, const SQLBoolean& rhs); 63 | SQLBoolean operator>=(const SQLBoolean& lhs, const SQLBoolean& rhs); 64 | 65 | SQLBoolean operator<(const SQLBoolean& lhs, const SQLBoolean& rhs); 66 | SQLBoolean operator<=(const SQLBoolean& lhs, const SQLBoolean& rhs); 67 | 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /database/include/sql/types/character.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | 5 | #ifndef SQL_CHARACTER_H 6 | #define SQL_CHARACTER_H 7 | 8 | // Project-specific includes 9 | #include 10 | #include 11 | 12 | template 13 | class SQLCharacter : public SQLNullable 14 | { 15 | public: 16 | SQLCharacter() 17 | : SQLNullable(true, true), m_string(nullptr), m_size(0) 18 | {} 19 | 20 | SQLCharacter(const SQLCharacter& other) 21 | : SQLNullable(false, other.IsNullable()), m_size(other.m_size) 22 | { 23 | // TODO: Error handling 24 | m_string = new T[m_size]; 25 | memcpy(m_string, other.m_string, sizeof(T) * m_size); 26 | } 27 | 28 | SQLCharacter(T* orig, uint32_t size, bool nullable = true) 29 | : SQLNullable(false, nullable), m_size(size), m_string(nullptr) 30 | { 31 | // TODO: Error handling 32 | m_string = new T[size]; 33 | memcpy(m_string, orig, sizeof(T) * size); 34 | } 35 | 36 | uint32_t m_size; 37 | T* m_string; 38 | 39 | SQLInteger length(); 40 | 41 | void concat(const SQLCharacter& other); 42 | static SQLCharacter concat(const SQLCharacter& lhs, const SQLCharacter& rhs); 43 | 44 | SQLCharacter substr(size_t start_pos, size_t len); 45 | static SQLCharacter substr(const SQLCharacter& str, size_t start_pos, size_t len); 46 | }; 47 | 48 | typedef SQLCharacter SQLCharacterASCII; 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /database/include/sql/types/common.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016 Neil Moore, Jason Stavrinaky, Micheal McGee, Robert Medina 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 4 | * software and associated documentation files (the "Software"), to deal in the Software 5 | * without restriction, including without limitation the rights to use, copy, modify, 6 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | * 9 | * The above copyright notice and this permission notice shall be included in all copies 10 | * or substantial portions of the Software. 11 | * 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 14 | * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 15 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 16 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 17 | * USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | */ 19 | 20 | #ifndef SQL_TYPES_COMMON_H 21 | #define SQL_TYPES_COMMON_H 22 | 23 | #include "boolean.h" 24 | #include "datetime.h" 25 | #include "exact_numeric.h" 26 | 27 | enum SQLTypes 28 | { 29 | //SQL_NONE = 0, redeclaration error when both common.h files are included 30 | SQL_BOOLEAN = 1, 31 | SQL_SMALLINT, 32 | SQL_INTEGER, 33 | SQL_BIGINT, 34 | SQL_DATE, 35 | SQL_TIME, 36 | SQL_TIMESTAMP 37 | }; 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /database/include/sql/types/datetime.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016 Neil Moore, Jason Stavrinaky, Micheal McGee, Robert Medina 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 4 | * software and associated documentation files (the "Software"), to deal in the Software 5 | * without restriction, including without limitation the rights to use, copy, modify, 6 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | * 9 | * The above copyright notice and this permission notice shall be included in all copies 10 | * or substantial portions of the Software. 11 | * 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 14 | * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 15 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 16 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 17 | * USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | */ 19 | 20 | #ifndef OMDB_DATETIME_H 21 | #define OMDB_DATETIME_H 22 | 23 | // Standard Library includes 24 | #include 25 | #include 26 | 27 | // Project-specific includes 28 | #include 29 | #include 30 | 31 | #include 32 | 33 | class SQLTimestamp; 34 | 35 | /** 36 | * \brief Representation of the SQL:2003 DATE data type 37 | */ 38 | class SQLDate : public SQLNullable 39 | { 40 | public: 41 | SQLDate(); 42 | SQLDate(const SQLDate& other); 43 | SQLDate(uint16_t year, uint8_t month, uint8_t day, bool nullable = true); 44 | SQLDate(TervelData value); 45 | 46 | //! Year 47 | uint16_t m_year; 48 | 49 | //! Month in the year 50 | uint8_t m_month; 51 | 52 | //! Day in the month 53 | uint8_t m_day; 54 | 55 | bool IsValid(); 56 | 57 | SQLDate& operator=(SQLDate& other); 58 | }; 59 | 60 | SQLBoolean operator==(const SQLDate& lhs, const SQLDate& rhs); 61 | SQLBoolean operator!=(const SQLDate& lhs, const SQLDate& rhs); 62 | 63 | SQLBoolean operator< (const SQLDate& lhs, const SQLDate& rhs); 64 | SQLBoolean operator<=(const SQLDate& lhs, const SQLDate& rhs); 65 | 66 | SQLBoolean operator> (const SQLDate& lhs, const SQLDate& rhs); 67 | SQLBoolean operator>=(const SQLDate& lhs, const SQLDate& rhs); 68 | 69 | /** 70 | * \brief Representation of the SQL:2003 TIME data type 71 | */ 72 | class SQLTime : public SQLNullable 73 | { 74 | public: 75 | SQLTime(); 76 | SQLTime(const SQLTime& time); 77 | SQLTime(uint16_t hour, uint16_t minute, uint32_t second, bool nullable = true); 78 | SQLTime(TervelData value); 79 | 80 | //! Hour of the day 81 | uint16_t m_hour; 82 | 83 | //! Minute of the hour 84 | uint16_t m_minute; 85 | 86 | //! Second of the minute 87 | uint32_t m_second; 88 | // TODO: Fraction of second support 89 | 90 | //! Timezone displacement from UTC in hours 91 | int16_t m_tz_hour; 92 | 93 | //! Amount of timezone displacement from UTC within hour. 94 | int16_t m_tz_minute; 95 | 96 | //! Time zone displacement is set if true 97 | bool m_with_timezone; 98 | 99 | void SetTimeZoneDisplacement(uint16_t hours, uint16_t minutes); 100 | 101 | bool IsValid(); 102 | 103 | SQLTime& operator=(SQLTime& other); 104 | }; 105 | 106 | SQLBoolean operator==(const SQLTime& lhs, const SQLTime& rhs); 107 | SQLBoolean operator!=(const SQLTime& lhs, const SQLTime& rhs); 108 | 109 | SQLBoolean operator< (const SQLTime& lhs, const SQLTime& rhs); 110 | SQLBoolean operator<=(const SQLTime& lhs, const SQLTime& rhs); 111 | 112 | SQLBoolean operator> (const SQLTime& lhs, const SQLTime& rhs); 113 | SQLBoolean operator>=(const SQLTime& lhs, const SQLTime& rhs); 114 | 115 | #endif 116 | -------------------------------------------------------------------------------- /database/include/sql/types/exact_numeric.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016 Neil Moore, Jason Stavrinaky, Micheal McGee, Robert Medina 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 4 | * software and associated documentation files (the "Software"), to deal in the Software 5 | * without restriction, including without limitation the rights to use, copy, modify, 6 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | * 9 | * The above copyright notice and this permission notice shall be included in all copies 10 | * or substantial portions of the Software. 11 | * 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 14 | * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 15 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 16 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 17 | * USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | */ 19 | 20 | #ifndef SQL_EXACT_NUMERIC_H 21 | #define SQL_EXACT_NUMERIC_H 22 | 23 | // Project-specific includes 24 | #include 25 | #include 26 | 27 | #include 28 | 29 | template 30 | class SQLExactNumeric : public SQLNullable 31 | { 32 | public: 33 | SQLExactNumeric() 34 | : SQLNullable(true, true), m_data(0) {} 35 | 36 | SQLExactNumeric(const SQLExactNumeric& other) 37 | : SQLNullable(false, other.IsNullable()), m_data(other.m_data) {} 38 | 39 | SQLExactNumeric(T value, bool nullable = true) 40 | : SQLNullable(false, nullable), m_data(value) {} 41 | 42 | SQLExactNumeric(TervelData value) 43 | : SQLNullable(false, true) 44 | { 45 | if(value.null == 1) 46 | { 47 | m_is_null = true; 48 | return; 49 | } 50 | 51 | switch(value.type) 52 | { 53 | case SMALL_INT: 54 | if(sizeof(T) == sizeof(SQLSmallIntType)) 55 | { 56 | ShortData short_data = static_cast(value.data_value); 57 | m_data = short_data.value; 58 | } 59 | else 60 | { 61 | m_is_null = true; 62 | } 63 | break; 64 | case INTEGER: 65 | if(sizeof(T) == sizeof(SQLIntegerType)) 66 | { 67 | IntData int_data = static_cast(value.data_value); 68 | m_data = int_data.value; 69 | } 70 | else 71 | { 72 | m_is_null = true; 73 | } 74 | break; 75 | case BIG_INT: 76 | if(sizeof(T) == sizeof(SQLBigIntType)) 77 | { 78 | m_data = value.data_value; 79 | } 80 | else 81 | { 82 | m_is_null = true; 83 | } 84 | break; 85 | // Incompatible types, set to null 86 | case FLOAT: 87 | case DATE: 88 | case TIME: 89 | case BOOLEAN: 90 | default: 91 | m_is_null = true; 92 | break; 93 | } 94 | } 95 | 96 | T m_data; 97 | 98 | SQLExactNumeric& operator=(const SQLExactNumeric& other) 99 | { 100 | this->m_data = other.m_data; 101 | 102 | return *this; 103 | } 104 | }; 105 | 106 | template 107 | SQLBoolean operator==(const SQLExactNumeric& lhs, SQLExactNumeric& rhs) 108 | { 109 | if(lhs.IsNull() || rhs.IsNull()) 110 | { 111 | return SQLBoolean(SQL_UNKNOWN); 112 | } 113 | 114 | if(lhs.m_data == rhs.m_data) 115 | { 116 | return SQLBoolean(SQL_TRUE); 117 | } 118 | else 119 | { 120 | return SQLBoolean(SQL_FALSE); 121 | } 122 | } 123 | 124 | template 125 | SQLBoolean operator!=(const SQLExactNumeric& lhs, const SQLExactNumeric& rhs) 126 | { 127 | return !(lhs == rhs); 128 | } 129 | 130 | // Integer types 131 | typedef SQLExactNumeric SQLSmallInt; 132 | typedef SQLExactNumeric SQLInteger; 133 | typedef SQLExactNumeric SQLBigInt; 134 | 135 | #endif 136 | -------------------------------------------------------------------------------- /database/include/util/common.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016 Neil Moore, Jason Stavrinaky, Micheal McGee, Robert Medina 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 4 | * software and associated documentation files (the "Software"), to deal in the Software 5 | * without restriction, including without limitation the rights to use, copy, modify, 6 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | * 9 | * The above copyright notice and this permission notice shall be included in all copies 10 | * or substantial portions of the Software. 11 | * 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 14 | * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 15 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 16 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 17 | * USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | */ 19 | 20 | #ifndef UTIL_COMMON_H 21 | #define UTIL_COMMON_H 22 | 23 | #include 24 | 25 | #include "packets.h" 26 | 27 | bool checkDateFormat(std::string str); 28 | 29 | void serializeMetaDataPacket(ResultMetaDataPacket packet, char* out_buffer); 30 | void serializeResultPacket(ResultPacket packet, char* out_buffer); 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /database/include/util/network/common.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016 Neil Moore, Jason Stavrinaky, Micheal McGee, Robert Medina 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 4 | * software and associated documentation files (the "Software"), to deal in the Software 5 | * without restriction, including without limitation the rights to use, copy, modify, 6 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | * 9 | * The above copyright notice and this permission notice shall be included in all copies 10 | * or substantial portions of the Software. 11 | * 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 14 | * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 15 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 16 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 17 | * USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | */ 19 | 20 | #ifndef UTIL_NET_COMMON_H 21 | #define UTIL_NET_COMMON_H 22 | 23 | // Standard Library includes 24 | #include 25 | #include 26 | 27 | // Linux-specific includes 28 | #include 29 | #include 30 | #include 31 | 32 | #define CONN_BACKLOG 20 33 | 34 | namespace omdb 35 | { 36 | /** 37 | * @brief Enumeration of error classifications 38 | * 39 | * TODO: This should be split into two enums, one for broad categories and 40 | * one for specific errors within those categories 41 | */ 42 | enum NetworkStatusCodes 43 | { 44 | D_RECV_PART = 4, 45 | D_SEND_PART = 3, 46 | D_RECV_FULL = 2, 47 | D_SEND_FULL = 1, 48 | SUCCESS = 0, 49 | E_INV_PARAM = -1, 50 | E_ADDRINFO = -2, 51 | E_SOCKET = -3, 52 | E_BIND = -4, 53 | E_LISTEN = -5, 54 | E_ACCEPT = -6, 55 | E_SEND = -7, 56 | E_RECV = -8, 57 | E_CLOSE = -9 58 | }; 59 | 60 | /** 61 | * @brief Struct to wrap both project-specific errors and platform errors. 62 | * 63 | * @detail The status code is the overarching code that determines whether 64 | * the secondary code should be considered a platform error or a 65 | * project-specific error. 66 | */ 67 | struct NetworkStatus 68 | { 69 | NetworkStatus(uint32_t code = NetworkStatusCodes::SUCCESS, 70 | int32_t sec_code = 0) 71 | : status_code(code), secondary_code(sec_code) 72 | {} 73 | 74 | /** 75 | * The status code used to classify errors. 76 | */ 77 | int32_t status_code; 78 | 79 | /** 80 | * The platform error code or a subclassification 81 | * of the project-specific status code. 82 | */ 83 | int32_t secondary_code; 84 | }; 85 | 86 | NetworkStatus ListenToPort(uint16_t port_id, 87 | uint32_t* socket_fd, 88 | bool dont_block = true); 89 | 90 | NetworkStatus AcceptConnection(uint32_t socket_fd, 91 | uint32_t* conn_fd, 92 | sockaddr_storage* conn_addr); 93 | } 94 | 95 | #endif 96 | -------------------------------------------------------------------------------- /database/include/util/network/connection.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016 Neil Moore, Jason Stavrinaky, Micheal McGee, Robert Medina 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 4 | * software and associated documentation files (the "Software"), to deal in the Software 5 | * without restriction, including without limitation the rights to use, copy, modify, 6 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | * 9 | * The above copyright notice and this permission notice shall be included in all copies 10 | * or substantial portions of the Software. 11 | * 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 14 | * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 15 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 16 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 17 | * USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | */ 19 | 20 | #ifndef UTIL_NET_CONN_H 21 | #define UTIL_NET_CONN_H 22 | 23 | // Standard Library includes 24 | #include 25 | 26 | // Linux-specific includes 27 | #include 28 | 29 | // Project includes 30 | #include 31 | 32 | namespace omdb 33 | { 34 | /** 35 | * @brief This class represents a connection between this application 36 | * and one of its clients. 37 | * 38 | * @note The amount of abstraction done by this class has not been decided yet. 39 | */ 40 | class Connection 41 | { 42 | public: 43 | Connection(); 44 | Connection(int32_t socket_fd, sockaddr_storage conn_info); 45 | 46 | ~Connection(); 47 | 48 | bool IsValid(); 49 | 50 | void close(); 51 | 52 | NetworkStatus send(const char* in_buffer, size_t length); 53 | 54 | NetworkStatus recv(char* out_buffer, size_t length); 55 | 56 | private: 57 | //! Holds the validity of this connection(valid socket, active connection, etc.). 58 | bool m_is_valid; 59 | 60 | //! The raw socket file descriptor 61 | uint32_t m_socket_fd; 62 | 63 | //! Holds miscellaneous information about the connected peer. 64 | sockaddr_storage m_conn_info; 65 | }; 66 | } 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /database/include/util/omdb_stdlib.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016 Neil Moore, Jason Stavrinaky, Micheal McGee, Robert Medina 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 4 | * software and associated documentation files (the "Software"), to deal in the Software 5 | * without restriction, including without limitation the rights to use, copy, modify, 6 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | * 9 | * The above copyright notice and this permission notice shall be included in all copies 10 | * or substantial portions of the Software. 11 | * 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 14 | * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 15 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 16 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 17 | * USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | */ 19 | 20 | #ifndef UTIL_STDLIB_H 21 | #define UTIL_STDLIB_H 22 | 23 | // C++ includes 24 | #include 25 | #include 26 | 27 | // C includes 28 | #include 29 | 30 | /** 31 | * \brief Implements a safe advancement of the given iterator over a specified distance 32 | * 33 | * \return True if the advance is safe, false if it fails. 34 | */ 35 | template 36 | bool safe_advance(T& itr, const T end, size_t distance) 37 | { 38 | typedef typename std::iterator_traits::iterator_category tag; 39 | static_assert(std::is_base_of::value, 40 | "Iterators passed to safe_advance must be forward iterators"); 41 | 42 | while(itr != end && distance > 0) 43 | { 44 | itr++; 45 | distance--; 46 | } 47 | 48 | // If this returns true, then the iterator never reached end 49 | // Else it reached end early 50 | return (distance == 0); 51 | } 52 | 53 | void setSignalHandler(int signal, std::function handler_functor); 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /database/include/util/packets.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by mike on 1/14/16. 3 | // 4 | 5 | #ifndef OPENMEMDB_LIBOMDB_H 6 | #define OPENMEMDB_LIBOMDB_H 7 | 8 | // C++ stdlib include 9 | #include 10 | 11 | // Project includes 12 | #include 13 | 14 | #define MESSAGE_SIZE 300 15 | 16 | const uint8_t THE_TERMINATOR = 0xFF; 17 | const uint32_t DB_NAME_LEN = 50; 18 | const uint32_t COL_NAME_LEN = 25; 19 | const uint32_t MAX_NUM_COLUMNS = 20; 20 | 21 | /** 22 | * Enum used to describe the type of statement being sent 23 | */ 24 | enum class CommandType: uint8_t { 25 | SQL_STATEMENT = 0x01, 26 | DB_COMMAND = 0x02, 27 | INVALID_COMMAND 28 | }; 29 | 30 | /** 31 | * Enum used to describe the type of packet being sent 32 | */ 33 | enum class PacketType: uint8_t { 34 | NONE = 0, 35 | COMMAND, 36 | COMMAND_RESULT, 37 | CONNECTION, 38 | RESULT_METADATA, 39 | RESULT_DATA, 40 | INVALID_PACKET 41 | }; 42 | 43 | /** Represents result of database command */ 44 | struct CommandResult { 45 | bool isSuccess; 46 | int numAffected; 47 | }; 48 | 49 | struct CommandPacket { 50 | PacketType type; 51 | CommandType commandType; // The type of command requested to be executed: SQL_STATEMENT or DB_COMMAND 52 | char message[MESSAGE_SIZE]; 53 | uint8_t terminator; 54 | }__attribute__((packed)); 55 | 56 | struct CommandResultPacket { 57 | PacketType type; 58 | ResultStatus status; 59 | ManipStatus secondaryStatus; 60 | uint32_t rowsAffected; 61 | uint8_t terminator; 62 | } __attribute__((packed)); 63 | 64 | struct ConnectionPacket { 65 | PacketType type; 66 | /** The name of the database */ 67 | char name[DB_NAME_LEN]; // The name of the database connected to. 68 | }__attribute__((packed)); 69 | 70 | 71 | struct ResultColumn { 72 | char name[COL_NAME_LEN]; // The column name 73 | uint16_t type; // The SQL type of the column 74 | }__attribute__((packed)); 75 | 76 | 77 | struct ResultMetaDataPacket { 78 | PacketType type; 79 | ResultStatus status; 80 | uint32_t numColumns; 81 | uint32_t resultPacketSize; // Size of the ResultPacket that follows this packet 82 | ResultColumn columns[MAX_NUM_COLUMNS]; // Array containing name of each column and SQL type associated with it 83 | uint8_t terminator; 84 | }__attribute__((packed)); 85 | 86 | /** 87 | * Used to return results in both queries and commands 88 | * for query see comments beside field 89 | * for command 90 | * resultSize // number of rows affected 91 | * status // status 92 | * rowLen // errorCode 93 | */ 94 | struct ResultPacket { 95 | PacketType type; // 1 byte 96 | ResultStatus status; // 2 bytes 97 | uint16_t rowLen; // Length of the row in columns, number of columns in the row 98 | uint32_t resultSize; // Size in bytes that the data array will be 99 | uint64_t* data; 100 | uint8_t terminator; 101 | } __attribute__((packed)); 102 | 103 | 104 | #endif //OPENMEMDB_LIBOMDB_H 105 | -------------------------------------------------------------------------------- /database/include/util/result.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016 Neil Moore, Jason Stavrinaky, Micheal McGee, Robert Medina 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 4 | * software and associated documentation files (the "Software"), to deal in the Software 5 | * without restriction, including without limitation the rights to use, copy, modify, 6 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | * 9 | * The above copyright notice and this permission notice shall be included in all copies 10 | * or substantial portions of the Software. 11 | * 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 14 | * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 15 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 16 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 17 | * USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | */ 19 | 20 | #ifndef OMDB_RESULT_H 21 | #define OMDB_RESULT_H 22 | 23 | enum class ResultStatus : uint16_t 24 | { 25 | SUCCESS = 0, 26 | FAILURE, 27 | FAILURE_DB_UNKNOWN_STATE, 28 | FAILURE_OUT_MEMORY, 29 | FAILURE_SYNTAX, 30 | }; 31 | 32 | enum class ManipStatus : uint32_t 33 | { 34 | SUCCESS = 0, 35 | ERR, 36 | ERR_UNKNOWN_STATEMENT, 37 | ERR_NO_MEMORY, 38 | ERR_TABLE_NOT_EXIST, 39 | ERR_TABLE_CMD_INVALID, 40 | ERR_CONTENTION, 41 | ERR_PARTIAL, 42 | ERR_PARTIAL_CONTENTION, 43 | ERR_FAILED_CONSTRAINT, 44 | }; 45 | 46 | enum class ConstraintStatus : uint32_t 47 | { 48 | SUCCESS = 0, 49 | ERR_NULL, 50 | ERR_ROW_LEN, 51 | }; 52 | 53 | enum class ResultType : uint8_t 54 | { 55 | QUERY = 0, 56 | COMMAND, 57 | OTHER, 58 | }; 59 | 60 | struct ResultBase 61 | { 62 | ResultBase(ResultStatus s, ResultType t = ResultType::OTHER) : type(t), status(s) {} 63 | virtual ~ResultBase() {} 64 | 65 | ResultType type; 66 | ResultStatus status; 67 | }; 68 | 69 | template 70 | struct Result : public ResultBase 71 | { 72 | Result(ResultStatus s, T res) : ResultBase(s), result(res) {} 73 | 74 | T result; 75 | }; 76 | 77 | // Common result types 78 | using UintResult = Result; 79 | using Uint64Result = Result; 80 | using IntResult = Result; 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /database/include/util/types.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016 Neil Moore, Jason Stavrinaky, Micheal McGee, Robert Medina 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 4 | * software and associated documentation files (the "Software"), to deal in the Software 5 | * without restriction, including without limitation the rights to use, copy, modify, 6 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | * 9 | * The above copyright notice and this permission notice shall be included in all copies 10 | * or substantial portions of the Software. 11 | * 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 14 | * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 15 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 16 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 17 | * USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | */ 19 | 20 | #ifndef OMDB_UTIL_TYPES_H 21 | #define OMDB_UTIL_TYPES_H 22 | 23 | /** 24 | * \brief Enumeration of the data types supported by the database. 25 | */ 26 | enum DataType : int8_t 27 | { 28 | NONE = -1, 29 | BOOLEAN = 0, 30 | SMALL_INT, 31 | INTEGER, 32 | BIG_INT, 33 | FLOAT, 34 | DATE, 35 | TIME 36 | }; 37 | 38 | /* The following classes use a technique called "type punning" to efficiently 39 | * store data while still allowing for easy access to it via the struct 40 | * member interface. */ 41 | 42 | /** 43 | * \brief Representation of the boolean data type in memory 44 | */ 45 | union BooleanData 46 | { 47 | struct 48 | { 49 | uint8_t data; 50 | uint64_t pad : 56; 51 | }; 52 | 53 | uint64_t value; 54 | }; 55 | 56 | /** 57 | * \brief Representation of the float data type in memory 58 | */ 59 | union FloatData 60 | { 61 | struct 62 | { 63 | float data; 64 | uint32_t pad; 65 | }; 66 | 67 | uint64_t value; 68 | }; 69 | 70 | /** 71 | * \brief Representation of the short integer (16-bit integer) data type in memory 72 | */ 73 | union ShortData 74 | { 75 | struct 76 | { 77 | int16_t data; 78 | uint64_t pad : 48; 79 | }; 80 | 81 | uint64_t value; 82 | }; 83 | 84 | /** 85 | * \brief Representation of the integer (32-bit integer) data type in memory 86 | */ 87 | union IntData 88 | { 89 | struct 90 | { 91 | int32_t data; 92 | int32_t pad; 93 | }; 94 | 95 | uint64_t value; 96 | }; 97 | 98 | /** 99 | * \brief Representation of the long integer (64-bit integer) data type in memory 100 | */ 101 | struct LongData 102 | { 103 | int64_t value; 104 | }; 105 | 106 | /** 107 | * \brief Representation of an ISO 8601 date in memory 108 | */ 109 | union DateData 110 | { 111 | struct 112 | { 113 | uint16_t year; 114 | uint8_t month; 115 | uint8_t day; 116 | uint32_t pad; 117 | }; 118 | 119 | uint64_t value; 120 | }; 121 | 122 | /** 123 | * \brief Representation of an ISO 8601 time in memory 124 | */ 125 | union TimeData 126 | { 127 | struct 128 | { 129 | uint8_t hour; 130 | uint8_t minute; 131 | uint8_t second; 132 | int8_t tz_hour; 133 | int8_t tz_minute; 134 | uint32_t pad : 24; 135 | }; 136 | 137 | uint64_t value; 138 | }; 139 | 140 | /** 141 | * @brief A wrapper of the Data union to be used in Tervel. This data type must 142 | * not be larger than 64 bits in size. 143 | */ 144 | union TervelData 145 | { 146 | struct 147 | { 148 | int64_t tervel_status : 3; //!< Tervel requires this be given to them 149 | uint64_t type : 3; //!< This is mapped to \refer DataType 150 | uint64_t null : 1; //!< Set if the value is NULL 151 | 152 | uint64_t data_value : 57; //!< 153 | }; 154 | 155 | int64_t value; 156 | } __attribute__((packed)); 157 | 158 | // If this triggers, something has gone really wrong 159 | static_assert(8 == sizeof(TervelData), "TervelData must be exactly 64 bits long"); 160 | 161 | /** 162 | * \brief Defines a lower and upper bound for a range of data 163 | */ 164 | struct DataRange 165 | { 166 | TervelData start; 167 | TervelData end; 168 | }; 169 | 170 | #endif 171 | -------------------------------------------------------------------------------- /database/include/workmanager/work_manager.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016 Neil Moore, Jason Stavrinaky, Micheal McGee, Robert Medina 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 4 | * software and associated documentation files (the "Software"), to deal in the Software 5 | * without restriction, including without limitation the rights to use, copy, modify, 6 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | * 9 | * The above copyright notice and this permission notice shall be included in all copies 10 | * or substantial portions of the Software. 11 | * 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 14 | * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 15 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 16 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 17 | * USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | */ 19 | 20 | #ifndef WORKMGR_H 21 | #define WORKMGR_H 22 | 23 | // Tervel includes 24 | #include 25 | 26 | // Standard library includes 27 | #include 28 | #include 29 | #include 30 | 31 | // Linux-specific includes 32 | #include 33 | #include 34 | #include 35 | 36 | // Project includes 37 | #include 38 | #include 39 | 40 | class DataStore; 41 | 42 | /** 43 | * @brief Class that handles the main thread and load balancing. 44 | */ 45 | class WorkManager 46 | { 47 | public: 48 | WorkManager(uint32_t num_threads, tervel::Tervel* tervel); 49 | ~WorkManager(); 50 | 51 | /** 52 | * @brief An enumeration of all error codes that can be returned when 53 | * running any member function. 54 | */ 55 | enum Errors 56 | { 57 | E_NONE = 0, 58 | E_TERVEL_ERR = -1, 59 | E_NET_ERR = -2, 60 | E_OTHER_ERR = -3 61 | }; 62 | 63 | int32_t Initialize(); 64 | 65 | int32_t Run(); 66 | 67 | void Abort(); 68 | 69 | //! This constant also determines the maximum number of threads 70 | //! in the system. 71 | static const uint32_t MAX_NUM_MUTEXES = 64; 72 | 73 | private: 74 | 75 | uint32_t GetAvailableThread(); 76 | 77 | bool ReceiveCommand(omdb::Connection& conn); 78 | 79 | bool SendResult(omdb::Connection& conn, const JointResult& result); 80 | 81 | //! Tervel object to give to the worker threads 82 | tervel::Tervel* m_tervel; 83 | 84 | //! Tervel thread context so the work manager can initialize Tervel objects 85 | tervel::ThreadContext* m_context; 86 | 87 | //! Number of threads that are supposed to be running 88 | uint32_t m_num_threads; 89 | 90 | //! Worker thread data storage 91 | std::vector m_thread_data; 92 | 93 | //! Holds the futures for currently running jobs 94 | std::vector> m_thread_results; 95 | 96 | //! The listening server socket file descriptor 97 | uint32_t m_server_socket_fd; 98 | 99 | //! The list of current connections 100 | std::vector m_connections; 101 | 102 | //! Mutex pool 103 | ThreadNotifier m_thread_notifiers[MAX_NUM_MUTEXES]; 104 | 105 | //! The mapping of job to connection 106 | std::map m_job_to_connection; 107 | 108 | //! The active data store object 109 | DataStore* m_data_store; 110 | }; 111 | 112 | #endif 113 | -------------------------------------------------------------------------------- /database/include/workmanager/work_thread.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016 Neil Moore, Jason Stavrinaky, Micheal McGee, Robert Medina 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 4 | * software and associated documentation files (the "Software"), to deal in the Software 5 | * without restriction, including without limitation the rights to use, copy, modify, 6 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | * 9 | * The above copyright notice and this permission notice shall be included in all copies 10 | * or substantial portions of the Software. 11 | * 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 14 | * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 15 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 16 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 17 | * USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #define THREAD_SLEEP_MS 100 25 | 26 | /** 27 | * @brief Abstraction of a worker thread. 28 | */ 29 | class WorkThread 30 | { 31 | public: 32 | static void Run(WorkThreadData* data); 33 | 34 | static JointResult ExecuteStatement(ParsedStatement* statement, DataStore* store); 35 | static ManipResult ExecuteCommand(ParsedStatement* statement, DataStore* store); 36 | static MultiRecordResult ExecuteQuery(ParsedStatement* statement, DataStore* store); 37 | 38 | static Job GenerateJob(int job_num, std::string command, DataStore* store); 39 | private: 40 | }; 41 | -------------------------------------------------------------------------------- /database/libomdb/ConsoleDemo/Makefile: -------------------------------------------------------------------------------- 1 | CC=g++ 2 | 3 | INC_DIR := -I../ 4 | 5 | CFLAGS := -std=c++11 $(INC_DIR) -g -Wall -Wextra 6 | LDFLAGS := -pthread -L ../ -lomdb 7 | 8 | EXEC_NAME=omdb_console 9 | OBJECTS := main.o 10 | 11 | all: $(EXEC_NAME) 12 | @echo -e "Compilation done!" 13 | 14 | $(EXEC_NAME): $(OBJECTS) 15 | @echo -e "Compiling OMDB console application" 16 | $(CC) $(OBJECTS) $(LDFLAGS) -o $(EXEC_NAME) 17 | 18 | %.o : %.cc 19 | @echo -e "Compiling source file" 20 | $(CC) $(CFLAGS) -c $< -o $@ 21 | @echo -e "Done compiling" 22 | 23 | clean: 24 | rm -f $(EXEC_NAME) 25 | rm -f $(OBJECTS) 26 | -------------------------------------------------------------------------------- /database/libomdb/ConsoleDemo/main.cc: -------------------------------------------------------------------------------- 1 | // 2 | // Created by mike on 3/22/16. 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include "omdb_lib.h" 10 | 11 | /** 12 | * Prints a line of 80 chars of passed in sybmol 13 | */ 14 | void printLine(char symbol) { 15 | for (int i = 0; i < 80; ++i) { 16 | std::cout << symbol; 17 | } 18 | std::cout< "; 24 | std::getline(std::cin, input, '\n'); 25 | 26 | return input; 27 | } 28 | 29 | void printErrorString(libomdb::ResultStatus err_code) 30 | { 31 | using libomdb::ResultStatus; 32 | switch(err_code) 33 | { 34 | case ResultStatus::FAILURE_DB_UNKNOWN_STATE: 35 | std::cout << "Database is in an unknown state!" << std::endl; 36 | break; 37 | case ResultStatus::FAILURE_OUT_MEMORY: 38 | std::cout << "Database cannot allocate more memory!" << std::endl; 39 | break; 40 | case ResultStatus::FAILURE_SYNTAX: 41 | std::cout << "Syntax error in statement. Please try again." << std::endl; 42 | break; 43 | case ResultStatus::FAILURE: 44 | default: 45 | std::cout << "General unknown error when executing statement" << std::endl; 46 | break; 47 | } 48 | } 49 | 50 | libomdb::Connection doConnect(std::string command) { 51 | if (command.compare("connect") != 0) { 52 | std::cout << "Be sure to type connect to connect :-)" << std::endl; 53 | return libomdb::Connection::errorConnection(); 54 | } 55 | // Connect to the database with the given instructions 56 | std::string ip; 57 | int port; 58 | bool valid_port = false; 59 | std::string database; 60 | 61 | std::cout << "What is the ip to connect to?" << std::endl; 62 | ip = getInput(); 63 | std::cout << "What is the port?" << std::endl; 64 | while(!valid_port) 65 | { 66 | try { 67 | port = std::stoi(getInput()); 68 | } catch (std::invalid_argument& inv_arg) { 69 | continue; 70 | } catch (std::out_of_range& out_range) { 71 | continue; 72 | } 73 | 74 | valid_port = true; 75 | } 76 | std::cout << "What is the database name?" << std::endl; 77 | database = getInput(); 78 | 79 | printf("Connecting with (%s, %d, %s)\n", ip.c_str(), port, database.c_str()); 80 | 81 | auto connection = libomdb::Connection::connect(ip, port, database); 82 | if (connection.getMetaData().isValid()) { 83 | std::cout << "Successfully connected to " << database << std::endl; 84 | } else { 85 | std::cout << "Connection unsuccessful" << std::endl; 86 | } 87 | return connection; 88 | } 89 | 90 | void doQuery(libomdb::Connection connection, std::string command) { 91 | std::cout << "Sending '" << command << "' to server" << std::endl; 92 | auto result = connection.executeQuery(command); 93 | 94 | if(result.status != libomdb::ResultStatus::SUCCESS) { 95 | printErrorString(result.status); 96 | return; 97 | } 98 | 99 | // Print all the results in a pretty little box 100 | // Start by printing the metadata columns 101 | auto metaData = result.getMetaData(); 102 | printLine('-'); 103 | std::cout << "| "; 104 | for (uint32_t i = 0; i < metaData.getColumnCount(); ++i) { 105 | std::cout << metaData.getColumnLabel(i) << "\t| "; 106 | } 107 | std::cout << std::endl; 108 | printLine('-'); 109 | while (result.next()) { 110 | // Print one row per line 111 | std::cout << "| "; 112 | for (uint32_t i = 0; i < metaData.getColumnCount(); ++i) { 113 | std::cout << (result.getValue(i)>>7) << "\t| "; 114 | } 115 | std::cout << std::endl; 116 | printLine('-'); 117 | } 118 | } 119 | 120 | void doCommand(libomdb::Connection connection, std::string command) { 121 | auto result = connection.executeCommand(command); 122 | if (result.status == libomdb::ResultStatus::SUCCESS) { 123 | std::cout << "Executed command '" << command << "' , affected " << result.numAffected << " rows:" << std::endl; 124 | } else { 125 | printErrorString(result.status); 126 | } 127 | } 128 | 129 | int main () { 130 | auto connection = libomdb::Connection::errorConnection(); 131 | // Ask the user to connect to a database 132 | // What port and ip is the database running on 133 | std::string command; 134 | std::cout << "Welcome to OpenMemDB" << std::endl; 135 | std::cout << "To connect to a database type connect" << std::endl; 136 | command = getInput(); 137 | 138 | while(command.compare("exit") != 0) { 139 | if (!command.empty()) { 140 | char firstLetter = command.at(0); 141 | if (firstLetter == 's' || firstLetter == 'S') { 142 | if (!connection.getMetaData().isValid()) { 143 | std::cout << "You must first connect to a database" << std::endl; 144 | } else { 145 | doQuery(connection, command); 146 | } 147 | } else { 148 | if (!connection.getMetaData().isValid()) { 149 | // Try to connect to the database 150 | connection = doConnect(command); 151 | } else { 152 | doCommand(connection, command); 153 | } 154 | } 155 | } 156 | 157 | command = getInput(); 158 | } 159 | 160 | std::cout << "Thanks for using OpenMemDB" << std::endl; 161 | return 0; 162 | } 163 | -------------------------------------------------------------------------------- /database/libomdb/Makefile: -------------------------------------------------------------------------------- 1 | # Compiler to use 2 | CC=g++ 3 | 4 | INC_DIR := -I../ \ 5 | 6 | # Basic flags that will be shared between debug and release configurations 7 | CFLAGS=-Wall -Wextra -g $(INC_DIR) -std=c++11 8 | 9 | LDFLAGS=-rdynamic -pthread 10 | 11 | LIB_NAME := libomdb.a 12 | 13 | SOURCES := ./connection.cc \ 14 | ./libomdb_result.cc \ 15 | ./serialization_helper.cc \ 16 | ./omdb_lib.cc \ 17 | 18 | OBJECTS = $(SOURCES:.cc=.o) 19 | 20 | all: $(SOURCES) $(LIB_NAME) 21 | 22 | $(LIB_NAME): $(OBJECTS) 23 | ar rvs $(LIB_NAME) $(OBJECTS) 24 | ranlib $(LIB_NAME) 25 | 26 | %.o : %.cc 27 | $(CC) $(CFLAGS) -c $< -o $@ 28 | 29 | clean: 30 | rm -f $(LIB_NAME) 31 | rm $(OBJECTS) 32 | -------------------------------------------------------------------------------- /database/libomdb/Tests/TestSerialization/Makefile: -------------------------------------------------------------------------------- 1 | CC=g++ 2 | CFLAGS=-std=c++11 -I../../ -I../../../include/util -g -Wall -Wextra 3 | LDFLAGS=-pthread 4 | 5 | EXEC_NAME=test_serialization 6 | 7 | OBJECTS= ../../../source/util/serialization_helper.o \ 8 | testSerialization.o 9 | 10 | all: $(EXEC_NAME) 11 | @echo -e "Compilation done!" 12 | 13 | $(EXEC_NAME): $(OBJECTS) 14 | $(CC) $(LDFLAGS) $(OBJECTS) -o $(EXEC_NAME) 15 | 16 | %.o : %.cc 17 | $(CC) $(CFLAGS) -c $< -o $@ 18 | 19 | clean: 20 | rm -f $(EXEC_NAME) 21 | rm -f $(OBJECTS) 22 | -------------------------------------------------------------------------------- /database/libomdb/Tests/TestSerialization/testSerialization.cc: -------------------------------------------------------------------------------- 1 | /** 2 | * Tests the serialization_helper methods 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include "../../include/util/serialization_helper.h" 10 | #include "../../include/util/libomdb.h" 11 | #include "result.h" 12 | 13 | bool testCommandPacketSerialization(); 14 | bool testConnectionPacketSerialization(); 15 | bool testResultPacketSerialization(); 16 | bool testResultMetaDataPacketSerialization(); 17 | 18 | 19 | int main () { 20 | 21 | bool commandPassed = testCommandPacketSerialization(); 22 | bool connectionPassed = testConnectionPacketSerialization(); 23 | bool resultMetaDataPassed = testResultMetaDataPacketSerialization(); 24 | bool resultPassed = testResultPacketSerialization(); 25 | std::cout << "Command Serialization Passed: " << commandPassed << std::endl; 26 | std::cout << "Connection Serialization Passed: " << connectionPassed << std::endl; 27 | std::cout << "ResultMetaData Serialization Passed: " << resultMetaDataPassed < COL_NAME_LEN) ? COL_NAME_LEN : label.length(); 107 | memcpy(resultMetaDataPacket.columns[i].name, label.c_str(), len); 108 | } 109 | 110 | resultMetaDataPacket.numColumns = 5; 111 | resultMetaDataPacket.terminator = THE_TERMINATOR; 112 | 113 | // Serialize packet 114 | char* serializedPacket = SerializeResultMetaDataPacket(resultMetaDataPacket); 115 | 116 | // Deserialize packet 117 | ResultMetaDataPacket deserializedPacket = DeserializeResultMetaDataPacket(serializedPacket); 118 | 119 | assert(deserializedPacket.type == PacketType::RESULT_METADATA); 120 | assert(deserializedPacket.numColumns == 5); 121 | delete[] serializedPacket; 122 | 123 | return true; 124 | } 125 | -------------------------------------------------------------------------------- /database/libomdb/Tests/Test_libomdb/Makefile: -------------------------------------------------------------------------------- 1 | CC=g++ 2 | 3 | INC_DIR := -I../../ 4 | 5 | CFLAGS := -std=c++11 $(INC_DIR) -g -Wall -Wextra 6 | LDFLAGS := -pthread -L ../../ -lomdb 7 | 8 | SERVER_INC_DIR = -I../../ \ 9 | -I../../../include/ 10 | 11 | SERVER_CFLAGS := -std=c++11 $(SERVER_INC_DIR) -g -Wall -Wextra 12 | SERVER_LDFLAGS := -pthread 13 | 14 | EXEC_NAME=test_libomdb 15 | 16 | SERVER_NAME=temp_server 17 | 18 | OBJECTS := main.o 19 | 20 | SERVER_OBJECTS := temp_server.o \ 21 | serialization_helper.o 22 | 23 | SERVER_SRC = $(SERVER_OBJECTS:.o=.cc) 24 | 25 | all: $(EXEC_NAME) $(SERVER_NAME) 26 | @echo -e "Compilation done!" 27 | 28 | $(EXEC_NAME): $(OBJECTS) 29 | @echo -e "Compiling OMDB test client" 30 | $(CC) $(OBJECTS) $(LDFLAGS) -o $(EXEC_NAME) 31 | 32 | $(SERVER_NAME): $(SERVER_OBJECTS) 33 | @echo -e "Compiling OMDB test server" 34 | $(CC) $(SERVER_OBJECTS) $(SERVER_LDFLAGS) -o $(SERVER_NAME) 35 | 36 | temp_server.o: temp_server.cc 37 | @echo -e "Compiling server source" 38 | $(CC) $(SERVER_CFLAGS) -c $< -o $@ 39 | 40 | serialization_helper.o: serialization_helper.cc 41 | @echo -e "Compiling server source" 42 | $(CC) $(SERVER_CFLAGS) -c $< -o $@ 43 | 44 | %.o : %.cc 45 | @echo -e "Compiling source file" 46 | $(CC) $(CFLAGS) -c $< -o $@ 47 | @echo -e "Done compiling" 48 | 49 | clean: 50 | rm -f $(EXEC_NAME) 51 | rm -f $(OBJECTS) 52 | rm -f $(SERVER_OBJECTS) 53 | rm -f temp_server 54 | -------------------------------------------------------------------------------- /database/libomdb/Tests/Test_libomdb/main.cc: -------------------------------------------------------------------------------- 1 | // 2 | // Created by mike on 2/22/16. 3 | // 4 | 5 | #include 6 | 7 | #include "omdb_lib.h" 8 | 9 | /** 10 | * This test assumes that there is a table calles users 11 | * This table "exists" in the temp_server 12 | * The temp_server must be running before this test can be run 13 | */ 14 | int main () 15 | { 16 | // Connect to server // need to write test server first 17 | auto connection = libomdb::Connection::connect("localhost", 3490, "fakeDB"); 18 | // Send request to server 19 | libomdb::Result queryResult = connection.executeQuery("SELECT name from users;"); 20 | // Check that results are as expected 21 | std::cout << "MetaData col count: " << queryResult.getMetaData().getColumnCount() << std::endl; 22 | while(queryResult.next()) { 23 | for (uint32_t i = 0, j = queryResult.getMetaData().getColumnCount(); i < j; ++i) { 24 | std::cout << "Value at i: " << queryResult.getValue(i) << std::endl; 25 | } 26 | } 27 | // Send another request to the server 28 | std::string insertCommand = "INSERT INTO users VALUES (fake name, 100, 10);"; 29 | auto commandResult = connection.executeCommand(insertCommand); 30 | // Give result to user 31 | 32 | // Close the connection to the db 33 | connection.disconnect(); 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /database/libomdb/Tests/Test_libomdb/serialization_helper.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mike on 1/17/16. 3 | * Contains functions used to serialize and deserialize packets 4 | * @author Mike McGee 5 | */ 6 | 7 | #ifndef OPENMEMDB_SERIALIZATION_HELPER_H 8 | #define OPENMEMDB_SERIALIZATION_HELPER_H 9 | 10 | #include "util/packets.h" 11 | 12 | /**************************************************************** 13 | * Serialization functions 14 | ****************************************************************/ 15 | 16 | /** 17 | * Converts CommandPacket into char* that can be sent over socket 18 | * @param packet The CommandPacket to be serialized 19 | * @return a char[] representing the packet 20 | */ 21 | char* SerializeCommandPacket(CommandPacket packet); 22 | 23 | /** 24 | * Converts ConnectionPacket into char* that can be sent over socket 25 | * @param packet The ConnectionPacket to serialize 26 | * @return a char[] representing the packet 27 | */ 28 | char* SerializeConnectionPacket(ConnectionPacket packet); 29 | 30 | /** 31 | * Converts ResultMetaDataPacket into char* that can be sent over socket 32 | * @param packet The ResultMetaDataPacket to serialize 33 | * @return a char[] representing the packet 34 | */ 35 | char* SerializeResultMetaDataPacket(ResultMetaDataPacket packet); 36 | 37 | /** 38 | * Converts ResultPacket into char* that can be sent over socket 39 | * @param packet The ResultPacket to serialize 40 | * @return a char[] representing the packet 41 | */ 42 | char* SerializeResultPacket(ResultPacket packet); 43 | 44 | /***************************************************************** 45 | * Deserialization functions 46 | *****************************************************************/ 47 | 48 | /** 49 | * Converts char* into CommandPacket 50 | * @param serializedPacket The char* representing the CommandPacket 51 | * @return A CommandPacket with the data from the serializedPacket 52 | */ 53 | CommandPacket DeserializeCommandPacket(char* serializedPacket); 54 | 55 | /** 56 | * Converts char* into ConnectionPacket 57 | * @param serializedPacket The char* representing the ConnectionPacket 58 | * @return A ConnectionPacket with the data from the serializedPacket 59 | */ 60 | ConnectionPacket DeserializeConnectionPacket(const char* serializedPacket); 61 | 62 | /** 63 | * Converts char* to ResultMetaDataPacket 64 | * @param serializedPacker The char* representing the ResultMetaDataPacket 65 | * @return A ResultMetaDataPacket with the data from the serializedPacket 66 | */ 67 | ResultMetaDataPacket DeserializeResultMetaDataPacket(char* serializedPacket); 68 | 69 | /** 70 | * Converts char* to a ResultPacket 71 | * @param serializedPacket The char* representing the ResultPacket 72 | * @return A ResultPacket with the data from the serializedPacket 73 | */ 74 | ResultPacket DeserializeResultPacket(char* serializedPacket); 75 | #endif //OPENMEMDB_SERIALIZATION_HELPER_H 76 | -------------------------------------------------------------------------------- /database/libomdb/libomdb_result.cc: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | Copyright (c) 2015 University of Central Florida's Computer Software Engineering 4 | Scalable & Secure Systems (CSE - S3) Lab 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | */ 21 | 22 | #include "omdb_lib.h" 23 | 24 | 25 | /************************************************************************ 26 | * ResultMetaData Implementations * 27 | ************************************************************************/ 28 | libomdb::ResultMetaData::ResultMetaData(std::vector data) 29 | :m_data(data){} 30 | 31 | uint32_t libomdb::ResultMetaData::getColumnCount() { 32 | return this->m_data.size(); 33 | } 34 | 35 | 36 | std::string libomdb::ResultMetaData::getColumnLabel(int index) { 37 | return this->m_data.at(index).label; 38 | } 39 | 40 | // TODO: Replace return type with Neil's SQL_TYPE 41 | libomdb::SQL_TYPE libomdb::ResultMetaData::getColumnType(int index) { 42 | return this->m_data.at(index).type; 43 | } 44 | 45 | libomdb::ResultMetaData libomdb::ResultMetaData::buildResultMetaDataObject( 46 | std::vector data) { 47 | libomdb::ResultMetaData* resultMetaData = new libomdb::ResultMetaData(data); 48 | return *resultMetaData; 49 | } 50 | /************************************************************************* 51 | * Result Implementations * 52 | *************************************************************************/ 53 | libomdb::Result::Result(std::vector rows, 54 | ResultMetaData resultMetaData) 55 | :m_rows(rows), m_metaData(resultMetaData) {} 56 | 57 | 58 | libomdb::Result libomdb::Result::buildResultObject(std::vector rows, 59 | ResultMetaData metaData) { 60 | return libomdb::Result(rows, metaData); 61 | } 62 | 63 | 64 | libomdb::ResultMetaData libomdb::Result::getMetaData() { 65 | return this->m_metaData; 66 | } 67 | 68 | 69 | int64_t libomdb::Result::getValue(int index) { 70 | // Accesses the back element because pop_back() is provided 71 | // by std. This will affect the ordering. 72 | return this->m_rows.back().at(index); 73 | } 74 | 75 | 76 | bool libomdb::Result::next() { 77 | if (this->m_rows.empty()) { 78 | return false; 79 | } else { 80 | this->m_rows.pop_back(); 81 | return !this->m_rows.empty(); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /database/libomdb/omdb_lib.cc: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016 Neil Moore, Jason Stavrinaky, Micheal McGee, Robert Medina 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 4 | * software and associated documentation files (the "Software"), to deal in the Software 5 | * without restriction, including without limitation the rights to use, copy, modify, 6 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | * 9 | * The above copyright notice and this permission notice shall be included in all copies 10 | * or substantial portions of the Software. 11 | * 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 14 | * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 15 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 16 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 17 | * USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | */ 19 | -------------------------------------------------------------------------------- /database/libomdb/serialization_helper.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mike on 1/17/16. 3 | * Contains functions used to serialize and deserialize packets 4 | * @author Mike McGee 5 | */ 6 | 7 | #ifndef OPENMEMDB_SERIALIZATION_HELPER_H 8 | #define OPENMEMDB_SERIALIZATION_HELPER_H 9 | 10 | #include "omdb_lib.h" 11 | 12 | using namespace libomdb; 13 | 14 | /**************************************************************** 15 | * Serialization functions 16 | ****************************************************************/ 17 | 18 | /** 19 | * Converts CommandPacket into char* that can be sent over socket 20 | * @param packet The CommandPacket to be serialized 21 | * @return a char[] representing the packet 22 | */ 23 | char* SerializeCommandPacket(CommandPacket packet); 24 | 25 | /** 26 | * Converts ConnectionPacket into char* that can be sent over socket 27 | * @param packet The ConnectionPacket to serialize 28 | * @return a char[] representing the packet 29 | */ 30 | char* SerializeConnectionPacket(ConnectionPacket packet); 31 | 32 | /** 33 | * Converts ResultMetaDataPacket into char* that can be sent over socket 34 | * @param packet The ResultMetaDataPacket to serialize 35 | * @return a char[] representing the packet 36 | */ 37 | char* SerializeResultMetaDataPacket(ResultMetaDataPacket packet); 38 | 39 | /** 40 | * Converts ResultPacket into char* that can be sent over socket 41 | * @param packet The ResultPacket to serialize 42 | * @return a char[] representing the packet 43 | */ 44 | char* SerializeResultPacket(ResultPacket packet); 45 | 46 | /***************************************************************** 47 | * Deserialization functions 48 | *****************************************************************/ 49 | 50 | /** 51 | * Converts char* into CommandPacket 52 | * @param serializedPacket The char* representing the CommandPacket 53 | * @return A CommandPacket with the data from the serializedPacket 54 | */ 55 | CommandPacket DeserializeCommandPacket(char* serializedPacket); 56 | 57 | /** 58 | * Converts char* into ConnectionPacket 59 | * @param serializedPacket The char* representing the ConnectionPacket 60 | * @return A ConnectionPacket with the data from the serializedPacket 61 | */ 62 | ConnectionPacket DeserializeConnectionPacket(const char* serializedPacket); 63 | 64 | /** 65 | * Converts char* to ResultMetaDataPacket 66 | * @param serializedPacker The char* representing the ResultMetaDataPacket 67 | * @return A ResultMetaDataPacket with the data from the serializedPacket 68 | */ 69 | ResultMetaDataPacket DeserializeResultMetaDataPacket(char* serializedPacket); 70 | 71 | /** 72 | * Converts char* to a ResultPacket 73 | * @param serializedPacket The char* representing the ResultPacket 74 | * @return A ResultPacket with the data from the serializedPacket 75 | */ 76 | ResultPacket DeserializeResultPacket(char* serializedPacket); 77 | #endif //OPENMEMDB_SERIALIZATION_HELPER_H 78 | -------------------------------------------------------------------------------- /database/source/main.cc: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016 Neil Moore, Jason Stavrinaky, Micheal McGee, Robert Medina 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 4 | * software and associated documentation files (the "Software"), to deal in the Software 5 | * without restriction, including without limitation the rights to use, copy, modify, 6 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | * 9 | * The above copyright notice and this permission notice shall be included in all copies 10 | * or substantial portions of the Software. 11 | * 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 14 | * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 15 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 16 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 17 | * USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | /** 25 | * \brief The entry point of the application. 26 | */ 27 | int main(int argc, char** argv) 28 | { 29 | int num_threads = 8; 30 | 31 | for(int i = 1; i < argc; i++) 32 | { 33 | if(strcmp(argv[i], "help") == 0) 34 | { 35 | printf("Thanks for using OpenMemDB!\n"); 36 | printf("Usage: openmemdb [help] []\n"); 37 | printf("Defaults to using 8 threads if no parameter is found.\n"); 38 | return 0; 39 | } 40 | 41 | std::string arg(argv[i]); 42 | try 43 | { 44 | num_threads = std::stoi(arg); 45 | } 46 | catch(const std::invalid_argument& inv_arg) 47 | { 48 | std::cout << "Invalid commandline argument! './openmemdb help' for usage " 49 | "instructions" << std::endl; 50 | std::cout << "Defaulting to 8 threads..." << std::endl; 51 | num_threads = 8; 52 | } 53 | } 54 | 55 | // TODO: Is the plus 1 needed? 56 | tervel::Tervel* tervel_main = new tervel::Tervel(num_threads + 1); 57 | WorkManager work_manager(num_threads, tervel_main); 58 | 59 | // Setup some signal handlers 60 | setSignalHandler(SIGINT, [&work_manager] (int) { work_manager.Abort(); }); 61 | setSignalHandler(SIGTERM, [&work_manager] (int) { work_manager.Abort(); }); 62 | setSignalHandler(SIGSEGV, [&work_manager] (int) { work_manager.Abort(); }); 63 | setSignalHandler(SIGABRT, [&work_manager] (int) { work_manager.Abort(); }); 64 | 65 | int32_t status = 0; 66 | 67 | // Initialize the work manager 68 | status = work_manager.Initialize(); 69 | if(status != WorkManager::E_NONE) 70 | { 71 | printf("Work manager failed to initialize!\n"); 72 | printf("Error code = %d\n", status); 73 | return 1; 74 | } 75 | 76 | // Run the server! 77 | status = work_manager.Run(); 78 | if(status != WorkManager::E_NONE) 79 | { 80 | printf("Work manager failed to run!\n"); 81 | printf("Error code = %d\n", status); 82 | return 1; 83 | } 84 | 85 | printf("Shutting down program...\n"); 86 | 87 | return 0; 88 | } 89 | 90 | -------------------------------------------------------------------------------- /database/source/sql/statements/data_manipulation.cc: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016 Neil Moore, Jason Stavrinaky, Micheal McGee, Robert Medina 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 4 | * software and associated documentation files (the "Software"), to deal in the Software 5 | * without restriction, including without limitation the rights to use, copy, modify, 6 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | * 9 | * The above copyright notice and this permission notice shall be included in all copies 10 | * or substantial portions of the Software. 11 | * 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 14 | * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 15 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 16 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 17 | * USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | */ 19 | 20 | // Standard library includes 21 | #include 22 | 23 | // Project includes 24 | #include "sql/statements/data_manipulation.h" 25 | -------------------------------------------------------------------------------- /database/source/sql/types/boolean.cc: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016 Neil Moore, Jason Stavrinaky, Micheal McGee, Robert Medina 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 4 | * software and associated documentation files (the "Software"), to deal in the Software 5 | * without restriction, including without limitation the rights to use, copy, modify, 6 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | * 9 | * The above copyright notice and this permission notice shall be included in all copies 10 | * or substantial portions of the Software. 11 | * 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 14 | * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 15 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 16 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 17 | * USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | */ 19 | 20 | #include 21 | 22 | SQLBoolean::SQLBoolean() 23 | : SQLNullable(true, true), m_value(SQL_UNKNOWN) 24 | {} 25 | 26 | SQLBoolean::SQLBoolean(const SQLBoolean& other) 27 | : SQLNullable(other.IsNull(), other.IsNullable()), m_value(other.m_value) 28 | {} 29 | 30 | SQLBoolean::SQLBoolean(SQLBoolean& other) 31 | : SQLNullable(other.IsNull(), other.IsNullable()), m_value(other.m_value) 32 | {} 33 | 34 | SQLBoolean::SQLBoolean(bool value) 35 | : SQLNullable(false, true), m_value(value ? SQL_TRUE : SQL_FALSE) 36 | {} 37 | 38 | SQLBoolean::SQLBoolean(TervelData value) 39 | : SQLNullable(false, true) 40 | { 41 | if(value.null == 1 || value.type == BOOLEAN) 42 | { 43 | m_is_null = true; 44 | return; 45 | } 46 | 47 | // TODO: Convert to BooleanData and then pull it out? 48 | m_value = (BooleanValue)(value.data_value); 49 | } 50 | 51 | SQLBoolean::SQLBoolean(BooleanValue value) 52 | : SQLNullable(false), m_value(value) 53 | {} 54 | 55 | SQLBoolean::SQLBoolean(BooleanValue value, bool nullable) 56 | : SQLNullable(false, nullable), m_value(value) 57 | {} 58 | 59 | bool SQLBoolean::IsUnknown() const 60 | { 61 | return (IsNull() || m_value == SQL_UNKNOWN); 62 | } 63 | 64 | bool SQLBoolean::IsTrue() const 65 | { 66 | return (!IsNull() && m_value == SQL_TRUE); 67 | } 68 | 69 | SQLBoolean& SQLBoolean::operator=(SQLBoolean other) 70 | { 71 | this->m_value = other.m_value; 72 | return *this; 73 | } 74 | 75 | SQLBoolean operator!(SQLBoolean value) 76 | { 77 | switch(value.m_value) 78 | { 79 | case SQL_FALSE: 80 | return SQL_TRUE; 81 | case SQL_TRUE: 82 | return SQL_FALSE; 83 | case SQL_UNKNOWN: 84 | default: 85 | return SQL_UNKNOWN; 86 | } 87 | } 88 | 89 | SQLBoolean operator||(const SQLBoolean& lhs, const SQLBoolean& rhs) 90 | { 91 | if(lhs.IsUnknown() || rhs.IsUnknown()) 92 | { 93 | return SQLBoolean(SQL_UNKNOWN); 94 | } 95 | 96 | return (lhs.m_value == SQL_TRUE) || (rhs.m_value == SQL_TRUE); 97 | } 98 | 99 | SQLBoolean operator&&(const SQLBoolean& lhs, const SQLBoolean& rhs) 100 | { 101 | return !((!lhs) || (!rhs)); 102 | } 103 | 104 | 105 | SQLBoolean operator==(const SQLBoolean& lhs, const SQLBoolean& rhs) 106 | { 107 | if(lhs.IsUnknown() || rhs.IsUnknown()) 108 | { 109 | return SQLBoolean(SQL_UNKNOWN); 110 | } 111 | 112 | if(lhs.m_value == rhs.m_value) 113 | { 114 | return SQLBoolean(SQL_TRUE); 115 | } 116 | else 117 | { 118 | return SQLBoolean(SQL_FALSE); 119 | } 120 | } 121 | 122 | SQLBoolean operator!=(const SQLBoolean& lhs, const SQLBoolean& rhs) 123 | { 124 | return !(lhs == rhs); 125 | } 126 | 127 | SQLBoolean operator<(const SQLBoolean& lhs, const SQLBoolean& rhs) 128 | { 129 | if(lhs.IsUnknown() || rhs.IsUnknown()) 130 | { 131 | return SQLBoolean(SQL_UNKNOWN); 132 | } 133 | 134 | if(lhs.m_value < rhs.m_value) 135 | { 136 | return SQLBoolean(SQL_TRUE); 137 | } 138 | else 139 | { 140 | return SQLBoolean(SQL_FALSE); 141 | } 142 | } 143 | 144 | SQLBoolean operator<=(const SQLBoolean& lhs, const SQLBoolean& rhs) 145 | { 146 | return !(lhs > rhs); 147 | } 148 | 149 | SQLBoolean operator>(const SQLBoolean& lhs, const SQLBoolean& rhs) 150 | { 151 | return rhs < lhs; 152 | } 153 | 154 | SQLBoolean operator>=(const SQLBoolean& lhs, const SQLBoolean& rhs) 155 | { 156 | return !(lhs < rhs); 157 | } 158 | -------------------------------------------------------------------------------- /database/source/util/common.cc: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016 Neil Moore, Jason Stavrinaky, Micheal McGee, Robert Medina 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 4 | * software and associated documentation files (the "Software"), to deal in the Software 5 | * without restriction, including without limitation the rights to use, copy, modify, 6 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | * 9 | * The above copyright notice and this permission notice shall be included in all copies 10 | * or substantial portions of the Software. 11 | * 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 14 | * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 15 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 16 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 17 | * USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | */ 19 | 20 | #include 21 | 22 | #include "util/common.h" 23 | 24 | /** 25 | * \brief Checks the given string for ISO 8601 compliance 26 | */ 27 | bool checkDateFormat(std::string str) 28 | { 29 | if(str.length() < 10) { return false; } 30 | 31 | for(int i = 0; i < 10; i++) 32 | { 33 | switch(i) 34 | { 35 | case 0: 36 | case 1: 37 | case 2: 38 | case 3: 39 | case 5: 40 | case 6: 41 | case 8: 42 | case 9: 43 | if(isdigit(str[i]) == 0) { return false; } 44 | break; 45 | case 4: 46 | case 7: 47 | if(str[i] != '-') { return false; } 48 | break; 49 | default: 50 | return false; 51 | } 52 | } 53 | 54 | return true; 55 | } 56 | 57 | void serializeMetaDataPacket(ResultMetaDataPacket packet, char* out_buffer) 58 | { 59 | // Assume the buffer is long enough for this 60 | std::memset(out_buffer, 0, sizeof(ResultMetaDataPacket)); 61 | std::memcpy(out_buffer, &packet, sizeof(ResultMetaDataPacket)); 62 | } 63 | 64 | void serializeResultPacket(ResultPacket packet, char* out_buffer) 65 | { 66 | std::memcpy(out_buffer, &packet, 9); 67 | if(packet.data == nullptr) 68 | { 69 | std::memset(out_buffer + 10, packet.terminator, sizeof(char)); 70 | } 71 | else 72 | { 73 | std::memcpy(out_buffer + 10, packet.data, packet.resultSize); 74 | out_buffer[9 + packet.resultSize + 1] = packet.terminator; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /database/source/util/network/common.cc: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016 Neil Moore, Jason Stavrinaky, Micheal McGee, Robert Medina 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 4 | * software and associated documentation files (the "Software"), to deal in the Software 5 | * without restriction, including without limitation the rights to use, copy, modify, 6 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | * 9 | * The above copyright notice and this permission notice shall be included in all copies 10 | * or substantial portions of the Software. 11 | * 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 14 | * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 15 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 16 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 17 | * USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | */ 19 | 20 | // Standard Library includes 21 | #include 22 | #include 23 | 24 | // Linux-specific includes 25 | #include 26 | 27 | // Project includes 28 | #include 29 | 30 | /** 31 | * @brief Creates and initializes a socket that listens to the given port. 32 | * 33 | * @note TODO: Replace raw socket file descriptor with @refer omdb::Connection object 34 | */ 35 | omdb::NetworkStatus omdb::ListenToPort(uint16_t port_id, 36 | uint32_t* socket_fd, 37 | bool dont_block) 38 | { 39 | // If the pointer isn't valid, can't do anything with it. 40 | if(socket_fd == nullptr) 41 | { 42 | return NetworkStatus(omdb::E_INV_PARAM); 43 | } 44 | 45 | addrinfo hints; 46 | addrinfo* name_info_list; 47 | 48 | int32_t status = 0; 49 | 50 | memset(&hints, 0, sizeof(addrinfo)); 51 | hints.ai_family = AF_UNSPEC; // Use either IPv4 or IPv6 52 | hints.ai_socktype = SOCK_STREAM; // TCP 53 | hints.ai_flags = AI_PASSIVE; // Server address 54 | 55 | std::string port_id_str = std::to_string(port_id); 56 | 57 | // Gets all possible address/port pairs we can bind to. 58 | status = getaddrinfo(NULL, port_id_str.c_str(), 59 | &hints, &name_info_list); 60 | 61 | if(status != 0) 62 | { 63 | return NetworkStatus(omdb::E_ADDRINFO, status); 64 | } 65 | 66 | int sock_flags = 0; 67 | if(dont_block) 68 | { 69 | sock_flags = SOCK_NONBLOCK; 70 | } 71 | 72 | addrinfo* final_addr = nullptr; 73 | for(addrinfo* itr = name_info_list; itr != nullptr; itr = itr->ai_next) 74 | { 75 | status = socket(itr->ai_family, 76 | itr->ai_socktype | sock_flags, 77 | itr->ai_protocol); 78 | 79 | if(status == -1) 80 | { 81 | continue; 82 | } 83 | else 84 | { 85 | *socket_fd = status; 86 | } 87 | 88 | int32_t opt_status = 0; 89 | status = setsockopt(*socket_fd, SOL_SOCKET, SO_REUSEADDR, 90 | &opt_status, sizeof(int32_t)); 91 | 92 | if(status == -1) 93 | { 94 | return omdb::NetworkStatus(omdb::E_SOCKET, errno); 95 | } 96 | 97 | status = bind(*socket_fd, itr->ai_addr, itr->ai_addrlen); 98 | if(status == -1) 99 | { 100 | close(*socket_fd); 101 | continue; 102 | } 103 | 104 | final_addr = itr; 105 | break; 106 | } 107 | 108 | freeaddrinfo(name_info_list); 109 | 110 | if(final_addr == nullptr) 111 | { 112 | // NOTE: This only returns the last error! 113 | return omdb::NetworkStatus(omdb::E_BIND, errno); 114 | } 115 | 116 | // Attempt to listen to the bound socket/port pair. 117 | status = listen(*socket_fd, CONN_BACKLOG); 118 | if(status == -1) 119 | { 120 | return omdb::NetworkStatus(omdb::E_LISTEN, errno); 121 | } 122 | 123 | return omdb::NetworkStatus(omdb::SUCCESS); 124 | } 125 | 126 | /** 127 | * @brief Attempt to accept a connection waiting on the socket's assigned port. 128 | * 129 | * @note TODO: Replace the raw socket file descriptor with omdb::Connection 130 | */ 131 | omdb::NetworkStatus omdb::AcceptConnection(uint32_t socket_fd, 132 | uint32_t* conn_fd, 133 | sockaddr_storage* conn_addr) 134 | { 135 | socklen_t addr_len = 0; 136 | 137 | // Needed to use a special version of accept() to make sure it's non-blocking 138 | int32_t status = accept4(socket_fd, reinterpret_cast(conn_addr), 139 | &addr_len, SOCK_NONBLOCK); 140 | 141 | // Error handling 142 | if(status == -1) 143 | { 144 | *conn_fd = 0; 145 | 146 | if(errno == EAGAIN || errno == EWOULDBLOCK) 147 | { 148 | return omdb::NetworkStatus(omdb::SUCCESS); 149 | } 150 | 151 | return omdb::NetworkStatus(omdb::E_ACCEPT, errno); 152 | } 153 | 154 | *conn_fd = status; 155 | 156 | return omdb::NetworkStatus(omdb::SUCCESS); 157 | } 158 | -------------------------------------------------------------------------------- /database/source/util/network/connection.cc: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016 Neil Moore, Jason Stavrinaky, Micheal McGee, Robert Medina 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 4 | * software and associated documentation files (the "Software"), to deal in the Software 5 | * without restriction, including without limitation the rights to use, copy, modify, 6 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | * 9 | * The above copyright notice and this permission notice shall be included in all copies 10 | * or substantial portions of the Software. 11 | * 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 14 | * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 15 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 16 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 17 | * USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | */ 19 | 20 | // Standard library includes 21 | #include 22 | #include 23 | 24 | // Linux-specific includes 25 | #include 26 | 27 | // Project includes 28 | #include 29 | 30 | /** 31 | * @brief Constructor that takes in an already-created socket and relevant 32 | * information. 33 | */ 34 | omdb::Connection::Connection(int32_t socket_fd, sockaddr_storage conn_info) 35 | : m_is_valid(true), m_socket_fd(socket_fd), m_conn_info(conn_info) 36 | {} 37 | 38 | /** 39 | * @brief Default constructor to shut up some standard library containers. 40 | * 41 | * @detail Sets the valid flag to false to represent that it's not actually a 42 | * connection, just a placeholder. 43 | */ 44 | omdb::Connection::Connection() 45 | : m_is_valid(false) 46 | {} 47 | 48 | /** 49 | * @brief Destructor 50 | */ 51 | omdb::Connection::~Connection() 52 | { 53 | } 54 | 55 | /** 56 | * @brief Returns if the connection has been deemed to represent an actual connection. 57 | */ 58 | bool omdb::Connection::IsValid() 59 | { 60 | return m_is_valid; 61 | } 62 | 63 | /** 64 | * @brief Closes the associated socket file descriptor 65 | */ 66 | void omdb::Connection::close() 67 | { 68 | ::close(m_socket_fd); 69 | } 70 | 71 | /** 72 | * @brief Sends the content in the given buffer over the associated socket. 73 | */ 74 | omdb::NetworkStatus omdb::Connection::send(const char* in_buffer, size_t length) 75 | { 76 | // TODO: Let the caller know this is an invalid connection! 77 | if(!m_is_valid) 78 | { 79 | return omdb::NetworkStatus(omdb::E_SEND, 0); 80 | } 81 | 82 | int32_t status = ::send(m_socket_fd, reinterpret_cast(in_buffer), 83 | length, MSG_DONTWAIT); 84 | 85 | // Error handling 86 | if(status == -1) 87 | { 88 | // Have to check for both for portability reasons 89 | if(errno == EAGAIN || errno == EWOULDBLOCK) 90 | { 91 | return omdb::NetworkStatus(omdb::D_SEND_PART); 92 | } 93 | 94 | // Some error has occurred 95 | return omdb::NetworkStatus(omdb::E_SEND, errno); 96 | } 97 | else 98 | { 99 | return omdb::NetworkStatus(omdb::D_SEND_FULL); 100 | } 101 | } 102 | 103 | /** 104 | * @brief Fills the given buffer with whatever data is queued up for this socket. 105 | */ 106 | omdb::NetworkStatus omdb::Connection::recv(char* out_buffer, size_t length) 107 | { 108 | // TODO: Let the caller know this is an invalid connection! 109 | if(!m_is_valid) 110 | { 111 | return omdb::NetworkStatus(omdb::E_RECV); 112 | } 113 | 114 | int32_t status = ::recv(m_socket_fd, reinterpret_cast(out_buffer), 115 | length, MSG_DONTWAIT); 116 | 117 | // Check if the TCP connection has closed 118 | if(status == 0) 119 | { 120 | return omdb::NetworkStatus(omdb::E_CLOSE); 121 | } 122 | 123 | if(status == -1) 124 | { 125 | // Check for the need to call recv() again 126 | if(errno == EAGAIN || errno == EWOULDBLOCK) 127 | { 128 | return omdb::NetworkStatus(omdb::D_RECV_PART); 129 | } 130 | 131 | // Another check if the connection is closed 132 | if(errno == ECONNRESET) 133 | { 134 | return omdb::NetworkStatus(omdb::E_CLOSE); 135 | } 136 | 137 | // Some other error has occurred 138 | return omdb::NetworkStatus(omdb::E_RECV, errno); 139 | } 140 | else 141 | { 142 | return omdb::NetworkStatus(omdb::D_RECV_FULL); 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /database/source/util/omdb_stdlib.cc: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016 Neil Moore, Jason Stavrinaky, Micheal McGee, Robert Medina 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 4 | * software and associated documentation files (the "Software"), to deal in the Software 5 | * without restriction, including without limitation the rights to use, copy, modify, 6 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | * 9 | * The above copyright notice and this permission notice shall be included in all copies 10 | * or substantial portions of the Software. 11 | * 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 14 | * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 15 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 16 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 17 | * USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | */ 19 | 20 | #include "util/omdb_stdlib.h" 21 | 22 | #include 23 | 24 | static std::map> handlers; 25 | 26 | static void signalDispatch(int sig) 27 | { 28 | // Safe to assume that if this is called, a handler was setup 29 | handlers[sig](sig); 30 | 31 | ::signal(sig, SIG_DFL); 32 | ::raise(sig); 33 | } 34 | 35 | void setSignalHandler(int signal, std::function handler_functor) 36 | { 37 | handlers[signal] = handler_functor; 38 | 39 | ::signal(signal, signalDispatch); 40 | } 41 | -------------------------------------------------------------------------------- /database/tests/DataStoreTest.h: -------------------------------------------------------------------------------- 1 | #ifndef DATASTORETEST_H 2 | #define DATASTORETEST_H 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "TestResult.h" 12 | 13 | typedef std::tuple i2tuple; 14 | 15 | class DataStoreTest 16 | { 17 | 18 | 19 | public: 20 | DataStoreTest(); 21 | DataStoreTest& with(int mode); 22 | DataStoreTest& generateCases(int complexity); 23 | DataStoreTest& generateCompatCases(int complexity); 24 | DataStoreTest& setThreadCount(int count); 25 | TestResult test(); 26 | void printStatementsToFile(); 27 | 28 | 29 | private: 30 | 31 | struct thread_data 32 | { 33 | //tervel test and datastore must be shared by all threads 34 | tervel::Tervel* tervel_test; 35 | 36 | //tervel::ThreadContext* main_context; 37 | DataStore *data; 38 | }share; 39 | 40 | 41 | int complexity, mode, threadCount; 42 | bool isRandomized = false; 43 | std::vector statements; 44 | std::vector test_data; 45 | std::vector table_name; 46 | std::vector select_data; 47 | std::vector all_data; 48 | 49 | void parseComplexity(int complexity); 50 | static void createTest(std::vector statements, void *t_data); 51 | static void dropTest(std::vector table_name, void *t_data); 52 | static void insertTest(std::vector record, void *t_data); 53 | static void selectTest(std::vector select_statements, void *t_data); 54 | static void mixedTest(std::vector all_statements, void *t_data); 55 | static tervel::ThreadContext* loadTables(std::vector statements, void *t_data); 56 | static tervel::ThreadContext* loadRows(std::vector records, 57 | std::vector statements, void *t_data); 58 | i2tuple calculateArrayCut(int threadCount, int threadNumber); 59 | 60 | }; 61 | 62 | 63 | #endif // DATASTORETEST_H 64 | -------------------------------------------------------------------------------- /database/tests/GraphTest.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "GraphTest.h" 6 | #include "Test.h" 7 | #include "DataStoreTest.h" 8 | #include "Modes.h" 9 | #include "TestResult.h" 10 | 11 | 12 | GraphTest::GraphTest(int mode, int threadCount) 13 | { 14 | 15 | switch(mode) 16 | { 17 | 18 | case MODE_CREATE: 19 | createPerformanceTest(threadCount); 20 | break; 21 | case MODE_DROP: 22 | dropPerformanceTest(threadCount); 23 | break; 24 | case MODE_INSERT: 25 | insertPerformanceTest(threadCount); 26 | break; 27 | case MODE_SELECT: 28 | selectPerformanceTest(threadCount); 29 | break; 30 | case MODE_MIXED: 31 | mixedPerformanceTest(threadCount); 32 | break; 33 | } 34 | 35 | 36 | } 37 | 38 | // ombdt is a plaintext file that contains test data (used by the python script to generate the graphs) 39 | // Current format: 40 | 41 | /* 42 | * TestName 43 | * test case count 44 | * Thread1 time 45 | * Thread2 time 46 | * Thread3 time 47 | * Thread 4 time 48 | * ... etc 49 | */ 50 | 51 | void GraphTest::createOrAppendOutputFile(int mode, int time, int threadCount) 52 | { 53 | std::ofstream outputFile; 54 | 55 | 56 | // first thread, make a new file 57 | if(threadCount == 1) 58 | { 59 | outputFile.open("test_data.omdbt"); 60 | if(outputFile.is_open()) 61 | { 62 | 63 | switch(mode) 64 | { 65 | case MODE_CREATE: 66 | outputFile << "create_test\n"; 67 | break; 68 | case MODE_DROP: 69 | outputFile << "drop_test\n"; 70 | break; 71 | case MODE_INSERT: 72 | outputFile << "insert_test\n"; 73 | break; 74 | case MODE_SELECT: 75 | outputFile << "select_test\n"; 76 | break; 77 | case MODE_MIXED: 78 | outputFile << "mixed_test\n"; 79 | break; 80 | } 81 | outputFile << threadCount << "\n"; 82 | outputFile << time << "\n"; 83 | outputFile.close(); 84 | } 85 | } 86 | else // any other thread count means we just append 87 | { 88 | outputFile.open("test_data.omdbt", std::ios::app); 89 | if(outputFile.is_open()) 90 | { 91 | outputFile << time << "\n"; 92 | outputFile.close(); 93 | } 94 | } 95 | } 96 | 97 | void GraphTest::createPerformanceTest(int threadCount) 98 | { 99 | DataStoreTest dataStoreTest; 100 | 101 | TestResult result = dataStoreTest.with(MODE_CREATE) 102 | .generateCases(0b0000) 103 | .setThreadCount(threadCount) 104 | .test(); 105 | 106 | createOrAppendOutputFile(MODE_CREATE, result.duration, threadCount); 107 | 108 | } 109 | 110 | void GraphTest::dropPerformanceTest(int threadCount) 111 | { 112 | DataStoreTest dataStoreTest; 113 | 114 | TestResult result = dataStoreTest.with(MODE_DROP) 115 | .generateCases(0b0000) 116 | .setThreadCount(threadCount) 117 | .test(); 118 | 119 | createOrAppendOutputFile(MODE_DROP, result.duration, threadCount); 120 | 121 | } 122 | 123 | void GraphTest::insertPerformanceTest(int threadCount) 124 | { 125 | DataStoreTest dataStoreTest; 126 | 127 | TestResult result = dataStoreTest.with(MODE_INSERT) 128 | .generateCases(0b0000) 129 | .setThreadCount(threadCount) 130 | .test(); 131 | 132 | createOrAppendOutputFile(MODE_INSERT, result.duration, threadCount); 133 | } 134 | 135 | void GraphTest::selectPerformanceTest(int threadCount) 136 | { 137 | DataStoreTest dataStoreTest; 138 | 139 | TestResult result = dataStoreTest.with(MODE_SELECT) 140 | .generateCases(0b0000) 141 | .setThreadCount(threadCount) 142 | .test(); 143 | 144 | createOrAppendOutputFile(MODE_SELECT, result.duration, threadCount); 145 | } 146 | 147 | void GraphTest::mixedPerformanceTest(int threadCount) 148 | { 149 | DataStoreTest dataStoreTest; 150 | 151 | TestResult result = dataStoreTest.with(MODE_MIXED) 152 | .generateCases(0b0000) 153 | .setThreadCount(threadCount) 154 | .test(); 155 | 156 | createOrAppendOutputFile(MODE_SELECT, result.duration, threadCount); 157 | } -------------------------------------------------------------------------------- /database/tests/GraphTest.h: -------------------------------------------------------------------------------- 1 | #ifndef GRAPHTEST_H 2 | #define GRAPHTEST_H 3 | 4 | #include 5 | 6 | 7 | class GraphTest 8 | { 9 | public: 10 | GraphTest(int mode, int threadCount); 11 | void createOrAppendOutputFile(int mode, int time, int threadCount); 12 | void createPerformanceTest(int threadCount); 13 | void dropPerformanceTest(int threadCount); 14 | void insertPerformanceTest(int threadCount); 15 | void selectPerformanceTest(int threadCount); 16 | void mixedPerformanceTest(int threadCount); 17 | 18 | }; 19 | 20 | #endif // TESTRESULT_H -------------------------------------------------------------------------------- /database/tests/Makefile: -------------------------------------------------------------------------------- 1 | # Compiler to use 2 | CC=g++ 3 | 4 | # NAWK-compatible AWK 5 | NAWK=gawk 6 | 7 | TERVEL_DIR=../../Tervel 8 | INC_DIR=../include 9 | SRC_DIR=../source 10 | EXEC=tests 11 | 12 | TOOLS_DIR=../tools 13 | 14 | LEMON_GRAM_LOC=$(realpath ./include/sql/parser/parse.y) 15 | 16 | # Basic flags that will be shared between debug and release configurations 17 | CFLAGS=-Wall -Wextra -g -std=c++11 -I$(INC_DIR) -I$(TERVEL_DIR) 18 | 19 | LDFLAGS=-L$(TERVEL_DIR) -rdynamic -pthread -std=c++11 20 | 21 | SOURCES=$(shell find $(SRC_DIR) -name "*.cc" ! -name "main.cc") 22 | 23 | SOURCES += $(shell find $(TERVEL_DIR)/tervel/util/ -name "*.cc") 24 | SOURCES += $(shell find -name "*.cc") 25 | 26 | OBJECTS=$(SOURCES:.cc=.o) 27 | 28 | all: $(SOURCES) $(EXEC) 29 | 30 | release: CFLAGS += -O2 31 | release: $(EXEC) 32 | 33 | $(EXEC): $(OBJECTS) 34 | $(CC) $(LDFLAGS) $(OBJECTS) -o $@ 35 | 36 | .cc.o: 37 | $(CC) $(CFLAGS) -c $< -o $@ 38 | 39 | clean: 40 | rm -f $(EXEC) 41 | rm -f $(OBJECTS) 42 | 43 | lemon: 44 | make -C $(TOOLS_DIR)/lemon 45 | cd $(TOOLS_DIR)/lemon && ./lemon -p $(LEMON_GRAM_LOC) 46 | mv $(INC_DIR)/sql/parser/parse.h $(INC_DIR)/sql/parser/parse.h.tmp 47 | mv $(INC_DIR)/sql/parser/parse.c $(SRC_DIR)/sql/parser/parse.c 48 | $(NAWK) -f $(TOOLS_DIR)/lemon/addopcodes.awk $(INC_DIR)/sql/parser/parse.h.tmp >$(INC_DIR)/sql/parser/parse.h 49 | rm $(INC_DIR)/sql/parser/parse.h.tmp 50 | -------------------------------------------------------------------------------- /database/tests/Modes.h: -------------------------------------------------------------------------------- 1 | #ifndef MODES_H 2 | #define MODES_H 3 | 4 | enum TestType 5 | { 6 | MODE_UNSET = -1, 7 | MODE_CREATE = 0, 8 | MODE_DROP = 1, 9 | MODE_INSERT = 2, 10 | MODE_SELECT = 3, 11 | MODE_MIXED = 4 12 | }; 13 | 14 | 15 | #endif // MODES_H -------------------------------------------------------------------------------- /database/tests/README.md: -------------------------------------------------------------------------------- 1 | # Title 2 | 3 | ## Building 4 | Navigate to the database/tests folder and run 5 | 6 | make 7 | 8 | ## Running 9 | 10 | ./tests 11 | 12 | ## Creating a test 13 | 14 | Right now to change what test is being done, you will need to change the test directly in GraphTest. 15 | 16 | Currently there are 3 modes to choose from: 17 | 18 | * MODE_CREATE 19 | * MODE_DROP 20 | * MODE_INSERT 21 | 22 | Mode insert is very early on, it is only set up but doesn't actually work. 23 | 24 | Drop test example: 25 | 26 | ``` c++ 27 | TestResult result = dataStoreTest.with(MODE_CREATE) 28 | .generateCases(0b0000) 29 | .test(); 30 | ``` 31 | 32 | ## Threads 33 | 34 | * Threads are created using the C++11 thread library within DataStoreTest::test() 35 | 36 | ## Test creation flow 37 | 38 | 1. The first function to be called is DataStoreTest::with(int mode). This function sets up the test we are going to use according to the struct in Modes.h 39 | * Eventually we want to allow setting manually made sql statements here 40 | 41 | 2. DataStoreTest::generateCases(int complexity) is called 42 | * DataStoreTest::generateCases(int complexity) in a complexity bitmask and parses it to get information about the test. The information stored in the bitmask is as follows 43 | 44 | dasdsa 45 | 46 | * The Tervel object is created right after DataStoreTest::parseComplexity() since thats when we find out how many threads there is going to be 47 | 48 | * Then the test statements are created based on the mode. Currently they are just the same statement for performance testing but they will also be randomized in the future 49 | 50 | 3. Finally we call DataStoreTest::test(). -------------------------------------------------------------------------------- /database/tests/Randomizer.cc: -------------------------------------------------------------------------------- 1 | #include "Randomizer.h" 2 | 3 | #include 4 | #include 5 | 6 | // Generate a random string with max length len 7 | // TODO: replace with random dictionary words 8 | std::string Randomizer::generateString(const int length) 9 | { 10 | char str[length]; 11 | static const char alphanum[] = 12 | "0123456789" 13 | "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 14 | "abcdefghijklmnopqrstuvwxyz"; 15 | 16 | for(int i = 0; i < length; ++i) 17 | { 18 | str[i] = alphanum[generateInt((sizeof(alphanum) - 1))]; 19 | } 20 | 21 | str[length] = 0; 22 | 23 | string ret(str); 24 | return ret; 25 | } 26 | 27 | int Randomizer::generateInt(const int max) 28 | { 29 | // Seed 30 | random_device rd; 31 | 32 | // Initialize generator 33 | mt19937 gen(rd()); 34 | 35 | // Make a random uniform distribution 36 | uniform_int_distribution<> numbers(0,max); 37 | 38 | return numbers(gen); 39 | 40 | } -------------------------------------------------------------------------------- /database/tests/Randomizer.h: -------------------------------------------------------------------------------- 1 | #ifndef RANDOMIZER_H 2 | #define RANDOMIZER_H 3 | 4 | #include 5 | 6 | using namespace std; 7 | 8 | 9 | class Randomizer 10 | { 11 | public: 12 | static int generateInt(const int max); 13 | static string generateString(const int length); 14 | }; 15 | 16 | 17 | #endif // RANDOMIZER_H -------------------------------------------------------------------------------- /database/tests/SQLGenerator.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "Randomizer.h" 6 | #include "SQLGenerator.h" 7 | 8 | SQLGenerator::SQLGenerator(){} 9 | 10 | vector SQLGenerator::generateCreateCases(int complexity, int amount) 11 | { 12 | std::vector statements; 13 | // Todo: Check bitmask for complexity level, and 14 | // create cases based on that 15 | 16 | for(int i = 0; i < amount; i++) 17 | { 18 | std::string curStatement = generateCreateStatement(complexity); 19 | statements.push_back(curStatement); 20 | } 21 | 22 | return statements; 23 | } 24 | 25 | 26 | // TODO: use complexity bitmask for the generation 27 | // Plan so far: mutation factor (number of columns) 28 | // integer mutation 29 | 30 | // TODO: fix occasions where it makes a name with no characters 31 | string SQLGenerator::generateCreateStatement(int complexity) 32 | { 33 | // complexity is a bitmask, the last digit represents column number randomization 34 | std::string base = "CREATE TABLE "; 35 | std::string ret = base; 36 | 37 | // Randomize name and length 38 | int nameLength = Randomizer::generateInt(9) + 1; 39 | std::string name = Randomizer::generateString(nameLength); 40 | 41 | // Add the name of the table to our result string 42 | ret += name; 43 | 44 | // Set up ret for the columns 45 | ret += " ("; 46 | 47 | // Bit mask, the last bit represents randomizing amount of columns. 48 | int columnAmountRandomization = complexity & 00001; 49 | 50 | if(columnAmountRandomization == 1) 51 | { 52 | int colAmount = Randomizer::generateInt(4) + 2; 53 | 54 | // Randomize all the columns except the last one 55 | for(int i = 0; i < colAmount-1; i++) 56 | { 57 | // Randomize column name 58 | nameLength = Randomizer::generateInt(4) + 1; 59 | std::string colName = Randomizer::generateString(nameLength); 60 | ret += colName; 61 | ret += " INTEGER, "; 62 | 63 | } 64 | 65 | // Fill in the end of the statement 66 | nameLength = Randomizer::generateInt(4) + 1; 67 | std::string colName = Randomizer::generateString(nameLength); 68 | 69 | ret += colName; 70 | 71 | ret += " INTEGER);"; 72 | 73 | return ret; 74 | 75 | } 76 | else 77 | { 78 | nameLength = Randomizer::generateInt(4) + 1; 79 | std::string colName = Randomizer::generateString(nameLength); 80 | ret += colName; 81 | 82 | ret += " INTEGER, "; 83 | 84 | nameLength = Randomizer::generateInt(4) + 1; 85 | colName = Randomizer::generateString(nameLength); 86 | 87 | ret += colName; 88 | 89 | ret += " INTEGER);"; 90 | 91 | return ret; 92 | } 93 | } 94 | 95 | vector SQLGenerator::generateSelectCases(int complexity, int amount) 96 | { 97 | 98 | std::vector selectStatements; 99 | return selectStatements; 100 | } 101 | 102 | string SQLGenerator::generateSelectStatement(int complexity) 103 | { 104 | 105 | return "SELECT *"; 106 | } 107 | 108 | -------------------------------------------------------------------------------- /database/tests/SQLGenerator.h: -------------------------------------------------------------------------------- 1 | #ifndef SQLGENERATOR_H 2 | #define SQLGENERATOR_H 3 | 4 | #include 5 | #include 6 | 7 | 8 | class SQLGenerator 9 | { 10 | public: 11 | 12 | SQLGenerator(); 13 | 14 | // Generate create statements 15 | std::vector generateCreateCases(int complexity, int amount); 16 | 17 | // Generate one create statement 18 | std::string generateCreateStatement(int complexity); 19 | 20 | // Generate select statements 21 | std::vector generateSelectCases(int complexity, int amount); 22 | 23 | private: 24 | 25 | 26 | // SELECT creation, just templates for now, we need to do create table, and insert tests first 27 | std::string generateSelectStatement(int complexity); 28 | 29 | 30 | }; 31 | 32 | 33 | 34 | #endif // SQLGENERATOR_H -------------------------------------------------------------------------------- /database/tests/Test.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "Test.h" 6 | #include "Randomizer.h" 7 | #include "Modes.h" 8 | #include "SQLGenerator.h" 9 | #include 10 | 11 | 12 | 13 | Test::Test(){} 14 | 15 | Test& Test::with(int mode) 16 | { 17 | this->mode = mode; 18 | 19 | return *this; 20 | } 21 | 22 | Test& Test::test() 23 | { 24 | printf("Test mode: %d\n", mode); 25 | 26 | switch(mode) 27 | { 28 | 29 | case MODE_UNSET: 30 | printf("Select a mode! \n"); 31 | break; 32 | 33 | case MODE_CREATE: 34 | 35 | printf("Start CREATE test: \n"); 36 | 37 | //cout << statements[0] << endl; 38 | 39 | break; 40 | } 41 | 42 | return *this; 43 | } 44 | 45 | Test& Test::generateCases(int complexity, int amount) 46 | { 47 | 48 | 49 | SQLGenerator sqlGenerator; 50 | 51 | switch(mode) 52 | { 53 | case MODE_CREATE: 54 | printf("Generating CREATE test cases \n"); 55 | 56 | statements = sqlGenerator.generateCreateCases(complexity, amount); 57 | printf("%d\n", statements.size()); 58 | 59 | 60 | break; 61 | 62 | } 63 | return *this; 64 | } 65 | 66 | void Test::clean() 67 | { 68 | mode = -1; 69 | statements.clear(); 70 | } -------------------------------------------------------------------------------- /database/tests/Test.h: -------------------------------------------------------------------------------- 1 | #ifndef TEST_H 2 | #define TEST_H 3 | 4 | #include 5 | #include 6 | 7 | 8 | class Test 9 | { 10 | public: 11 | Test(); 12 | 13 | Test& with(int testMode); 14 | Test& test(); // return TestResult 15 | Test& generateCases(int complexity, int amount); 16 | bool isRandomized; 17 | int mode, complexity, threadCount; 18 | std::vector statements; 19 | 20 | 21 | private: 22 | void clean(); 23 | 24 | protected: 25 | 26 | 27 | }; 28 | 29 | #endif // TEST_H -------------------------------------------------------------------------------- /database/tests/TestConstants.h: -------------------------------------------------------------------------------- 1 | #ifndef TESTCONSTANTS_H 2 | #define TESTCONSTANTS_H 3 | 4 | // Use a namespace to declare constants 5 | namespace TestConstants 6 | { 7 | const int MaxTables = 10000; 8 | const int MaxInserts = 500000; 9 | const int MaxSelects = 10000; 10 | const int MaxMixed = 10000; 11 | 12 | const int InsertToTables = 1; 13 | const int SelectFromTables = 1; 14 | } 15 | 16 | #endif -------------------------------------------------------------------------------- /database/tests/TestResult.cc: -------------------------------------------------------------------------------- 1 | #include "TestResult.h" 2 | 3 | TestResult::TestResult(unsigned long duration, int threadCount) 4 | { 5 | this->duration = duration; 6 | 7 | this->threadCount = threadCount; 8 | } 9 | -------------------------------------------------------------------------------- /database/tests/TestResult.h: -------------------------------------------------------------------------------- 1 | #ifndef TESTRESULT_H 2 | #define TESTRESULT_H 3 | 4 | class TestResult 5 | { 6 | public: 7 | TestResult(unsigned long duration, int threadCount); 8 | int threadCount; 9 | unsigned long duration; 10 | 11 | private: 12 | 13 | }; 14 | 15 | 16 | #endif // TESTRESULT_H 17 | -------------------------------------------------------------------------------- /database/tests/db_testing/README.md: -------------------------------------------------------------------------------- 1 | # DB_TESTING 2 | Testing Suite for VoltDB, MariaDB, and MemSQL 3 | -------------------------------------------------------------------------------- /database/tests/db_testing/maria_test/connector.java: -------------------------------------------------------------------------------- 1 | import org.mariadb.*; 2 | 3 | 4 | -------------------------------------------------------------------------------- /database/tests/db_testing/maria_test/main.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dar13/OpenMemDB/d3927e43cfccc34d694bc0ec01e9c524d8fefbdf/database/tests/db_testing/maria_test/main.java -------------------------------------------------------------------------------- /database/tests/db_testing/maria_test/makefile: -------------------------------------------------------------------------------- 1 | CP = -classpath 2 | JFLAGS = -g 3 | JC = javac 4 | JJ = java 5 | CLASS_FILES = "." 6 | .SUFFIXES: .java .class 7 | .java.class: 8 | $(JC) $(JFLAGS) $(CP) $(CLASS_FILES) $*.java 9 | 10 | CLASSES = \ 11 | main.java \ 12 | thread.java \ 13 | connector.java \ 14 | 15 | default: classes 16 | 17 | classes: $(CLASSES:.java=.class) 18 | 19 | run: 20 | $(JJ) $(CP) $(CLASS_FILES) main 21 | 22 | clean: 23 | $(RM) *.class 24 | -------------------------------------------------------------------------------- /database/tests/db_testing/maria_test/thread.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dar13/OpenMemDB/d3927e43cfccc34d694bc0ec01e9c524d8fefbdf/database/tests/db_testing/maria_test/thread.java -------------------------------------------------------------------------------- /database/tests/db_testing/memsql_test/Makefile: -------------------------------------------------------------------------------- 1 | #Compiler to use 2 | CC=gcc 3 | 4 | SRC_DIR=. 5 | 6 | SOURCES=$(shell find $(SRC_DIR) -name "*.cc") 7 | 8 | OBJECTS=$(SOURCES:.c=.o) 9 | 10 | all: 11 | $(SOURCES) $(EXEC) 12 | 13 | $(EXEC): $(OBJECTS) 14 | $(CC) $(LDLFLAGS) -o $@ 15 | 16 | clean: 17 | rm -f $(EXEC) 18 | rm -f $(OBJECTS) 19 | -------------------------------------------------------------------------------- /database/tests/db_testing/memsql_test/README: -------------------------------------------------------------------------------- 1 | In order to run MemSQL test you must be in the home directory of the server 2 | 3 | Step 1: Start MemSQL 4 | Run the following commands: 5 | a) sudo memsql-ops start 6 | b) sudo memsql-ops memsql-start --all 7 | 8 | Step 2: Generate test sql_statements.omdbt 9 | cd to tests directory 10 | Make 11 | generate the sql statements for whatever test you want to run using the following command 12 | ./tests sqltf [st|irt] 13 | 14 | Step 3: Run test script 15 | cd to the home directory 16 | run the following command 17 | sudo ./memsql_test_setup.sh 18 | 19 | Step 4: Repeat steps 2 and three for remaining test 20 | 21 | Step 5: When done with tests clean up memsql 22 | a) sudo memsql-ops memsql-stop --all 23 | b) sudo memsql-ops stop 24 | 25 | -------------------------------------------------------------------------------- /database/tests/db_testing/memsql_test/main.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by mike on 4/8/16. 3 | // 4 | 5 | #include 6 | 7 | #include "test_file_parser.h" 8 | #include "test_runner.h" 9 | 10 | #define DISTINCT_THREAD_COUNT 4 11 | 12 | const static unsigned int threads[4] = {1, 2, 4, 8}; 13 | 14 | int main() { 15 | FILE* fp = fopen("../../sql_statements.omdbt", "r"); 16 | if (fp == NULL) { 17 | fprintf(stderr, "File not read correctly\n"); 18 | return 1; 19 | } 20 | 21 | allocateCommandArraysAndTestString(); 22 | 23 | if (!parseTestFile(fp)) { 24 | printf("Parsing failed, aborting...\n"); 25 | exit(1); 26 | } 27 | 28 | printf("testName is %s\n", testName); 29 | 30 | if (strcmp(testName, "insert_test") == 0) { 31 | for (int i = 0; i < DISTINCT_THREAD_COUNT; ++i) { 32 | executeInsertTest(threads[i]); 33 | } 34 | } else if (strcmp(testName, "create_test") == 0) { 35 | for (int i = 0; i < DISTINCT_THREAD_COUNT; ++i) { 36 | executeCreateTest(threads[i]); 37 | } 38 | } else if (strcmp(testName, "select_test")) { 39 | for (int i = 0; i < DISTINCT_THREAD_COUNT; ++i) { 40 | executeSelectTest(threads[i]); 41 | } 42 | } else { 43 | printf("Unknown test name: %s\n", testName); 44 | } 45 | 46 | deallocateCommandArraysAndTestString(); 47 | 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /database/tests/db_testing/memsql_test/src/Commands.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.List; 3 | import java.util.stream.Collectors; 4 | 5 | /** 6 | * Created by mike on 4/11/16. 7 | */ 8 | public class Commands { 9 | private final ArrayList createCommands; 10 | private final ArrayList insertCommands; 11 | private final ArrayList selectCommands; 12 | private final ArrayList starterInserts; 13 | private final ArrayList mixedCommands; 14 | 15 | public Commands(List commands) { 16 | this.createCommands = getCommands(commands, "CREATE"); 17 | this.insertCommands = getCommands(commands, "INSERT"); 18 | this.selectCommands = getCommands(commands, "SELECT"); 19 | this.starterInserts = getBeginingInserts(commands); 20 | this.mixedCommands = getMixedCommands(commands); 21 | } 22 | 23 | public ArrayList getCreateCommands() { 24 | return createCommands; 25 | } 26 | 27 | public ArrayList getInsertCommands() { 28 | return insertCommands; 29 | } 30 | 31 | public ArrayList getSelectCommands() { 32 | return selectCommands; 33 | } 34 | 35 | public ArrayList getStarterInserts(){return starterInserts;} 36 | 37 | public ArrayList getMixedCommands() { 38 | return mixedCommands; 39 | } 40 | 41 | private ArrayList getCommands(List commands, String start) { 42 | return commands.stream().filter(s -> s.startsWith(start)).collect(Collectors.toCollection(ArrayList::new)); 43 | } 44 | 45 | private ArrayList getBeginingInserts(List commands) { 46 | ArrayList toReturn = new ArrayList<>(); 47 | // Progress up to insert statements 48 | int i = 0; 49 | while (!commands.get(i).equalsIgnoreCase("insert") && i != commands.size()) { 50 | i++; 51 | } 52 | 53 | // Add all insert statements until you get to mix 54 | while (!commands.get(i).equalsIgnoreCase("mixed") && i != commands.size()) { 55 | // Test 56 | if (commands.get(i).startsWith("INSERT")) { 57 | toReturn.add(commands.get(i)); 58 | } 59 | ++i; 60 | } 61 | 62 | return toReturn; 63 | } 64 | 65 | private ArrayList getMixedCommands(List commands) { 66 | ArrayList toReturn = new ArrayList<>(); 67 | // Move up to mixed statement 68 | int i = 0; 69 | while (!commands.get(i).equalsIgnoreCase("mixed") && i != commands.size()) { 70 | ++i; 71 | } 72 | 73 | // Move passed mixed word 74 | ++i; 75 | 76 | // Add all remaining commands to toReturn 77 | while (i < commands.size()) { 78 | if (commands.get(i).equalsIgnoreCase("end")) { 79 | break; 80 | } 81 | toReturn.add(commands.get(i)); 82 | i++; 83 | } 84 | 85 | return toReturn; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /database/tests/db_testing/memsql_test/src/Constants.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mike on 4/11/16. 3 | */ 4 | public class Constants { 5 | public static final String dbClassName = "com.mysql.jdbc.Driver"; 6 | public static final String CONNECTION = "jdbc:mysql://127.0.0.1:3307/"; 7 | public static final String USER = "root"; 8 | public static final String PASSWORD = ""; 9 | } 10 | -------------------------------------------------------------------------------- /database/tests/db_testing/memsql_test/src/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Main-Class: Sample 3 | 4 | -------------------------------------------------------------------------------- /database/tests/db_testing/memsql_test/src/Worker.java: -------------------------------------------------------------------------------- 1 | import java.sql.Connection; 2 | import java.sql.DriverManager; 3 | import java.sql.SQLException; 4 | import java.sql.Statement; 5 | import java.util.List; 6 | import java.util.Properties; 7 | import java.util.concurrent.BrokenBarrierException; 8 | import java.util.concurrent.CyclicBarrier; 9 | 10 | /** 11 | * Created by mike on 4/11/16. 12 | */ 13 | public class Worker implements Runnable { 14 | private final int numThreads; 15 | private final long numOps; 16 | private final List commands; 17 | private final int threadNum; 18 | private final CyclicBarrier gate; 19 | 20 | public Worker(int numThreads, long numOps, List commands, int threadNum, CyclicBarrier gate) { 21 | this.numThreads = numThreads; 22 | this.numOps = numOps; 23 | this.commands = commands; 24 | this.threadNum = threadNum; 25 | this.gate = gate; 26 | } 27 | 28 | 29 | @Override 30 | public void run() { 31 | 32 | Properties properties = new Properties(); 33 | properties.put("user", Constants.USER); 34 | properties.put("password", Constants.PASSWORD); 35 | try (Connection conn = DriverManager.getConnection(Constants.CONNECTION, properties)) { 36 | executeSQL(conn, "USE test"); 37 | int startIndex = (commands.size() / numThreads) * threadNum; 38 | int totOps = (commands.size()/numThreads); 39 | 40 | // Wait for the gate that is controlled by the main thread before running 41 | try { 42 | this.gate.await(); 43 | } catch (InterruptedException e) { 44 | e.printStackTrace(); 45 | } catch (BrokenBarrierException e) { 46 | e.printStackTrace(); 47 | } 48 | 49 | for (int i = 0; i < totOps; ++i) { 50 | executeSQL(conn, commands.get(i+startIndex)); 51 | } 52 | } catch (SQLException e) { 53 | e.printStackTrace(); 54 | } 55 | 56 | } 57 | 58 | public static void executeSQL(Connection conn, String sql) throws SQLException { 59 | try (Statement stmt = conn.createStatement()) { 60 | //System.out.println("Attempting to execute statement: "+sql); 61 | stmt.execute(sql); 62 | } catch (SQLException e) { 63 | e.printStackTrace(); 64 | System.err.println("Trying to execute statement: "+sql); 65 | System.exit(1); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /database/tests/db_testing/memsql_test/test_file_parser.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by mike on 4/8/16. 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include "test_file_parser.h" 10 | 11 | 12 | void allocateCommandArraysAndTestString() { 13 | testName = (char*) malloc(MAX_COMMAND_LENGTH); 14 | } 15 | 16 | void deallocateCommandArraysAndTestString() { 17 | free(testName); 18 | } 19 | 20 | 21 | bool parseTestFile(FILE* fp) { 22 | // String to hold each command 23 | char* commandString = (char*) malloc(MAX_COMMAND_LENGTH); 24 | 25 | //First line is supposed to be test name 26 | testName = (char*) malloc(MAX_COMMAND_LENGTH); 27 | fgets(testName, MAX_COMMAND_LENGTH, fp); 28 | 29 | // Make sure that the first line specified the test to run 30 | if (strcmp(testName, "create_test\n") != 0 && strcmp(testName, "insert_test\n") != 0 && 31 | strcmp(testName, "select_test\n")) { 32 | printf("Test type was not first line; recieved %s\n", testName); 33 | return false; 34 | } 35 | 36 | // Read the first command 37 | fgets(commandString, MAX_COMMAND_LENGTH, fp); 38 | // Read the file until the word end 39 | while (strcmp(commandString, TERMINATOR_STRING) != 0) { 40 | if (strcmp(commandString, "create\n") == 0) { 41 | 42 | int i = 0; 43 | const char createStatementPrefix[] = "CREATE"; 44 | size_t crPrefLen = strlen(createStatementPrefix); 45 | 46 | // Reading create statements while statements start with CREATE 47 | while (strncmp(fgets(commandString, MAX_COMMAND_LENGTH, fp), createStatementPrefix, crPrefLen) == 0) { 48 | // Add command to create array 49 | // Remove trailing newline '\n' before adding to command list 50 | strtok(commandString, "\n"); 51 | strcpy(createStrings[i], commandString); 52 | createStrings[i][strlen(commandString)] = '\0'; 53 | i++; 54 | } 55 | 56 | } else if (strcmp(commandString, "insert\n") == 0) { 57 | 58 | int i = 0; 59 | const char insertStatementPrefix[] = "INSERT"; 60 | size_t insPrefLen = strlen(insertStatementPrefix); 61 | 62 | // Read insert statements while lines begin with INSERT 63 | while (strncmp(fgets(commandString, MAX_COMMAND_LENGTH, fp), insertStatementPrefix, insPrefLen) == 0) { 64 | // Add command to insert array 65 | // Remove trailing newline '\n' before adding to command list 66 | strtok(commandString, "\n"); 67 | strncpy(insertStrings[i], commandString, strlen(commandString)); 68 | insertStrings[i][strlen(commandString)] = '\0'; 69 | i++; 70 | } 71 | 72 | } else if (strcmp(commandString, "select\n") == 0) { 73 | 74 | int i = 0; 75 | const char selectStatementPrefix[] = "SELECT"; 76 | size_t selPrefLen = strlen(selectStatementPrefix); 77 | 78 | // Read select statements while lines begin with SELECT 79 | while (strncmp(fgets(commandString, MAX_COMMAND_LENGTH, fp), selectStatementPrefix, selPrefLen) == 0) { 80 | // Add command to select array 81 | // Remove trailing newline '\n' before adding to command list 82 | strtok(commandString, "\n"); 83 | strncpy(selectStrings[i], commandString, strlen(commandString)); 84 | selectStrings[i][strlen(commandString)] = '\0'; 85 | i++; 86 | } 87 | 88 | } else if (strcmp(commandString, "end")) { 89 | printf("Parsing completed!\n"); 90 | return true; 91 | }else { 92 | printf("Unrecognized command identifier: %s\n", commandString); 93 | return false; 94 | } 95 | } 96 | 97 | return true; 98 | } 99 | -------------------------------------------------------------------------------- /database/tests/db_testing/memsql_test/test_file_parser.h: -------------------------------------------------------------------------------- 1 | #ifndef OPENMEMDB_TEST_FILE_PARSER_H 2 | #define OPENMEMDB_TEST_FILE_PARSER_H 3 | 4 | #define MAX_COMMAND_LENGTH 200 5 | #define MAX_COMMANDS 500000 6 | #define TERMINATOR_STRING "end" 7 | 8 | #include 9 | #include 10 | 11 | enum TestType { 12 | CREATE, 13 | INSERT, 14 | SELECT 15 | }; 16 | 17 | /** 18 | * The arrays holding the command strings 19 | */ 20 | char createStrings[MAX_COMMANDS][MAX_COMMAND_LENGTH]; 21 | char selectStrings[MAX_COMMANDS][MAX_COMMAND_LENGTH]; 22 | char insertStrings[MAX_COMMANDS][MAX_COMMAND_LENGTH]; 23 | 24 | char* testName; 25 | 26 | /** 27 | * Allocates memory for the command arrays and test name 28 | */ 29 | void allocateCommandArraysAndTestString(); 30 | 31 | /** 32 | * De-allocates command array space 33 | */ 34 | void deallocateCommandArraysAndTestString(); 35 | 36 | /** 37 | * Parses the test file and creates the command arrays 38 | * 39 | * @param fp The pointer to the test file 40 | * @return True if parsing worked properly, false otherwise 41 | */ 42 | bool parseTestFile(FILE* fp); 43 | 44 | 45 | #endif //OPENMEMDB_TEST_FILE_PARSER_H 46 | -------------------------------------------------------------------------------- /database/tests/db_testing/memsql_test/test_runner.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by mike on 4/10/16. 3 | // 4 | 5 | #ifndef OPENMEMDB_TEST_RUNNER_H 6 | #define OPENMEMDB_TEST_RUNNER_H 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #define HOST "localhost" 16 | #define USER "root" 17 | #define PWD "" 18 | #define PORT 3306 19 | 20 | char** createStatements; 21 | char** insertStatements; 22 | char** selectStatements; 23 | 24 | unsigned int NUM_OPERATIONS; 25 | 26 | typedef struct worker_args { 27 | size_t id; 28 | unsigned int startIndex; 29 | unsigned int numThreads; 30 | } worker_args; 31 | 32 | void setStatements(char** creates, char** inserts, char** selects); 33 | 34 | void setNumOps(unsigned int numOps); 35 | 36 | bool connectToMemSql(MYSQL* conn, const char* host, const char* user, const char* pwd, const size_t port); 37 | 38 | bool createDatabase(MYSQL* conn); 39 | 40 | bool dropDatabase(MYSQL* conn); 41 | 42 | void* createWorker(void* threadArgs); 43 | 44 | void* insertWorker(void* threadArgs); 45 | 46 | void* selectWorker(void* threadArgs); 47 | 48 | clock_t executeCreateTest(unsigned int numThreads); 49 | 50 | clock_t executeInsertTest(unsigned int numThreads); 51 | 52 | clock_t executeSelectTest(unsigned int numThreads); 53 | 54 | #endif //OPENMEMDB_TEST_RUNNER_H 55 | -------------------------------------------------------------------------------- /database/tests/db_testing/volt_test/Connector.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Java application that connects to voltdb and measures the execution time 3 | * 4 | */ 5 | 6 | import org.voltdb.*; 7 | import org.voltdb.client.*; 8 | import java.util.ArrayList; 9 | import java.sql.*; 10 | import java.io.*; 11 | import java.util.List; 12 | import java.util.concurrent.*; 13 | 14 | public class Connector 15 | { 16 | private String[] serverName; 17 | private int[] serverPort; 18 | private org.voltdb.client.Client db; 19 | private Connection conn; 20 | 21 | //generate a list of client connections to connect to the cluster host 22 | public void generateServers(int size, int port) 23 | { 24 | //admin port necessary to connect to servers and offset is port increment 25 | int offset = 6; 26 | 27 | serverName = new String[size]; 28 | serverPort = new int[size]; 29 | for(int i = 0; i < size; i++) 30 | { 31 | serverName[i] = "localhost"; 32 | serverPort[i] = port + i*offset; 33 | } 34 | } 35 | 36 | //establish a connection to the cluster host 37 | public void init(int size) 38 | { 39 | try { 40 | 41 | //initalize voltdb client and server list 42 | int port = 21212; 43 | ClientConfig config = new ClientConfig("advent","xyzzy"); 44 | config.setProcedureCallTimeout(90*10000); 45 | config.setConnectionResponseTimeout(180 * 10000); 46 | db = ClientFactory.createClient(config); 47 | generateServers(size, port); 48 | 49 | //connect nodes to host 50 | for(int i = 0; i < size; i++) 51 | db.createConnection("localhost", 21212); 52 | 53 | } catch(Exception e) 54 | { 55 | System.out.println("Failed to connect to a server"); 56 | e.printStackTrace(); 57 | } 58 | } 59 | 60 | //Stored Procedure method, different from AdHoc usage 61 | //reads in sql statements in a batch and splits them up to each thread 62 | public long runProcedure(ArrayList batch, int threadCount) 63 | { 64 | ArrayList list = new ArrayList(); 65 | final CyclicBarrier gate = new CyclicBarrier(threadCount+1); 66 | 67 | //list of sql instructions passed to each thread 68 | ArrayList> mixedSQL = splitBatch(batch, threadCount); 69 | 70 | try { 71 | //spawn threads 72 | for(int i = 0; i < threadCount; i++) 73 | { 74 | //System.out.println("Thread #"+i+ "is running"); 75 | //for(int k = 0; k < mixedSQL.get(i).size(); k++) 76 | // System.out.println(mixedSQL.get(i).get(k)); 77 | Runnable spawn = null; 78 | spawn = new Worker(db, mixedSQL.get(i), gate); 79 | 80 | list.add(new Thread(spawn)); 81 | } 82 | 83 | //execute threads 84 | long start = System.currentTimeMillis(); 85 | list.forEach(Thread::start); 86 | try 87 | { 88 | gate.await(); 89 | } catch(Exception e) 90 | { 91 | System.out.println("Gate could not invoke await()"); 92 | e.printStackTrace(); 93 | } 94 | 95 | for(Thread t:list) 96 | { 97 | t.join(); 98 | } 99 | 100 | long stop = System.currentTimeMillis(); 101 | long executeTime = stop - start; 102 | 103 | return executeTime; 104 | 105 | } catch(Exception e) 106 | { 107 | System.out.println("runProcedure() threw an error"); 108 | e.printStackTrace(); 109 | return -1; 110 | } 111 | } 112 | 113 | private void printList(List list) 114 | { 115 | for(int i = 0; i < list.size(); i++) 116 | { 117 | System.out.println(list.get(i)); 118 | } 119 | } 120 | 121 | //splits sql statements evenly to threads 122 | private ArrayList> splitBatch(ArrayList batch, int divide) 123 | { 124 | if(divide == 0) 125 | System.out.println("Cannot divide by zero"); 126 | 127 | int remainder = batch.size()%divide; 128 | int quotient = batch.size()/divide; 129 | ArrayList> splitArray = new ArrayList>(); 130 | int previous = 0; 131 | int next = quotient; 132 | 133 | //split array into sublists according to their ranges 134 | for(int i = 0; i < divide-1; i++) 135 | { 136 | List temp = batch.subList(previous, next); 137 | splitArray.add(temp); 138 | previous = previous + quotient; 139 | next = next + quotient; 140 | } 141 | 142 | //last split has remainder added to end 143 | splitArray.add(batch.subList(previous, next+remainder)); 144 | return splitArray; 145 | } 146 | 147 | public void close() 148 | { 149 | try { 150 | db.drain(); 151 | db.close(); 152 | } catch(Exception e) 153 | { 154 | System.out.println("Couldn't close connection"); 155 | e.printStackTrace(); 156 | } 157 | } 158 | 159 | public void shutdown() 160 | { 161 | try 162 | { 163 | db.callProcedure("@Shutdown"); 164 | } catch(org.voltdb.client.ProcCallException e) 165 | { 166 | System.out.println("Database shutting down"); 167 | } catch(Exception e) 168 | { 169 | e.printStackTrace(); 170 | } 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /database/tests/db_testing/volt_test/Insert.java: -------------------------------------------------------------------------------- 1 | //Stored procedure for selects 2 | //This procedure is necessary since AdHoc is super slow 3 | 4 | import org.voltdb.*; 5 | 6 | public class Insert extends VoltProcedure 7 | { 8 | public final SQLStmt Insert = new SQLStmt( 9 | "INSERT INTO TestT0 VALUES (?,?);"); 10 | 11 | public VoltTable[] run(long value, long date) throws VoltAbortException 12 | { 13 | voltQueueSQL(Insert, value, date); 14 | return voltExecuteSQL(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /database/tests/db_testing/volt_test/README: -------------------------------------------------------------------------------- 1 | //------------------------Introduction------------------------------------------- 2 | This Java application connects to voltdb using a localhost configuration to perfrom multicore programming tests on certain functions 3 | The results are displayed as a line graph. 4 | 5 | The flow of the application is to establish a connection to the desired database. Perform uniform testing on that database and then 6 | save that result into a test result graph. 7 | 8 | The line graph is displayed as number of threads and execution time (seconds probably) 9 | 10 | A requirement is that all the databases must be running before the test so the connection can be made. This may be provided already in the a script depending 11 | if it exists. 12 | 13 | //----------------------------------------------------------------------------- 14 | 15 | //------------Java Application-------------------------------------- 16 | connector - Uses voltdb client to create a connection, do inserts, other procedures that can be defined in another class or defined in ddl.sql 17 | main - runs benchmark applciation 18 | thread - Uses voltdb client to make concurrent procedures such as inserts or reads. 19 | deployment.xml - Cluster config file 20 | 21 | //------------------------------------------------------------------ 22 | 23 | //--------How to Run------------------------------------- 24 | Quick Run Guide: 25 | 1.) ./prep.sh "test flag" 26 | 2.) ./start.sh 27 | 3.) ./sqlcmd 28 | In sqlcmd prompt type 29 | 4.) load classes /home/OpenMemDb/OpenMemDB/database/tests/db_testing/volt_test/catalog.jar; 30 | 5.) file /home/OpenMemDb/OpenMemDB/database/tests/db_testing/volt_test/create.txt; 31 | 6.) exit; 32 | 7.) sudo ./run.sh "thread count" 33 | 8.) ./stop.sh 34 | *NOTE: if the java application is changed run ./benchmark.sh* 35 | *NOTE: execTime.txt is not removed after each run so test results are piled on each other* 36 | 37 | Long Steps: 38 | 1.) Run the server with this script 39 | ./start.sh 40 | 41 | EXAMPLE: 42 | ./start.sh 43 | 44 | *NOTE: SitesperHost should never exceed 24 sites, VoltDB reccommends 16 or 4* 45 | 46 | 2.) Wait for VoltDB to finish setting up. It should say "Server completed initialization." 47 | 48 | 3.) Run ./prep.sh to remove any leftover files from previous runs and compiles the Java Application. 49 | This also compiles the stored procedures Java classes which we will use in the next step. 50 | 51 | EXAMPLE: 52 | ./prep.sh 53 | 54 | 4.) Now that VoltDB is setup we will load it with our stored procedure class and load up our schema. 55 | Run ./sqlcmd in the voltdb/bin directory. This will take you to the sqlcmd prompt. 56 | 57 | *NOTE you can exit out of sqlcmd prompt by typing exit;* 58 | 59 | EXAMPLE: 60 | ./sqlcmd 61 | 62 | 5.) Now type in load classes /path/to/catalog.jar; 63 | Once that is done it should say Command Succeeded. 64 | 65 | EXAMPLE: 66 | load classes /home/OpenMemDb/OpenMemDB/database/tests/db_testing/volt_test/catalog.jar; 67 | 68 | 6.) Now type in file /path/to/create.txt 69 | 70 | EXAMPLE: 71 | file /home/OpenMemDb/OpenMemDB/database/tests/db_testing/volt_test/create.txt; 72 | 73 | 7.) VoltDB database is now loaded with the precompiled tables and stored procedures. 74 | !!BE SURE TO EXIT OUT OF SQLCMD!! 75 | Do so by typing exit; when you are inside the sqlcmd prompt. This is an important step 76 | since ./run.sh script will look for the VoltDB create processes sqlcmd process may confuse 77 | the taskset within run script. 78 | 79 | 9.) Next run the run script, this will ru nthe Java application 80 | 81 | sudo ./run.sh "number of threads" 82 | 83 | This will run the java app and also limits the program to a define amount of cores. 84 | This also includes the VoltDB process will be limited to those cores. 85 | 86 | *NOTE run.sh by DEFAULT uses only one node in the cluster* 87 | Example: 88 | sudo ./run.sh 8 89 | 90 | 10.) This will run the application which will connect to VoltDB database. Wait until the application returns "Done testing" 91 | 92 | 11.) Test results are written to execTime.txt. The top result is insert test time. The bottom result is select test time. 93 | Test results will display Execution Time: "time taken" Threads: "number of threads". 94 | 95 | *NOTE: Time is in milliseconds* 96 | 97 | 12.) Now that you are done with the tests it is time to cleanup! Run ./stop.sh to stop VoltDB, this will take some time to shutoff 98 | so wait before starting VoltDB again or VoltDB will state that ports are still in use. 99 | 100 | To see results type vim execTime.txt 101 | //------------------------------------------------------- 102 | 103 | //--------------------------Interupting the Results--------------------------- 104 | The tests return the number of threads and the time it took to insert those results. Time is in milliseconds, the top result is insert test 105 | and the bottom result is select test. 106 | //------------------------------------------------------ 107 | -------------------------------------------------------------------------------- /database/tests/db_testing/volt_test/Run.java: -------------------------------------------------------------------------------- 1 | import java.util.Scanner; 2 | import java.io.*; 3 | import java.util.ArrayList; 4 | 5 | public class Run 6 | { 7 | public static void main(String[] args) 8 | { 9 | //Execuion time, node size, filename, batch of sql statements, connector 10 | //int size = Integer.parseInt(args[0]); 11 | int size = 1; 12 | int threadCount = Integer.parseInt(args[0]); 13 | long time = 0; 14 | ArrayList sqlStmt; 15 | Connector link = new Connector(); 16 | 17 | //Create connection to client 18 | link.init(size); 19 | 20 | //read input file, run instructions using threads, print results to file 21 | sqlStmt = readFile("input.txt"); 22 | time = time + link.runProcedure(sqlStmt, threadCount); 23 | 24 | System.out.println("Done, results written to execTime.txt"); 25 | String result = printOut(time, threadCount); 26 | 27 | writeFile("execTime.txt", result); 28 | link.close(); 29 | } 30 | 31 | private static String printOut(long time, int threadCount) 32 | { 33 | return "Execution time: " + String.valueOf(time) + " Threads: " + String.valueOf(threadCount) + '\n'; 34 | } 35 | 36 | //file format 37 | private static ArrayList readFile(String filename) 38 | { 39 | try 40 | { 41 | Scanner read = new Scanner(new File(filename)); 42 | ArrayList file = new ArrayList(); 43 | 44 | while(read.hasNextLine()) 45 | { 46 | file.add(read.nextLine()); 47 | } 48 | return file; 49 | } catch (Exception e) 50 | { 51 | e.printStackTrace(); 52 | return null; 53 | } 54 | } 55 | 56 | private static void writeFile(String filename, String content) 57 | { 58 | File file = null; 59 | boolean temp; 60 | 61 | try 62 | { 63 | file = new File(filename); 64 | temp = file.createNewFile(); 65 | FileWriter writer = new FileWriter(file, true); 66 | writer.write(content); 67 | writer.flush(); 68 | writer.close(); 69 | } catch(Exception e) 70 | { 71 | e.printStackTrace(); 72 | } 73 | 74 | } 75 | 76 | //useful for AdHoc since it takes in a multiple SQL statements as a String 77 | private static String arrayToString(ArrayList array) 78 | { 79 | String convertArray = ""; 80 | for(int i = 0; i < array.size(); i++) 81 | { 82 | convertArray = convertArray.concat(array.get(i)); 83 | } 84 | 85 | return convertArray; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /database/tests/db_testing/volt_test/Select.java: -------------------------------------------------------------------------------- 1 | //Stored procedure for selects 2 | //This procedure is necessary since AdHoc is super slow 3 | 4 | import org.voltdb.*; 5 | 6 | public class Select extends VoltProcedure 7 | { 8 | public final SQLStmt Select = new SQLStmt( 9 | "SELECT TestT0.B FROM TestT0 WHERE TestT0.B=?;"); 10 | 11 | public VoltTable[] run(long value) throws VoltAbortException 12 | { 13 | voltQueueSQL(Select, value); 14 | return voltExecuteSQL(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /database/tests/db_testing/volt_test/SelectB.java: -------------------------------------------------------------------------------- 1 | //Stored procedure for selects 2 | //This procedure is necessary since AdHoc is super slow 3 | 4 | import org.voltdb.*; 5 | 6 | public class SelectB extends VoltProcedure 7 | { 8 | public final SQLStmt SelectB = new SQLStmt( 9 | "SELECT TestT0.B FROM TestT0;"); 10 | 11 | public VoltTable[] run(long id) throws VoltAbortException 12 | { 13 | //id is a placeholder so votldb won't error out 14 | voltQueueSQL(SelectB); 15 | return voltExecuteSQL(true); 16 | } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /database/tests/db_testing/volt_test/Worker.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.io.*; 3 | import java.util.concurrent.*; 4 | import org.voltdb.client.*; 5 | import org.voltdb.*; 6 | 7 | public class Worker implements Runnable 8 | { 9 | private org.voltdb.client.Client myApp; 10 | private List batch_list; 11 | private CyclicBarrier gate; 12 | private VoltTable[] results; 13 | 14 | // each thread uses voltdb database, sql batch instructions 15 | public Worker(org.voltdb.client.Client myApp, List batch, CyclicBarrier gate) 16 | { 17 | this.myApp = myApp; 18 | this.batch_list = batch; 19 | this.gate = gate; 20 | } 21 | 22 | //Special run Method to run batch sql statements, it parse the batch and determine which stored procedure is used 23 | @Override 24 | public void run() 25 | { 26 | ClientResponse response = null; 27 | try 28 | { 29 | //wait for gate controlled by main 30 | try 31 | { 32 | this.gate.await(); 33 | } catch(InterruptedException e) 34 | { 35 | e.printStackTrace(); 36 | } catch(BrokenBarrierException e) 37 | { 38 | e.printStackTrace(); 39 | } 40 | 41 | //AdHoc executes multiple sql statements each seperated by ; threads their own instructions 42 | //myApp.callProcedure("@AdHoc", sqlStmt); 43 | // date and value are lists of all of the arguments that this thread should run the stored procedure with 44 | for(int j = 0; j < batch_list.size(); j++) 45 | { 46 | // grab sql statement from batch 47 | String flag = batch_list.get(j); 48 | long value = 0; 49 | 50 | if (flag.contains("INSERT")) { 51 | // Leaving date static as the epoch 52 | value = grabInsertData(flag); 53 | response = myApp.callProcedure("Insert", value, 2); 54 | if(response.getStatus() != ClientResponse.SUCCESS) 55 | { 56 | throw new RuntimeException(response.getStatusString()); 57 | } 58 | } else if (flag.contains("SELECT")) { 59 | try 60 | { 61 | run_everywhere(); 62 | } catch(Exception e) 63 | { 64 | e.printStackTrace(); 65 | } 66 | } 67 | } 68 | 69 | } catch (NoConnectionsException e) 70 | { 71 | System.out.println("Couldn't connect to server"); 72 | e.printStackTrace(); 73 | } catch(IOException e) 74 | { 75 | e.printStackTrace(); 76 | } catch(ProcCallException e) 77 | { 78 | System.out.println("Procedure exception"); 79 | e.printStackTrace(); 80 | } 81 | } 82 | 83 | private void run_everywhere() throws Exception 84 | { 85 | VoltTable results[] = myApp.callProcedure("@GetPartitionKeys", "INTEGER").getResults(); 86 | VoltTable keys = results[0]; 87 | 88 | for(int k = 0; k < keys.getRowCount(); k++) 89 | { 90 | long key = keys.fetchRow(k).getLong(1); 91 | VoltTable table = myApp.callProcedure("SelectB", key).getResults()[0]; 92 | //System.out.println("Partition "+key+"row count = " + table.fetchRow(0).getLong(0)); 93 | } 94 | } 95 | 96 | //useful for AdHoc since it takes in a multiple SQL statements as a String 97 | private String arrayToString(List array) 98 | { 99 | String convertArray = ""; 100 | for(int i = 0; i < array.size(); i++) 101 | { 102 | convertArray = convertArray.concat(array.get(i)); 103 | } 104 | 105 | return convertArray; 106 | } 107 | 108 | //grabs insert data from sql statement, type of instruction in order, and select data 109 | private long grabInsertData(String sqlStmt) 110 | { 111 | long insertData = 0; 112 | if(sqlStmt.contains("INSERT")) 113 | { 114 | //remove string data around insert data 115 | //this is a static sql instruction with exception to the value in second column 116 | String frontStatement = "INSERT INTO TestT0 VALUES ('2016-04-12',"; 117 | String backStatement = ");"; 118 | sqlStmt = sqlStmt.replace(frontStatement,""); 119 | sqlStmt = sqlStmt.replace(backStatement,""); 120 | 121 | insertData = Long.valueOf(sqlStmt); 122 | } 123 | 124 | return insertData; 125 | } 126 | 127 | } 128 | 129 | -------------------------------------------------------------------------------- /database/tests/db_testing/volt_test/create.txt: -------------------------------------------------------------------------------- 1 | CREATE TABLE TestT0 (B BIGINT NOT NULL, A TIMESTAMP); 2 | PARTITION TABLE TestT0 ON COLUMN B; 3 | CREATE PROCEDURE FROM CLASS Insert; 4 | PARTITION PROCEDURE Insert ON TABLE TestT0 COLUMN B; 5 | CREATE PROCEDURE FROM CLASS Select; 6 | PARTITION PROCEDURE Select ON TABLE TestT0 COLUMN B; 7 | CREATE PROCEDURE FROM CLASS SelectB; 8 | PARTITION PROCEDURE SelectB ON TABLE TestT0 COLUMN B; 9 | -------------------------------------------------------------------------------- /database/tests/db_testing/volt_test/deployment.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /database/tests/db_testing/volt_test/makefile: -------------------------------------------------------------------------------- 1 | CP = -classpath 2 | JFLAGS = -g 3 | JC = javac 4 | JJ = java 5 | CLASS_FILES = ".:/home/OpenMemDb/voltdb/voltdb/*" 6 | #CLASS_FILES = ".:/home/heyblackduck/workspace/voltdb/voltdb/*" 7 | .SUFFIXES: .java .class 8 | .java.class: 9 | $(JC) $(JFLAGS) $(CP) $(CLASS_FILES) $*.java 10 | 11 | CLASSES = \ 12 | Run.java \ 13 | Worker.java \ 14 | Connector.java \ 15 | Insert.java \ 16 | Select.java \ 17 | SelectB.java \ 18 | 19 | default: classes 20 | 21 | classes: $(CLASSES:.java=.class) 22 | 23 | run: 24 | $(JJ) $(CP) $(CLASS_FILES) main 25 | 26 | clean: 27 | $(RM) *.class 28 | -------------------------------------------------------------------------------- /database/tests/db_testing/volt_test/parseSQL.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | filename="../../sql_statements.omdbt" 4 | outputFile="input.txt" 5 | #declare -a create 6 | declare -a input 7 | flag="" 8 | 9 | echo "Reading SQL statements" 10 | #Reads file and determines how each line will be stored based on flags 11 | while read line 12 | do 13 | #Set up flag to determine how the read line will be used 14 | case "$line" in 15 | "create" ) flag="create" ;; 16 | "insert" ) flag="insert" ;; 17 | "select" ) flag="select" ;; 18 | "drop" ) flag="drop" ;; 19 | "mixed" ) flag="mixed" ;; 20 | esac 21 | 22 | # parse flags so input only contains insert and select 23 | if [ "$flag" == "insert" ] || [ "$flag" == "select" ] || [ "$flag" == "mixed" ] && [ "$line" != "$flag" ] && [ "$line" != "end" ]; then 24 | echo $line >> $outputFile 25 | fi 26 | done < $filename 27 | echo "Done reading SQL statements" 28 | -------------------------------------------------------------------------------- /database/tests/db_testing/volt_test/prep.sh: -------------------------------------------------------------------------------- 1 | if [[ $# -eq 0 ]]; then 2 | echo "Need an argument" 3 | exit 0 4 | fi 5 | 6 | testFlag=$1 7 | 8 | #Compile Java Application 9 | echo "Removing old class files and compiling Java" 10 | make clean && make 11 | 12 | #Clean up directory and recompile 13 | echo "Removing old catalog jar file" 14 | rm -f catalog.jar 15 | echo "Compiling stored procedure into catalog.jar" 16 | jar cvf catalog.jar *.class 17 | 18 | printf "%s\n" "New Test Run: " >> execTime.txt 19 | 20 | echo "removed old text files" 21 | rm -f select.txt drop.txt insert.txt mixed.txt 22 | 23 | echo "Running OpenMemDB tests" 24 | cd ../.. 25 | /home/OpenMemDb/OpenMemDB/database/tests/tests sqltf $testFlag -c 26 | cd /home/OpenMemDb/OpenMemDB/database/tests/db_testing/volt_test/ 27 | 28 | echo "Spliting sql instructions into seperate files" 29 | ./parseSQL.sh 30 | 31 | -------------------------------------------------------------------------------- /database/tests/db_testing/volt_test/run.sh: -------------------------------------------------------------------------------- 1 | #Runs java app 2 | 3 | #Limits number of cores used 4 | if [ "$(id -u)" != "0" ]; then 5 | echo "Sorry, you need to be root." 6 | exit 1 7 | fi 8 | 9 | 10 | set_num_cpus() 11 | { 12 | arg=$1 13 | dec=1 14 | 15 | taskset -c -a -p 0-$((arg - dec)) $(pidof java) > /dev/null 16 | #taskset -c -a -p 0-$((arg - dec)) $(pidof java) > /dev/null 17 | } 18 | 19 | # Runs java App 20 | set_num_cpus $1 21 | java -classpath ".:/home/OpenMemDb/voltdb/voltdb/*" Run $1 22 | -------------------------------------------------------------------------------- /database/tests/db_testing/volt_test/start.sh: -------------------------------------------------------------------------------- 1 | # Start up script to initalize database 2 | size=1 3 | 4 | #if test -f "deployment.xml"; then rm -f deployment.xml; fi 5 | 6 | # Create default deployment file 7 | #printf " 8 | # 9 | # 10 | # 11 | # 12 | # 13 | # \n" "$size" >> deployment.xml 14 | 15 | # Voltdb Default Ports http=8080 admin=21211 client=21212 internal=3021 jmx=9090 zookeeper=7181 16 | ~/voltdb/bin/voltdb create --deployment=deployment.xml 17 | 18 | -------------------------------------------------------------------------------- /database/tests/db_testing/volt_test/stop.sh: -------------------------------------------------------------------------------- 1 | # A script that stops the server by using voltadmin shutdown -H localhost:"adminport" 2 | # Admin port should be a default value 3 | 4 | size=$1 5 | admin=21211 6 | ~/voltdb/bin/voltadmin shutdown -H localhost:$admin 7 | 8 | #offset=1000 9 | #for((i=0; i < size; i++)) 10 | #do 11 | # ~/voltdb/bin/voltadmin shutdown -H localhost:$((admin+i*offset)) 12 | #done 13 | rm -rf ~/OpenMemDB/database/tests/db_testing/volt_test/voltdbroot 14 | rm -rf ~/OpenMemDB/database/tests/db_testing/volt_test/log 15 | 16 | #screen -d nodes 17 | 18 | #Clean up detached screens 19 | #screen -ls | grep Detached | cut -d. -f1 | awk '{print $1}' | xargs kill 20 | -------------------------------------------------------------------------------- /database/tests/graph_test.py: -------------------------------------------------------------------------------- 1 | from matplotlib import pyplot as plt 2 | from matplotlib import style 3 | from matplotlib.ticker import MultipleLocator, FormatStrFormatter 4 | 5 | test_data = [] 6 | 7 | # read in test results file 8 | with open("test_data.omdbt", "r") as f: 9 | for line in f: 10 | for word in line.split(): 11 | test_data.append(word) 12 | 13 | test_name = test_data[0] 14 | test_case_count = test_data[1] 15 | 16 | speedup_time1 = [] 17 | speedup_time2 = [] 18 | speedup_time3 = [] 19 | speedup_ideal = ['1','2','4','8','16','32','64'] 20 | 21 | for x in range(2, 9): 22 | speedup_time1.append(float(test_data[x])) 23 | 24 | for x in range(9, 16): 25 | speedup_time2.append(float(test_data[x])) 26 | 27 | for x in range(16, 23): 28 | speedup_time3.append(float(test_data[x])) 29 | 30 | 31 | # create and show plot 32 | xticks = ['1','2','4','8','16','32','64'] 33 | x = list(range(len(speedup_time1))) 34 | 35 | style.use('ggplot') 36 | plt.plot(x, speedup_time1, linewidth=3, label="OpenMemDB") 37 | plt.plot(x, speedup_time2, linewidth=3, label="MemSQL") 38 | plt.plot(x, speedup_time3, linewidth=3, label="VoltDB") 39 | plt.plot(x, speedup_ideal, linewidth=3, label="Ideal") 40 | 41 | plt.xticks(x, xticks) 42 | plt.title(test_name) 43 | plt.legend(loc='upper left', numpoints = 1) 44 | plt.ylabel('Speedup') 45 | plt.xlabel('Thread Count') 46 | plt.savefig("test_graph.png") -------------------------------------------------------------------------------- /database/tests/main.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "Test.h" 6 | #include "DataStoreTest.h" 7 | #include "Modes.h" 8 | #include "TestResult.h" 9 | #include "GraphTest.h" 10 | 11 | void printCommands(); 12 | 13 | int main(int argc, char* argv[]) 14 | { 15 | if(argv[1] && argv[2]) 16 | { 17 | if(strcmp(argv[1], "pct") == 0) 18 | { 19 | int threadCount; 20 | std::ofstream outputFile; 21 | 22 | sscanf(argv[2], "%d", &threadCount); 23 | 24 | GraphTest graphTest(MODE_CREATE, threadCount); 25 | } 26 | 27 | if(strcmp(argv[1], "pdt") == 0) 28 | { 29 | int threadCount; 30 | sscanf(argv[2], "%d", &threadCount); 31 | 32 | GraphTest graphTest(MODE_DROP, threadCount); 33 | } 34 | 35 | if(strcmp(argv[1], "pirt") == 0) 36 | { 37 | int threadCount; 38 | sscanf(argv[2], "%d", &threadCount); 39 | 40 | GraphTest graphTest(MODE_INSERT, threadCount); 41 | } 42 | 43 | if(strcmp(argv[1], "pst") == 0) 44 | { 45 | int threadCount; 46 | sscanf(argv[2], "%d", &threadCount); 47 | 48 | GraphTest graphTest(MODE_SELECT, threadCount); 49 | } 50 | 51 | if(strcmp(argv[1], "pmt") == 0) 52 | { 53 | int threadCount; 54 | sscanf(argv[2], "%d", &threadCount); 55 | 56 | GraphTest graphTest(MODE_MIXED, threadCount); 57 | } 58 | 59 | if(strcmp(argv[1], "sqltf") == 0) 60 | { 61 | DataStoreTest test; 62 | 63 | if(strcmp(argv[2], "ct") == 0) 64 | { 65 | 66 | if(argv[3] && strcmp(argv[3], "-c") == 0) 67 | { 68 | test.with(MODE_CREATE) 69 | .generateCompatCases(0b0000) 70 | .printStatementsToFile(); 71 | } 72 | else 73 | { 74 | test.with(MODE_CREATE) 75 | .generateCases(0b0000) 76 | .printStatementsToFile(); 77 | } 78 | } 79 | if(strcmp(argv[2], "dt") == 0) 80 | { 81 | 82 | if(argv[3] && strcmp(argv[3], "-c") == 0) 83 | { 84 | test.with(MODE_DROP) 85 | .generateCompatCases(0b0000) 86 | .printStatementsToFile(); 87 | } 88 | else 89 | { 90 | test.with(MODE_DROP) 91 | .generateCases(0b0000) 92 | .printStatementsToFile(); 93 | } 94 | } 95 | if(strcmp(argv[2], "irt") == 0) 96 | { 97 | 98 | if(argv[3] && strcmp(argv[3], "-c") == 0) 99 | { 100 | test.with(MODE_INSERT) 101 | .generateCompatCases(0b0000) 102 | .printStatementsToFile(); 103 | } 104 | else 105 | { 106 | test.with(MODE_INSERT) 107 | .generateCases(0b0000) 108 | .printStatementsToFile(); 109 | } 110 | 111 | } 112 | if(strcmp(argv[2], "st") == 0) 113 | { 114 | 115 | 116 | if(argv[3] && strcmp(argv[3], "-c") == 0) 117 | { 118 | test.with(MODE_SELECT) 119 | .generateCompatCases(0b0000) 120 | .printStatementsToFile(); 121 | } 122 | else 123 | { 124 | test.with(MODE_SELECT) 125 | .generateCases(0b0000) 126 | .printStatementsToFile(); 127 | } 128 | 129 | } 130 | if(strcmp(argv[2], "mt") == 0) 131 | { 132 | 133 | if(argv[3] && strcmp(argv[3], "-c") == 0) 134 | { 135 | test.with(MODE_MIXED) 136 | .generateCompatCases(0b0000) 137 | .printStatementsToFile(); 138 | } 139 | else 140 | { 141 | test.with(MODE_MIXED) 142 | .generateCases(0b0000) 143 | .printStatementsToFile(); 144 | } 145 | 146 | } 147 | } 148 | } 149 | else 150 | { 151 | printf("Invalid argument, here is a list of commands: \n"); 152 | printCommands(); 153 | } 154 | 155 | return 1; 156 | } 157 | 158 | void printCommands() 159 | { 160 | printf("Performance test commands \n\n"); 161 | printf("\tCreate table test:\tpct \n"); 162 | printf("\tDrop table test:\tpdt \n"); 163 | printf("\tInsert row test:\tpirt \n"); 164 | printf("\tSelect test:\t\tpst \n"); 165 | 166 | printf("_______________________________________________________________\n\n"); 167 | 168 | printf("Print generated sql statments to file\n\n"); 169 | printf("\tsqltf \n\n"); 170 | printf("\tWhere is:\n\n"); 171 | printf("\t\tct\n\t\tdt\n\t\tirt\n\t\tst\n\n"); 172 | printf("\tFor create, drop, insert, and select, respectively\n"); 173 | printf("\n\tthe -c flag with any of the sqltf commands\n"); 174 | printf("\twill print it in compatibility mode with other DBs\n"); 175 | 176 | printf("_______________________________________________________________\n\n"); 177 | 178 | 179 | } -------------------------------------------------------------------------------- /database/tests/performance_test.sh: -------------------------------------------------------------------------------- 1 | echo "Initializing test..." 2 | 3 | case $1 in 4 | "ct") 5 | echo "Performing Create Test" 6 | ./tests pct 1 7 | ./tests pct 2 8 | ./tests pct 4 9 | ./tests pct 8 10 | ./tests pct 16 11 | ./tests pct 32 12 | ./tests pct 64 13 | python graph_test.py 14 | 15 | ;; 16 | "dtt") 17 | echo "Performing Drop Table Test" 18 | ./tests pdt 1 19 | ./tests pdt 2 20 | ./tests pdt 4 21 | ./tests pdt 8 22 | ./tests pdt 16 23 | ./tests pdt 32 24 | ./tests pdt 64 25 | python graph_test.py 26 | 27 | ;; 28 | "irt") 29 | echo "Performing Insert Row Test" 30 | ./tests pirt 1 31 | ./tests pirt 2 32 | ./tests pirt 4 33 | ./tests pirt 8 34 | ./tests pirt 16 35 | ./tests pirt 32 36 | ./tests pirt 64 37 | python graph_test.py 38 | ;; 39 | 40 | "st") 41 | echo "Performing Select Test" 42 | ./tests pst 1 43 | ./tests pst 2 44 | ./tests pst 4 45 | ./tests pst 8 46 | ./tests pst 16 47 | ./tests pst 32 48 | ./tests pst 64 49 | 50 | python graph_test.py 51 | ;; 52 | 53 | "st") 54 | echo "Performing Mixed Test" 55 | ./tests pmt 1 56 | ./tests pmt 2 57 | ./tests pmt 4 58 | ./tests pmt 8 59 | ./tests pmt 16 60 | ./tests pmt 32 61 | ./tests pmt 64 62 | 63 | python graph_test.py 64 | ;; 65 | 66 | *) 67 | echo "No test selected options are:" 68 | echo "ct: Create Test" 69 | echo "dtt: Drop Table Test" 70 | echo "irt: Insert Row Test" 71 | echo "st: Select Test" 72 | 73 | 74 | esac 75 | 76 | -------------------------------------------------------------------------------- /database/tests/voltdb.sh: -------------------------------------------------------------------------------- 1 | filename="sql_statements.omdbt" 2 | declare -a create 3 | declare -a insert 4 | declare -a select 5 | declare -a drop 6 | flag="" 7 | test="" 8 | 9 | #Reads file and determines how each line will be stored based on flags 10 | test=$(head -n 1 $filename) 11 | echo $test 12 | while read line 13 | do 14 | #Set up flag to determine how the read line will be used 15 | case "$line" in 16 | "create" ) flag="create" ;; 17 | "insert" ) flag="insert" ;; 18 | "select" ) flag="select" ;; 19 | "drop" ) flag="drop" ;; 20 | *) continue 21 | esac 22 | 23 | #Copies data into array depending on flag and makes sure that flag is not copied as well 24 | if [ "$flag" == "create" ] && [ "$line" != "$flag" ]; then 25 | create+=("$line") 26 | fi 27 | 28 | if [ "$flag" == "insert" ] && [ "$line" != "$flag" ]; then 29 | insert+=("$line") 30 | fi 31 | 32 | if [ "$flag" == "select" ] && [ "$line" != "$flag" ]; then 33 | select+=("$line") 34 | fi 35 | 36 | if [ "$flag" == "drop" ] && [ "$line" != "$flag" ]; then 37 | drop+=("$line") 38 | fi 39 | 40 | done < $filename 41 | 42 | #print array 43 | printf "%s\n" "${create[@]}" "${insert[@]}" "${select[@]}" "${drop[@]}" >> output.sql 44 | 45 | #TODO: start voltdb 46 | 47 | if [ $test == "create_test" ]; then 48 | startTime=$(date +%s%N)/1000 49 | while 50 | 51 | -------------------------------------------------------------------------------- /database/tools/lemon/Makefile: -------------------------------------------------------------------------------- 1 | all: lemon.c 2 | gcc lemon.c -o lemon 3 | -------------------------------------------------------------------------------- /database/tools/lemon/addopcodes.awk: -------------------------------------------------------------------------------- 1 | #!/usr/bin/awk 2 | # 3 | # This script appends additional token codes to the end of the 4 | # parse.h file that lemon generates. These extra token codes are 5 | # not used by the parser. But they are used by the tokenizer and/or 6 | # the code generator. 7 | # 8 | # 9 | BEGIN { 10 | max = 0 11 | } 12 | /^#define TK_/ { 13 | print $0 14 | if( max<$3 ) max = $3 15 | } 16 | END { 17 | printf "#define TK_%-29s %4d\n", "TO_TEXT", ++max 18 | printf "#define TK_%-29s %4d\n", "TO_BLOB", ++max 19 | printf "#define TK_%-29s %4d\n", "TO_NUMERIC", ++max 20 | printf "#define TK_%-29s %4d\n", "TO_INT", ++max 21 | printf "#define TK_%-29s %4d\n", "TO_REAL", ++max 22 | printf "#define TK_%-29s %4d\n", "ISNOT", ++max 23 | printf "#define TK_%-29s %4d\n", "END_OF_FILE", ++max 24 | printf "#define TK_%-29s %4d\n", "ILLEGAL", ++max 25 | printf "#define TK_%-29s %4d\n", "SPACE", ++max 26 | printf "#define TK_%-29s %4d\n", "UNCLOSED_STRING", ++max 27 | printf "#define TK_%-29s %4d\n", "FUNCTION", ++max 28 | printf "#define TK_%-29s %4d\n", "COLUMN", ++max 29 | printf "#define TK_%-29s %4d\n", "AGG_FUNCTION", ++max 30 | printf "#define TK_%-29s %4d\n", "AGG_COLUMN", ++max 31 | printf "#define TK_%-29s %4d\n", "UMINUS", ++max 32 | printf "#define TK_%-29s %4d\n", "UPLUS", ++max 33 | printf "#define TK_%-29s %4d\n", "REGISTER", ++max 34 | } 35 | --------------------------------------------------------------------------------