\documentclass{article} \title{Database Connection for the CPS Facilitator Tool} \author{Jos Kraaijeveld} \date{\today} \usepackage{moreverb} \usepackage{fullpage} \usepackage{framed} \usepackage{float} \usepackage{multirow} \usepackage[final]{pdfpages} \usepackage{hyperref} \begin{document} \maketitle \pagebreak \tableofcontents \pagebreak \section{Introduction} This document describes the database design and implementation for the CPS Facilitator Tool. The goal is to make sure everyone can communicate with the RDF-based database without having to write queries. The DBInterface is written in PHP and requires slight PHP knowledge before use. It is heavily based on initial work by Bas van Nuland. \\ If you use this framework, you can skip to the `How to use'-part of this document (\ref{howtouse}). If you are planning to improve this framework, I recommend reading the RDF Primer\footnote{http://www.w3.org/TR/rdf-primer/} and SPARQL Query Language for RDF\footnote{http://www.w3.org/TR/rdf-sparql-query/}. A full specification of the current implementation can be found in section \ref{spec}. The areas I suggest improving upon first are described in section \ref{futurework}. \section{How to use}\label{howtouse} \subsection{Initialization} Before the database can be used, you should initialize a \textit{DatabaseInterface} object. This is the only database class you will use. This is done calling the DatabaseInterface constructor. \begin{verbatimtab} $db = new DatabaseInterface(); \end{verbatimtab} \subsection{Basic queries} \subsubsection{Retrieving data} Getting data is done by calling the get method of the DatabaseInterface class. The specification for this method is as follows. \\ \\ \begin{tabular}{| l || r |} \hline \multicolumn{2}{|c|}{Function get()} \\ \hline First argument: \$type & String \\ \hline Second argument: \$arguments & Array \\ \hline Return type: & Array/Variable \\ \hline \end{tabular} \\ \\ The return type is an Array of objects with the type specified as the first argument. For instance, if the first argument is ``user", the function will return an array of User objects. The second argument can be left out if you want to retrieve all entries of a specific type. Below are a few examples showing the usage of get(). A description of what arguments are possible per type is given in section \ref{arguments}. \begin{figure}[H] \caption{Retrieving all questions and echo their title.} \begin{framed} \begin{verbatimtab} $questions = $db->get("question"); foreach ($questions as $question) { echo $question->title; } \end{verbatimtab} \end{framed} \end{figure} \begin{figure}[H] \caption{Retrieving all surveys containing questions with IDs q1 and q2, created by the user Jos, printing all questions in those surveys} \begin{framed} \begin{verbatimtab} //To get all surveys created by the user Jos, we need his UID. //We first query the database for the User object belonging to Jos. $userResults = $db->get("user", array("name" => "Jos")); //Assuming there is a result, the UID is: $josUID = $userResults[0]->uid; //Now to get the requested surveys: $surveys = $db->get("survey", array("questions" => array("q1", "q2"), "creator" => $josUID)); //And to print all the questions in these surveys: foreach($surveys as $survey) { echo "All the questions in " . $survey->name; foreach($survey->questions as $question) { print_r($question); } } \end{verbatimtab} \end{framed} \end{figure} \subsubsection{Storing data} Storing data is easy, as long as you stick to using the given PHP Classes. Retrieve these classes by using the get() function, and pass them as a parameter to the set() function of the DatabaseInterface. This set() function will determine what type the object is and store it at the correct location. The method overview is as follows: \\ \\ \begin{tabular}{| l || r |} \hline \multicolumn{2}{|c|}{Function set()} \\ \hline First argument: \$rToolObject & Variable \\ \hline \end{tabular} \\ \\ Another important thing to note is that currently it will overwrite a previous object with the same UID in the database. The following examples show how to create new objects and save them, as well as edit old objects and save them. \begin{figure}[H] \caption{Creating a new Answer object and storing this in the database.} \begin{framed} \begin{verbatimtab} //For this example, I choose a random question to answer $questions = $db->get("question"); $question = $questions[2]; //Note two things: //1 - If you pass 'null' as first argument when creating any object // A new UID will be generated, indicating a new object. //2 - Depending on the question, there can be multiple answers // This means the values-argument (third argument) is an array. $answer = new Answer(null, $question, array("12345", "four")); //Save the answer in the database $db->set($answer); \end{verbatimtab} \end{framed} \end{figure} \begin{figure}[H] \caption{Getting a Survey object from the database and removing the first question. Also alter this question.} \begin{framed} \begin{verbatimtab} //Get the survey $surveyResults = $db->get("survey", array("uid" => "b91d39e8667372e220bb861b3f94b5bd")); $survey = surveyResults[0]; //Remove the question $question = $survey->questions[0]; unset($survey->questions[0]); //Change the question $question->title = "New Title"; //Save the survey and question $db->batchSet(array($survey, $question)); \end{verbatimtab} \end{framed} \end{figure} \subsection{Arguments}\label{arguments} The arguments you can supply when calling the get() function differ greatly per type. Unfortunately, there is no way around this, so here is a complete overview of arguments per type. \\ \begin{tabular}{| l | c | c | l |} \hline \textbf{Type} & \textbf{Argument name} & \textbf{Argument type} & \textbf{Extra notes} \\ \hline \hline \multirow{3}{*}{Answer} & uid & String & \\ & question & String & UID of the question \\ & values & Array of Strings & \\ \hline \hline \multirow{4}{*}{AnswerSet} & uid & String & \\ & survey & String & UID of the Survey \\ & respondent & String & UID of the Respondent \\ & answers & Array of Strings & UIDs of the Answers \\ \hline \hline \multirow{4}{*}{Application} & uid & String & \\ & title & String & \\ & description & String & \\ & style & String & \\ \hline \hline \multirow{5}{*}{Question} & code & String & \\ & title & String & \\ & type & String & \\ & description & String & \\ & category & String & \\ & definedanswers & Array of Strings & String values of possible answers \\ \hline \hline \multirow{3}{*}{Respondent/User}& uid & String & \\ & name & String & \\ & password & String & Use hashes to store passwords \\ \hline \hline \multirow{6}{*}{Session} & uid & String & \\ & title & String & \\ & creator & String & UID of the User \\ & datetime & String & Unix Timestamp. No way to search on intervals (yet). \\ & applications & Array of Strings & UIDs of the Applications \\ & surveys & Array of Strings & UIDs of the Surveys \\ & answersets & Array of Strings & UIDs of the AnswerSets \\ \hline \hline \multirow{4}{*}{Survey} & uid & String & \\ & title & String & \\ & description & String & \\ & creator & String & UID of the user that created this survey \\ & questions & Array of Strings & UIDs of the Questions \\ \hline \hline \end{tabular} \\ Whenever an Array has to be supplied, it will match for results that satisfy \textit{all} the constraints given in the array. \section{Specification}\label{spec} \subsection{Models} The framework heavily relies on the Object Oriented Programming paradigm, and only allows you to create, edit and store data through instances of precreated classes. All these classes inherit from a global ResearchToolObject class. A UML class diagram of the model classes can be found in Appendix \ref{models}. \subsection{Connectors} Although the front end developer only uses one general DatabaseInterface, the different files for the different datatypes are accessed by seperate connectors. A connector has to implement the IConnector interface, which mainly enforces the get() and set() methods to ensure a connector can perform as expected. The rest of the methods are implemented in the baseclass Connector, which should be extended. In every connector, the get() and set() methods are different. A get() method builds the querystring based on the given arguments, then retrieves the data and performs other necessary queries (like retrieving a different object from another file) to ensure the PHP DataModel is comoplete. A set() method has to store the data accordingly. \subsection{PHPDoc} PHPDoc for the database classes can be found at \href{http://svn.tbm.tudelft.nl/TBM-CPS/RESEARCHTOOL/Doc/Backend/PHPDoc/index.html}{SVN}. \section{Future Work}\label{futurework} //TODO \appendix \pagebreak \section{Class diagram of the models}\label{models} \begin{figure} \includepdf[scale=1.22]{DBModels.pdf} \end{figure} \end{document}