← cproj

project restructure

3ade7bcbb3d0cc7852b401568b5915bad9b2aea6 · ovidiucs · Dec 17, 2019 20:44

+642 · 11 files changed

  • graph/db/Tupfile +1 −0
  • graph/db/Tuprules.tup +18 −0
  • graph/db/bin/sqltest binary
  • graph/db/bin/sqltest.db binary
  • graph/db/include/console.h +148 −0
  • graph/db/include/sqltest.h +92 −0
  • graph/db/lib/Tupfile +2 −0
  • graph/db/obj/Tupfile +2 −0
  • graph/db/src/sqltest.c +350 −0
  • graph/db/tests/Tupfile +2 −0
  • graph/db/tests/sqltest_test.c +27 −0
diff --git a/graph/db/Tupfile b/graph/db/Tupfile
new file mode 100644
index 0000000..f0fe651
--- /dev/null
+++ b/graph/db/Tupfile
@@ -0,0 +1 @@
+include_rules
diff --git a/graph/db/Tuprules.tup b/graph/db/Tuprules.tup
new file mode 100644
index 0000000..7b93ad5
--- /dev/null
+++ b/graph/db/Tuprules.tup
@@ -0,0 +1,18 @@
+&incdir  = include/
+&objdir  = obj/
+&docsdis = docs/
+&srcdir  = src/
+&bindir  = bin/
+
+CFLAGS += -Weverything
+CFLAGS += -fcolor-diagnostics
+CFLAGS += -std=c11
+CFLAGS += -g
+CFLAGS += -Og
+CFLAGS += -Wall
+CFLAGS += -ggdb3
+TPL += --templates templates/custom/
+
+!cc = |> clang $(CFLAGS) -I&(incdir) -c %f -o &(objdir)/%o |> %B.o
+!ar = |> ar crs %o %f |>
+!docs = |> doxygenparser $(TPL) --debug %f |>
diff --git a/graph/db/bin/sqltest b/graph/db/bin/sqltest
new file mode 100755
index 0000000..0f9f417
Binary files /dev/null and b/graph/db/bin/sqltest differ
diff --git a/graph/db/bin/sqltest.db b/graph/db/bin/sqltest.db
new file mode 100644
index 0000000..a60d7d4
Binary files /dev/null and b/graph/db/bin/sqltest.db differ
diff --git a/graph/db/include/console.h b/graph/db/include/console.h
new file mode 100644
index 0000000..5e3ebbd
--- /dev/null
+++ b/graph/db/include/console.h
@@ -0,0 +1,148 @@
+
+ /**
+ *  @dir include
+ *  @brief include directory for header files
+ *
+ */
+ /**
+ *
+ *  @file console.h
+ *  @brief Function prototypes for the console driver.
+ *
+ *  This contains the prototypes for the console
+ *  driver and eventually any macros, constants,
+ *  or global variables you will need.
+ *
+ *  @author Ovidiu Constantinescu (ovidiucs)
+ */
+
+     #ifndef _MY_CONSOLE_H
+    #define _MY_CONSOLE_H
+
+    #include <video_defines.h>
+
+    /** @brief Prints character ch at the current location
+     *         of the cursor.
+     *
+     *  If the character is a newline (`\n`), the cursor should
+     *  be moved to the next line (scrolling if necessary).  If
+     *  the character is a carriage return (`\r`), the cursor
+     *  should be immediately reset to the beginning of the current
+     *  line, causing any future output to overwrite any existing
+     *  output on the line.  If backsapce (`\b`) is encountered,
+     *  the previous character should be erased (write a space
+     *  over it and move the cursor back one column).  It is up
+     *  to you how you want to handle a backspace occurring at the
+     *  beginning of a line.
+     *
+     *  @param ch the character to print
+     *  @return The input character
+     */
+    int putbyte( char ch );
+
+    /** @brief Prints the string s, starting at the current
+     *         location of the cursor.
+     *
+     *  If the string is longer than the current line, the
+     *  string should fill up the current line and then
+     *  continue on the next line. If the string exceeds
+     *  available space on the entire console, the screen
+     *  should scroll up one line, and then the string should
+     *  continue on the new line.  If `\n`, `\r`, and `\b` are
+     *  encountered within the string, they should be handled
+     *  as per putbyte. If len is not a positive integer or s
+     *  is null, the function has no effect.
+     *
+     *  @param s The string to be printed.
+     *  @param len The length of the string s.
+     *  @return Void.
+     */
+    void putbytes(const char* s, int len);
+
+    /** @brief Changes the foreground and background color
+     *         of future characters printed on the console.
+     *
+     *  If the color code is invalid, the function has no effect.
+     *
+     *  @param color The new color code.
+     *  @return Void.
+     */
+    void set_term_color(int color);
+
+    /** @brief Writes the current foreground and background
+     *         color of characters printed on the console
+     *         into the argument color.
+     *  @param color The address to which the current color
+     *         information will be written.
+     *  @return Void.
+     */
+    void get_term_color(int* color);
+
+    /** @brief Sets the position of the cursor to the
+     *         position (row, col).
+     *
+     *  Subsequent calls to putbytes should cause the console
+     *  output to begin at the new position. If the cursor is
+     *  currently hidden, a call to set_cursor() must not show
+     *  the cursor.
+     *
+     *  @param row The new row for the cursor.
+     *  @param col The new column for the cursor.
+     *  @return Void.
+     */
+    void set_cursor(int row, int col);
+
+    /** @brief Writes the current position of the cursor
+     *         into the arguments row and col.
+     *  @param row The address to which the current cursor
+     *         row will be written.
+     *  @param col The address to which the current cursor
+     *         column will be written.
+     *  @return Void.
+     */
+    void get_cursor(int* row, int* col);
+
+    /** @brief Hides the cursor.
+     *
+     *  Subsequent calls to putbytes must not cause the
+     *  cursor to show again.
+     *
+     *  @return Void.
+     */
+    void hide_cursor();
+
+    /** @brief Shows the cursor.
+     *
+     *  If the cursor is already shown, the function has no effect.
+     *
+     *  @return Void.
+     */
+    void show_cursor();
+
+    /** @brief Clears the entire console.
+     *  @return Void.
+     */
+    void clear_console();
+
+    /** @brief Prints character ch with the specified color
+     *         at position (row, col).
+     *
+     *  If any argument is invalid, the function has no effect.
+     *
+     *  @param row The row in which to display the character.
+     *  @param col The column in which to display the character.
+     *  @param ch The character to display.
+     *  @param color The color to use to display the character.
+     *  @return Void.
+     */
+    void draw_char(int row, int col, int ch, int color);
+
+    /** @brief Returns the character displayed at position (row, col).
+     *  @param row Row of the character.
+     *  @param col Column of the character.
+     *  @return The character at (row, col).
+     */
+    char get_char(int row, int col);
+
+    #endif /* _MY_CONSOLE_H */
+
diff --git a/graph/db/include/sqltest.h b/graph/db/include/sqltest.h
new file mode 100644
index 0000000..678475d
--- /dev/null
+++ b/graph/db/include/sqltest.h
@@ -0,0 +1,92 @@
+
+ /*!
+  *  @dir include
+  *  @brief include directory for header files
+  *
+ */
+ /*!
+  *  @file sqltest.h
+  *  @brief Function prototypes sqlite3 test program
+  *
+  *  @author Ovidiu Constantinescu (ovidiucs)
+  *  @bug No known bugs.
+ */
+
+ /*!
+  *  @defgroup func Functions
+  *  @defgroup sfunc Static Functions
+ */
+
+/*! @brief Mainmenu function
+  *  Each open SQLite database is represented by a pointer
+  *  to an instance of the opaque structure named "sqlite3".
+  *  @ingroup func
+  *  @param db an sqlite3 database
+  *  @return int Success code
+  */
+int mainmenu(sqlite3 *db);
+
+/*! @brief Inserting database records
+  * @ingroup      func
+  *
+  * @param[in] db Pass a database instance
+  * @param[in] data Data to be inserted
+  * @return err
+  * @code{.c}
+  *		char iSQL = "INSERT INTO Friends(Name,Age) VALUES ('Tom',10);";
+  *		int rc = dbInsert(database, iSQL );
+  * @endcode
+*/
+int dbInsert(sqlite3 *db, char *data);
+
+/*! @brief Select data from an sqlite3 database.
+  * @ingroup      func
+  *
+  * @param[in] db Pass a database instance
+  * @param[in] data Data to be selected
+  * @return err
+  * @code{.c}
+  *		char iSQL = "SELECT * FROM Friends;";
+  *		int rc = dbInsert(database, iSQL );
+  * @endcode
+  * @todo limit queries
+*/
+int dbSelect(sqlite3 *db, char *data);
+
+/*! @brief Update data from an sqlite3 database.
+  * @ingroup      func
+  *
+  * @param[in] db Pass a database instance
+  * @param[in] data Data to be updated
+  * @return err
+  * @code{.c}
+  *		char uSQL = "UPDATE Friends SET Name = 'Jerry' WHRE id = 1;";
+  *		int rc = dbUpdate(database, uSQL );
+  * @endcode
+  * @todo limit queries
+*/
+int dbUpdate(sqlite3 *db, char *data);
+
+/*! @brief Setup function for a mysqllite database
+  * @ingroup      func
+  *
+  * @param[in] p_db -> address of pointer to a db
+  * @return int -> if the database is opened or created successfully SQLITE_OK is returned otherwise an error is returned.
+  * @code{.c}
+  *		int rc = setup(&db);
+  *
+  * @endcode
+*/
+int setup(sqlite3 **p_db);
+
+/*!
+ * @brief traverse SELECT statements with multiple records.
+ * @ingroup sfunc
+ *
+ * @param data Ignored in this case, see the documentation for sqlite3_exec
+ * @param argc The number of columns in the result set
+ * @param argv The row's data
+ * @param azColName  The column names
+ * @return int
+ */
+static int callback(void *data, int argc, char **argv, char **azColName );
diff --git a/graph/db/lib/Tupfile b/graph/db/lib/Tupfile
new file mode 100644
index 0000000..4180b27
--- /dev/null
+++ b/graph/db/lib/Tupfile
@@ -0,0 +1,2 @@
+include_rules
+: foreach ../obj/*.o |> !ar |> db.a
diff --git a/graph/db/obj/Tupfile b/graph/db/obj/Tupfile
new file mode 100644
index 0000000..91180c2
--- /dev/null
+++ b/graph/db/obj/Tupfile
@@ -0,0 +1,2 @@
+include_rules
+: foreach ../src/sq*.c |> !cc |>
diff --git a/graph/db/src/sqltest.c b/graph/db/src/sqltest.c
new file mode 100644
index 0000000..0b47a47
--- /dev/null
+++ b/graph/db/src/sqltest.c
@@ -0,0 +1,350 @@
+/*!
+ * @dir src
+ * @brief source directory
+ * @file
+ * @brief the main project file
+ */
+
+#include <stdio.h> 								// fprintf, printf
+#include <stdlib.h> 							// exit,
+#include <readline/readline.h>  	// readline
+#include <readline/history.h> 		//
+#include <sqlite3.h>							//
+#include "../include/sqltest.h"    //
+
+/*! @defgroup defines Defines
+ * @{ */
+
+/** @brief Enable or disable debug*/
+#define DEBUG 0
+/** @brief Enable or disable writing to memory*/
+#define MEMWRITE 0
+
+/*!
+ @} */
+
+/*! @defgroup globals Global Variables
+ * @{ */
+
+/** @brief SQL insert table entries **/
+static char *sSql = "DROP TABLE IF EXISTS Friends;"
+		"CREATE TABLE Friends(Id INTEGER PRIMARY KEY, Name TEXT, Age INTEGER);"
+		"INSERT INTO Friends(Name,Age) VALUES ('Tom',10);"
+		"INSERT INTO Friends(Name,Age) VALUES ('Rebecca',32);"
+		"INSERT INTO Friends(Name,Age) VALUES ('Jim',34);"
+		"INSERT INTO Friends(Name,Age) VALUES ('Roger',12);"
+		"INSERT INTO Friends(Name,Age) VALUES ('Robert',16);";
+
+/** @brief SQL Update function **/
+static char *uSql = "UPDATE Friends SET Name = 'Jerry' WHRE id = 1;";
+
+/*!
+ @} */
+
+/*!
+	*  @brief	Main program function.
+	*  @returns int	error code
+	*  @code{.shell-session}
+	*  ./sqltest
+	* Opened database connection succesfully
+	*
+	* -----------------------
+	* 1. View database entries
+	* 2. Update database records
+	* 3. Delete database record
+	* 4. Insert test data.
+	*         41. From Command Line.
+	*         42. From File.
+	* 5. Quit
+	*
+	* -----------------------
+	* Enter a choice >
+	*  @endcode
+	*
+*/
+
+int main(int argc, char **argv) {
+	//  Each opened SQLite database is represented by a pointer
+  //  to an instance of the opaque structure named sqlite3
+
+  sqlite3 *db = NULL;
+  int rc;
+
+  // This string will hold the english language of the error description
+  char *zErrMsg;
+
+  // Ensure that the proper arguments are given.
+  if (argc != 3 && argc != 1) {
+      fprintf(stderr, "Usage: %s DATABASE SQL-STATEMENT\n", argv[0]);
+      // Return error code
+      return 1;
+  } else if (argc == 3) {
+			rc = setup(&db);
+  } else {
+			rc = setup(&db);
+      // Execute the main menu function
+	    mainmenu(db);
+  }
+  return 0;
+}
+
+int setup(sqlite3 **p_db) {
+
+	sqlite3 *db = NULL;
+  int rc;
+
+#if MEMWRITE == 1
+	  rc = psqlite3_open(":memory:", &db);
+#else
+	  rc = sqlite3_open("sqltest.db", &db);
+#endif
+	  // Test that the return code is OK
+	  if (rc != SQLITE_OK) {
+
+	      fprintf(stderr,"Error opening sqlite3 database in memory %s\n",sqlite3_errmsg(db) );
+	      fprintf(stderr,"Clearing resoursces used for sqlite3_open\n");
+				/*
+					* Whether or not an error occurs when it is opened,
+					* resources associated with the database connection
+					* handle should be released by passing it to
+					* sqlite3_close() when it is no longer required.
+				*/
+				sqlite3_close(db);
+				fprintf(stderr,"Database closed.\n");
+
+	   }
+		// Let us know if the database connection was succesfull.
+		fprintf(stdout,"Opened database connection succesfully\n");
+
+	  // Display the SQLite version - debug
+
+#if DEBUG == 1
+	  // The sqlite3_stmt represents a single SQL statement
+	  sqlite3_stmt *res;
+	  // Seeing if the global variable is printed
+	  fprintf(stdout,"The SQL statement is: %s\n", sSql);
+
+	  /*
+			* The sqlite3_prepare is the constructor for the sqlite3_stmt
+			* compile sql text into byte code that will do the work for querying
+			* 1st arg - database connection - obtained  from sqlite3_open()
+			* 2nd arg - zSql - statement to be compiled
+			* 3rd arg - nByte - negative -> read up to the first zero terminator
+			* 4th arg - *ppStmt pointing to a compiled statement that can be run with sqlite3_step()
+			* the calling proc is responsable for deleting the SQL statement with sqlite3_finalize()
+			* 5th arg - pzTail point to the first byte past the end of the first SQL  staement
+		*/
+	  rc = sqlite3_prepare_v2(db, "SELECT sqlite_version()", -1, &res, 0);
+	  fprintf(stderr,"%d\n\r",rc);
+	  if (rc == SQLITE_ROW) {
+		  fprintf(stdout,"SQLite Version is: %s\n",sqlite3_column_text(res,0));
+	  }
+#endif
+
+	  *p_db = db;
+	  return 0;
+}
+
+int mainmenu(sqlite3 *db) {
+	char menu[] =
+			"\n-----------------------\n"
+			"1. View database entries\n"
+			"2. Update database records\n"
+			"3. Delete database record\n"
+			"4. Insert test data.\n"
+			"\t41. From Command Line.\n"
+			"\t42. From File.\n"
+			"5. Quit\n"
+			"\n-----------------------\n";
+
+	char response[1024];
+	char *buf;
+	int rc=0;
+	unsigned int item = 0;
+	for (;;) {
+		fputs(menu,stdout);
+
+		fputs("Enter a choice > ",stdout);
+//		fflush();
+		if(fgets(response, sizeof(response), stdin) == NULL) {
+			exit(1);
+		}
+		if(sscanf(response,"%u",&item) != 1) {
+			fprintf(stderr,"Error reading commnad. Please enter a valid integer\n");
+		} else {
+		switch (item) {
+			case 1:
+				buf = readline("Enter query: > ");
+				dbSelect(db, buf);
+				free(buf);
+				break;
+			case 2:
+				fputs("dbDelete`\n",stdout);
+				fgets(response, sizeof(response), stdin);
+				//dbDelete(db, response);
+				break;
+			case 3:
+				fputs("dbUpdate()\n",stdout);
+				break;
+			case 41:
+				buf = readline("Insert test data via command.\n");
+					if (!dbInsert(db,buf) ) {
+					fprintf(stdout,"Inserted data OK\n");
+					}
+				break;
+			case 42:
+					if (!dbInsert(db,sSql) ) {
+					fprintf(stdout,"Inserted data succesfully\n");
+					}
+				break;
+			case 5:
+				fputs("Quiting.\n",stdout);
+				goto Exit;
+			default:
+				fputs("Please choose a valid menu option\n",stdout);
+			}
+		}
+	}
+		Exit:
+	return 0;
+}
+// --------------------------- End MainMenu ---------------------------
+
+int dbInsert(sqlite3 *db, char *data) {
+
+	/*
+   * Check that a database was passed and we have an open database connection
+   * Note: do not close db connection while sqlite3_exec is running
+   * Note: do not modify the sql statement while sqlite3_exec is running
+	*/
+  if ( db == NULL ) {
+    fprintf(stderr,"Error with database access, exiting\n");
+    return 1;
+  }
+  char *zErrMsg = NULL;
+	/*
+   * wrapper function does sqlite3_prepare(),sqlite3_step(), sqlite3_column(), sqlite3_finalize()
+   * 1st arg - an open database
+   * 2nd arg - SQL to be evaluated
+   * 3rd arg - callback function - invoked for each result row comming out of the evaluated statements
+   * int (*callback)(void*, int, char**, char**)
+   * 4th arg - 1st arg to callback function - relaying the argument to it.
+   * 5th arg - error message writte (char **)
+	*/
+		int rc = sqlite3_exec(db,data,0,0,&zErrMsg);
+		/*
+		 * @todo When there is an SQL syntax error
+		 * the database closes. Syntax errors should not close the DB .
+		 * Determine the correct behavior.
+		*/
+			if ( rc != SQLITE_OK ) {
+				fprintf(stderr, "SQL error occured: %s\n", zErrMsg);
+				sqlite3_free(zErrMsg);
+
+				return rc;
+				}
+  return 0;
+}
+
+// --------------------------- dbSelect ---------------------------
+
+
+int dbSelect(sqlite3 *db, char *data) {
+  // Note: does not use the wrapper function (test) -
+  // pointer to a prepared statement - called by prepare
+  sqlite3_stmt *res;
+
+  // Check that a database was passed and we have an open database connection
+  if ( db == NULL ) {
+    fprintf(stderr,"Error with database access, exiting\n");
+    return 1;
+  }
+  char *zErrMsg = NULL;
+  int rc = 0;
+
+  //1. Prepare
+  // int rc = sqlite3_prepare_v2(db,data,-1,&res,0);
+
+#if DEBUG == 1
+  fprintf(stderr,"Database is: %s ; Data is: %s, ; Return Code is: %d ; stmt is %p\n",
+		  db,data,rc,res);
+#endif
+
+  rc = sqlite3_prepare_v2(db, data, -1, &res, 0);
+
+#if DEBUG == 1
+  fprintf(stderr,"Database is: %s ; Data is: %s, ; Return Code is: %d ; stmt is %p\n",
+		  db,data,rc,res );
+#endif
+  // On success the sqlite3_prepare() returns SQLITE_OK
+  if ( rc != SQLITE_OK ) {
+	 fprintf(stderr, "SQL error occured: %s with code %d\n", zErrMsg, rc);
+	 sqlite3_free(zErrMsg);
+
+	 return 1;
+  }
+	/*
+   * 2.Step
+   * 1st arg - pointed data by sqlite_stmt
+   * returns integer - the result of the operation
+   * Useful routines;
+	 */
+  rc = sqlite3_step(res);
+		  for ( int i = 0; i < sqlite3_data_count(res) ; i++ ) {
+	       fprintf(stdout,"| %s\t",sqlite3_column_origin_name(res,i));
+	  }
+	  fprintf(stdout,"\r\n");
+  while ( rc == SQLITE_ROW ) {
+	  int i = 0;
+  	// If the return code is SQLITE_ROW we can now iterate thorugh the entire column, row by row
+    // - sqlite3_data_count() will return 0 if sqlite3_step was not called
+	  for ( i = 0; i < sqlite3_data_count(res) ; i++ ) {
+	       fprintf(stdout,"| %s\t",sqlite3_column_text(res,i));
+	   }
+	  fprintf(stdout,"\r\n");
+  // Grab next row
+	 rc = sqlite3_step(res);
+   }
+  // Finalize - clean up after using.
+  rc = sqlite3_finalize(res);
+  if ( rc != SQLITE_OK ) {
+	  fprintf(stderr,"SQL error occured on sqlite3_finalize(): %s with code: %d\n",zErrMsg, rc);
+	  sqlite3_free(zErrMsg);
+
+	  return 1;
+  }
+
+  return 0;
+}
+
+#if 0
+static int callback(void *data, int argc, char **argv, char **azColName ) {
+  return 0;
+}
+#endif
+// --------------------------- dbUpdate ---------------------------
+int dbUpdate (sqlite3 *db, char *data) {
+   sqlite3_stmt *res;
+   // Vars
+   const char *msg = "Called callback function\n";
+   char *zErrMsg = NULL;
+   int rc = 0;
+   // Check that db is presnet
+   if ( db == NULL ) {
+    fprintf(stderr,"Error with database access, exiting\n");
+    return 1;
+   }
+   // Prepare & check
+   rc = sqlite3_prepare_v2(db, data, -1, &res, 0);
+			if (rc != SQLITE_OK) {
+			fprintf(stderr, "SQL error occured: %s with code %d\n", zErrMsg, rc);
+			sqlite3_free(zErrMsg);
+
+			return 1;
+			}
+//    rc = sqlite3_exec (db, data,callback,(void*) msg, &zErrMsg);
+    fprintf(stdout,"%d\n",rc);
+
+   return 0;
+}
+// Delete data
diff --git a/graph/db/tests/Tupfile b/graph/db/tests/Tupfile
new file mode 100644
index 0000000..9fc97bf
--- /dev/null
+++ b/graph/db/tests/Tupfile
@@ -0,0 +1,2 @@
+include_rules
+
diff --git a/graph/db/tests/sqltest_test.c b/graph/db/tests/sqltest_test.c
new file mode 100644
index 0000000..c69925e
--- /dev/null
+++ b/graph/db/tests/sqltest_test.c
@@ -0,0 +1,27 @@
+ /**
+ *  @dir tests
+ *  @brief Unit testing folder
+ *  @details No other details
+ */
+
+#include <criterion/criterion.h>
+#include <sqlite3.h>
+#include "../include/sqltest.h"
+
+#include <stdio.h> // fprintf, printf
+#include <stdlib.h> // exit,
+
+/**
+* Variables used by tests
+*/
+
+Test(tSuite_1, t_001){
+  sqlite3 *db = NULL;
+  // test contents
+  cr_assert(setup(db) == 0);
+}
+
+/**
+* Setup and teardown
+*/
+