Because of code confidentiality, this page only demonstrates the framework
Database Query Language: SimpleQL
A relational database is the most common means of data storage and retrieval in the modern age. A relational database model stores data into one or more tables, where each table has columns and rows. The columns represent a value that can be attributed to an entry (such as color
, name
, or ID
) and the rows represent individual entries or records (such as Name
, my_cat
, or ABC_1695
). For instance, the table pictured below has each row corresponding to a car (a data type), and the columns group a car’s vendors, model, etc. such that this information can be easily retrieved.
However, a database can do much more than simply store information. You must be able to retrieve specific information in an efficient manner. For relational databases, the structured query language (SQL) is a defined method of retrieving information programmatically. It looks like real English, where a valid command for the above table could be:
SELECT Model from Cars marketplace where Price < 30000
which would return a list of models:
[Corvette, Corvette, Malibu, Malibu, Malibu]
Darabase Commands
These commands affect the structure of the database and the running of the command shell. They include the creation and removal of tables, but do not deal with any actual data (items of type string
, double
, int
or bool
).
CREATE
Add a new table to the database:
CREATE Syntax
Creates a new table with N columns (where N > 0). Each column contains data of type [coltype]
and is accessed with the name [coltype]
. Table names and column names should be guaranteed to be space-free. No two columns in the same table can have the same name (you do not need to check). Valid data types for coltype are {double, int, bool, string}
. This table is initially empty.
CREATE Output
Print the following on a single line followed by a newline:
QUIT
Exit the program and delete all data in the database.
QUIT Syntax
QUIT
Cleans up all internal data (i.e. no memory leaks) and exits the program. The program exits with a return 0
from main()
.
QUIT Output
Print a goodbye message, followed by a newline.
Thanks for being simple!
REMOVE
Remove existing table from the database, deleting all data in the table and its definition.
REMOVE Syntax
Removes the table specified by [tablename]
and all associated data from the database, including any created index.
REMOVE Output
Print a confirmation of table deletion, followed by a newline, as follows:
Table Commands
These commands work on one or more tables and are responsible for interacting with actual data, including insertion, deletion, printing, and indexing.
INSERT
Insert new rows at the end (append) of the specified table.
INSERT Syntax
Inserts N
new rows into the table specified by tablename. The first line of the command specifies the tablename and the number of rows, N > 0
, to be inserted. The next N
lines specify the values to be inserted into the table. Each line contains M
values, where M
is guaranteed to be equal to the number of columns in the table. The first value, [value11]
, should be inserted into the first column of the table in the first inserted row, the second value, [value12]
, into the second column of the table in the first inserted row, and so on. Additionally, the types of the values are guaranteed to be the same as the types of the columns they are inserted into. For example, if the second column of the table contains integers, [value12]
is guaranteed to be an int
. Further, string
items are guaranteed to be a single string of whitespace delimited characters (i.e. foo bar
is invalid, but foo_bar
is acceptable).
INSERT Output
Print the message shown below, followed by a newline, where N
is the number of rows inserted, [startN]
is the index of the first row added in the table, and [endN]
is the index of the last row added to the table, 0 based. So, if there were K
rows in the table prior to insertion, [startN] = K
, and [endN] = K + N - 1
.
Print values from selected columns, in the given order, from specified rows.
PRINT Syntax
Directs the program to print the columns specified by [print_colname1]
, [print_colname2]
, … [print_colnameN]
from some/all rows in [tablename]
. If there is no condition, the command is of the form PRINT ... ALL
, and the matching columns from all rows of the table are printed strictly in insertion order. If there is a condition, the command is of the form PRINT ... WHERE [colname] [OP] [value]
, and only rows whose values in the selected [colname]
pass the condition are printed. The rules for the conditional portion are the same as for the DELETE command. The number and order of the column names given in the command do not have to match the number or order of columns in the specified table.
If no index exists or there is a hash
index on the conditional column, the results should be printed in order of insertion into the table.
If a bst index exists on the conditional column, the results should be printed in the order in the BST (least item to greatest item for std::map
constructed with the default std::less
operator), with ties broken by order of insertion into the table.
PRINT Output
Print the requested data followed by a summary. Printing the data is accomplished by printing a single line with the names of the selected columns, followed by a single line from each specified row, where the values of each of the selected columns are separated by a single space. Every line should be followed by a newline.
To print the summary, on a single line, print the number of rows M
printed, and the [tablename]
from which the rows were printed, followed by a newline.
DELETE
Delete selected rows from the specified table.
DELETE Syntax
Deletes all rows from the table specified by [tablename]
where the value of the entry in [colname]
satisfies the operation [OP]
with the given value [value]
. You can assume that [value]
will always be of the same type as [colname]
. For example, to delete all rows from table1 where the entries in column name equal John, the command would be:
Or, to delete all rows from tableSmall
where the entries in column size are greater than 15
, the command would be:
[OP]
can be from the set {<, >, =}
.
DELETE Output
Print a summary of the number of rows deleted from the table as shown below, followed by a newline:
JOIN
Join two tables where values in selected columns match, and print results.
JOIN Syntax
Directs the program to print the data in N
columns, selected by [print_colname1]
, [print_colname2]
, … [print_colnameN]
. The [print_colname]
s will be the names of columns in either the first table [tablename1]
or the second table [tablename2]
, as chosen by the 1/2
argument directly following each </code>[print_colname]</code>.
JOIN Output
Print the requested data followed by a summary. Printing the data is accomplished by printing a single line with the names of the selected columns, followed by a single line from each joined row, where the values of each of the selected columns are separated by a single space. Every line should be followed by a newline.
To print the summary, on a single line, print the number of rows N
printed, and both [tablename1]
and [tablename2]
which were joined, followed by a newline.
GENERATE
Create a search index on the selected column in the specified table.
GENERATE Syntax
Directs the program to create an index of the type [indextype]
on the column [colname]
in the table [tablename]
, where [indextype]
is limited to the set {hash, bst}
, denoting a hash table index and a binary search tree index respectively. Given the [indextype]
hash on column [colname]
, the program should create a hash table that allows a row in the table to be found rapidly given a particular value in the column [colnam]
. Given the [indextype]
bst on column [colname]
, the program should create a binary search tree that allows rows in the table to be found rapidly given a particular value in the column [colname]
. Only one user-generated Index may exist per table, at any one time. If a valid index is requested on a table that already has one, discard the old index before building the new one.
When bst
is the specified index type, a std::map
should be applied; when hash
is the specified index type, a std::unordered_map
should be utilized. It is acceptable for both types to exist at the same time, but only one should be in use or contain data at any given time.