FreshCode test assignment (clojure)
Description
This task should introduce you a design pattern from one of our projects and give you a chance to show off your design skills.
Project is provided with a simple Star Wars data set for a PostgreSQL database. There is an SQL script that will initialize the database the first time it is started.
Working with the project
Prerequisites
To get started with this project you will need to first install the following software (follow the links to get installation instruction for your operating system):
Start Up/Shut Down
To get started with the development run this commands in your terminal:
bb up # starts the database
bb repl # starts project repl
To shut down the database:
bb down
Debugging
For ease of debugging, the project contains hashp dependency, that is required in the dev.user
namespace and is available in all namespaces after repl startup.
Running tests
There are commands for runnig tests:
bb test # run both unit and integration tests
bb test:unit # run unit tests only
bb test:integration # run integration tests only
Linting
There are commands to find and fix lint errors:
bb lint # find problems
bb lint:fix # fix them
Your assignment
Table Manager
You need to implement a table manager functionality. Assume that your table manager has to deal with a PostgreSQL database only.
Your table manager should be capable of doing the following:
-
List all tables.
-
Get table structure. (including column names, column data types, if column is nullable)
-
Get table data.
-
Check if table with specified name is defined.
-
Check if table is empty.
-
Run query (if you are not using
ITable
protocol).
List all tables
There should be a function that, given a table manager entity, lists all available tables or tables satisfying certain requirements.
A filter may be supplied. Filter is a predicate that takes a table and returns true
if it satisfies a condition.
A table may be represented as a name string or as a data structure implementing ITable
protocol.
(list-tables table-manager)
;; => ["table-1" "table-2" ...]
;; or
;; => [^ITable table-1 ^ITable table-2 ...]
(list-tables table-manager has-specific-column?)
;; => ["table-2" "table-4"]
;; or
;; => [^ITable table-2 ^ITable table-4]
Get table structure
There should be a function that, given a table manager entity and a table name, gets the table strucrure (including column names, column structure).
(table-structure table-manager "table-name")
;; => {:column-names ["col-1" "col-2" ...]
;; :column-structs {"col-1" {:sql-type "varchar"
;; :nullable? false}
;; ...}
Get table data
There should be a function that, given a table manager entity and a table name, gets table.
A table may be represented as a collection of hash maps or as a data structure implementing SQL script`ITable` protocol.
Function returns nil
if there is no table with given name.
(table-data table-manager table-id)
;; => [{"col-1" value-1 "col-2" value-2 ...} ...]
;;
;; => or ^ITable table
If table is defined
There should be a function that, given a table manager entity and a table name, returns true
if the table is defined.
(has-table? table-manager "table-name")
;; => true
If table is empty
There should be a function that, given a table manager entity and a table name, returns true
if table is empty.
(empty-table? table-manager "table-name")
;; => true (if empty)
Run query
If you are not using ITable
protocol, there should be a function that, given a table manager and a query structure, should run a query against a database and return a result.
(run-query table-manager ["select name from planet limit 10 order by name"])
;; => ["Alderaan" "Aleen Minor" "Bespin" "Bestine IV" "Cato Neimoidia"]
ITable protocol
You cam implement the ITable
protocol for your tables to make it responsible for building, running and caching queries.
Protocol should have methods capable of 1. getting table name. 2. getting table structure. 3. running and caching queries
Testing Your Assignment
You should write test for all table manager methods and for the following queries against the Star Wars sample database:
-
Get planets list.
-
Get males list.
-
Match all pairs from the same planet.
-
Get people’s mass by planet.