diff --git a/docs/CreateParser.html b/docs/CreateParser.html new file mode 100644 index 0000000..512f766 --- /dev/null +++ b/docs/CreateParser.html @@ -0,0 +1,3 @@ +CreateParser

HaSSQL-1.0.0: Haskell Simple Structured Query Language

Safe HaskellSafe
LanguageHaskell2010

CreateParser

Description

 
Synopsis

Documentation

data CreateExpr Source #

CreateExpr is a constructor for Create Queries

Constructors

Create 

Fields

Instances
Eq CreateExpr Source # 
Instance details

Defined in CreateParser

Show CreateExpr Source # 
Instance details

Defined in CreateParser

createExpr :: Parser CreateExpr Source #

createExpr aggerates all parsers to parse CREATE query

evaluateCreate :: Either ParseError CreateExpr -> Maybe Database -> Maybe Database Source #

evaluateCreate evaluates parsed CreateExpr to create a new table and add columns to it. + First argument is parsed CreateExpr + Second argument is databse instance

\ No newline at end of file diff --git a/docs/Database.html b/docs/Database.html new file mode 100644 index 0000000..faa9723 --- /dev/null +++ b/docs/Database.html @@ -0,0 +1,65 @@ +Database

HaSSQL-1.0.0: Haskell Simple Structured Query Language

Safe HaskellSafe
LanguageHaskell2010

Database

Description

 
Synopsis

Documentation

sampleCommands :: IO Integer Source #

sampleCommands is for debugging purposes.

data Column Source #

Column stores a column in a table as a list of its values along with the datatype and name of column

Constructors

Column 
Instances
Eq Column Source # 
Instance details

Defined in Database

Methods

(==) :: Column -> Column -> Bool #

(/=) :: Column -> Column -> Bool #

Show Column Source # 
Instance details

Defined in Database

newColumn :: String -> Datatype -> [String] -> Maybe Column Source #

newColumn Returns new column (Maybe Column) + First argument is name of column + Second argument is datatype + Third argument is list of values

data Table Source #

Table stores a map of columns (key is column Name) with table name and list of names of columns

Constructors

Table 
Instances
Eq Table Source # 
Instance details

Defined in Database

Methods

(==) :: Table -> Table -> Bool #

(/=) :: Table -> Table -> Bool #

Show Table Source # 
Instance details

Defined in Database

Methods

showsPrec :: Int -> Table -> ShowS #

show :: Table -> String #

showList :: [Table] -> ShowS #

newTable :: String -> ([String], Map String Column) -> [Int] -> Maybe Table Source #

newTable returns new table (Maybe Table) + First argument is table name + Second argument is (list of colNames, Map of those colnames -> Columns)

data Database Source #

Database stores a database with a name and map of tables indexed by their names

Constructors

Database 
Instances
Eq Database Source # 
Instance details

Defined in Database

Show Database Source # 
Instance details

Defined in Database

newDatabase :: String -> Map String Table -> Maybe Database Source #

newDatabase returns new database (Maybe Database) + First argument is datbase name + Second argument map of tables indexed by their names

data Datatype Source #

Datatype is for datatype in a column

Constructors

INT 
STRING 
BOOL 
Instances
Eq Datatype Source # 
Instance details

Defined in Database

Show Datatype Source # 
Instance details

Defined in Database

containsTable :: String -> Maybe Database -> Bool Source #

containsTable is True if database contains table, o/w False + First argument is tableName + Second argument is database object (Maybe database)

containsColumn :: String -> Maybe Database -> String -> Bool Source #

containsColumn returns True if table within database contains a column, o/w false + First argument is column name + Second argument is database (Maybe Database) + Third argument is table name

getTable :: String -> Maybe Database -> Maybe Table Source #

getTable returns table from database (Maybe Table) + First argument is table name + Second argument is database (Maybe Database)

count :: Maybe Table -> Int Source #

count returns the number of entries in a table + First argument is table (Maybe Table)

getColumn :: String -> Maybe Table -> Maybe Column Source #

getColumn returns column in specific table of a database (Maybe Column) + First argument is name of column (String) + Second argument is table (Maybe Table)

addNewTable :: String -> Maybe Database -> Maybe Database Source #

addNewTable adds an empty table to database and returns new database (Maybe Database) + First argument is tableName (String) + Second argument is database (Maybe Database)

addColumnToTable :: String -> Datatype -> Table -> Table Source #

addColumnToTable adds a column to a table and returns new table (Table) + First argument is column name (String) + Second argument is column datatype (Datatype) + Third argumenr is old table (Table)

addColumn :: String -> Datatype -> Maybe Database -> String -> Maybe Database Source #

addColumn adds a column to specific table in database and returns new database (Maybe Database) + First argument is column name (String) + Second argumenr is column datatype (Datatype) + Third argumenr is database (Maybe Database) + Fourth argumenr is table name (String)

insertOne :: String -> Datatype -> Maybe Database -> String -> String -> Maybe Database Source #

insertOne inserts one entry in one column of one table in a database + First argument is value (String) + Second argument is it's datatype (Datatype) + Third argument is old database (Maybe Database) + Fourth argument is table name (String) + Fifth argumenr is column name (String)

isValidDatatype :: Maybe Table -> [String] -> [Datatype] -> Bool Source #

isValidDatatype checks if datatypes corresponding to column names list are in sync with the table in database or not. Returns true if they both conform + First argumenr is table (Maybe Table) + Second argument is list of column names [String] + Third argument is list of datatypes [Datatype]

addPrimaryKeyToTable :: Table -> Table Source #

addPrimaryKeyToTable adds one primary key to a table + First argument is a table (Table)

addPrimaryKey :: Maybe Database -> String -> Maybe Database Source #

addPrimaryKey adds one primary key to table in database + First argument is database (Maybe Database) + Second argument is table name (String)

insert :: [String] -> [String] -> [Datatype] -> Maybe Database -> String -> Maybe Database Source #

insert inserts an entry (row) in database -> table and returns new database + First argumenr is list of colNames [String] + Second argument is corresponding list of values [String] + Third argumenr is corresponding list of datatypes [Datatype] + Fourth argument old database (Maybe Database) + Fifth argument is table name (String)

insertDefault :: [String] -> Maybe Database -> String -> Maybe Database Source #

insertDefault inserts an entry in the default column order. This does not check for datatype as of now. + First argument is list of values + Second argument is old database + Third argument is tableName

getColList :: String -> Maybe Database -> [Column] Source #

getColList is a Utility function for find*

findEntryAtIndex :: String -> Maybe Database -> Int -> [(Int, String, Datatype, String)] Source #

findEntryAtIndex finds entry at index in table and returns as [tuples] where tuple = (col name, col type, col value) + First argument is tableName + Second argument is database + Third argument is index

litValue :: String -> Datatype -> ValueExpr Source #

litValue is a utility function to support evaluation of ValueExpr on columns (which are stored as String)

find :: Either ParseError ValueExpr -> Maybe Database -> String -> [[(Int, String, Datatype, String)]] Source #

find finds all entries in (db -> table) with value, datype and returns as [entries] where entry=[tuples] where tuple = (col name, col type, col value) + First argument is value (Right) ValueExpr that evaluates to true or false + Second argument is database (Maybe Database) + Third argument is table name

deleteFromList :: Int -> [a] -> [a] Source #

deleteFromList is a utility function to delete an entry from a list

deleteEntryAtIndex :: Int -> Maybe Database -> String -> Maybe Database Source #

deleteEntryAtIndex deletes an entry from the table + First argument is the index in table for the entry to be deleted + Second argument is the database (Maybe Database) + Third argument is table name

deleteEntryAtIndices :: [Int] -> Maybe Database -> String -> Maybe Database Source #

deleteEntryAtIndices is used to delete multiple entries from a specific table of a database + First argument is list of indices [Int] + Second argument is database (Maybe Database) + Third argumenr is table name (String)

delete :: Either ParseError ValueExpr -> Maybe Database -> String -> Maybe Database Source #

delete deletes all entries that follow a specific condition from a table + First argument is condition + Second argument is Maybe Database + Third argument is table name (String)

orderBy :: Either ParseError ValueExpr -> [[(Int, String, Datatype, String)]] -> [[(Int, String, Datatype, String)]] Source #

orderBy orders the entries given by find based on the value given by expression + First argument is the expression that gives the deciding value + Second argument is the entrylist returned by find / select

select :: [(String, String)] -> [[(Int, String, Datatype, String)]] -> [[(Int, String, Datatype, String)]] Source #

select selects specific columns from the output of find/orderBy and returns list of entries with those columns only + First argument is column alias (if new name of the columns is needed, then this is used). If this is empty, all columns with default names are returned + Second argument is output of find/orderBy

\ No newline at end of file diff --git a/docs/DeleteParser.html b/docs/DeleteParser.html new file mode 100644 index 0000000..e5021ca --- /dev/null +++ b/docs/DeleteParser.html @@ -0,0 +1,3 @@ +DeleteParser

HaSSQL-1.0.0: Haskell Simple Structured Query Language

Safe HaskellSafe
LanguageHaskell2010

DeleteParser

Description

 
Synopsis

Documentation

data DeleteExpr Source #

DeleteExpr is a constructor type for Delete Queries.

Constructors

Delete 

Fields

Instances
Eq DeleteExpr Source # 
Instance details

Defined in DeleteParser

Show DeleteExpr Source # 
Instance details

Defined in DeleteParser

deleteExpr :: Parser DeleteExpr Source #

deleteExpr' aggerates all parsers to parse CREATE query

evaluateDelete :: Either ParseError DeleteExpr -> Maybe Database -> Maybe Database Source #

evaluateDelete evaluates parsed DeleteExpr to delete rows in database table + First argument is parsed DeleteExpr + Second argument is databse instance

\ No newline at end of file diff --git a/docs/ExpressionParser.html b/docs/ExpressionParser.html new file mode 100644 index 0000000..2c1b264 --- /dev/null +++ b/docs/ExpressionParser.html @@ -0,0 +1,11 @@ +ExpressionParser

HaSSQL-1.0.0: Haskell Simple Structured Query Language

Safe HaskellSafe
LanguageHaskell2010

ExpressionParser

Description

 
Synopsis

Documentation

data ValueExpr Source #

ValueExpr represnts a expression

Constructors

NumLit Integer

NumLit type constructor for integer constants that takes integer as argument

Iden String

Iden type constructor for identifier that takes string as argument

PrefOp String ValueExpr

PrefOp for prefix operators that takes operator(String) and a ValueExpr

BinOp ValueExpr String ValueExpr

BinOp for binary operators that takes operator(String) and two ValueExpr

Parens ValueExpr

Parens type constructor that ValueExpr as argument that is ought to be in parenthesis.

StringLit String

StringLit type constructor for string literals that takes string as argument

Star

Star for * symbol

BoolLit Bool

BoolLit type constructor for boolean constants that takes bool as argument

Instances
Eq ValueExpr Source # 
Instance details

Defined in ExpressionParser

Show ValueExpr Source # 
Instance details

Defined in ExpressionParser

data EvalType Source #

EvalType represnts a return type of evaluator

Constructors

Int Integer

EvalType holds am integral return type

Boolean Bool

Boolean holds a boolean return type

Error String

Error holds a error string

Instances
Eq EvalType Source # 
Instance details

Defined in ExpressionParser

Show EvalType Source # 
Instance details

Defined in ExpressionParser

num :: Parser ValueExpr Source #

num wraps a parsed integer literal in ValueExpr datatype

iden :: [String] -> Parser ValueExpr Source #

iden wraps a parsed identifier literal in ValueExpr datatype + Argument is a blacklist

boolean :: Parser ValueExpr Source #

bolean wraps a parsed boolean literal in ValueExpr datatype

parensValue :: Parser ValueExpr Source #

parensValue wraps a parsed parenthesis expression in ValueExpr datatype

term :: [String] -> Parser ValueExpr Source #

term contains all possible expression types

table :: [[Operator Char () ValueExpr]] Source #

table contains precedence, associativity of integer and boolean operators

valueExpr :: [String] -> Parser ValueExpr Source #

valueExpr parses a given string to ValueExpr datatype + Input is a blacklist

stringLit :: Parser ValueExpr Source #

stringLit wraps a parsed string literal in ValueExpr datatype

star :: Parser ValueExpr Source #

star wraps a parsed * keyword in ValueExpr datatype

evaluate :: Map String ValueExpr -> Either ParseError ValueExpr -> EvalType Source #

evaluate evaluates a parsed ValueExpr to integer EvalType if possible otherwise Exception + First argument is map of variables and corresponding values. + Second argument is a parsed expression type.

evaluate2 :: Map String ValueExpr -> Either ParseError ValueExpr -> EvalType Source #

evaluate2 evaluates a parsed ValueExpr to boolean EvalTypeif possible otherwise Exception + First argument is map of variables and corresponding values. + Second argument is a parsed expression type.

evaluateExpr :: Map String ValueExpr -> ValueExpr -> Integer Source #

evaluateExpr evaluates a ValueExpr to Integer if possible otherwise Exception + First argument is map of variables and corresponding values. + Second argument is a parsed expression (ValueExpr) type.

evaluateExpr2 :: Map String ValueExpr -> ValueExpr -> Bool Source #

evaluateExpr2 evaluates a ValueExpr to Bool if possible otherwise Exception + First argument is map of variables and corresponding values. + Second argument is a parsed expression (ValueExpr) type.

\ No newline at end of file diff --git a/docs/Funcs.html b/docs/Funcs.html new file mode 100644 index 0000000..95b5613 --- /dev/null +++ b/docs/Funcs.html @@ -0,0 +1,4 @@ +Funcs

HaSSQL-1.0.0: Haskell Simple Structured Query Language

Safe HaskellSafe
LanguageHaskell2010

Funcs

Description

 
Synopsis

Documentation

regularParse :: Parser a -> String -> Either ParseError a Source #

The regularParse parses a expression regularlly

parseWithEof :: Parser a -> String -> Either ParseError a Source #

The parseWithEof is a wrapper that throws error if you haven’t consumed all the input

parseWithLeftOver :: Parser a -> String -> Either ParseError (a, String) Source #

The parseWithLeftOver is wrapper that tell you what was not consumed from the input by input parser

parseWithWSEof :: Parser a -> String -> Either ParseError a Source #

The parseWithWSEof wrapper allows parsing when input constains and leading whitespaces

lexeme :: Parser a -> Parser a Source #

The lexeme is wrapper parser that eats up any following whitespaces after parsing.

integer :: Parser Integer Source #

The integer parses a integer constant

identifier :: Parser String Source #

The identifier parses a identifier string

symbol :: String -> Parser String Source #

The symbol parses a single character symbol or operator + It takes string as arguments and comapres it with parsed string.

comma :: Parser Char Source #

The comma parses comma

openParen :: Parser Char Source #

The openParen parses Opening paranthesis

closeParen :: Parser Char Source #

The closeParen parses closing paranthesis

keyword :: String -> Parser String Source #

The keyowrd parses a occurence of string given as input + It takes a string to pe parsed as only input

parens :: Parser a -> Parser a Source #

The parens function parses anything between opening and closing paranthesis

identifierBlacklist :: [String] -> Parser String Source #

The identifierBlacklist parses only that identifiers that are not in blacklist + It takes a blacklist of type List as an argument

whitespace :: Parser () Source #

The whitespace parses any number of any type of whiespaces

keyword_ :: String -> Parser () Source #

The keyword_ parses keywords and ignores them

symbol_ :: String -> Parser () Source #

The symbol_ parses symbol and ignores them

commaSep1 :: Parser a -> Parser [a] Source #

The commaSep1 parses comma seperated items and returns a list

stringToken :: Parser String Source #

The stringToken parses a string literal in single quotes

boolToken :: Parser Bool Source #

The boolToken parses boolean constants True and False

\ No newline at end of file diff --git a/docs/HaSSQL.haddock b/docs/HaSSQL.haddock new file mode 100644 index 0000000..95cf0cb Binary files /dev/null and b/docs/HaSSQL.haddock differ diff --git a/docs/HaSSQL.txt b/docs/HaSSQL.txt new file mode 100644 index 0000000..d5e50cd --- /dev/null +++ b/docs/HaSSQL.txt @@ -0,0 +1,553 @@ +-- Hoogle documentation, generated by Haddock +-- See Hoogle, http://www.haskell.org/hoogle/ + + +-- | Haskell Simple Structured Query Language +-- +-- Please see the README on GitHub at +-- https://github.com/shraiysh/hasql#readme +@package HaSSQL +@version 1.0.0 + + +module Funcs + +-- | The regularParse parses a expression regularlly +regularParse :: Parser a -> String -> Either ParseError a + +-- | The parseWithEof is a wrapper that throws error if you haven’t +-- consumed all the input +parseWithEof :: Parser a -> String -> Either ParseError a + +-- | The parseWithLeftOver is wrapper that tell you what was not +-- consumed from the input by input parser +parseWithLeftOver :: Parser a -> String -> Either ParseError (a, String) + +-- | The parseWithWSEof wrapper allows parsing when input constains +-- and leading whitespaces +parseWithWSEof :: Parser a -> String -> Either ParseError a + +-- | The lexeme is wrapper parser that eats up any following +-- whitespaces after parsing. +lexeme :: Parser a -> Parser a + +-- | The integer parses a integer constant +integer :: Parser Integer + +-- | The identifier parses a identifier string +identifier :: Parser String + +-- | The symbol parses a single character symbol or operator It +-- takes string as arguments and comapres it with parsed string. +symbol :: String -> Parser String + +-- | The comma parses comma +comma :: Parser Char + +-- | The openParen parses Opening paranthesis +openParen :: Parser Char + +-- | The closeParen parses closing paranthesis +closeParen :: Parser Char + +-- | The keyowrd parses a occurence of string given as input It +-- takes a string to pe parsed as only input +keyword :: String -> Parser String + +-- | The parens function parses anything between opening and closing +-- paranthesis +parens :: Parser a -> Parser a + +-- | The identifierBlacklist parses only that identifiers that are +-- not in blacklist It takes a blacklist of type List as an argument +identifierBlacklist :: [String] -> Parser String + +-- | The whitespace parses any number of any type of whiespaces +whitespace :: Parser () + +-- | The keyword_ parses keywords and ignores them +keyword_ :: String -> Parser () + +-- | The symbol_ parses symbol and ignores them +symbol_ :: String -> Parser () + +-- | The commaSep1 parses comma seperated items and returns a list +commaSep1 :: Parser a -> Parser [a] + +-- | The stringToken parses a string literal in single quotes +stringToken :: Parser String + +-- | The boolToken parses boolean constants True and +-- False +boolToken :: Parser Bool + + +module ExpressionParser + +-- | ValueExpr represnts a expression +data ValueExpr + +-- | NumLit type constructor for integer constants that takes +-- integer as argument +NumLit :: Integer -> ValueExpr + +-- | Iden type constructor for identifier that takes string as +-- argument +Iden :: String -> ValueExpr + +-- | PrefOp for prefix operators that takes operator(String) and a +-- ValueExpr +PrefOp :: String -> ValueExpr -> ValueExpr + +-- | BinOp for binary operators that takes operator(String) and two +-- ValueExpr +BinOp :: ValueExpr -> String -> ValueExpr -> ValueExpr + +-- | Parens type constructor that ValueExpr as argument that +-- is ought to be in parenthesis. +Parens :: ValueExpr -> ValueExpr + +-- | StringLit type constructor for string literals that takes +-- string as argument +StringLit :: String -> ValueExpr + +-- | Star for * symbol +Star :: ValueExpr + +-- | BoolLit type constructor for boolean constants that takes bool +-- as argument +BoolLit :: Bool -> ValueExpr + +-- | EvalType represnts a return type of evaluator +data EvalType + +-- | EvalType holds am integral return type +Int :: Integer -> EvalType + +-- | Boolean holds a boolean return type +Boolean :: Bool -> EvalType + +-- | Error holds a error string +Error :: String -> EvalType + +-- | num wraps a parsed integer literal in ValueExpr datatype +num :: Parser ValueExpr + +-- | iden wraps a parsed identifier literal in ValueExpr +-- datatype Argument is a blacklist +iden :: [String] -> Parser ValueExpr + +-- | bolean wraps a parsed boolean literal in ValueExpr +-- datatype +boolean :: Parser ValueExpr + +-- | parensValue wraps a parsed parenthesis expression in +-- ValueExpr datatype +parensValue :: Parser ValueExpr + +-- | term contains all possible expression types +term :: [String] -> Parser ValueExpr + +-- | table contains precedence, associativity of integer and boolean +-- operators +table :: [[Operator Char () ValueExpr]] + +-- | valueExpr parses a given string to ValueExpr datatype +-- Input is a blacklist +valueExpr :: [String] -> Parser ValueExpr + +-- | stringLit wraps a parsed string literal in ValueExpr +-- datatype +stringLit :: Parser ValueExpr + +-- | star wraps a parsed * keyword in ValueExpr +-- datatype +star :: Parser ValueExpr + +-- | evaluate evaluates a parsed ValueExpr to integer +-- EvalType if possible otherwise Exception First argument is map +-- of variables and corresponding values. Second argument is a parsed +-- expression type. +evaluate :: Map String ValueExpr -> Either ParseError ValueExpr -> EvalType + +-- | evaluate2 evaluates a parsed ValueExpr to boolean +-- EvalTypeif possible otherwise Exception First argument is map +-- of variables and corresponding values. Second argument is a parsed +-- expression type. +evaluate2 :: Map String ValueExpr -> Either ParseError ValueExpr -> EvalType + +-- | evaluateExpr evaluates a ValueExpr to Integer if +-- possible otherwise Exception First argument is map of variables and +-- corresponding values. Second argument is a parsed expression +-- (ValueExpr) type. +evaluateExpr :: Map String ValueExpr -> ValueExpr -> Integer + +-- | evaluateExpr2 evaluates a ValueExpr to Bool if possible +-- otherwise Exception First argument is map of variables and +-- corresponding values. Second argument is a parsed expression +-- (ValueExpr) type. +evaluateExpr2 :: Map String ValueExpr -> ValueExpr -> Bool +instance GHC.Show.Show ExpressionParser.EvalType +instance GHC.Classes.Eq ExpressionParser.EvalType +instance GHC.Show.Show ExpressionParser.ValueExpr +instance GHC.Classes.Eq ExpressionParser.ValueExpr + + +module Database + +-- | sampleCommands is for debugging purposes. +sampleCommands :: IO Integer + +-- | Column stores a column in a table as a list of its values along +-- with the datatype and name of column +data Column +Column :: String -> Datatype -> [String] -> Column +[cName] :: Column -> String +[cDatatype] :: Column -> Datatype +[cValues] :: Column -> [String] + +-- | newColumn Returns new column (Maybe Column) First argument is +-- name of column Second argument is datatype Third argument is list of +-- values +newColumn :: String -> Datatype -> [String] -> Maybe Column + +-- | Table stores a map of columns (key is column Name) with table +-- name and list of names of columns +data Table +Table :: String -> [String] -> Map String Column -> [Int] -> Table +[tName] :: Table -> String +[tColNameList] :: Table -> [String] +[tColumns] :: Table -> Map String Column +[tPKeys] :: Table -> [Int] + +-- | newTable returns new table (Maybe Table) First argument is +-- table name Second argument is (list of colNames, Map of those colnames +-- -> Columns) +newTable :: String -> ([String], Map String Column) -> [Int] -> Maybe Table + +-- | Database stores a database with a name and map of tables +-- indexed by their names +data Database +Database :: String -> Map String Table -> Database +[dName] :: Database -> String +[dTables] :: Database -> Map String Table + +-- | newDatabase returns new database (Maybe Database) First +-- argument is datbase name Second argument map of tables indexed by +-- their names +newDatabase :: String -> Map String Table -> Maybe Database + +-- | Datatype is for datatype in a column +data Datatype +INT :: Datatype +STRING :: Datatype +BOOL :: Datatype + +-- | containsTable is True if database contains table, o/w False +-- First argument is tableName Second argument is database object (Maybe +-- database) +containsTable :: String -> Maybe Database -> Bool + +-- | containsColumn returns True if table within database contains a +-- column, o/w false First argument is column name Second argument is +-- database (Maybe Database) Third argument is table name +containsColumn :: String -> Maybe Database -> String -> Bool + +-- | getTable returns table from database (Maybe Table) First +-- argument is table name Second argument is database (Maybe Database) +getTable :: String -> Maybe Database -> Maybe Table + +-- | count returns the number of entries in a table First argument +-- is table (Maybe Table) +count :: Maybe Table -> Int + +-- | getColumn returns column in specific table of a database (Maybe +-- Column) First argument is name of column (String) Second argument is +-- table (Maybe Table) +getColumn :: String -> Maybe Table -> Maybe Column + +-- | addNewTable adds an empty table to database and returns new +-- database (Maybe Database) First argument is tableName (String) Second +-- argument is database (Maybe Database) +addNewTable :: String -> Maybe Database -> Maybe Database + +-- | addColumnToTable adds a column to a table and returns new table +-- (Table) First argument is column name (String) Second argument is +-- column datatype (Datatype) Third argumenr is old table (Table) +addColumnToTable :: String -> Datatype -> Table -> Table + +-- | addColumn adds a column to specific table in database and +-- returns new database (Maybe Database) First argument is column name +-- (String) Second argumenr is column datatype (Datatype) Third argumenr +-- is database (Maybe Database) Fourth argumenr is table name (String) +addColumn :: String -> Datatype -> Maybe Database -> String -> Maybe Database + +-- | insertOne inserts one entry in one column of one table in a +-- database First argument is value (String) Second argument is it's +-- datatype (Datatype) Third argument is old database (Maybe Database) +-- Fourth argument is table name (String) Fifth argumenr is column name +-- (String) +insertOne :: String -> Datatype -> Maybe Database -> String -> String -> Maybe Database + +-- | isValidDatatype checks if datatypes corresponding to column +-- names list are in sync with the table in database or not. Returns true +-- if they both conform First argumenr is table (Maybe Table) Second +-- argument is list of column names [String] Third argument is list of +-- datatypes [Datatype] +isValidDatatype :: Maybe Table -> [String] -> [Datatype] -> Bool + +-- | addPrimaryKeyToTable adds one primary key to a table First +-- argument is a table (Table) +addPrimaryKeyToTable :: Table -> Table + +-- | addPrimaryKey adds one primary key to table in database First +-- argument is database (Maybe Database) Second argument is table name +-- (String) +addPrimaryKey :: Maybe Database -> String -> Maybe Database + +-- | insert inserts an entry (row) in database -> table and +-- returns new database First argumenr is list of colNames [String] +-- Second argument is corresponding list of values [String] Third +-- argumenr is corresponding list of datatypes [Datatype] Fourth argument +-- old database (Maybe Database) Fifth argument is table name (String) +insert :: [String] -> [String] -> [Datatype] -> Maybe Database -> String -> Maybe Database + +-- | insertDefault inserts an entry in the default column order. +-- This does not check for datatype as of now. First argument is list of +-- values Second argument is old database Third argument is tableName +insertDefault :: [String] -> Maybe Database -> String -> Maybe Database + +-- | getColList is a Utility function for find* +getColList :: String -> Maybe Database -> [Column] + +-- | findEntryAtIndex finds entry at index in table and returns as +-- [tuples] where tuple = (col name, col type, col value) First argument +-- is tableName Second argument is database Third argument is index +findEntryAtIndex :: String -> Maybe Database -> Int -> [(Int, String, Datatype, String)] + +-- | litValue is a utility function to support evaluation of +-- ValueExpr on columns (which are stored as String) +litValue :: String -> Datatype -> ValueExpr + +-- | find finds all entries in (db -> table) with value, datype +-- and returns as [entries] where entry=[tuples] where tuple = (col name, +-- col type, col value) First argument is value (Right) ValueExpr that +-- evaluates to true or false Second argument is database (Maybe +-- Database) Third argument is table name +find :: Either ParseError ValueExpr -> Maybe Database -> String -> [[(Int, String, Datatype, String)]] + +-- | deleteFromList is a utility function to delete an entry from a +-- list +deleteFromList :: Int -> [a] -> [a] + +-- | deleteEntryAtIndex deletes an entry from the table First +-- argument is the index in table for the entry to be deleted Second +-- argument is the database (Maybe Database) Third argument is table name +deleteEntryAtIndex :: Int -> Maybe Database -> String -> Maybe Database + +-- | deleteEntryAtIndices is used to delete multiple entries from a +-- specific table of a database First argument is list of indices [Int] +-- Second argument is database (Maybe Database) Third argumenr is table +-- name (String) +deleteEntryAtIndices :: [Int] -> Maybe Database -> String -> Maybe Database + +-- | delete deletes all entries that follow a specific condition +-- from a table First argument is condition Second argument is Maybe +-- Database Third argument is table name (String) +delete :: Either ParseError ValueExpr -> Maybe Database -> String -> Maybe Database + +-- | orderBy orders the entries given by find based on the value +-- given by expression First argument is the expression that gives the +-- deciding value Second argument is the entrylist returned by find / +-- select +orderBy :: Either ParseError ValueExpr -> [[(Int, String, Datatype, String)]] -> [[(Int, String, Datatype, String)]] + +-- | select selects specific columns from the output of find/orderBy +-- and returns list of entries with those columns only First argument is +-- column alias (if new name of the columns is needed, then this is +-- used). If this is empty, all columns with default names are returned +-- Second argument is output of find/orderBy +select :: [(String, String)] -> [[(Int, String, Datatype, String)]] -> [[(Int, String, Datatype, String)]] +instance GHC.Classes.Eq Database.Database +instance GHC.Show.Show Database.Database +instance GHC.Classes.Eq Database.Table +instance GHC.Show.Show Database.Table +instance GHC.Classes.Eq Database.Column +instance GHC.Show.Show Database.Column +instance GHC.Classes.Eq Database.Datatype +instance GHC.Show.Show Database.Datatype + + +module DeleteParser + +-- | DeleteExpr is a constructor type for Delete Queries. +data DeleteExpr +Delete :: ValueExpr -> ValueExpr -> DeleteExpr + +-- | iTname is name of the table +[dTname] :: DeleteExpr -> ValueExpr + +-- | iWhere contains where clause expression +[dWhere] :: DeleteExpr -> ValueExpr + +-- | deleteExpr' aggerates all parsers to parse CREATE query +deleteExpr :: Parser DeleteExpr + +-- | makeDelete creates empty DeleteExpr object +makeDelete :: DeleteExpr + +-- | evaluateDelete evaluates parsed DeleteExpr to delete +-- rows in database table First argument is parsed DeleteExpr +-- Second argument is databse instance +evaluateDelete :: Either ParseError DeleteExpr -> Maybe Database -> Maybe Database +instance GHC.Show.Show DeleteParser.DeleteExpr +instance GHC.Classes.Eq DeleteParser.DeleteExpr + + +module CreateParser + +-- | CreateExpr is a constructor for Create Queries +data CreateExpr +Create :: ValueExpr -> [(ValueExpr, Datatype)] -> CreateExpr + +-- | iTname is name of the table +[iTname] :: CreateExpr -> ValueExpr + +-- | iColLists contains list of column names and their dataype +-- values +[iColLists] :: CreateExpr -> [(ValueExpr, Datatype)] + +-- | createExpr aggerates all parsers to parse CREATE query +createExpr :: Parser CreateExpr + +-- | makeCreate creates empty CreateExpr object +makeCreate :: CreateExpr + +-- | evaluateCreate evaluates parsed CreateExpr to create a +-- new table and add columns to it. First argument is parsed +-- CreateExpr Second argument is databse instance +evaluateCreate :: Either ParseError CreateExpr -> Maybe Database -> Maybe Database +instance GHC.Show.Show CreateParser.CreateExpr +instance GHC.Classes.Eq CreateParser.CreateExpr + + +module InsertParser + +-- | InsertExpr is a constructor type for Insert Queries +data InsertExpr +Insert :: ValueExpr -> [ValueExpr] -> [ValueExpr] -> InsertExpr + +-- | iTname is name of the table +[iTable] :: InsertExpr -> ValueExpr + +-- | iColumns are name of columns +[iColumns] :: InsertExpr -> [ValueExpr] + +-- | iValues are values to insert (NumLit, StringLit, BoolLit) +[iValues] :: InsertExpr -> [ValueExpr] + +-- | insertExpr aggerates all parsers to parse INSERT query +insertExpr :: Parser InsertExpr + +-- | makeInsert creates empty InsertExpr object +makeInsert :: InsertExpr + +-- | evaluateInsert evaluates insert expression ans insert values to +-- table First argument is InserExpr Second argument is database instance +evaluateInsert :: Either ParseError InsertExpr -> Maybe Database -> Maybe Database +instance GHC.Show.Show InsertParser.InsertExpr +instance GHC.Classes.Eq InsertParser.InsertExpr + + +module QueryParser + +-- | QueryExpr represents a SELECT statement +data QueryExpr +Select :: [(ValueExpr, Maybe String)] -> ValueExpr -> Maybe ValueExpr -> [ValueExpr] -> Maybe ValueExpr -> [ValueExpr] -> QueryExpr + +-- | qeSelectList contains list of selected columns +[qeSelectList] :: QueryExpr -> [(ValueExpr, Maybe String)] + +-- | qeFromClause contains table name +[qefromClause] :: QueryExpr -> ValueExpr + +-- | qeWhere contains where clause expression +[qeWhere] :: QueryExpr -> Maybe ValueExpr + +-- | qeGroupBy contains list of groupby expresions +[qeGroupBy] :: QueryExpr -> [ValueExpr] + +-- | qeHaving contains havingby expression +[qeHaving] :: QueryExpr -> Maybe ValueExpr + +-- | qeOrderBy contains list of orderby clause expressions +[qeOrderBy] :: QueryExpr -> [ValueExpr] + +-- | queryExpr aggregates all parsers to parse a SELECT statement +queryExpr :: Parser QueryExpr + +-- | makeSelect makes a empty QueryExpr object +makeSelect :: QueryExpr + +-- | evaluateQuery evaluates a query expression First argument is +-- parsed query expression Second argument is Maybe Database instance +evaluateQuery :: Either ParseError QueryExpr -> Maybe Database -> [[(Int, String, Datatype, String)]] +instance GHC.Show.Show QueryParser.QueryExpr +instance GHC.Classes.Eq QueryParser.QueryExpr + + +module SQLParser + +-- | SQLExpr is a wrapping type constructor for Select, Insert and +-- Delete statements. 'SELECT QueryExpr' contains +data SQLExpr + +-- | Parses a SELECT query +SELECT :: QueryExpr -> SQLExpr + +-- | Parses a INSERT Query +INSERT :: InsertExpr -> SQLExpr + +-- | Parses a CREATE Query +CREATE :: CreateExpr -> SQLExpr + +-- | Parses a DELETE Query +DELETE :: DeleteExpr -> SQLExpr + +-- | ResType is a wrapping type constructor for the response types +-- of each of the above statements. +data ResType + +-- | Database instance for insert, create and delete queries +DB :: Maybe Database -> ResType + +-- | Return object for SELECT queries +OUT :: [[(Int, String, Datatype, String)]] -> ResType +ERROR :: String -> ResType + +-- | sqlExpr describes an SQL expression. +sqlExpr :: Parser SQLExpr + +-- | evaluateSQL evaluates each Expression using individual case +-- statements +evaluateSQL :: Either ParseError SQLExpr -> ResType -> ResType + +-- | getHeader returns string of headers of table First argument +-- is list of headers +getHeaders :: [(Int, String, Datatype, String)] -> String + +-- | getHeader returns string of depicting one entire row First +-- argument is a row +getRow :: [(Int, String, Datatype, String)] -> String + +-- | getRows prints the rows which are the output of select query +-- The argument is output of select parsed query +getRows :: [[(Int, String, Datatype, String)]] -> IO () + +-- | queryPrinter prints the Select query output in a tabular +-- fashion The argument is output of select parsed query +queryPrinter :: ResType -> IO () +instance GHC.Show.Show SQLParser.ResType +instance GHC.Classes.Eq SQLParser.ResType +instance GHC.Show.Show SQLParser.SQLExpr +instance GHC.Classes.Eq SQLParser.SQLExpr diff --git a/docs/InsertParser.html b/docs/InsertParser.html new file mode 100644 index 0000000..d0c43d6 --- /dev/null +++ b/docs/InsertParser.html @@ -0,0 +1,3 @@ +InsertParser

HaSSQL-1.0.0: Haskell Simple Structured Query Language

Safe HaskellSafe
LanguageHaskell2010

InsertParser

Description

 
Synopsis

Documentation

data InsertExpr Source #

InsertExpr is a constructor type for Insert Queries

Constructors

Insert 

Fields

Instances
Eq InsertExpr Source # 
Instance details

Defined in InsertParser

Show InsertExpr Source # 
Instance details

Defined in InsertParser

insertExpr :: Parser InsertExpr Source #

insertExpr aggerates all parsers to parse INSERT query

evaluateInsert :: Either ParseError InsertExpr -> Maybe Database -> Maybe Database Source #

evaluateInsert evaluates insert expression ans insert values to table + First argument is InserExpr + Second argument is database instance

\ No newline at end of file diff --git a/docs/QueryParser.html b/docs/QueryParser.html new file mode 100644 index 0000000..66f7e2c --- /dev/null +++ b/docs/QueryParser.html @@ -0,0 +1,3 @@ +QueryParser

HaSSQL-1.0.0: Haskell Simple Structured Query Language

Safe HaskellSafe
LanguageHaskell2010

QueryParser

Description

 
Synopsis

Documentation

data QueryExpr Source #

QueryExpr represents a SELECT statement

Constructors

Select 

Fields

Instances
Eq QueryExpr Source # 
Instance details

Defined in QueryParser

Show QueryExpr Source # 
Instance details

Defined in QueryParser

queryExpr :: Parser QueryExpr Source #

queryExpr aggregates all parsers to parse a SELECT statement

evaluateQuery :: Either ParseError QueryExpr -> Maybe Database -> [[(Int, String, Datatype, String)]] Source #

evaluateQuery evaluates a query expression + First argument is parsed query expression + Second argument is Maybe Database instance

\ No newline at end of file diff --git a/docs/SQLParser.html b/docs/SQLParser.html new file mode 100644 index 0000000..200612e --- /dev/null +++ b/docs/SQLParser.html @@ -0,0 +1,6 @@ +SQLParser

HaSSQL-1.0.0: Haskell Simple Structured Query Language

Safe HaskellSafe
LanguageHaskell2010

SQLParser

Description

 
Synopsis

Documentation

data SQLExpr Source #

SQLExpr is a wrapping type constructor for Select, Insert and Delete statements. + 'SELECT QueryExpr' contains

Constructors

SELECT QueryExpr

Parses a SELECT query

INSERT InsertExpr

Parses a INSERT Query

CREATE CreateExpr

Parses a CREATE Query

DELETE DeleteExpr

Parses a DELETE Query

Instances
Eq SQLExpr Source # 
Instance details

Defined in SQLParser

Methods

(==) :: SQLExpr -> SQLExpr -> Bool #

(/=) :: SQLExpr -> SQLExpr -> Bool #

Show SQLExpr Source # 
Instance details

Defined in SQLParser

data ResType Source #

ResType is a wrapping type constructor for the response types of each of the above statements.

Constructors

DB (Maybe Database)

Database instance for insert, create and delete queries

OUT [[(Int, String, Datatype, String)]]

Return object for SELECT queries

ERROR String 
Instances
Eq ResType Source # 
Instance details

Defined in SQLParser

Methods

(==) :: ResType -> ResType -> Bool #

(/=) :: ResType -> ResType -> Bool #

Show ResType Source # 
Instance details

Defined in SQLParser

sqlExpr :: Parser SQLExpr Source #

sqlExpr describes an SQL expression.

evaluateSQL :: Either ParseError SQLExpr -> ResType -> ResType Source #

evaluateSQL evaluates each Expression using individual case statements

getHeaders :: [(Int, String, Datatype, String)] -> String Source #

getHeader returns string of headers of table + First argument is list of headers

getRow :: [(Int, String, Datatype, String)] -> String Source #

getHeader returns string of depicting one entire row + First argument is a row

getRows :: [[(Int, String, Datatype, String)]] -> IO () Source #

getRows prints the rows which are the output of select query + The argument is output of select parsed query

queryPrinter :: ResType -> IO () Source #

queryPrinter prints the Select query output in a tabular fashion + The argument is output of select parsed query

\ No newline at end of file diff --git a/docs/doc-index.html b/docs/doc-index.html new file mode 100644 index 0000000..a8163f4 --- /dev/null +++ b/docs/doc-index.html @@ -0,0 +1 @@ +HaSSQL-1.0.0: Haskell Simple Structured Query Language (Index)

HaSSQL-1.0.0: Haskell Simple Structured Query Language

Index

addColumnDatabase
addColumnToTableDatabase
addNewTableDatabase
addPrimaryKeyDatabase
addPrimaryKeyToTableDatabase
BinOpExpressionParser
BOOLDatabase
BooleanExpressionParser
booleanExpressionParser
BoolLitExpressionParser
boolTokenFuncs
cDatatypeDatabase
closeParenFuncs
cNameDatabase
Column 
1 (Type/Class)Database
2 (Data Constructor)Database
commaFuncs
commaSep1Funcs
containsColumnDatabase
containsTableDatabase
countDatabase
CREATESQLParser
CreateCreateParser
CreateExprCreateParser
createExprCreateParser
cValuesDatabase
Database 
1 (Type/Class)Database
2 (Data Constructor)Database
DatatypeDatabase
DBSQLParser
DELETESQLParser
DeleteDeleteParser
deleteDatabase
deleteEntryAtIndexDatabase
deleteEntryAtIndicesDatabase
DeleteExprDeleteParser
deleteExprDeleteParser
deleteFromListDatabase
dNameDatabase
dTablesDatabase
dTnameDeleteParser
dWhereDeleteParser
ERRORSQLParser
ErrorExpressionParser
EvalTypeExpressionParser
evaluateExpressionParser
evaluate2ExpressionParser
evaluateCreateCreateParser
evaluateDeleteDeleteParser
evaluateExprExpressionParser
evaluateExpr2ExpressionParser
evaluateInsertInsertParser
evaluateQueryQueryParser
evaluateSQLSQLParser
findDatabase
findEntryAtIndexDatabase
getColListDatabase
getColumnDatabase
getHeadersSQLParser
getRowSQLParser
getRowsSQLParser
getTableDatabase
iColListsCreateParser
iColumnsInsertParser
IdenExpressionParser
idenExpressionParser
identifierFuncs
identifierBlacklistFuncs
INSERTSQLParser
InsertInsertParser
insertDatabase
insertDefaultDatabase
InsertExprInsertParser
insertExprInsertParser
insertOneDatabase
INTDatabase
IntExpressionParser
integerFuncs
isValidDatatypeDatabase
iTableInsertParser
iTnameCreateParser
iValuesInsertParser
keywordFuncs
keyword_Funcs
lexemeFuncs
litValueDatabase
makeCreateCreateParser
makeDeleteDeleteParser
makeInsertInsertParser
makeSelectQueryParser
newColumnDatabase
newDatabaseDatabase
newTableDatabase
numExpressionParser
NumLitExpressionParser
openParenFuncs
orderByDatabase
OUTSQLParser
ParensExpressionParser
parensFuncs
parensValueExpressionParser
parseWithEofFuncs
parseWithLeftOverFuncs
parseWithWSEofFuncs
PrefOpExpressionParser
qefromClauseQueryParser
qeGroupByQueryParser
qeHavingQueryParser
qeOrderByQueryParser
qeSelectListQueryParser
qeWhereQueryParser
QueryExprQueryParser
queryExprQueryParser
queryPrinterSQLParser
regularParseFuncs
ResTypeSQLParser
sampleCommandsDatabase
SELECTSQLParser
SelectQueryParser
selectDatabase
SQLExprSQLParser
sqlExprSQLParser
StarExpressionParser
starExpressionParser
STRINGDatabase
StringLitExpressionParser
stringLitExpressionParser
stringTokenFuncs
symbolFuncs
symbol_Funcs
Table 
1 (Type/Class)Database
2 (Data Constructor)Database
tableExpressionParser
tColNameListDatabase
tColumnsDatabase
termExpressionParser
tNameDatabase
tPKeysDatabase
ValueExprExpressionParser
valueExprExpressionParser
whitespaceFuncs
\ No newline at end of file diff --git a/docs/doc-index.json b/docs/doc-index.json new file mode 100644 index 0000000..232362c --- /dev/null +++ b/docs/doc-index.json @@ -0,0 +1 @@ +[{"display_html":"regularParse :: Parser a -> String -> Either ParseError a","name":"regularParse","module":"Funcs","link":"Funcs.html#v:regularParse"},{"display_html":"parseWithEof :: Parser a -> String -> Either ParseError a","name":"parseWithEof","module":"Funcs","link":"Funcs.html#v:parseWithEof"},{"display_html":"parseWithLeftOver :: Parser a -> String -> Either ParseError (a, String)","name":"parseWithLeftOver","module":"Funcs","link":"Funcs.html#v:parseWithLeftOver"},{"display_html":"parseWithWSEof :: Parser a -> String -> Either ParseError a","name":"parseWithWSEof","module":"Funcs","link":"Funcs.html#v:parseWithWSEof"},{"display_html":"lexeme :: Parser a -> Parser a","name":"lexeme","module":"Funcs","link":"Funcs.html#v:lexeme"},{"display_html":"integer :: Parser Integer","name":"integer","module":"Funcs","link":"Funcs.html#v:integer"},{"display_html":"identifier :: Parser String","name":"identifier","module":"Funcs","link":"Funcs.html#v:identifier"},{"display_html":"symbol :: String -> Parser String","name":"symbol","module":"Funcs","link":"Funcs.html#v:symbol"},{"display_html":"comma :: Parser Char","name":"comma","module":"Funcs","link":"Funcs.html#v:comma"},{"display_html":"openParen :: Parser Char","name":"openParen","module":"Funcs","link":"Funcs.html#v:openParen"},{"display_html":"closeParen :: Parser Char","name":"closeParen","module":"Funcs","link":"Funcs.html#v:closeParen"},{"display_html":"keyword :: String -> Parser String","name":"keyword","module":"Funcs","link":"Funcs.html#v:keyword"},{"display_html":"parens :: Parser a -> Parser a","name":"parens","module":"Funcs","link":"Funcs.html#v:parens"},{"display_html":"identifierBlacklist :: [String] -> Parser String","name":"identifierBlacklist","module":"Funcs","link":"Funcs.html#v:identifierBlacklist"},{"display_html":"whitespace :: Parser ()","name":"whitespace","module":"Funcs","link":"Funcs.html#v:whitespace"},{"display_html":"keyword_ :: String -> Parser ()","name":"keyword_","module":"Funcs","link":"Funcs.html#v:keyword_"},{"display_html":"symbol_ :: String -> Parser ()","name":"symbol_","module":"Funcs","link":"Funcs.html#v:symbol_"},{"display_html":"commaSep1 :: Parser a -> Parser [a]","name":"commaSep1","module":"Funcs","link":"Funcs.html#v:commaSep1"},{"display_html":"stringToken :: Parser String","name":"stringToken","module":"Funcs","link":"Funcs.html#v:stringToken"},{"display_html":"boolToken :: Parser Bool","name":"boolToken","module":"Funcs","link":"Funcs.html#v:boolToken"},{"display_html":"data ValueExpr","name":"ValueExpr BoolLit Star StringLit Parens BinOp PrefOp Iden NumLit","module":"ExpressionParser","link":"ExpressionParser.html#t:ValueExpr"},{"display_html":"data EvalType","name":"EvalType Boolean Error Int","module":"ExpressionParser","link":"ExpressionParser.html#t:EvalType"},{"display_html":"num :: Parser ValueExpr","name":"num","module":"ExpressionParser","link":"ExpressionParser.html#v:num"},{"display_html":"iden :: [String] -> Parser ValueExpr","name":"iden","module":"ExpressionParser","link":"ExpressionParser.html#v:iden"},{"display_html":"boolean :: Parser ValueExpr","name":"boolean","module":"ExpressionParser","link":"ExpressionParser.html#v:boolean"},{"display_html":"parensValue :: Parser ValueExpr","name":"parensValue","module":"ExpressionParser","link":"ExpressionParser.html#v:parensValue"},{"display_html":"term :: [String] -> Parser ValueExpr","name":"term","module":"ExpressionParser","link":"ExpressionParser.html#v:term"},{"display_html":"table :: [[Operator Char () ValueExpr]]","name":"table","module":"ExpressionParser","link":"ExpressionParser.html#v:table"},{"display_html":"valueExpr :: [String] -> Parser ValueExpr","name":"valueExpr","module":"ExpressionParser","link":"ExpressionParser.html#v:valueExpr"},{"display_html":"stringLit :: Parser ValueExpr","name":"stringLit","module":"ExpressionParser","link":"ExpressionParser.html#v:stringLit"},{"display_html":"star :: Parser ValueExpr","name":"star","module":"ExpressionParser","link":"ExpressionParser.html#v:star"},{"display_html":"evaluate :: Map String ValueExpr -> Either ParseError ValueExpr -> EvalType","name":"evaluate","module":"ExpressionParser","link":"ExpressionParser.html#v:evaluate"},{"display_html":"evaluate2 :: Map String ValueExpr -> Either ParseError ValueExpr -> EvalType","name":"evaluate2","module":"ExpressionParser","link":"ExpressionParser.html#v:evaluate2"},{"display_html":"evaluateExpr :: Map String ValueExpr -> ValueExpr -> Integer","name":"evaluateExpr","module":"ExpressionParser","link":"ExpressionParser.html#v:evaluateExpr"},{"display_html":"evaluateExpr2 :: Map String ValueExpr -> ValueExpr -> Bool","name":"evaluateExpr2","module":"ExpressionParser","link":"ExpressionParser.html#v:evaluateExpr2"},{"display_html":"sampleCommands :: IO Integer","name":"sampleCommands","module":"Database","link":"Database.html#v:sampleCommands"},{"display_html":"data Column = Column {}","name":"Column Column cValues cDatatype cName","module":"Database","link":"Database.html#t:Column"},{"display_html":"newColumn :: String -> Datatype -> [String] -> Maybe Column","name":"newColumn","module":"Database","link":"Database.html#v:newColumn"},{"display_html":"data Table = Table {}","name":"Table Table tPKeys tColumns tColNameList tName","module":"Database","link":"Database.html#t:Table"},{"display_html":"newTable :: String -> ([String], Map String Column) -> [Int] -> Maybe Table","name":"newTable","module":"Database","link":"Database.html#v:newTable"},{"display_html":"data Database = Database {}","name":"Database Database dTables dName","module":"Database","link":"Database.html#t:Database"},{"display_html":"newDatabase :: String -> Map String Table -> Maybe Database","name":"newDatabase","module":"Database","link":"Database.html#v:newDatabase"},{"display_html":"data Datatype","name":"Datatype BOOL INT STRING","module":"Database","link":"Database.html#t:Datatype"},{"display_html":"containsTable :: String -> Maybe Database -> Bool","name":"containsTable","module":"Database","link":"Database.html#v:containsTable"},{"display_html":"containsColumn :: String -> Maybe Database -> String -> Bool","name":"containsColumn","module":"Database","link":"Database.html#v:containsColumn"},{"display_html":"getTable :: String -> Maybe Database -> Maybe Table","name":"getTable","module":"Database","link":"Database.html#v:getTable"},{"display_html":"count :: Maybe Table -> Int","name":"count","module":"Database","link":"Database.html#v:count"},{"display_html":"getColumn :: String -> Maybe Table -> Maybe Column","name":"getColumn","module":"Database","link":"Database.html#v:getColumn"},{"display_html":"addNewTable :: String -> Maybe Database -> Maybe Database","name":"addNewTable","module":"Database","link":"Database.html#v:addNewTable"},{"display_html":"addColumnToTable :: String -> Datatype -> Table -> Table","name":"addColumnToTable","module":"Database","link":"Database.html#v:addColumnToTable"},{"display_html":"addColumn :: String -> Datatype -> Maybe Database -> String -> Maybe Database","name":"addColumn","module":"Database","link":"Database.html#v:addColumn"},{"display_html":"insertOne :: String -> Datatype -> Maybe Database -> String -> String -> Maybe Database","name":"insertOne","module":"Database","link":"Database.html#v:insertOne"},{"display_html":"isValidDatatype :: Maybe Table -> [String] -> [Datatype] -> Bool","name":"isValidDatatype","module":"Database","link":"Database.html#v:isValidDatatype"},{"display_html":"addPrimaryKeyToTable :: Table -> Table","name":"addPrimaryKeyToTable","module":"Database","link":"Database.html#v:addPrimaryKeyToTable"},{"display_html":"addPrimaryKey :: Maybe Database -> String -> Maybe Database","name":"addPrimaryKey","module":"Database","link":"Database.html#v:addPrimaryKey"},{"display_html":"insert :: [String] -> [String] -> [Datatype] -> Maybe Database -> String -> Maybe Database","name":"insert","module":"Database","link":"Database.html#v:insert"},{"display_html":"insertDefault :: [String] -> Maybe Database -> String -> Maybe Database","name":"insertDefault","module":"Database","link":"Database.html#v:insertDefault"},{"display_html":"getColList :: String -> Maybe Database -> [Column]","name":"getColList","module":"Database","link":"Database.html#v:getColList"},{"display_html":"findEntryAtIndex :: String -> Maybe Database -> Int -> [(Int, String, Datatype, String)]","name":"findEntryAtIndex","module":"Database","link":"Database.html#v:findEntryAtIndex"},{"display_html":"litValue :: String -> Datatype -> ValueExpr","name":"litValue","module":"Database","link":"Database.html#v:litValue"},{"display_html":"find :: Either ParseError ValueExpr -> Maybe Database -> String -> [[(Int, String, Datatype, String)]]","name":"find","module":"Database","link":"Database.html#v:find"},{"display_html":"deleteFromList :: Int -> [a] -> [a]","name":"deleteFromList","module":"Database","link":"Database.html#v:deleteFromList"},{"display_html":"deleteEntryAtIndex :: Int -> Maybe Database -> String -> Maybe Database","name":"deleteEntryAtIndex","module":"Database","link":"Database.html#v:deleteEntryAtIndex"},{"display_html":"deleteEntryAtIndices :: [Int] -> Maybe Database -> String -> Maybe Database","name":"deleteEntryAtIndices","module":"Database","link":"Database.html#v:deleteEntryAtIndices"},{"display_html":"delete :: Either ParseError ValueExpr -> Maybe Database -> String -> Maybe Database","name":"delete","module":"Database","link":"Database.html#v:delete"},{"display_html":"orderBy :: Either ParseError ValueExpr -> [[(Int, String, Datatype, String)]] -> [[(Int, String, Datatype, String)]]","name":"orderBy","module":"Database","link":"Database.html#v:orderBy"},{"display_html":"select :: [(String, String)] -> [[(Int, String, Datatype, String)]] -> [[(Int, String, Datatype, String)]]","name":"select","module":"Database","link":"Database.html#v:select"},{"display_html":"data DeleteExpr = Delete {}","name":"DeleteExpr Delete dTname dWhere","module":"DeleteParser","link":"DeleteParser.html#t:DeleteExpr"},{"display_html":"deleteExpr :: Parser DeleteExpr","name":"deleteExpr","module":"DeleteParser","link":"DeleteParser.html#v:deleteExpr"},{"display_html":"makeDelete :: DeleteExpr","name":"makeDelete","module":"DeleteParser","link":"DeleteParser.html#v:makeDelete"},{"display_html":"evaluateDelete :: Either ParseError DeleteExpr -> Maybe Database -> Maybe Database","name":"evaluateDelete","module":"DeleteParser","link":"DeleteParser.html#v:evaluateDelete"},{"display_html":"data CreateExpr = Create {}","name":"CreateExpr Create iTname iColLists","module":"CreateParser","link":"CreateParser.html#t:CreateExpr"},{"display_html":"createExpr :: Parser CreateExpr","name":"createExpr","module":"CreateParser","link":"CreateParser.html#v:createExpr"},{"display_html":"makeCreate :: CreateExpr","name":"makeCreate","module":"CreateParser","link":"CreateParser.html#v:makeCreate"},{"display_html":"evaluateCreate :: Either ParseError CreateExpr -> Maybe Database -> Maybe Database","name":"evaluateCreate","module":"CreateParser","link":"CreateParser.html#v:evaluateCreate"},{"display_html":"data InsertExpr = Insert {}","name":"InsertExpr Insert iTable iColumns iValues","module":"InsertParser","link":"InsertParser.html#t:InsertExpr"},{"display_html":"insertExpr :: Parser InsertExpr","name":"insertExpr","module":"InsertParser","link":"InsertParser.html#v:insertExpr"},{"display_html":"makeInsert :: InsertExpr","name":"makeInsert","module":"InsertParser","link":"InsertParser.html#v:makeInsert"},{"display_html":"evaluateInsert :: Either ParseError InsertExpr -> Maybe Database -> Maybe Database","name":"evaluateInsert","module":"InsertParser","link":"InsertParser.html#v:evaluateInsert"},{"display_html":"data QueryExpr = Select {}","name":"QueryExpr Select qeSelectList qefromClause qeWhere qeGroupBy qeHaving qeOrderBy","module":"QueryParser","link":"QueryParser.html#t:QueryExpr"},{"display_html":"queryExpr :: Parser QueryExpr","name":"queryExpr","module":"QueryParser","link":"QueryParser.html#v:queryExpr"},{"display_html":"makeSelect :: QueryExpr","name":"makeSelect","module":"QueryParser","link":"QueryParser.html#v:makeSelect"},{"display_html":"evaluateQuery :: Either ParseError QueryExpr -> Maybe Database -> [[(Int, String, Datatype, String)]]","name":"evaluateQuery","module":"QueryParser","link":"QueryParser.html#v:evaluateQuery"},{"display_html":"data SQLExpr","name":"SQLExpr DELETE CREATE INSERT SELECT","module":"SQLParser","link":"SQLParser.html#t:SQLExpr"},{"display_html":"data ResType","name":"ResType ERROR OUT DB","module":"SQLParser","link":"SQLParser.html#t:ResType"},{"display_html":"sqlExpr :: Parser SQLExpr","name":"sqlExpr","module":"SQLParser","link":"SQLParser.html#v:sqlExpr"},{"display_html":"evaluateSQL :: Either ParseError SQLExpr -> ResType -> ResType","name":"evaluateSQL","module":"SQLParser","link":"SQLParser.html#v:evaluateSQL"},{"display_html":"getHeaders :: [(Int, String, Datatype, String)] -> String","name":"getHeaders","module":"SQLParser","link":"SQLParser.html#v:getHeaders"},{"display_html":"getRow :: [(Int, String, Datatype, String)] -> String","name":"getRow","module":"SQLParser","link":"SQLParser.html#v:getRow"},{"display_html":"getRows :: [[(Int, String, Datatype, String)]] -> IO ()","name":"getRows","module":"SQLParser","link":"SQLParser.html#v:getRows"},{"display_html":"queryPrinter :: ResType -> IO ()","name":"queryPrinter","module":"SQLParser","link":"SQLParser.html#v:queryPrinter"}] \ No newline at end of file diff --git a/docs/haddock-bundle.min.js b/docs/haddock-bundle.min.js new file mode 100644 index 0000000..1061714 --- /dev/null +++ b/docs/haddock-bundle.min.js @@ -0,0 +1,2 @@ +!function e(t,n,o){function r(s,a){if(!n[s]){if(!t[s]){var l="function"==typeof require&&require;if(!a&&l)return l(s,!0);if(i)return i(s,!0);var c=new Error("Cannot find module '"+s+"'");throw c.code="MODULE_NOT_FOUND",c}var u=n[s]={exports:{}};t[s][0].call(u.exports,function(e){var n=t[s][1][e];return r(n||e)},u,u.exports,e,t,n,o)}return n[s].exports}for(var i="function"==typeof require&&require,s=0;s element with id '"+e+"'");return t}function r(e){for(var t=e.target,n=t.id,r=o(n),i=r.element.open,s=0,l=r.toggles;s0&&(d[n.id]={element:n,openByDefault:!!n.open,toggles:[]},n.addEventListener("toggle",r))}}function s(e){var t=o(e).element;t.open=!t.open}function a(){var e=Object.keys(p);document.cookie="toggled="+encodeURIComponent(e.join("+"))}function l(){var e=h.getCookie("toggled");if(e)for(var t=0,n=e.split("+");t=0&&e.followActiveLink()),"s"===t.key&&"input"!==t.target.tagName.toLowerCase()&&(t.preventDefault(),e.show())})},t.prototype.hide=function(){this.setState({isVisible:!1,searchString:""})},t.prototype.show=function(){this.state.isVisible||(this.focusPlease=!0,this.setState({isVisible:!0,activeLinkIndex:-1}))},t.prototype.toggleVisibility=function(){this.state.isVisible?this.hide():this.show()},t.prototype.navigateLinks=function(e){var t=Math.max(-1,Math.min(this.linkIndex-1,this.state.activeLinkIndex+e));this.navigatedByKeyboard=!0,this.setState({activeLinkIndex:t})},t.prototype.followActiveLink=function(){this.activeLinkAction&&this.activeLinkAction()},t.prototype.updateResults=function(){var e=this.input&&this.input.value||"",t={};this.state.fuse.search(e).forEach(function(e){var n=e.item.module;(t[n]||(t[n]=[])).push(e)});var n=[];for(var o in t)!function(e){var o=t[e],r=0;o.forEach(function(e){r+=1/e.score}),n.push({module:e,totalScore:1/r,items:o})}(o);n.sort(function(e,t){return e.totalScore-t.totalScore}),this.setState({searchString:e,isVisible:!0,moduleResults:n})},t.prototype.componentDidUpdate=function(){if(this.searchResults&&this.activeLink&&this.navigatedByKeyboard){var e=this.activeLink.getClientRects()[0],t=this.searchResults.getClientRects()[0].top;e.bottom>window.innerHeight?this.searchResults.scrollTop+=e.bottom-window.innerHeight+80:e.top=0}function s(e,t){var n=o(e.className||"");n.indexOf(" "+t+" ")<0&&(e.className=r(n+" "+t))}function a(e,t){var n=o(e.className||"");n=n.replace(" "+t+" "," "),e.className=r(n)}function l(e,t,n,o){return null==o&&(o=!i(e,t)),o?(a(e,n),s(e,t)):(a(e,t),s(e,n)),o}function c(e){var t=document.getElementById("page-menu");if(t&&t.firstChild){var n=t.firstChild.cloneNode(!1);n.innerHTML=e,t.appendChild(n)}}function u(){return Array.prototype.slice.call(document.getElementsByTagName("link")).filter(function(e){return-1!=e.rel.indexOf("style")&&e.title})}function h(){var e=u(),t="";e.forEach(function(e){t+="
  • "+e.title+"
  • "}),e.length>1&&c("")}function d(e){for(var t=u(),n=null,o=0;on)return i(e,this.pattern,o);var r=this.options,a=r.location,l=r.distance,c=r.threshold,u=r.findAllMatches,h=r.minMatchCharLength;return s(e,this.pattern,this.patternAlphabet,{location:a,distance:l,threshold:c,findAllMatches:u,minMatchCharLength:h})}}]),e}();e.exports=l},function(e,t,n){"use strict";var o=n(0),r=function e(t,n,r){if(n){var i=n.indexOf("."),s=n,a=null;-1!==i&&(s=n.slice(0,i),a=n.slice(i+1));var l=t[s];if(null!==l&&void 0!==l)if(a||"string"!=typeof l&&"number"!=typeof l)if(o(l))for(var c=0,u=l.length;c0&&void 0!==arguments[0]?arguments[0]:[],t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1,n=[],o=-1,r=-1,i=0,s=e.length;i=t&&n.push([o,r]),o=-1)}return e[i-1]&&i-o>=t&&n.push([o,i-1]),n}},function(e,t,n){"use strict";e.exports=function(e){for(var t={},n=e.length,o=0;o2&&void 0!==arguments[2]?arguments[2]:/ +/g,r=new RegExp(t.replace(o,"\\$&").replace(n,"|")),i=e.match(r),s=!!i,a=[];if(s)for(var l=0,c=i.length;l=E;P-=1){var R=P-1,U=n[e.charAt(R)];if(U&&(b[R]=1),j[P]=(j[P+1]<<1|1)&U,0!==I&&(j[P]|=(L[P+1]|L[P])<<1|1|L[P+1]),j[P]&N&&(C=o(t,{errors:I,currentLocation:R,expectedLocation:g,distance:c}))<=y){if(y=C,(_=R)<=g)break;E=Math.max(1,2*g-_)}}if(o(t,{errors:I+1,currentLocation:g,expectedLocation:g,distance:c})>y)break;L=j}return{isMatch:_>=0,score:0===C?.001:C,matchedIndices:r(b,v)}}},function(e,t,n){"use strict";function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var r=function(){function e(e,t){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:"",t=[];if(this.options.tokenize)for(var n=e.split(this.options.tokenSeparator),o=0,r=n.length;o0&&void 0!==arguments[0]?arguments[0]:[],t=arguments[1],n=this.list,o={},r=[];if("string"==typeof n[0]){for(var i=0,s=n.length;i1)throw new Error("Key weight has to be > 0 and <= 1");p=p.name}else a[p]={weight:1};this._analyze({key:p,value:this.options.getFn(u,p),record:u,index:l},{resultMap:o,results:r,tokenSearchers:e,fullSearcher:t})}return{weights:a,results:r}}},{key:"_analyze",value:function(e,t){var n=e.key,o=e.arrayIndex,r=void 0===o?-1:o,i=e.value,s=e.record,l=e.index,c=t.tokenSearchers,u=void 0===c?[]:c,h=t.fullSearcher,d=void 0===h?[]:h,p=t.resultMap,f=void 0===p?{}:p,v=t.results,g=void 0===v?[]:v;if(void 0!==i&&null!==i){var m=!1,y=-1,_=0;if("string"==typeof i){this._log("\nKey: "+(""===n?"-":n));var k=d.search(i);if(this._log('Full text: "'+i+'", score: '+k.score),this.options.tokenize){for(var b=i.split(this.options.tokenSeparator),x=[],w=0;w-1&&(E=(E+y)/2),this._log("Score average:",E);var T=!this.options.tokenize||!this.options.matchAllTokens||_>=u.length;if(this._log("\nCheck Matches: "+T),(m||k.isMatch)&&T){var j=f[l];j?j.output.push({key:n,arrayIndex:r,value:i,score:E,matchedIndices:k.matchedIndices}):(f[l]={item:s,output:[{key:n,arrayIndex:r,value:i,score:E,matchedIndices:k.matchedIndices}]},g.push(f[l]))}}else if(a(i))for(var P=0,R=i.length;P-1&&(s.arrayIndex=i.arrayIndex),t.matches.push(s)}}}),this.options.includeScore&&n.push(function(e,t){t.score=e.score});for(var o=0,r=e.length;o2;)A.push(arguments[s]);for(n&&null!=n.children&&(A.length||A.push(n.children),delete n.children);A.length;)if((r=A.pop())&&void 0!==r.pop)for(s=r.length;s--;)A.push(r[s]);else"boolean"==typeof r&&(r=null),(i="function"!=typeof t)&&(null==r?r="":"number"==typeof r?r=String(r):"string"!=typeof r&&(i=!1)),i&&o?a[a.length-1]+=r:a===O?a=[r]:a.push(r),o=i;var l=new e;return l.nodeName=t,l.children=a,l.attributes=null==n?void 0:n,l.key=null==n?void 0:n.key,void 0!==I.vnode&&I.vnode(l),l}function o(e,t){for(var n in t)e[n]=t[n];return e}function r(e){!e.__d&&(e.__d=!0)&&1==j.push(e)&&(I.debounceRendering||E)(i)}function i(){var e,t=j;for(j=[];e=t.pop();)e.__d&&L(e)}function s(e,t,n){return"string"==typeof t||"number"==typeof t?void 0!==e.splitText:"string"==typeof t.nodeName?!e._componentConstructor&&a(e,t.nodeName):n||e._componentConstructor===t.nodeName}function a(e,t){return e.__n===t||e.nodeName.toLowerCase()===t.toLowerCase()}function l(e){var t=o({},e.attributes);t.children=e.children;var n=e.nodeName.defaultProps;if(void 0!==n)for(var r in n)void 0===t[r]&&(t[r]=n[r]);return t}function c(e,t){var n=t?document.createElementNS("http://www.w3.org/2000/svg",e):document.createElement(e);return n.__n=e,n}function u(e){var t=e.parentNode;t&&t.removeChild(e)}function h(e,t,n,o,r){if("className"===t&&(t="class"),"key"===t);else if("ref"===t)n&&n(null),o&&o(e);else if("class"!==t||r)if("style"===t){if(o&&"string"!=typeof o&&"string"!=typeof n||(e.style.cssText=o||""),o&&"object"==typeof o){if("string"!=typeof n)for(var i in n)i in o||(e.style[i]="");for(var i in o)e.style[i]="number"==typeof o[i]&&!1===T.test(i)?o[i]+"px":o[i]}}else if("dangerouslySetInnerHTML"===t)o&&(e.innerHTML=o.__html||"");else if("o"==t[0]&&"n"==t[1]){var s=t!==(t=t.replace(/Capture$/,""));t=t.toLowerCase().substring(2),o?n||e.addEventListener(t,p,s):e.removeEventListener(t,p,s),(e.__l||(e.__l={}))[t]=o}else if("list"!==t&&"type"!==t&&!r&&t in e)d(e,t,null==o?"":o),null!=o&&!1!==o||e.removeAttribute(t);else{var a=r&&t!==(t=t.replace(/^xlink\:?/,""));null==o||!1===o?a?e.removeAttributeNS("http://www.w3.org/1999/xlink",t.toLowerCase()):e.removeAttribute(t):"function"!=typeof o&&(a?e.setAttributeNS("http://www.w3.org/1999/xlink",t.toLowerCase(),o):e.setAttribute(t,o))}else e.className=o||""}function d(e,t,n){try{e[t]=n}catch(e){}}function p(e){return this.__l[e.type](I.event&&I.event(e)||e)}function f(){for(var e;e=P.pop();)I.afterMount&&I.afterMount(e),e.componentDidMount&&e.componentDidMount()}function v(e,t,n,o,r,i){R++||(U=null!=r&&void 0!==r.ownerSVGElement,D=null!=e&&!("__preactattr_"in e));var s=g(e,t,n,o,i);return r&&s.parentNode!==r&&r.appendChild(s),--R||(D=!1,i||f()),s}function g(e,t,n,o,r){var i=e,s=U;if(null!=t&&"boolean"!=typeof t||(t=""),"string"==typeof t||"number"==typeof t)return e&&void 0!==e.splitText&&e.parentNode&&(!e._component||r)?e.nodeValue!=t&&(e.nodeValue=t):(i=document.createTextNode(t),e&&(e.parentNode&&e.parentNode.replaceChild(i,e),y(e,!0))),i.__preactattr_=!0,i;var l=t.nodeName;if("function"==typeof l)return C(e,t,n,o);if(U="svg"===l||"foreignObject"!==l&&U,l=String(l),(!e||!a(e,l))&&(i=c(l,U),e)){for(;e.firstChild;)i.appendChild(e.firstChild);e.parentNode&&e.parentNode.replaceChild(i,e),y(e,!0)}var u=i.firstChild,h=i.__preactattr_,d=t.children;if(null==h){h=i.__preactattr_={};for(var p=i.attributes,f=p.length;f--;)h[p[f].name]=p[f].value}return!D&&d&&1===d.length&&"string"==typeof d[0]&&null!=u&&void 0!==u.splitText&&null==u.nextSibling?u.nodeValue!=d[0]&&(u.nodeValue=d[0]):(d&&d.length||null!=u)&&m(i,d,n,o,D||null!=h.dangerouslySetInnerHTML),k(i,t.attributes,h),U=s,i}function m(e,t,n,o,r){var i,a,l,c,h,d=e.childNodes,p=[],f={},v=0,m=0,_=d.length,k=0,b=t?t.length:0;if(0!==_)for(L=0;L<_;L++){var x=d[L],w=x.__preactattr_;null!=(S=b&&w?x._component?x._component.__k:w.key:null)?(v++,f[S]=x):(w||(void 0!==x.splitText?!r||x.nodeValue.trim():r))&&(p[k++]=x)}if(0!==b)for(L=0;L2?[].slice.call(arguments,2):e.children)},Component:N,render:function(e,t,n){return v(n,e,{},!1,t,!1)},rerender:i,options:I};void 0!==t?t.exports=F:self.preact=F}()},{}]},{},[3]); +//# sourceMappingURL=haddock-bundle.min.js.map diff --git a/docs/hslogo-16.png b/docs/hslogo-16.png new file mode 100644 index 0000000..0ff8579 Binary files /dev/null and b/docs/hslogo-16.png differ diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000..5d44f2d --- /dev/null +++ b/docs/index.html @@ -0,0 +1,76 @@ + + + + + + HaSSQL-1.0.0: Haskell Simple Structured Query Language + + + + + + + +
    + +

    HaSSQL-1.0.0: Haskell Simple Structured Query Language

    +
    +
    +
    +

    HaSSQL-1.0.0: Haskell Simple Structured Query Language

    +
    +

    Usage and Syntax

    +
      +
    1. Create Table
    2. +
      create table <table_name> (<column_name> <datatype> ,<column_name> <datatype> ... )
      +
    3. Insert Record
    4. +
      insert into <table_name> (<column_name>,<column_name> ...) values (<value>, <value> ...)
      +

      To add entries in columns by default:

      insert into <table_name> values (<value>, <<>value> ...)

      +
    5. Delete records
    6. +
      insert into <table_name> (<column_name>,<column_name> ...) values (<value>, <value> ...)
      +
    7. Select records
    8. +
      select <column_name> as <alias>, <column_name> as <alias> ... from <table_name> where <value_expession> order by <value_expession>, <value_expession> ...
      +
      select <column_name> <alias>, <column_name> <alias> ... from <table_name> where <value_expession> order by <value_expession>, <value_expession> ...
      +

      To select all columns:

      select * from <table_name> where <value_expession> order by <value_expession>, <value_expession> ...<

      +
    9. Displaying the whole database instance
    10. +
      output
      +
    11. Exiting:
    12. +
      exit
      +
    +

    Please see the README on GitHub at https://github.com/IITH-SBJoshi/haskell-8#readme

    +
    +
    +
    +

    Modules

    +
      +
    • CreateParser contains functions to parse + CREATE query and evaluate it.
    • +
    • Database The core module which manages all + the data.
    • +
    • DeleteParser contains functions to parse + DELETE query and evaluate it.
    • +
    • ExpressionParser contains functions + to parse expressions and evaluate them.
    • +
    • Funcs Contains standard parsers for building up + other parsers
    • +
    • InsertParser contains functions to parse + INSERT query and evaluate it.
    • +
    • QueryParser contains functions to parse + SELECT query and evaluate it.
    • +
    • SQLParser Integrate all SQL statements into + a single module
    • +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/meta.json b/docs/meta.json new file mode 100644 index 0000000..a655a0f --- /dev/null +++ b/docs/meta.json @@ -0,0 +1 @@ +{"haddock_version":"2.22.0","quickjump_version":1} \ No newline at end of file diff --git a/docs/minus.gif b/docs/minus.gif new file mode 100644 index 0000000..1deac2f Binary files /dev/null and b/docs/minus.gif differ diff --git a/docs/ocean.css b/docs/ocean.css new file mode 100644 index 0000000..ba6af9c --- /dev/null +++ b/docs/ocean.css @@ -0,0 +1,647 @@ +/* @group Fundamentals */ + +* { margin: 0; padding: 0 } + +/* Is this portable? */ +html { + background-color: white; + width: 100%; + height: 100%; +} + +body { + background: white; + color: black; + text-align: left; + min-height: 100%; + position: relative; +} + +p { + margin: 0.8em 0; +} + +ul, ol { + margin: 0.8em 0 0.8em 2em; +} + +dl { + margin: 0.8em 0; +} + +dt { + font-weight: bold; +} +dd { + margin-left: 2em; +} + +a { text-decoration: none; } +a[href]:link { color: rgb(196,69,29); } +a[href]:visited { color: rgb(171,105,84); } +a[href]:hover { text-decoration:underline; } + +a[href].def:link, a[href].def:visited { color: black; } +a[href].def:hover { color: rgb(78, 98, 114); } + +/* @end */ + +/* @group Show and hide with JS */ + +body.js-enabled .hide-when-js-enabled { + display: none; +} + +/* @end */ + +/* @group Fonts & Sizes */ + +/* Basic technique & IE workarounds from YUI 3 + For reasons, see: + http://yui.yahooapis.com/3.1.1/build/cssfonts/fonts.css + */ + +body { + font:13px/1.4 sans-serif; + *font-size:small; /* for IE */ + *font:x-small; /* for IE in quirks mode */ +} + +h1 { font-size: 146.5%; /* 19pt */ } +h2 { font-size: 131%; /* 17pt */ } +h3 { font-size: 116%; /* 15pt */ } +h4 { font-size: 100%; /* 13pt */ } +h5 { font-size: 100%; /* 13pt */ } + +select, input, button, textarea { + font:99% sans-serif; +} + +table { + font-size:inherit; + font:100%; +} + +pre, code, kbd, samp, tt, .src { + font-family:monospace; + *font-size:108%; + line-height: 124%; +} + +.links, .link { + font-size: 85%; /* 11pt */ +} + +#module-header .caption { + font-size: 182%; /* 24pt */ +} + +#module-header .caption sup { + font-size: 70%; + font-weight: normal; +} + +.info { + font-size: 85%; /* 11pt */ +} + +#table-of-contents, #synopsis { + /* font-size: 85%; /* 11pt */ +} + + +/* @end */ + +/* @group Common */ + +.caption, h1, h2, h3, h4, h5, h6, summary { + font-weight: bold; + color: rgb(78,98,114); + margin: 0.8em 0 0.4em; +} + +* + h1, * + h2, * + h3, * + h4, * + h5, * + h6 { + margin-top: 2em; +} + +h1 + h2, h2 + h3, h3 + h4, h4 + h5, h5 + h6 { + margin-top: inherit; +} + +ul.links { + list-style: none; + text-align: left; + float: right; + display: inline-table; + margin: 0 0 0 1em; +} + +ul.links li { + display: inline; + border-left: 1px solid #d5d5d5; + white-space: nowrap; + padding: 0; +} + +ul.links li a { + padding: 0.2em 0.5em; +} + +.hide { display: none; } +.show { display: inherit; } +.clear { clear: both; } + +.collapser { + background-image: url(minus.gif); + background-repeat: no-repeat; +} +.expander { + background-image: url(plus.gif); + background-repeat: no-repeat; +} +.collapser, .expander { + padding-left: 14px; + margin-left: -14px; + cursor: pointer; +} +p.caption.collapser, +p.caption.expander { + background-position: 0 0.4em; +} + +.instance.collapser, .instance.expander { + margin-left: 0px; + background-position: left center; + min-width: 9px; + min-height: 9px; +} + +summary { + cursor: pointer; + outline: none; + list-style-image: url(plus.gif); + list-style-position: outside; +} + +details[open] > summary { + list-style-image: url(minus.gif); +} + +pre { + padding: 0.25em; + margin: 0.8em 0; + background: rgb(229,237,244); + overflow: auto; + border-bottom: 0.25em solid white; + /* white border adds some space below the box to compensate + for visual extra space that paragraphs have between baseline + and the bounding box */ +} + +.src { + background: #f0f0f0; + padding: 0.2em 0.5em; +} + +.keyword { font-weight: normal; } +.def { font-weight: bold; } + +@media print { + #footer { display: none; } +} + +/* @end */ + +/* @group Page Structure */ + +#content { + margin: 0 auto; + padding: 0 2em 6em; +} + +#package-header { + background: rgb(41,56,69); + border-top: 5px solid rgb(78,98,114); + color: #ddd; + padding: 0.2em; + position: relative; + text-align: left; +} + +#package-header .caption { + background: url(hslogo-16.png) no-repeat 0em; + color: white; + margin: 0 2em; + font-weight: normal; + font-style: normal; + padding-left: 2em; +} + +#package-header a:link, #package-header a:visited { color: white; } +#package-header a:hover { background: rgb(78,98,114); } + +#module-header .caption { + color: rgb(78,98,114); + font-weight: bold; + border-bottom: 1px solid #ddd; +} + +table.info { + float: right; + padding: 0.5em 1em; + border: 1px solid #ddd; + color: rgb(78,98,114); + background-color: #fff; + max-width: 40%; + border-spacing: 0; + position: relative; + top: -0.5em; + margin: 0 0 0 2em; +} + +.info th { + padding: 0 1em 0 0; +} + +div#style-menu-holder { + position: relative; + z-index: 2; + display: inline; +} + +#style-menu { + position: absolute; + z-index: 1; + overflow: visible; + background: #374c5e; + margin: 0; + text-align: center; + right: 0; + padding: 0; + top: 1.25em; +} + +#style-menu li { + display: list-item; + border-style: none; + margin: 0; + padding: 0; + color: #000; + list-style-type: none; +} + +#style-menu li + li { + border-top: 1px solid #919191; +} + +#style-menu a { + width: 6em; + padding: 3px; + display: block; +} + +#footer { + background: #ddd; + border-top: 1px solid #aaa; + padding: 0.5em 0; + color: #666; + text-align: center; + position: absolute; + bottom: 0; + width: 100%; + height: 3em; +} + +/* @end */ + +/* @group Front Matter */ + +#table-of-contents { + float: right; + clear: right; + background: #faf9dc; + border: 1px solid #d8d7ad; + padding: 0.5em 1em; + max-width: 20em; + margin: 0.5em 0 1em 1em; +} + +#table-of-contents .caption { + text-align: center; + margin: 0; +} + +#table-of-contents ul { + list-style: none; + margin: 0; +} + +#table-of-contents ul ul { + margin-left: 2em; +} + +#description .caption { + display: none; +} + +#synopsis { + display: block; + position: fixed; + right: 0; + height: 80%; + top: 10%; + padding: 0; + max-width: 75%; + /* Ensure that synopsis covers everything (including MathJAX markup) */ + z-index: 1; +} + +#synopsis summary { + display: block; + float: left; + width: 29px; + color: rgba(255,255,255,0); + height: 110px; + margin: 0; + font-size: 1px; + padding: 0; + background: url(synopsis.png) no-repeat 0px -8px; +} + +#synopsis details[open] > summary { + background: url(synopsis.png) no-repeat -64px -8px; +} + +#synopsis ul { + height: 100%; + overflow: auto; + padding: 0.5em; + margin: 0; +} + +#synopsis ul ul { + overflow: hidden; +} + +#synopsis ul, +#synopsis ul li.src { + background-color: #faf9dc; + white-space: nowrap; + list-style: none; + margin-left: 0; +} + +/* @end */ + +/* @group Main Content */ + +#interface div.top { margin: 2em 0; } +#interface h1 + div.top, +#interface h2 + div.top, +#interface h3 + div.top, +#interface h4 + div.top, +#interface h5 + div.top { + margin-top: 1em; +} +#interface .src .selflink, +#interface .src .link { + float: right; + color: #919191; + background: #f0f0f0; + padding: 0 0.5em 0.2em; + margin: 0 -0.5em 0 0; + -moz-user-select: none; +} +#interface .src .selflink { + border-left: 1px solid #919191; + margin: 0 -0.5em 0 0.5em; +} + +#interface span.fixity { + color: #919191; + border-left: 1px solid #919191; + padding: 0.2em 0.5em 0.2em 0.5em; + margin: 0 -1em 0 1em; +} + +#interface span.rightedge { + border-left: 1px solid #919191; + padding: 0.2em 0 0.2em 0; + margin: 0 0 0 1em; +} + +#interface table { border-spacing: 2px; } +#interface td { + vertical-align: top; + padding-left: 0.5em; +} + +#interface td.doc p { + margin: 0; +} +#interface td.doc p + p { + margin-top: 0.8em; +} + +.doc table { + border-collapse: collapse; + border-spacing: 0px; +} + +.doc th, +.doc td { + padding: 5px; + border: 1px solid #ddd; +} + +.doc th { + background-color: #f0f0f0; +} + +.clearfix:after { + clear: both; + content: " "; + display: block; + height: 0; + visibility: hidden; +} + +.subs ul { + list-style: none; + display: table; + margin: 0; +} + +.subs ul li { + display: table-row; +} + +.subs ul li dfn { + display: table-cell; + font-style: normal; + font-weight: bold; + margin: 1px 0; + white-space: nowrap; +} + +.subs ul li > .doc { + display: table-cell; + padding-left: 0.5em; + margin-bottom: 0.5em; +} + +.subs ul li > .doc p { + margin: 0; +} + +/* Render short-style data instances */ +.inst ul { + height: 100%; + padding: 0.5em; + margin: 0; +} + +.inst, .inst li { + list-style: none; + margin-left: 1em; +} + +/* Workaround for bug in Firefox (issue #384) */ +.inst-left { + float: left; +} + +.top p.src { + border-top: 1px solid #ccc; +} + +.subs, .doc { + /* use this selector for one level of indent */ + padding-left: 2em; +} + +.warning { + color: red; +} + +.arguments { + margin-top: -0.4em; +} +.arguments .caption { + display: none; +} + +.fields { padding-left: 1em; } + +.fields .caption { display: none; } + +.fields p { margin: 0 0; } + +/* this seems bulky to me +.methods, .constructors { + background: #f8f8f8; + border: 1px solid #eee; +} +*/ + +/* @end */ + +/* @group Auxillary Pages */ + + +.extension-list { + list-style-type: none; + margin-left: 0; +} + +#mini { + margin: 0 auto; + padding: 0 1em 1em; +} + +#mini > * { + font-size: 93%; /* 12pt */ +} + +#mini #module-list .caption, +#mini #module-header .caption { + font-size: 125%; /* 15pt */ +} + +#mini #interface h1, +#mini #interface h2, +#mini #interface h3, +#mini #interface h4 { + font-size: 109%; /* 13pt */ + margin: 1em 0 0; +} + +#mini #interface .top, +#mini #interface .src { + margin: 0; +} + +#mini #module-list ul { + list-style: none; + margin: 0; +} + +#alphabet ul { + list-style: none; + padding: 0; + margin: 0.5em 0 0; + text-align: center; +} + +#alphabet li { + display: inline; + margin: 0 0.25em; +} + +#alphabet a { + font-weight: bold; +} + +#index .caption, +#module-list .caption { font-size: 131%; /* 17pt */ } + +#index table { + margin-left: 2em; +} + +#index .src { + font-weight: bold; +} +#index .alt { + font-size: 77%; /* 10pt */ + font-style: italic; + padding-left: 2em; +} + +#index td + td { + padding-left: 1em; +} + +#module-list ul { + list-style: none; + margin: 0 0 0 2em; +} + +#module-list li { + clear: right; +} + +#module-list span.collapser, +#module-list span.expander { + background-position: 0 0.3em; +} + +#module-list .package { + float: right; +} + +:target { + background-color: #ffff00; +} + +/* @end */ diff --git a/docs/plus.gif b/docs/plus.gif new file mode 100644 index 0000000..2d15c14 Binary files /dev/null and b/docs/plus.gif differ diff --git a/docs/quick-jump.css b/docs/quick-jump.css new file mode 100644 index 0000000..468d803 --- /dev/null +++ b/docs/quick-jump.css @@ -0,0 +1,164 @@ +/* @group Search box layout */ + +#search { + position: fixed; + top: 3.2em; + bottom: 0; + left: calc(50% - 22em); + width: 44em; + z-index: 1000; + pointer-events: none; + overflow-y: auto; +} + +#search.hidden { + display: none; +} + +#search-form, #search-results { + box-shadow: 2px 2px 6px rgb(199, 204, 208); + pointer-events: all; +} + +#search-form input { + font-size: 1.25em; line-height: 2.3em; height: 2.4em; + display: block; + box-sizing: border-box; + width: 100%; + margin: 0; + padding: 0 0.75em; + border: 0.05em solid rgb(151, 179, 202); +} + +#search input:focus { + outline: none; +} + +#search p.error { + color: rgb(107, 24, 24); + font-weight: bold; +} + +#search-results { + box-sizing: border-box; + border: 0.05em solid #b2d5fb; + background: #e8f3ff; +} + +#search-form input + #search-results { + border-top: none; + top: 3em; + max-height: calc(100% - 3em); +} + +/* @end */ + +/* @group search results */ + +#search-results > ul { + margin: 0; + list-style: none; +} + +#search-results > ul > li, +#search-results > p, +#search-results > table { + padding: 0.5em 1em; + margin: 0; +} + +#search-results > ul > li { + border-bottom: 1px solid #b2d5fb; +} + +#search-results > ul > li > ul { + list-style: none; +} + +.search-module h4 { + margin: 0; +} + +.search-module > ul { + margin: 0.5em 0 0.5em 2em; +} + +.search-module > ul > li > a[href] { + display: block; + color: inherit; + padding: 0.25em 0.5em; +} + +.search-module > ul > li > a[href].active-link { + background: #faf9dc; +} + +.search-module a[href]:hover { + text-decoration: none; +} + +.search-result a a { + pointer-events: none; +} + +.search-result ul.subs { + display: inline-block; + margin: 0; padding: 0; +} + +.search-result ul.subs li { + display: none; +} + +.search-result ul.subs::after { + display: inline-block; + content: "..."; + color: rgb(78,98,114); + margin: 0 0.25em; +} + +.more-results { + color: rgb(99, 141, 173); + position: relative; +} + +.more-results::before { + content: "+"; + display: inline-block; + color: #b2d5fb; + font-weight: bold; + font-size: 1.25em; line-height: inherit; + position: absolute; + left: -1em; +} + +/* @end */ + +/* @group Keyboard shortcuts table */ + +.keyboard-shortcuts { + line-height: 1.6em; +} + +.keyboard-shortcuts th { + color: rgb(78,98,114); +} + +.keyboard-shortcuts td:first-child, +.keyboard-shortcuts th:first-child { + text-align: right; + padding-right: 0.6em; +} + +.key { + display: inline-block; + font-size: 0.9em; + min-width: 0.8em; line-height: 1.2em; + text-align: center; + background: #b2d5fb; + border: 1px solid #74a3d6; + padding: 0 0.2em; + margin: 0 0.1em; +} + +/* @end */ diff --git a/docs/quick-jump.min.js b/docs/quick-jump.min.js new file mode 100644 index 0000000..c03e083 --- /dev/null +++ b/docs/quick-jump.min.js @@ -0,0 +1,2 @@ +!function e(t,n,o){function r(s,a){if(!n[s]){if(!t[s]){var l="function"==typeof require&&require;if(!a&&l)return l(s,!0);if(i)return i(s,!0);var c=new Error("Cannot find module '"+s+"'");throw c.code="MODULE_NOT_FOUND",c}var u=n[s]={exports:{}};t[s][0].call(u.exports,function(e){var n=t[s][1][e];return r(n||e)},u,u.exports,e,t,n,o)}return n[s].exports}for(var i="function"==typeof require&&require,s=0;s=0&&e.followActiveLink()),"s"===t.key&&"input"!==t.target.tagName.toLowerCase()&&(t.preventDefault(),e.show())})},t.prototype.hide=function(){this.setState({isVisible:!1,searchString:""})},t.prototype.show=function(){this.state.isVisible||(this.focusPlease=!0,this.setState({isVisible:!0,activeLinkIndex:-1}))},t.prototype.toggleVisibility=function(){this.state.isVisible?this.hide():this.show()},t.prototype.navigateLinks=function(e){var t=Math.max(-1,Math.min(this.linkIndex-1,this.state.activeLinkIndex+e));this.navigatedByKeyboard=!0,this.setState({activeLinkIndex:t})},t.prototype.followActiveLink=function(){this.activeLinkAction&&this.activeLinkAction()},t.prototype.updateResults=function(){var e=this.input&&this.input.value||"",t={};this.state.fuse.search(e).forEach(function(e){var n=e.item.module;(t[n]||(t[n]=[])).push(e)});var n=[];for(var o in t)!function(e){var o=t[e],r=0;o.forEach(function(e){r+=1/e.score}),n.push({module:e,totalScore:1/r,items:o})}(o);n.sort(function(e,t){return e.totalScore-t.totalScore}),this.setState({searchString:e,isVisible:!0,moduleResults:n})},t.prototype.componentDidUpdate=function(){if(this.searchResults&&this.activeLink&&this.navigatedByKeyboard){var e=this.activeLink.getClientRects()[0],t=this.searchResults.getClientRects()[0].top;e.bottom>window.innerHeight?this.searchResults.scrollTop+=e.bottom-window.innerHeight+80:e.topn)return i(e,this.pattern,o);var r=this.options,a=r.location,l=r.distance,c=r.threshold,u=r.findAllMatches,h=r.minMatchCharLength;return s(e,this.pattern,this.patternAlphabet,{location:a,distance:l,threshold:c,findAllMatches:u,minMatchCharLength:h})}}]),e}();e.exports=l},function(e,t,n){"use strict";var o=n(0),r=function e(t,n,r){if(n){var i=n.indexOf("."),s=n,a=null;-1!==i&&(s=n.slice(0,i),a=n.slice(i+1));var l=t[s];if(null!==l&&void 0!==l)if(a||"string"!=typeof l&&"number"!=typeof l)if(o(l))for(var c=0,u=l.length;c0&&void 0!==arguments[0]?arguments[0]:[],t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1,n=[],o=-1,r=-1,i=0,s=e.length;i=t&&n.push([o,r]),o=-1)}return e[i-1]&&i-o>=t&&n.push([o,i-1]),n}},function(e,t,n){"use strict";e.exports=function(e){for(var t={},n=e.length,o=0;o2&&void 0!==arguments[2]?arguments[2]:/ +/g,r=new RegExp(t.replace(o,"\\$&").replace(n,"|")),i=e.match(r),s=!!i,a=[];if(s)for(var l=0,c=i.length;l=O;E-=1){var R=E-1,U=n[e.charAt(R)];if(U&&(b[R]=1),P[E]=(P[E+1]<<1|1)&U,0!==I&&(P[E]|=(L[E+1]|L[E])<<1|1|L[E+1]),P[E]&N&&(C=o(t,{errors:I,currentLocation:R,expectedLocation:_,distance:c}))<=m){if(m=C,(y=R)<=_)break;O=Math.max(1,2*_-y)}}if(o(t,{errors:I+1,currentLocation:_,expectedLocation:_,distance:c})>m)break;L=P}return{isMatch:y>=0,score:0===C?.001:C,matchedIndices:r(b,v)}}},function(e,t,n){"use strict";function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var r=function(){function e(e,t){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:"",t=[];if(this.options.tokenize)for(var n=e.split(this.options.tokenSeparator),o=0,r=n.length;o0&&void 0!==arguments[0]?arguments[0]:[],t=arguments[1],n=this.list,o={},r=[];if("string"==typeof n[0]){for(var i=0,s=n.length;i1)throw new Error("Key weight has to be > 0 and <= 1");d=d.name}else a[d]={weight:1};this._analyze({key:d,value:this.options.getFn(u,d),record:u,index:l},{resultMap:o,results:r,tokenSearchers:e,fullSearcher:t})}return{weights:a,results:r}}},{key:"_analyze",value:function(e,t){var n=e.key,o=e.arrayIndex,r=void 0===o?-1:o,i=e.value,s=e.record,l=e.index,c=t.tokenSearchers,u=void 0===c?[]:c,h=t.fullSearcher,p=void 0===h?[]:h,d=t.resultMap,f=void 0===d?{}:d,v=t.results,_=void 0===v?[]:v;if(void 0!==i&&null!==i){var g=!1,m=-1,y=0;if("string"==typeof i){this._log("\nKey: "+(""===n?"-":n));var k=p.search(i);if(this._log('Full text: "'+i+'", score: '+k.score),this.options.tokenize){for(var b=i.split(this.options.tokenSeparator),x=[],w=0;w-1&&(O=(O+m)/2),this._log("Score average:",O);var j=!this.options.tokenize||!this.options.matchAllTokens||y>=u.length;if(this._log("\nCheck Matches: "+j),(g||k.isMatch)&&j){var P=f[l];P?P.output.push({key:n,arrayIndex:r,value:i,score:O,matchedIndices:k.matchedIndices}):(f[l]={item:s,output:[{key:n,arrayIndex:r,value:i,score:O,matchedIndices:k.matchedIndices}]},_.push(f[l]))}}else if(a(i))for(var E=0,R=i.length;E-1&&(s.arrayIndex=i.arrayIndex),t.matches.push(s)}}}),this.options.includeScore&&n.push(function(e,t){t.score=e.score});for(var o=0,r=e.length;o2;)A.push(arguments[s]);for(n&&null!=n.children&&(A.length||A.push(n.children),delete n.children);A.length;)if((r=A.pop())&&void 0!==r.pop)for(s=r.length;s--;)A.push(r[s]);else"boolean"==typeof r&&(r=null),(i="function"!=typeof t)&&(null==r?r="":"number"==typeof r?r=String(r):"string"!=typeof r&&(i=!1)),i&&o?a[a.length-1]+=r:a===T?a=[r]:a.push(r),o=i;var l=new e;return l.nodeName=t,l.children=a,l.attributes=null==n?void 0:n,l.key=null==n?void 0:n.key,void 0!==I.vnode&&I.vnode(l),l}function o(e,t){for(var n in t)e[n]=t[n];return e}function r(e){!e.__d&&(e.__d=!0)&&1==P.push(e)&&(I.debounceRendering||O)(i)}function i(){var e,t=P;for(P=[];e=t.pop();)e.__d&&L(e)}function s(e,t,n){return"string"==typeof t||"number"==typeof t?void 0!==e.splitText:"string"==typeof t.nodeName?!e._componentConstructor&&a(e,t.nodeName):n||e._componentConstructor===t.nodeName}function a(e,t){return e.__n===t||e.nodeName.toLowerCase()===t.toLowerCase()}function l(e){var t=o({},e.attributes);t.children=e.children;var n=e.nodeName.defaultProps;if(void 0!==n)for(var r in n)void 0===t[r]&&(t[r]=n[r]);return t}function c(e,t){var n=t?document.createElementNS("http://www.w3.org/2000/svg",e):document.createElement(e);return n.__n=e,n}function u(e){var t=e.parentNode;t&&t.removeChild(e)}function h(e,t,n,o,r){if("className"===t&&(t="class"),"key"===t);else if("ref"===t)n&&n(null),o&&o(e);else if("class"!==t||r)if("style"===t){if(o&&"string"!=typeof o&&"string"!=typeof n||(e.style.cssText=o||""),o&&"object"==typeof o){if("string"!=typeof n)for(var i in n)i in o||(e.style[i]="");for(var i in o)e.style[i]="number"==typeof o[i]&&!1===j.test(i)?o[i]+"px":o[i]}}else if("dangerouslySetInnerHTML"===t)o&&(e.innerHTML=o.__html||"");else if("o"==t[0]&&"n"==t[1]){var s=t!==(t=t.replace(/Capture$/,""));t=t.toLowerCase().substring(2),o?n||e.addEventListener(t,d,s):e.removeEventListener(t,d,s),(e.__l||(e.__l={}))[t]=o}else if("list"!==t&&"type"!==t&&!r&&t in e)p(e,t,null==o?"":o),null!=o&&!1!==o||e.removeAttribute(t);else{var a=r&&t!==(t=t.replace(/^xlink\:?/,""));null==o||!1===o?a?e.removeAttributeNS("http://www.w3.org/1999/xlink",t.toLowerCase()):e.removeAttribute(t):"function"!=typeof o&&(a?e.setAttributeNS("http://www.w3.org/1999/xlink",t.toLowerCase(),o):e.setAttribute(t,o))}else e.className=o||""}function p(e,t,n){try{e[t]=n}catch(e){}}function d(e){return this.__l[e.type](I.event&&I.event(e)||e)}function f(){for(var e;e=E.pop();)I.afterMount&&I.afterMount(e),e.componentDidMount&&e.componentDidMount()}function v(e,t,n,o,r,i){R++||(U=null!=r&&void 0!==r.ownerSVGElement,D=null!=e&&!("__preactattr_"in e));var s=_(e,t,n,o,i);return r&&s.parentNode!==r&&r.appendChild(s),--R||(D=!1,i||f()),s}function _(e,t,n,o,r){var i=e,s=U;if(null!=t&&"boolean"!=typeof t||(t=""),"string"==typeof t||"number"==typeof t)return e&&void 0!==e.splitText&&e.parentNode&&(!e._component||r)?e.nodeValue!=t&&(e.nodeValue=t):(i=document.createTextNode(t),e&&(e.parentNode&&e.parentNode.replaceChild(i,e),m(e,!0))),i.__preactattr_=!0,i;var l=t.nodeName;if("function"==typeof l)return C(e,t,n,o);if(U="svg"===l||"foreignObject"!==l&&U,l=String(l),(!e||!a(e,l))&&(i=c(l,U),e)){for(;e.firstChild;)i.appendChild(e.firstChild);e.parentNode&&e.parentNode.replaceChild(i,e),m(e,!0)}var u=i.firstChild,h=i.__preactattr_,p=t.children;if(null==h){h=i.__preactattr_={};for(var d=i.attributes,f=d.length;f--;)h[d[f].name]=d[f].value}return!D&&p&&1===p.length&&"string"==typeof p[0]&&null!=u&&void 0!==u.splitText&&null==u.nextSibling?u.nodeValue!=p[0]&&(u.nodeValue=p[0]):(p&&p.length||null!=u)&&g(i,p,n,o,D||null!=h.dangerouslySetInnerHTML),k(i,t.attributes,h),U=s,i}function g(e,t,n,o,r){var i,a,l,c,h,p=e.childNodes,d=[],f={},v=0,g=0,y=p.length,k=0,b=t?t.length:0;if(0!==y)for(L=0;L2?[].slice.call(arguments,2):e.children)},Component:N,render:function(e,t,n){return v(n,e,{},!1,t,!1)},rerender:i,options:I};void 0!==t?t.exports=F:self.preact=F}()},{}]},{},[1]); +//# sourceMappingURL=quick-jump.min.js.map diff --git a/docs/src/CreateParser.html b/docs/src/CreateParser.html new file mode 100644 index 0000000..94860d1 --- /dev/null +++ b/docs/src/CreateParser.html @@ -0,0 +1,86 @@ +
    {-|
    +Module      : CreateParser
    +Description : contains functions to parse CREATE query and evaluate it.
    +-}
    +module CreateParser (
    +CreateExpr(..),
    +createExpr,
    +makeCreate, evaluateCreate ) where
    +
    +import Text.Parsec.String (Parser)
    +import Text.ParserCombinators.Parsec.Char
    +import Text.ParserCombinators.Parsec.Combinator
    +import Text.Parsec (parse , ParseError , try)
    +import Control.Applicative ((<*),(<$>), (*>), (<|>),(<$),(<*>))
    +import Control.Monad
    +import qualified Text.ParserCombinators.Parsec.Expr as E
    +
    +import Data.Maybe ()
    +import Funcs
    +import ExpressionParser
    +import Database
    +
    +-- |'int' parses INTEGER datatype
    +int :: Parser Datatype
    +int = INT <$ keyword "INTEGER"
    +
    +-- |'str' parses STRING datatype
    +str :: Parser Datatype
    +str =  STRING <$ keyword "STRING"
    +
    +-- |'bool' parses BOOL datatype
    +bool :: Parser Datatype
    +bool = BOOL <$ keyword "BOOL"
    +
    +-- |'dtypeExpr' parses Datatypes
    +dtypeExpr :: Parser Datatype
    +dtypeExpr = int <|> str <|> bool
    +
    +-- | 'CreateExpr' is a constructor for Create Queries
    +data CreateExpr = Create
    +                { iTname :: ValueExpr -- ^ 'iTname' is name of the table
    +                , iColLists:: [(ValueExpr , Datatype)] -- ^ 'iColLists' contains list of column names and their dataype values
    +                } deriving(Eq,Show)
    +
    +-- |'makeCreate' creates empty 'CreateExpr' object
    +makeCreate :: CreateExpr
    +makeCreate =  Create {iTname = Iden ""
    +                     ,iColLists = []
    +                 }
    +
    +-- |'tabeName' parses name of the table
    +tableName :: Parser ValueExpr
    +tableName = keyword_ "create" *> keyword_ "table" *> iden []
    +
    +-- |'column' parses column name and datatype as a tuple
    +column :: Parser (ValueExpr, Datatype)
    +column = (,) <$> iden [] <*> dtypeExpr
    +
    +-- |'columnList' parses comma seperated columns as list
    +columnList :: Parser [(ValueExpr,Datatype)]
    +columnList = parens (commaSep1 column)
    +
    +-- |'createExpr' aggerates all parsers to parse CREATE query
    +createExpr :: Parser CreateExpr
    +createExpr = Create <$> tableName <*> columnList
    +
    +-- |'addColumnList' is a recursive function to add columns to table
    +-- First argument is column list (Name, Datatype)
    +-- Second argument is Maybe Database instance
    +-- Third argument is string (table name)
    +addColumnList :: [(ValueExpr ,Datatype)] -> Maybe Database -> String -> Maybe Database
    +addColumnList [] db tb = db
    +addColumnList (x : xs) db tb = addColumnList xs (addColumn (eval (fst x)) (snd x) db tb) tb
    +
    +eval :: ValueExpr -> String
    +eval (Iden s) = s
    +
    +-- |'evaluateCreate' evaluates parsed 'CreateExpr' to create a new table and add columns to it.
    +-- First argument is parsed 'CreateExpr'
    +-- Second argument is databse instance
    +evaluateCreate :: Either ParseError CreateExpr -> Maybe Database -> Maybe Database
    +evaluateCreate (Right expr) db = do
    + let db_1 = addNewTable (eval (iTname expr)) db
    + addColumnList (iColLists expr) db_1 (eval (iTname expr))
    +
    +
    \ No newline at end of file diff --git a/docs/src/Database.html b/docs/src/Database.html new file mode 100644 index 0000000..0963cac --- /dev/null +++ b/docs/src/Database.html @@ -0,0 +1,390 @@ +
    {-|
    +Module:      Database
    +Description: The core module which manages all the data.
    +-}
    +module Database where
    +import qualified Data.Map
    +import Data.Maybe (fromJust, isNothing)
    +import Data.List (elemIndex, elemIndices)
    +import Data.Sort(sortBy)
    +-- import Data.List.Key (sort)
    +import qualified ExpressionParser as Exp
    +import qualified Text.Parsec.Error
    +
    +import qualified Funcs as F
    +
    +
    +-- for debugging only. To be removed once completed - called from main right now!
    +-- | 'sampleCommands' is for debugging purposes.
    +sampleCommands = do
    +    print "======================================="
    +
    +    let my_db = newDatabase "my_db 1" Data.Map.empty
    +    -- print $ my_db
    +
    +    let my_db_1 = addNewTable "table 1" my_db
    +    -- print $ my_db_1
    +
    +    let my_db = my_db_1
    +    let my_db_1 = addNewTable "table 2" my_db
    +    -- print $ my_db_1
    +
    +    let my_db = my_db_1
    +    let contains = containsTable "table 1" my_db
    +    -- print $ contains
    +
    +    let my_db_1 = addColumn "Name" STRING my_db "table 1"
    +    let my_db = my_db_1
    +    let my_db_1 = addColumn "Phone_number" INT my_db "table 1"
    +    let my_db = addColumn "BoolCol" BOOL my_db_1 "table 1"
    +    -- print my_db_1
    +
    +    -- let my_db = my_db_1
    +    -- let my_db_1 = insertOne "23" INT my_db "table 1" "column 1 for table 1"
    +    -- print my_db_1
    +
    +    -- let my_db = my_db_1
    +    -- let my_db_1 = insertOne "45" INT my_db "table 1" "column 1 for table 1"
    +    -- print my_db_1
    +
    +    let my_db_1 = insert ["Name", "Phone_number", "BoolCol"] ["Martha", "12345", "False"] [STRING, INT, BOOL] my_db "table 1"
    +    -- print my_db_1
    +    -- print(my_db_1)
    +    let my_db = my_db_1
    +    let my_db_1 = insert ["BoolCol", "Name", "Phone_number"] ["True", "Stewart", "78910"] [BOOL, STRING, INT] my_db "table 1"
    +    -- print(my_db_1)
    +
    +    let m = F.parseWithWSEof (Exp.valueExpr []) "BoolCol"
    +    let n = F.parseWithWSEof (Exp.valueExpr []) "Phone_number > 0"
    +    let o = F.parseWithWSEof (Exp.valueExpr []) "Phone_number = 78910"
    +    let p = F.parseWithWSEof (Exp.valueExpr []) "-1 * Phone_number"
    +    -- print m
    +    let x = delete o my_db_1 "table 1"
    +    print("Y=-------------------->")
    +    -- print x
    +    -- print n
    +    let x = find n my_db_1 "table 1"
    +    let y = orderBy p x
    +    print y
    +    let y = select [("BoolCol", "IsFemale"), ("Phone_number", "home_number")] $ orderBy p x
    +    -- print y
    +    -- print o
    +    let x = find o my_db_1 "table 1"
    +    -- print x
    +
    +    -- print my_db_1
    +
    +
    +    -- let my_db = my_db_1
    +    -- let my_db_1 = insert ["Name", "Phone number"] ["Stewart", "12321"] [STRING, INT] my_db "table 1"
    +
    +    -- let x = find (\value -> value == "Stewart") my_db_1 "table 1" "Name"
    +    -- print(x)
    +    -- let my_db = deleteEntryAtIndex 3 my_db_1 "table 1"
    +    -- print(my_db)
    +
    +    -- print my_db_1
    +
    +    return 0
    +
    +
    +-- I understand that the code in this file is terrible. That's because of my f*cked up data-structure. If I have sufficient time to rebuild the structure, I will do it. But it's gonna be a lot of work.
    +
    +-- | 'Column' stores a column in a table as a list of its values along with the datatype and name of column
    +data Column = Column {
    +    cName :: String,
    +    cDatatype :: Datatype, -- For Num => Num, String => String, Bool => Bool
    +    cValues :: [String]
    +} deriving (Show, Eq)
    +
    +-- |'newColumn' Returns new column (Maybe Column)
    +-- First argument is name of column
    +-- Second argument is datatype
    +-- Third argument is list of values
    +newColumn :: String -> Datatype -> [String] -> Maybe Column
    +newColumn name datatype values = Just Column {
    +    cName = name,
    +    cDatatype = datatype,
    +    cValues = values
    +}
    +
    +-- | 'Table' stores a map of columns (key is column Name) with table name and list of names of columns
    +data Table = Table {
    +    tName :: String,
    +    tColNameList :: [String],
    +    tColumns :: Data.Map.Map String Column,
    +    tPKeys :: [Int]
    +} deriving (Show, Eq)
    +
    +-- | 'newTable' returns new table (Maybe Table)
    +-- First argument is table name
    +-- Second argument is (list of colNames, Map of those colnames -> Columns)
    +newTable :: String -> ([String], Data.Map.Map String Column) -> [Int] -> Maybe Table
    +newTable name (colNameList, columns) pKeys= Just Table {
    +    tName = name,
    +    tColNameList = colNameList,
    +    tColumns = columns,
    +    tPKeys = pKeys
    +}
    +
    +-- | 'Database' stores a database with a name and map of tables indexed by their names
    +data Database = Database {
    +    dName :: String,
    +    dTables :: Data.Map.Map String Table
    +} deriving (Show, Eq)
    +
    +-- | 'newDatabase' returns new database (Maybe Database)
    +-- First argument is datbase name
    +-- Second argument map of tables indexed by their names
    +newDatabase :: String -> Data.Map.Map String Table -> Maybe Database
    +newDatabase name tables = Just Database {
    +    dName = name,
    +    dTables = tables
    +}
    +
    +-- | 'Datatype' is for datatype in a column
    +data Datatype = INT | STRING | BOOL deriving (Show, Eq)
    +
    +-- | 'containsTable' is True if database contains table, o/w False
    +-- First argument is tableName
    +-- Second argument is database object (Maybe database)
    +containsTable :: String -> Maybe Database -> Bool
    +containsTable tableName database = not (isNothing $ getTable tableName database)
    +
    +-- | 'containsColumn' returns True if table within database contains a column, o/w false
    +-- First argument is column name
    +-- Second argument is database (Maybe Database)
    +-- Third argument is table name
    +containsColumn :: String -> Maybe Database -> String -> Bool
    +containsColumn columnName database tableName = elem columnName (tColNameList $ fromJust $ getTable tableName database)
    +
    +-- | 'getTable' returns table from database (Maybe Table)
    +-- First argument is table name
    +-- Second argument is database (Maybe Database)
    +getTable :: String -> Maybe Database -> Maybe Table
    +getTable tableName database
    +    | isNothing database = Nothing
    +    | otherwise = Data.Map.lookup tableName $ dTables $ fromJust database
    +
    +-- | 'count' returns the number of entries in a table
    +-- First argument is table (Maybe Table)
    +count :: Maybe Table -> Int
    +count table
    +    | isNothing table || Data.Map.size (tColumns $ fromJust table) == 0 = 0
    +    | otherwise = let firstCol = snd $ Data.Map.elemAt 0 (tColumns $ fromJust table)
    +        in length (cValues firstCol)
    +
    +
    +-- | 'getColumn' returns column in specific table of a database (Maybe Column)
    +-- First argument is name of column (String)
    +-- Second argument is table (Maybe Table)
    +getColumn :: String -> Maybe Table -> Maybe Column
    +getColumn columnName table
    +    | isNothing table = Nothing
    +    | otherwise = Data.Map.lookup columnName (tColumns $ fromJust table)
    +
    +-- | 'addNewTable' adds an empty table to database and returns new database (Maybe Database)
    +-- First argument is tableName (String)
    +-- Second argument is database (Maybe Database)
    +addNewTable :: String -> Maybe Database -> Maybe Database
    +addNewTable tableName database
    +    | isNothing database = Nothing
    +    | otherwise = Just Database {
    +        dName = dName $ fromJust database,
    +        dTables = Data.Map.insert tableName (fromJust $ newTable tableName ([],Data.Map.empty) []) (dTables $ fromJust database)
    +    }
    +
    +-- | 'addColumnToTable' adds a column to a table and returns new table (Table)
    +-- First argument is column name (String)
    +-- Second argument is column datatype (Datatype)
    +-- Third argumenr is old table (Table)
    +addColumnToTable :: String -> Datatype -> Table -> Table
    +addColumnToTable columnName datatype table = fromJust $ newTable (tName table)
    +        ((tColNameList table) ++ [columnName], Data.Map.insert columnName (fromJust $ newColumn columnName datatype []) (tColumns table)) (tPKeys table)
    +
    +-- | 'addColumn' adds a column to specific table in database and returns new database (Maybe Database)
    +-- First argument is column name (String)
    +-- Second argumenr is column datatype (Datatype)
    +-- Third argumenr is database (Maybe Database)
    +-- Fourth argumenr is table name (String)
    +addColumn :: String -> Datatype -> Maybe Database -> String -> Maybe Database
    +addColumn columnName datatype database tableName
    +    | isNothing database || not (containsTable tableName database) = database
    +    | otherwise = newDatabase (dName $ fromJust database)
    +            (Data.Map.adjust (addColumnToTable columnName datatype) tableName $ dTables $ fromJust database)
    +
    +-- | 'insertOne' inserts one entry in one column of one table in a database
    +-- First argument is value (String)
    +-- Second argument is it's datatype (Datatype)
    +-- Third argument is old database (Maybe Database)
    +-- Fourth argument is table name (String)
    +-- Fifth argumenr is column name (String)
    +insertOne :: String -> Datatype -> Maybe Database -> String -> String -> Maybe Database
    +insertOne value datatype database tableName columnName
    +    | isNothing database || not (containsTable tableName database) || not (containsColumn columnName database tableName)
    +        = database -- Invalid table name or col name
    +    | datatype /= cDatatype (fromJust $ getColumn columnName $ getTable tableName database )= database -- Datatypes dont match
    +    | otherwise = newDatabase (dName $ fromJust database) (Data.Map.adjust f tableName $ dTables $ fromJust database)
    +    where f = (\table -> fromJust $ newTable (tName table) (tColNameList table, (Data.Map.adjust g columnName $ tColumns table)) (tPKeys table))
    +          g = (\column -> fromJust $ newColumn (cName column) (cDatatype column) ((cValues column) ++ [value]))
    +
    +
    +-- | 'isValidDatatype' checks if datatypes corresponding to column names list are in sync with the table in database or not. Returns true if they both conform
    +-- First argumenr is table (Maybe Table)
    +-- Second argument is list of column names [String]
    +-- Third argument is list of datatypes [Datatype]
    +isValidDatatype :: Maybe Table -> [String] -> [Datatype] -> Bool
    +isValidDatatype t colList typeList
    +    | isNothing t || (colList == [] && typeList == [] )= True
    +    | colList == [] || typeList == [] = False
    +    | otherwise =
    +        let (dType:dTypes) = typeList
    +            (col:cols) = colList
    +        in (dType == cDatatype (fromJust $ getColumn col t)) && (isValidDatatype t cols dTypes)
    +
    +-- | 'addPrimaryKeyToTable' adds one primary key to a table
    +-- First argument is a table (Table)
    +addPrimaryKeyToTable :: Table -> Table
    +addPrimaryKeyToTable table = fromJust $ newTable (tName table) (tColNameList table, tColumns table) (let pKeys = tPKeys table in if pKeys == [] then [0] else pKeys ++ [maximum pKeys + 1])
    +
    +-- | 'addPrimaryKey' adds one primary key to table in database
    +-- First argument is database (Maybe Database)
    +-- Second argument is table name (String)
    +addPrimaryKey :: Maybe Database -> String -> Maybe Database
    +addPrimaryKey db tableName = newDatabase (dName $ fromJust db)
    +        (Data.Map.adjust addPrimaryKeyToTable tableName $ dTables $ fromJust db)
    +
    +-- | 'insert' inserts an entry (row) in database -> table and returns new database
    +-- First argumenr is list of colNames [String]
    +-- Second argument is corresponding list of values [String]
    +-- Third argumenr is corresponding list of datatypes [Datatype]
    +-- Fourth argument old database (Maybe Database)
    +-- Fifth argument is table name (String)
    +insert :: [String] -> [String] -> [Datatype] -> Maybe Database -> String -> Maybe Database
    +insert columnNames values datatypes db tableName
    +    | length values /= length datatypes || not (isValidDatatype (getTable tableName db) columnNames datatypes) || length columnNames /= length values = db --Mismatch in length of names, values and datatypes
    +    | length values == 0 = addPrimaryKey db tableName -- Base case
    +    | otherwise = do
    +        let v = head values; vs = tail values
    +        let d = head datatypes; ds = tail datatypes
    +        let col = head columnNames; cols = tail columnNames
    +        let new_db = insertOne v d db tableName col
    +        insert cols vs ds new_db tableName
    +
    +
    +-- | 'insertDefault' inserts an entry in the default column order. This does not check for datatype as of now.
    +-- First argument is list of values
    +-- Second argument is old database
    +-- Third argument is tableName
    +insertDefault :: [String] -> Maybe Database -> String -> Maybe Database
    +insertDefault values db tableName
    +-- not datatypeOK colNameList values table = db
    +    | otherwise =
    +        let colNameList = tColNameList $ fromJust table
    +        in insert colNameList values (map (\name -> cDatatype $ fromJust $ getColumn name table) colNameList) db tableName
    +    where table = getTable tableName db
    +          colNameList = if isNothing table then [] else tColNameList $ fromJust table
    +
    +-- | 'getColList' is a Utility function for find*
    +getColList table db= Data.Map.elems (tColumns $ fromJust $ getTable table db)
    +
    +-- | 'findEntryAtIndex' finds entry at index in table and returns as [tuples] where tuple = (col name, col type, col value)
    +-- First argument is tableName
    +-- Second argument is database
    +-- Third argument is index
    +findEntryAtIndex :: String -> Maybe Database -> Int -> [(Int, String, Datatype, String)]
    +findEntryAtIndex tableName db index = [ cell | col <- getColList tableName db,
    +    let cell = ((tPKeys $ fromJust $ getTable tableName db) !! index, cName col, cDatatype col, (cValues col) !! index)]
    +
    +-- | 'litValue' is a utility function to support evaluation of ValueExpr on columns (which are stored as String)
    +litValue :: String -> Datatype -> Exp.ValueExpr
    +litValue value datatype
    +    | datatype == INT = Exp.NumLit (read value :: Integer)
    +    | datatype == BOOL = if value == "True" then Exp.BoolLit True else Exp.BoolLit False
    +    | datatype == STRING = Exp.StringLit value
    +
    +-- | 'find' finds all entries in (db -> table) with value, datype and returns as [entries] where entry=[tuples] where tuple = (col name, col type, col value)
    +-- First argument is value (Right) ValueExpr that evaluates to true or false
    +-- Second argument is database (Maybe Database)
    +-- Third argument is table name
    +find :: Either Text.Parsec.Error.ParseError Exp.ValueExpr -> Maybe Database -> String -> [[(Int, String, Datatype, String)]]
    +find (Right condition) db tableName
    +    | isNothing db || not (containsTable tableName db) = []
    +    | otherwise =
    +        let table = getTable tableName db
    +            nEntries = count table
    +            columns = Data.Map.elems $ tColumns $ fromJust table
    +            indices = [n | n <- [0..nEntries-1], let map = Data.Map.fromList [(colName, value) | col <- columns, let colName = cName col, let value = litValue ((cValues col) !! n) (cDatatype col)], Exp.evaluateExpr2 map condition]
    +        in [findEntryAtIndex tableName db n | n <- indices]
    +
    +-- | 'deleteFromList' is a utility function to delete an entry from a list
    +deleteFromList :: Int -> [a] -> [a]
    +deleteFromList index xs = (take index xs) ++ reverse(take (length xs - index - 1) (reverse xs))
    +
    +-- | 'deleteEntryAtIndex' deletes an entry from the table
    +-- First argument is the index in table for the entry to be deleted
    +-- Second argument is the database (Maybe Database)
    +-- Third argument is table name
    +deleteEntryAtIndex :: Int -> Maybe Database -> String -> Maybe Database
    +deleteEntryAtIndex index db tableName
    +    | isNothing db = Nothing
    +    | otherwise = do
    +        let my_db = fromJust db
    +        newDatabase (dName my_db) (Data.Map.adjust f tableName $ dTables my_db)
    +    where f = \table -> (fromJust $ newTable (tName table) (tColNameList table, (Data.Map.fromList new_cols)) (deleteFromList index $ tPKeys table))
    +          cols = Data.Map.elems $ tColumns $ fromJust $ getTable tableName db
    +          new_cols = [(cName col, fromJust $ newColumn (cName col) (cDatatype col) (deleteFromList index $ cValues col)) | col <- cols]
    +
    +-- | 'deleteEntryAtIndices' is used to delete multiple entries from a specific table of a database
    +-- First argument is list of indices [Int]
    +-- Second argument is database (Maybe Database)
    +-- Third argumenr is table name (String)
    +deleteEntryAtIndices :: [Int] -> Maybe Database -> String -> Maybe Database
    +deleteEntryAtIndices indexList db tableName
    +    | isNothing db || indexList == [] || not (containsTable tableName db) = db
    +    | otherwise =
    +        let (index:indices) = indexList
    +            newDB = deleteEntryAtIndex index db tableName
    +        in deleteEntryAtIndices [index-1 | index <- indices] newDB tableName
    +
    +-- | 'delete' deletes all entries that follow a specific condition from a table
    +-- First argument is condition
    +-- Second argument is Maybe Database
    +-- Third argument is table name (String)
    +delete :: Either Text.Parsec.Error.ParseError Exp.ValueExpr -> Maybe Database -> String -> Maybe Database
    +delete (Right condition) db tableName
    +    | isNothing db || not (containsTable tableName db) = db
    +    | otherwise =
    +        let table = getTable tableName db
    +            nEntries = count table
    +            columns = Data.Map.elems $ tColumns $ fromJust table
    +            indices = [n | n <- [0..nEntries-1], let map = Data.Map.fromList [(colName, value) | col <- columns, let colName = cName col, let value = litValue ((cValues col) !! n) (cDatatype col)], Exp.evaluateExpr2 map condition]
    +        in deleteEntryAtIndices indices db tableName
    +
    +-- | 'orderBy' orders the entries given by find based on the value given by expression
    +-- First argument is the expression that gives the deciding value
    +-- Second argument is the entrylist returned by find / select
    +orderBy :: Either Text.Parsec.Error.ParseError Exp.ValueExpr -> [[(Int, String, Datatype, String)]] -> [[(Int, String, Datatype, String)]]
    +orderBy (Right expr) entryList
    +    | length entryList == 0 = []
    +    | otherwise =
    +        sortBy (\entry1 entry2->
    +            let map1 = Data.Map.fromList [(colName, litValue (value) colDatatype) | (pKey, colName, colDatatype, value) <- entry1]
    +                map2 = Data.Map.fromList [(colName, litValue (value) colDatatype) | (pKey, colName, colDatatype, value) <- entry2]
    +                val1 = Exp.evaluateExpr map1 expr
    +                val2 = Exp.evaluateExpr map2 expr
    +            in compare val1 val2) entryList
    +
    +-- | 'select' selects specific columns from the output of find/orderBy and returns list of entries with those columns only
    +-- First argument is column alias (if new name of the columns is needed, then this is used). If this is empty, all columns with default names are returned
    +-- Second argument is output of find/orderBy
    +select :: [(String, String)] -> [[(Int, String, Datatype, String)]] -> [[(Int, String, Datatype, String)]]
    +select colAlias entryList
    +    | length entryList == 0 = []
    +    | length colAlias == 0 = entryList
    +    | otherwise =
    +        let alias = Data.Map.fromList colAlias
    +        in [newEntry | entry <- entryList,
    +            let newEntry = [(pKey, fromJust newName, datatype, value) | (pKey, name, datatype, value) <- entry, let newName = Data.Map.lookup name alias, not (isNothing newName)]]
    +
    +
    \ No newline at end of file diff --git a/docs/src/DeleteParser.html b/docs/src/DeleteParser.html new file mode 100644 index 0000000..60bf379 --- /dev/null +++ b/docs/src/DeleteParser.html @@ -0,0 +1,54 @@ +
    {-|
    +Module      : DeleteParser
    +Description : contains functions to parse DELETE query and evaluate it.
    +-}
    +module DeleteParser (
    +DeleteExpr(..),
    +deleteExpr,
    +makeDelete, evaluateDelete ) where
    +
    +import Text.Parsec.String (Parser)
    +import Text.ParserCombinators.Parsec.Char
    +import Text.ParserCombinators.Parsec.Combinator
    +import Text.Parsec (parse , ParseError , try)
    +import Control.Applicative ((<*),(<$>), (*>), (<|>),(<$),(<*>))
    +import Control.Monad
    +import qualified Text.ParserCombinators.Parsec.Expr as E
    +
    +import Data.Maybe ()
    +import Funcs
    +import ExpressionParser
    +import Database
    +
    +-- | 'DeleteExpr' is a constructor type for Delete Queries.
    +data DeleteExpr = Delete
    +                { dTname :: ValueExpr -- ^ 'iTname' is name of the table
    +                , dWhere :: ValueExpr  -- ^ 'iWhere' contains where clause expression
    +                } deriving(Eq,Show)
    +
    +-- |'makeDelete' creates empty 'DeleteExpr' object
    +makeDelete :: DeleteExpr
    +makeDelete =  Delete {dTname = Iden ""
    +                     ,dWhere = BoolLit False
    +                 }
    +
    +-- |'tabeName' parses name of the table
    +tableName :: Parser ValueExpr
    +tableName = keyword_ "delete" *> keyword_ "from" *> iden []
    +
    +-- |'whereClause' parses where clause
    +whereClause :: Parser ValueExpr
    +whereClause = keyword_ "where" *> valueExpr []
    +
    +-- |deleteExpr' aggerates all parsers to parse CREATE query
    +deleteExpr :: Parser DeleteExpr
    +deleteExpr = Delete <$> tableName <*> whereClause
    +
    +eval :: ValueExpr -> String
    +eval (Iden s) = s
    +
    +-- |'evaluateDelete' evaluates parsed 'DeleteExpr' to delete rows in database table
    +-- First argument is parsed 'DeleteExpr'
    +-- Second argument is databse instance
    +evaluateDelete:: Either ParseError DeleteExpr -> Maybe Database -> Maybe Database
    +evaluateDelete (Right expr) db = delete (Right (dWhere expr)) db (eval (dTname expr))
    \ No newline at end of file diff --git a/docs/src/ExpressionParser.html b/docs/src/ExpressionParser.html new file mode 100644 index 0000000..9434a55 --- /dev/null +++ b/docs/src/ExpressionParser.html @@ -0,0 +1,149 @@ +
    {-|
    +Module      : ExpressionParser
    +Description : contains functions to parse expressions and evaluate them.
    +-}
    +module ExpressionParser where
    +
    +import Text.Parsec.String (Parser)
    +import Text.ParserCombinators.Parsec.Char
    +import Text.ParserCombinators.Parsec.Combinator
    +import Text.Parsec (parse , ParseError , try)
    +import Control.Applicative (many, (<*),(<$>), (*>), (<|>),(<$),(<*>))
    +import Control.Monad (void,guard)
    +import qualified Text.ParserCombinators.Parsec.Expr as E
    +import Data.Map (Map)
    +import qualified Data.Map as Map
    +import Funcs
    +
    +-- |'ValueExpr' represnts a expression
    +data ValueExpr =  NumLit Integer -- ^ 'NumLit' type constructor for integer constants that takes integer as argument
    +               | Iden String -- ^ 'Iden' type constructor for identifier that takes string as argument
    +               | PrefOp String ValueExpr -- ^ 'PrefOp' for prefix operators that takes operator(String) and a 'ValueExpr'
    +               | BinOp ValueExpr String ValueExpr -- ^ 'BinOp' for binary operators that takes operator(String) and two 'ValueExpr'
    +               | Parens ValueExpr -- ^ 'Parens' type constructor that 'ValueExpr' as argument that is ought to be in parenthesis.
    +               | StringLit String -- ^ 'StringLit' type constructor for string literals that takes string as argument
    +               | Star -- ^ 'Star' for * symbol
    +               | BoolLit Bool -- ^ 'BoolLit' type constructor for boolean constants that takes bool as argument
    +                 deriving (Eq,Show)
    +
    +-- |'EvalType' represnts a return type of evaluator
    +data EvalType = Int Integer -- ^ 'Int' holds am integral return type
    +              | Boolean Bool -- ^ 'Boolean' holds a boolean return type
    +              | Error String -- ^ 'Error' holds a error string
    +                deriving (Eq,Show)
    +
    +-- |'num' wraps a parsed integer literal in 'ValueExpr' datatype
    +num :: Parser ValueExpr
    +num = NumLit <$> integer
    +
    +-- |'iden' wraps a parsed identifier literal in 'ValueExpr' datatype
    +-- Argument is a blacklist
    +iden :: [String] -> Parser ValueExpr
    +iden blacklist = Iden <$> identifierBlacklist (blacklist++["True","False","not","and","or"])
    +
    +-- |'bolean' wraps a parsed boolean literal in 'ValueExpr' datatype
    +boolean :: Parser ValueExpr
    +boolean =  BoolLit <$> boolToken
    +
    +-- |'parensValue' wraps a parsed parenthesis expression in 'ValueExpr' datatype
    +parensValue :: Parser ValueExpr
    +parensValue = Parens <$> parens (valueExpr [])
    +
    +-- |'term' contains all possible expression types
    +term :: [String] -> Parser ValueExpr
    +term blacklist = try boolean <|> iden blacklist  <|> num <|> parensValue <|> stringLit <|> star
    +
    +-- |'table' contains precedence, associativity of integer and boolean operators
    +table = [[prefix "-", prefix "+"]
    +         ,[binary "^" E.AssocLeft]
    +         ,[binary "*" E.AssocLeft
    +          ,binary "/" E.AssocLeft
    +          ,binary "%" E.AssocLeft]
    +         ,[binary "+" E.AssocLeft
    +          ,binary "-" E.AssocLeft]
    +         ,[binary "<=" E.AssocRight
    +          ,binary ">=" E.AssocRight
    +          ,binary "!=" E.AssocRight]
    +         ,[binary "<" E.AssocNone
    +          ,binary ">" E.AssocNone]
    +         ,[binary "=" E.AssocRight]
    +         ,[prefixK "not"]
    +         ,[binaryK "and" E.AssocLeft]
    +         ,[binaryK "or" E.AssocLeft]]
    +  where
    +    binary name assoc =
    +        E.Infix (mkBinOp name <$ symbol name) assoc
    +    mkBinOp nm a b = BinOp a nm b
    +    prefix name = E.Prefix (PrefOp name <$ symbol name)
    +    binaryK name assoc =
    +        E.Infix (mkBinOp name <$ keyword name) assoc
    +    prefixK name = E.Prefix (PrefOp name <$ keyword name)
    +
    +-- |'valueExpr' parses a given string to 'ValueExpr' datatype
    +-- Input is a blacklist
    +valueExpr :: [String] -> Parser ValueExpr
    +valueExpr blacklist = E.buildExpressionParser table (term blacklist)
    +
    +-- |'stringLit' wraps a parsed string literal in 'ValueExpr' datatype
    +stringLit :: Parser ValueExpr
    +stringLit = StringLit <$> stringToken
    +
    +-- |'star' wraps a parsed '*' keyword in 'ValueExpr' datatype
    +star :: Parser ValueExpr
    +star = Star <$ symbol "*"
    +
    +-- |'evaluate' evaluates a parsed 'ValueExpr' to integer 'EvalType' if possible otherwise Exception
    +-- First argument is map of variables and corresponding values.
    +-- Second argument is a parsed expression type.
    +evaluate :: (Map String ValueExpr) -> Either ParseError ValueExpr -> EvalType
    +evaluate map (Right e) = Int (evaluateExpr map e)
    +evaluate map (Left e) = Error (show e)
    +
    +-- |'evaluate2' evaluates a parsed 'ValueExpr' to boolean 'EvalType'if possible otherwise Exception
    +-- First argument is map of variables and corresponding values.
    +-- Second argument is a parsed expression type.
    +evaluate2 :: (Map String ValueExpr) -> Either ParseError ValueExpr -> EvalType
    +evaluate2 map (Right e) = Boolean (evaluateExpr2 map e)
    +evaluate2 map (Left e) = Error (show e)
    +
    +-- |'evaluateExpr' evaluates a 'ValueExpr' to Integer if possible otherwise Exception
    +-- First argument is map of variables and corresponding values.
    +-- Second argument is a parsed expression ('ValueExpr') type.
    +evaluateExpr :: (Map String ValueExpr) -> ValueExpr -> Integer
    +evaluateExpr map (Iden s) = do
    + let val = Map.lookup s map
    + case val of
    +  Just (NumLit i) -> i
    +evaluateExpr map (NumLit n) = n
    +evaluateExpr map (Parens v) = evaluateExpr map v
    +evaluateExpr map (PrefOp "-" v) = -(evaluateExpr map v)
    +evaluateExpr map (PrefOp "+" v) = (evaluateExpr map v)
    +evaluateExpr map (BinOp v1 "^" v2) = (evaluateExpr map v1)^(evaluateExpr map v2)
    +evaluateExpr map (BinOp v1 "*" v2) = (evaluateExpr map v1)*(evaluateExpr map v2)
    +evaluateExpr map (BinOp v1 "/" v2) = div (evaluateExpr map v1) (evaluateExpr map v2)
    +evaluateExpr map (BinOp v1 "%" v2) = mod (evaluateExpr map v1) (evaluateExpr map v2)
    +evaluateExpr map (BinOp v1 "+" v2) = (evaluateExpr map v1) + (evaluateExpr map v2)
    +evaluateExpr map (BinOp v1 "-" v2) = (evaluateExpr map v1) - (evaluateExpr map v2)
    +
    +-- |'evaluateExpr2' evaluates a 'ValueExpr' to Bool if possible otherwise Exception
    +-- First argument is map of variables and corresponding values.
    +-- Second argument is a parsed expression ('ValueExpr') type.
    +evaluateExpr2 :: (Map String ValueExpr) -> ValueExpr -> Bool
    +evaluateExpr2 map (Iden s) = do
    + let val = Map.lookup s map
    + case val of
    +  Just (BoolLit i) -> i
    +evaluateExpr2 map (BoolLit True) = True
    +evaluateExpr2 map (BoolLit False) = False
    +evaluateExpr2 map (Parens v) = evaluateExpr2 map v
    +evaluateExpr2 map (BinOp v1 "<=" v2) = (evaluateExpr map v1) <= (evaluateExpr map v2)
    +evaluateExpr2 map (BinOp v1 ">=" v2) = (evaluateExpr map v1) >= (evaluateExpr map v2)
    +evaluateExpr2 map (BinOp v1 "!=" v2) = (evaluateExpr map v1) /= (evaluateExpr map v2)
    +evaluateExpr2 map (BinOp v1 ">" v2) = (evaluateExpr map v1) > (evaluateExpr map v2)
    +evaluateExpr2 map (BinOp v1 "<" v2) = (evaluateExpr map v1) < (evaluateExpr map v2)
    +evaluateExpr2 map (BinOp v1 "=" v2) = (evaluateExpr map v1) == (evaluateExpr map v2)
    +evaluateExpr2 map (PrefOp "not" v) = not (evaluateExpr2 map v)
    +evaluateExpr2 map (BinOp v1 "and" v2) = (&&) (evaluateExpr2 map v1) (evaluateExpr2 map v2)
    +evaluateExpr2 map (BinOp v1 "or" v2) = (||) (evaluateExpr2 map v1) (evaluateExpr2 map v2)
    +
    +
    \ No newline at end of file diff --git a/docs/src/Funcs.html b/docs/src/Funcs.html new file mode 100644 index 0000000..5acb3e7 --- /dev/null +++ b/docs/src/Funcs.html @@ -0,0 +1,115 @@ +
    {-|
    +Module      : Funcs
    +Description : Contains standard parsers for building up other parsers
    +-}
    +module Funcs where
    +import Text.Parsec.String (Parser)
    +import Text.Parsec (parse , ParseError , try)
    +import Text.ParserCombinators.Parsec.Char (oneOf, digit, string, anyChar, char, letter)
    +import Text.ParserCombinators.Parsec.Combinator (many1, manyTill, anyToken, eof, choice, between
    +                                     ,sepBy,sepBy1, optionMaybe)
    +import Control.Applicative (many, (<*),(<$>), (*>), (<|>),(<$),(<*>))
    +import Control.Monad (void,guard)
    +
    +-- |The 'regularParse' parses a expression regularlly
    +regularParse :: Parser a -> String -> Either ParseError a
    +regularParse p = parse p ""
    +
    +-- |The 'parseWithEof' is a wrapper that throws error if you haven’t consumed all the input
    +parseWithEof :: Parser a -> String -> Either ParseError a
    +parseWithEof p = parse (p <* eof) ""
    +
    +-- |The 'parseWithLeftOver' is wrapper that tell you what was not consumed from the input by input parser
    +parseWithLeftOver :: Parser a -> String -> Either ParseError (a,String)
    +parseWithLeftOver p = parse ((,) <$> p <*> leftOver) ""
    +  where leftOver = manyTill anyToken eof
    +
    +-- |The 'parseWithWSEof' wrapper allows parsing when input constains and leading whitespaces
    +parseWithWSEof :: Parser a -> String -> Either ParseError a
    +parseWithWSEof p = parseWithEof (whiteSpace *> p)
    +  where whiteSpace = void $ many $ oneOf " \n\t"
    +
    +-- |The 'lexeme' is wrapper parser that eats up any following whitespaces after parsing.
    +lexeme :: Parser a -> Parser a
    +lexeme p = p <* whitespace
    +
    +-- |The 'integer' parses a integer constant
    +integer :: Parser Integer
    +integer =  read <$> lexeme (many1 digit)
    +
    +-- |The 'identifier' parses a identifier string
    +identifier :: Parser String
    +identifier = lexeme ((:) <$> firstChar <*> many nonFirstChar)
    +      where
    +            firstChar = letter <|> char '_'
    +            nonFirstChar =  digit <|> firstChar
    +
    +-- |The 'symbol' parses a single character symbol or operator
    +-- It takes string as arguments and comapres it with parsed string.
    +symbol :: String -> Parser String
    +symbol s = try $ lexeme $ do
    +    u <- many1 (oneOf "<>=+-^%/*!|")
    +    guard (s == u)
    +    return s
    +
    +-- |The 'comma' parses comma
    +comma :: Parser Char
    +comma = lexeme $ char ','
    +
    +-- |The 'openParen' parses Opening paranthesis
    +openParen :: Parser Char
    +openParen = lexeme $ char '('
    +
    +-- |The 'closeParen' parses closing paranthesis
    +closeParen :: Parser Char
    +closeParen = lexeme $ char ')'
    +
    +-- |The 'keyowrd' parses a occurence of string given as input
    +-- It takes a string to pe parsed as only input
    +keyword :: String -> Parser String
    +keyword k = try $ do
    +    i <- identifier
    +    guard (i == k)
    +    return k
    +
    +-- |The 'parens' function parses anything between opening and closing paranthesis
    +parens :: Parser a -> Parser a
    +parens = between openParen closeParen
    +
    +-- |The 'identifierBlacklist' parses only that identifiers that are not in blacklist
    +-- It takes a blacklist of type List as an argument
    +identifierBlacklist :: [String] -> Parser String
    +identifierBlacklist bl = do
    +    i <- identifier
    +    guard (i `notElem` bl)
    +    return i
    +
    +-- |The 'whitespace' parses any number of any type of whiespaces
    +whitespace :: Parser ()
    +whitespace = void $ many (oneOf " \t\n")
    +
    +-- |The 'keyword_' parses keywords and ignores them
    +keyword_ :: String -> Parser ()
    +keyword_ = void . keyword
    +
    +-- |The 'symbol_' parses symbol and ignores them
    +symbol_ :: String -> Parser ()
    +symbol_ = void . symbol
    +
    +-- |The 'commaSep1' parses comma seperated items and returns a list
    +commaSep1 :: Parser a -> Parser [a]
    +commaSep1 = (`sepBy1` comma)
    +
    +-- |The 'stringToken' parses a string literal in single quotes
    +stringToken :: Parser String
    +stringToken = lexeme (char '\'' *> manyTill anyChar (char '\''))
    +
    +-- |The 'boolToken' parses boolean constants 'True' and 'False'
    +boolToken :: Parser Bool
    +boolToken = do
    +  i <- identifier
    +  guard (i `elem` ["True","False"])
    +  if i == "True"
    +    then return True
    +  else return False
    +
    \ No newline at end of file diff --git a/docs/src/InsertParser.html b/docs/src/InsertParser.html new file mode 100644 index 0000000..902db58 --- /dev/null +++ b/docs/src/InsertParser.html @@ -0,0 +1,79 @@ +
    {-|
    +Module      : InsertParser
    +Description : contains functions to parse INSERT query and evaluate it.
    +-}
    +module InsertParser (
    +InsertExpr(..),
    +insertExpr,
    +makeInsert,evaluateInsert) where
    +
    +import Text.Parsec.String (Parser)
    +import Text.ParserCombinators.Parsec.Char
    +import Text.ParserCombinators.Parsec.Combinator
    +import Text.Parsec (parse , ParseError , try)
    +import Control.Applicative ((<*),(<$>), (*>), (<|>),(<$),(<*>))
    +import Control.Monad
    +import qualified Text.ParserCombinators.Parsec.Expr as E
    +
    +import Data.Maybe ()
    +import Funcs
    +import ExpressionParser
    +import Database
    +
    +-- | 'InsertExpr' is a constructor type for Insert Queries
    +data InsertExpr = Insert
    +                { iTable :: ValueExpr -- ^ 'iTname' is name of the table
    +                , iColumns :: [ValueExpr] -- ^ 'iColumns' are name of columns
    +                , iValues :: [ValueExpr] -- ^ 'iValues' are values to insert (NumLit, StringLit, BoolLit)
    +                } deriving(Eq,Show)
    +
    +-- |'makeInsert' creates empty 'InsertExpr' object
    +makeInsert :: InsertExpr
    +makeInsert =  Insert {iTable = Iden ""
    +                     ,iColumns = []
    +                     ,iValues = []}
    +
    +-- |'tabeName' parses name of the table
    +tableName :: Parser ValueExpr
    +tableName = keyword_ "insert" *> keyword_ "into" *> iden []
    +
    +-- |'columns' parses column name as list
    +columns :: Parser [ValueExpr]
    +columns = parens (commaSep1 (iden []))
    +
    +-- |'values' parses column values as list
    +values :: Parser [ValueExpr]
    +values =  keyword_ "values" *> parens (commaSep1 literal)
    + where literal = num <|> stringLit <|> boolean
    +
    +-- |'insertExpr' aggerates all parsers to parse INSERT query
    +insertExpr :: Parser InsertExpr
    +insertExpr =  Insert <$> tableName <*> option [] columns <*> values
    +
    +-- |'evaluateInsert' evaluates insert expression ans insert values to table
    +-- First argument is InserExpr
    +-- Second argument is database instance
    +evaluateInsert :: Either ParseError InsertExpr -> Maybe Database -> Maybe Database
    +evaluateInsert (Right expr) db
    + | (iColumns expr == []) =  insertDefault (getValues (iValues expr)) db (eval (iTable expr))
    + | otherwise = insert (getColumnNames (iColumns expr)) (getValues (iValues expr)) (getDataType (iValues expr)) db (eval (iTable expr))
    + where eval (Iden s) = s
    +
    +{-|
    +	Utility functions
    +-}
    +getDataType :: [ValueExpr] -> [Datatype]
    +getDataType [] = []
    +getDataType ((StringLit _) : xs) = STRING : getDataType xs
    +getDataType ((NumLit _) : xs) = INT : getDataType xs
    +getDataType ((BoolLit _) : xs) = BOOL : getDataType xs
    +
    +getColumnNames :: [ValueExpr] -> [String]
    +getColumnNames [] = []
    +getColumnNames ((Iden s) : xs) = s : getColumnNames xs
    +
    +getValues :: [ValueExpr] -> [String]
    +getValues [] = []
    +getValues ((StringLit s) : xs ) = s : getValues xs
    +getValues ((BoolLit b) : xs ) = (show b) : getValues xs
    +getValues ((NumLit i) : xs ) = (show i) : getValues xs
    \ No newline at end of file diff --git a/docs/src/Paths_HaSSQL.html b/docs/src/Paths_HaSSQL.html new file mode 100644 index 0000000..b693401 --- /dev/null +++ b/docs/src/Paths_HaSSQL.html @@ -0,0 +1,51 @@ +
    {-# LANGUAGE CPP #-}
    +{-# LANGUAGE NoRebindableSyntax #-}
    +{-# OPTIONS_GHC -fno-warn-missing-import-lists #-}
    +module Paths_HaSSQL (
    +    version,
    +    getBinDir, getLibDir, getDynLibDir, getDataDir, getLibexecDir,
    +    getDataFileName, getSysconfDir
    +  ) where
    +
    +import qualified Control.Exception as Exception
    +import Data.Version (Version(..))
    +import System.Environment (getEnv)
    +import Prelude
    +
    +#if defined(VERSION_base)
    +
    +#if MIN_VERSION_base(4,0,0)
    +catchIO :: IO a -> (Exception.IOException -> IO a) -> IO a
    +#else
    +catchIO :: IO a -> (Exception.Exception -> IO a) -> IO a
    +#endif
    +
    +#else
    +catchIO :: IO a -> (Exception.IOException -> IO a) -> IO a
    +#endif
    +catchIO = Exception.catch
    +
    +version :: Version
    +version = Version [1,0,0] []
    +bindir, libdir, dynlibdir, datadir, libexecdir, sysconfdir :: FilePath
    +
    +bindir     = "/home/sairamana/haskell-8/.stack-work/install/x86_64-linux/lts-13.12/8.6.4/bin"
    +libdir     = "/home/sairamana/haskell-8/.stack-work/install/x86_64-linux/lts-13.12/8.6.4/lib/x86_64-linux-ghc-8.6.4/HaSSQL-1.0.0-7Uqt8xOVdtp7stCdfEk5Mx"
    +dynlibdir  = "/home/sairamana/haskell-8/.stack-work/install/x86_64-linux/lts-13.12/8.6.4/lib/x86_64-linux-ghc-8.6.4"
    +datadir    = "/home/sairamana/haskell-8/.stack-work/install/x86_64-linux/lts-13.12/8.6.4/share/x86_64-linux-ghc-8.6.4/HaSSQL-1.0.0"
    +libexecdir = "/home/sairamana/haskell-8/.stack-work/install/x86_64-linux/lts-13.12/8.6.4/libexec/x86_64-linux-ghc-8.6.4/HaSSQL-1.0.0"
    +sysconfdir = "/home/sairamana/haskell-8/.stack-work/install/x86_64-linux/lts-13.12/8.6.4/etc"
    +
    +getBinDir, getLibDir, getDynLibDir, getDataDir, getLibexecDir, getSysconfDir :: IO FilePath
    +getBinDir = catchIO (getEnv "HaSSQL_bindir") (\_ -> return bindir)
    +getLibDir = catchIO (getEnv "HaSSQL_libdir") (\_ -> return libdir)
    +getDynLibDir = catchIO (getEnv "HaSSQL_dynlibdir") (\_ -> return dynlibdir)
    +getDataDir = catchIO (getEnv "HaSSQL_datadir") (\_ -> return datadir)
    +getLibexecDir = catchIO (getEnv "HaSSQL_libexecdir") (\_ -> return libexecdir)
    +getSysconfDir = catchIO (getEnv "HaSSQL_sysconfdir") (\_ -> return sysconfdir)
    +
    +getDataFileName :: FilePath -> IO FilePath
    +getDataFileName name = do
    +  dir <- getDataDir
    +  return (dir ++ "/" ++ name)
    +
    \ No newline at end of file diff --git a/docs/src/QueryParser.html b/docs/src/QueryParser.html new file mode 100644 index 0000000..bef095b --- /dev/null +++ b/docs/src/QueryParser.html @@ -0,0 +1,122 @@ +
    {-|
    +Module      : QueryParser
    +Description : contains functions to parse SELECT query and evaluate it.
    +-}
    +module QueryParser (
    +QueryExpr(..),
    +queryExpr,
    +makeSelect,evaluateQuery) where
    +
    +import Text.Parsec.String (Parser)
    +import Text.ParserCombinators.Parsec.Char
    +import Text.ParserCombinators.Parsec.Combinator
    +import Text.Parsec (parse , ParseError , try)
    +import Control.Applicative ((<*),(<$>), (*>), (<|>),(<$),(<*>))
    +import Control.Monad
    +import qualified Text.ParserCombinators.Parsec.Expr as E
    +
    +import Data.Maybe ()
    +import Funcs
    +import ExpressionParser
    +import Database
    +
    +-- |'QueryExpr' represents a SELECT statement
    +data QueryExpr = Select
    +      {qeSelectList :: [(ValueExpr,Maybe String)] -- ^ 'qeSelectList' contains list of selected columns
    +      ,qefromClause :: ValueExpr -- ^ 'qeFromClause' contains table name
    +      ,qeWhere :: Maybe ValueExpr  -- ^ 'qeWhere' contains where clause expression
    +      ,qeGroupBy :: [ValueExpr] -- ^ 'qeGroupBy' contains list of groupby expresions
    +      ,qeHaving :: Maybe ValueExpr  -- ^ 'qeHaving' contains havingby expression
    +      ,qeOrderBy :: [ValueExpr] -- ^ 'qeOrderBy' contains list of orderby clause expressions
    +      } deriving (Eq,Show)
    +
    +-- |'makeSelect' makes a empty 'QueryExpr' object
    +makeSelect :: QueryExpr
    +makeSelect = Select {qeSelectList = []
    +                    ,qefromClause = Iden ""
    +                    ,qeWhere = Nothing
    +                    ,qeGroupBy = []
    +                    ,qeHaving = Nothing
    +                    ,qeOrderBy = []}
    +
    +-- |'selectList' parses comma seperated 'selectItem'
    +selectList :: Parser [(ValueExpr, Maybe String)]
    +selectList = keyword_ "select" *> commaSep1 selectItem
    +
    +-- |'selectItem' parses selected list names and their alias
    +selectItem :: Parser (ValueExpr, Maybe String)
    +selectItem = (,) <$> valueExpr [] <*> optionMaybe (try alias)
    +  where alias = optional (keyword_ "as") *> identifierBlacklist ["from","where","group","having","order"]
    +
    +-- |'fromClause' parses from gets table name
    +fromClause :: Parser ValueExpr
    +fromClause = keyword_ "from" *> iden ["from","where","group","having","order"]
    +
    +-- |'whereClause' parses where clause
    +whereClause :: Parser ValueExpr
    +whereClause = keyword_ "where" *> valueExpr []
    +
    +-- |'groupByClause' parses group by clauses as list
    +groupByClause :: Parser [ValueExpr]
    +groupByClause = keyword_ "group" *> keyword_ "by"
    +                *> commaSep1 (valueExpr [])
    +
    +-- |'having' parses having by clause
    +having :: Parser ValueExpr
    +having = keyword_ "having" *> (valueExpr [])
    +
    +-- |'orderBy' parses order by clauses as lists
    +orderByClause :: Parser [ValueExpr]
    +orderByClause = keyword_ "order" *> keyword_ "by"
    +          *> commaSep1 (valueExpr [])
    +
    +-- |'queryExpr' aggregates all parsers to parse a SELECT statement
    +queryExpr :: Parser QueryExpr
    +queryExpr = Select
    +            <$> selectList
    +            <*> fromClause
    +            <*> optionMaybe whereClause
    +            <*> option [] groupByClause
    +            <*> optionMaybe having
    +            <*> option [] orderByClause
    +
    +eval :: ValueExpr -> String
    +eval (Iden s) = s
    +
    +-- |'evalWhere' evaluates a where clause
    +-- First argument is parsed where 'ValueExpr' 
    +-- Second argument is Maybe Database instance
    +-- Third arhument is table Name
    +evalWhere :: Maybe ValueExpr -> Maybe Database -> String -> [[(Int,String, Datatype, String)]]
    +evalWhere (Just expr) db tname = find (Right expr) db tname
    +evalWhere (Nothing) db tname = find (Right (BoolLit True)) db tname
    +
    +-- |'evalOrderBy' evaluates a order by clause
    +-- First argument is parsed orderby 'ValueExpr' list
    +-- Second argument is output of where clause
    +evalOrderBy :: [ValueExpr]-> [[(Int,String, Datatype, String)]] -> [[(Int,String, Datatype, String)]]
    +evalOrderBy [] out = out
    +evalOrderBy (x : xs) out = evalOrderBy xs (orderBy (Right x) out)
    +
    +-- |'evalSelect' converts select lists to String tuples
    +-- First argument is parsed select list
    +evalSelect :: [(ValueExpr, Maybe String)] -> [(String,String)]
    +evalSelect [(Star,Nothing)] = []
    +evalSelect [] = []
    +evalSelect (x : xs) = do
    +  case (snd x) of
    +    Nothing -> (eval (fst x),eval (fst x)) : evalSelect xs
    +    Just y -> (eval (fst x),y) : evalSelect xs
    +
    +-- |'evaluateQuery' evaluates a query expression
    +-- First argument is parsed query expression
    +-- Second argument is Maybe Database instance
    +evaluateQuery :: Either ParseError QueryExpr -> Maybe Database -> [[(Int,String, Datatype, String)]]
    +evaluateQuery (Right expr) db = do
    +  let out1 = evalWhere (qeWhere expr) db (eval (qefromClause expr))
    +  let out2 = evalOrderBy (qeOrderBy expr) out1
    +  select (evalSelect (qeSelectList expr)) out2
    +
    +
    +
    +
    \ No newline at end of file diff --git a/docs/src/SQLParser.html b/docs/src/SQLParser.html new file mode 100644 index 0000000..6d2a4d9 --- /dev/null +++ b/docs/src/SQLParser.html @@ -0,0 +1,81 @@ +
    {-|
    +Module:      SQLParser
    +Description: Integrate all SQL statements into a single module
    +-}
    +module SQLParser where
    +import Text.Parsec.String (Parser)
    +import Text.Parsec.Error (ParseError)
    +import Text.Parsec (parse)
    +import Text.ParserCombinators.Parsec.Combinator (eof)
    +import Control.Applicative ((<*),(<$>), (*>), (<|>),(<$),(<*>))
    +import Funcs
    +import ExpressionParser
    +import QueryParser
    +import InsertParser
    +import CreateParser
    +import DeleteParser
    +import Database
    +import Data.Map (Map)
    +import qualified Data.Map as Map
    +
    +-- | 'SQLExpr' is a wrapping type constructor for Select, Insert and Delete statements.
    +-- 'SELECT QueryExpr' contains 
    +data SQLExpr = SELECT QueryExpr -- ^Parses a SELECT query 
    +               | INSERT InsertExpr  -- ^ Parses a INSERT Query
    +               | CREATE CreateExpr -- ^ Parses a CREATE Query
    +               | DELETE DeleteExpr -- ^ Parses a DELETE Query
    +               deriving (Eq, Show)
    +
    +-- | 'ResType' is a wrapping type constructor for the response types of each of the above statements.
    +data ResType = DB (Maybe Database) -- ^ Database instance for insert, create and delete queries
    +              | OUT ([[(Int,String, Datatype, String)]]) -- ^ Return object for SELECT queries
    +              | ERROR String deriving(Eq,Show)
    +-- | 'sqlExpr' describes an SQL expression.
    +sqlExpr ::  Parser SQLExpr
    +sqlExpr = (SELECT <$> queryExpr ) <|> (INSERT <$> insertExpr) <|> (CREATE <$> createExpr) <|> (DELETE <$> deleteExpr)
    +
    +-- | 'evaluateSQL' evaluates each Expression using individual case statements
    +evaluateSQL :: Either ParseError SQLExpr -> ResType -> ResType
    +evaluateSQL (Right expr)  (DB db) = do
    +    case expr of
    +        SELECT e -> OUT (evaluateQuery (Right e) db)
    +        INSERT e -> DB (evaluateInsert (Right e) db)
    +        CREATE e -> DB (evaluateCreate (Right e) db)
    +        DELETE e -> DB (evaluateDelete (Right e) db)
    +evaluateSQL (Left error) db = ERROR (show error)
    +
    +-- |'getHeader' returns string of headers of table
    +-- First argument is list of headers
    +getHeaders :: [(Int,String,Datatype,String)] -> String
    +getHeaders [] = ""
    +getHeaders ((d,a,b,c) : xs) = (a++" ("++(show b)++"), ")++(getHeaders xs)
    +
    +-- |'getHeader' returns string of depicting one entire row
    +-- First argument is a row
    +getRow :: [(Int,String,Datatype,String)] -> String
    +getRow [] = ""
    +getRow ((d,a,b,c) : xs) = (c++", ")++(getRow xs)
    +
    +-- |'getRows' prints the rows which are the output of select query
    +-- The argument is output of select parsed query
    +getRows :: [[(Int,String,Datatype,String)]] -> IO ()
    +getRows [] = putStr ""
    +getRows (x: xs) =  putStrLn((let (a,b,c,d) = head x in show a++", ")++getRow x) *> (getRows xs)
    +
    +-- |'queryPrinter' prints the Select query output in a tabular fashion
    +-- The argument is output of select parsed query
    +queryPrinter :: ResType -> IO ()
    +queryPrinter (OUT output) =  do
    +  case output of
    +    [] -> print("")
    +    otherwise -> putStrLn("------------------------------------------------------------")
    +                 *> putStrLn("PK, "++getHeaders (head output))
    +                 *> putStrLn("------------------------------------------------------------")
    +                 *> (getRows output)
    +
    +
    +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/docs/src/highlight.js b/docs/src/highlight.js new file mode 100644 index 0000000..1e903bd --- /dev/null +++ b/docs/src/highlight.js @@ -0,0 +1,27 @@ + +var highlight = function (on) { + return function () { + var links = document.getElementsByTagName('a'); + for (var i = 0; i < links.length; i++) { + var that = links[i]; + + if (this.href != that.href) { + continue; + } + + if (on) { + that.classList.add("hover-highlight"); + } else { + that.classList.remove("hover-highlight"); + } + } + } +}; + +window.onload = function () { + var links = document.getElementsByTagName('a'); + for (var i = 0; i < links.length; i++) { + links[i].onmouseover = highlight(true); + links[i].onmouseout = highlight(false); + } +}; diff --git a/docs/src/style.css b/docs/src/style.css new file mode 100644 index 0000000..e83dc5e --- /dev/null +++ b/docs/src/style.css @@ -0,0 +1,55 @@ +body { + background-color: #fdf6e3; +} + +.hs-identifier { + color: #073642; +} + +.hs-identifier.hs-var { +} + +.hs-identifier.hs-type { + color: #5f5faf; +} + +.hs-keyword { + color: #af005f; +} + +.hs-string, .hs-char { + color: #cb4b16; +} + +.hs-number { + color: #268bd2; +} + +.hs-operator { + color: #d33682; +} + +.hs-glyph, .hs-special { + color: #dc322f; +} + +.hs-comment { + color: #8a8a8a; +} + +.hs-pragma { + color: #2aa198; +} + +.hs-cpp { + color: #859900; +} + +a:link, a:visited { + text-decoration: none; + border-bottom: 1px solid #eee8d5; +} + +a:hover, a.hover-highlight { + background-color: #eee8d5; +} diff --git a/docs/synopsis.png b/docs/synopsis.png new file mode 100644 index 0000000..85fb86e Binary files /dev/null and b/docs/synopsis.png differ