# The hk_classes programmer's tutorial

### Horst Knorr

`<hk_classes@knoda.org>`

Version 0.1.2

Abstract

This is a short, quick and dirty tutorial to make it easier to write programs with hk_classes. For further information see the programmer's class documentation. To compile the sourcecode of example.cpp use

    c++ -o example example.cpp  -ldl -lhk_classes -L/usr/local/hk_classes/ -I /usr/local/hk_classes/include/

All examples refer to the literature example database descriped in the knodatutorial.You should first create the database (best use knoda for this).

List of Examples

1.1. Get in contact with your SQL Server
2.1. Get in contact with a table
3.1. Preselect the driver and user information
4.1. Show data of a column
5.1. Alter data of a column
6.1. Add a row
7.1. Delete a row
8.1. Searching a column
9.1. Use a query

## Chapter 1. Get in contact with your SQL Server

Example 1.1. Get in contact with your SQL Server

    #define HAVE_SSTREAM 1
    #include <hk_classes.h>
    #include <iostream>
    int main()
    {
     hk_drivermanager* mydrivermanager = new hk_drivermanager();
     if (mydrivermanager==NULL) {cout <<"error creating mydrivermanager"<<endl;exit(1);}
     hk_connection* myconnection = mydrivermanager->new_connection();
     if (myconnection==NULL) {cout <<"error creating myconnection"<<endl;exit(1);}
     myconnection->connect();
     delete mydrivermanager;
    }

This is the shortest hk_classes program. First create a object instance of hk_drivermanager(). It handles the databasedriver management.

To connect to a SQL server you need a instance of hk_connection. By creating it, the wished database driver will be selected. When you connect with the "connect()"-command the password and some other information will be asked.

Nothing really visible happens here.To get in contact with your data just see the next chapters.

## Chapter 2. Get in contact with a table

Below you see the program of chapter 1 with some additional commands. A hk_database object represents a database, the name of the database can be set either with the constructor or with "set_name(const string&)".

A table or a query is be represented by a hk_datasource object (a query with a "SELECT statement is called in hk_classes a resultquery and can be created with hk_datasource* mydatasource=mydatabase->new_resultquery(); ).

Before you can see the data of a datasource you have to enable it (then the SQL-statement will be executed). The last command ("dump_data()") is just added so that you can see the data, please don't use it in your code.

Example 2.1. Get in contact with a table

      #define HAVE_SSTREAM 1
      #include <hk_classes.h>
      #include <iostream>
      int main()
      {
      hk_drivermanager* mydrivermanager = new hk_drivermanager();
      if (mydrivermanager==NULL) {cout <<"error creating mydrivermanager"<<endl;exit(1);}
      hk_connection* myconnection = mydrivermanager->new_connection();
      if (myconnection==NULL) {cout <<"error creating myconnection"<<endl;exit(1);}
      myconnection->connect();

      hk_database* mydatabase=myconnection->new_database("exampledb");
      if (mydatabase==NULL) {cout <<"error creating mydatabase"<<endl;exit(1);}
      hk_datasource* mydatasource= mydatabase->new_table("authors");
      if (mydatasource==NULL) {cout <<"error creating mydatasource"<<endl;exit(1);}
      mydatasource->enable();
      //the following internal debugging command should not be used. It is used here for
      //demonstration purposes only!!!!
      mydatasource->dump_data(); // DON'T USE THIS COMMAND IN YOUR PROGRAMMS!!!

      delete mydrivermanager;
      }

## Chapter 3. Preselect the driver and user information

Isn't it disturbing, that you have to select the database driver interactively? To stop it change the first part of your code:

Example 3.1. Preselect the driver and user information

    #define HAVE_SSTREAM 1
    #include <hk_classes.h>
    #include <iostream>
    int main()
    {
       hk_drivermanager* mydrivermanager = new hk_drivermanager();
       if (mydrivermanager==NULL) {cout <<"error creating mydrivermanager"<<endl;exit(1);}
       hk_connection* myconnection = mydrivermanager->new_connection("mysql");
       if (myconnection==NULL) {cout <<"error creating myconnection"<<endl;exit(1);}
       myconnection->set_host("localhost");
       myconnection->set_user("root");
       myconnection->set_password("mypasswd");
       myconnection->connect();
    .
    .
    .

## Chapter 4. Show data of a column

Now we try to show data of a specific column. For this we get a hk_column object. hk_column represents a specific column of a datasource. To display the data of the actual row use the command mycolumn->asstring(). The hk_datasource::column_by_name method allows you to select a column by it's name.

When you enable a datasource the row selector is in row 0 (the first row). To move the row selector use one of the hk_datasource methods:

- bool goto_row (unsigned long r)

- bool goto_first (void)

- bool goto_last (void)

- bool goto_next (void)

- bool goto_previous (void)

Example 4.1. Show data of a column

    #define HAVE_SSTREAM 1
    #include <hk_classes.h>
    #include <iostream>
    int main()
    {
       hk_drivermanager* mydrivermanager = new hk_drivermanager();
       if (mydrivermanager==NULL) {cout <<"error creating mydrivermanager"<<endl;exit(1);}
       hk_connection* myconnection = mydrivermanager->new_connection("mysql");
       if (myconnection==NULL) {cout <<"error creating myconnection"<<endl;exit(1);}
       myconnection->set_host("localhost");
       myconnection->set_user("root");
       myconnection->set_password("mypasswd");
       myconnection->connect();

       hk_database* mydatabase=myconnection->new_database("exampledb");
       if (mydatabase==NULL) {cout <<"error creating mydatabase"<<endl;exit(1);}
       hk_datasource* mydatasource= mydatabase->new_table("authors");
       if (mydatasource==NULL) {cout <<"error creating mydatasource"<<endl;exit(1);}
       mydatasource->enable();

       hk_column* mycolumn = mydatasource->column_by_name("name");
       if (mycolumn==NULL) {cout <<"error getting column"<<endl;exit(1);}
       cout <<"Value of the first row: "<<mycolumn->asstring()<<endl;
       mydatasource->goto_next();
       cout <<"Value of the second row: "<<mycolumn->asstring()<<endl;

       delete mydrivermanager;
    }

## Chapter 5. Alter data of a column

We alter now the data of the column. Just give the new value as a parameter to the method hk_column::set_asstring().

Example 5.1. Alter data of a column

    #define HAVE_SSTREAM 1
    #include <hk_classes.h>
    #include <iostream>
    int main()
    {
       hk_drivermanager* mydrivermanager = new hk_drivermanager();
       if (mydrivermanager==NULL) {cout <<"error creating mydrivermanager"<<endl;exit(1);}
       hk_connection* myconnection = mydrivermanager->new_connection("mysql");
       if (myconnection==NULL) {cout <<"error creating myconnection"<<endl;exit(1);}
       myconnection->set_host("localhost");
       myconnection->set_user("root");
       myconnection->set_password("mypasswd");
       myconnection->connect();

       hk_database* mydatabase=myconnection->new_database("exampledb");
       if (mydatabase==NULL) {cout <<"error creating mydatabase"<<endl;exit(1);}
       hk_datasource* mydatasource= mydatabase->new_table("authors");
       if (mydatasource==NULL) {cout <<"error creating mydatasource"<<endl;exit(1);}
       mydatasource->enable();

       hk_column* mycolumn = mydatasource->column_by_name("name");
       if (mycolumn==NULL) {cout <<"error getting column"<<endl;exit(1);}
       mycolumn->set_asstring("my new data");
       mydatasource->store_changed_data();
       delete mydrivermanager;
    }

The method mydatasource->store_changed_data(); will store the changes. The data will also be stored when you move the rowselector to another row (hk_datasource::goto_row()) or when you disable the datasource (hk_datasource::disable()).

## Chapter 6. Add a row

Adding a new row is very simple. Start the definition of the new dataset with the command hk_datasource::setmode_insertrow() and end it with the already well known method mydatasource->store_changed_data();. Between these two methods set the values for each column with the method hk_column::set_asstring(const string&). You have to create hk_column objects for every column (=field) you want to add data.

Example 6.1. Add a row

    #define HAVE_SSTREAM 1
    #include <hk_classes.h>
    #include <iostream>
    int main()
    {
       hk_drivermanager* mydrivermanager = new hk_drivermanager();
       if (mydrivermanager==NULL) {cout <<"error creating mydrivermanager"<<endl;exit(1);}
       hk_connection* myconnection = mydrivermanager->new_connection("mysql");
       if (myconnection==NULL) {cout <<"error creating myconnection"<<endl;exit(1);}
       myconnection->set_host("localhost");
       myconnection->set_user("root");
       myconnection->set_password("mypasswd");
       myconnection->connect();

       hk_database* mydatabase=myconnection->new_database("exampledb");
       if (mydatabase==NULL) {cout <<"error creating mydatabase"<<endl;exit(1);}
       hk_datasource* mydatasource= mydatabase->new_table("authors");
       if (mydatasource==NULL) {cout <<"error creating mydatasource"<<endl;exit(1);}
       mydatasource->enable();

       hk_column* mycolumn = mydatasource->column_by_name("name");
       if (mycolumn==NULL) {cout <<"error getting column"<<endl;exit(1);}
       mydatasource->setmode_insertrow();
       mycolumn->set_asstring("Fontane, Theodor");
       mydatasource->store_changed_data();

       delete mydrivermanager;
    }

## Chapter 7. Delete a row

Also not a great task. Goto the row you wish to delete and call hk_datasource::delete_actualrow()

Example 7.1. Delete a row

    #define HAVE_SSTREAM 1
    #include <hk_classes.h>
    #include <iostream>
    int main()
    {
       hk_drivermanager* mydrivermanager = new hk_drivermanager();
       if (mydrivermanager==NULL) {cout <<"error creating mydrivermanager"<<endl;exit(1);}
       hk_connection* myconnection = mydrivermanager->new_connection("mysql");
       if (myconnection==NULL) {cout <<"error creating myconnection"<<endl;exit(1);}
       myconnection->set_host("localhost");
       myconnection->set_user("root");
       myconnection->set_password("mypasswd");
       myconnection->connect();

       hk_database* mydatabase=myconnection->new_database("exampledb");
       if (mydatabase==NULL) {cout <<"error creating mydatabase"<<endl;exit(1);}
       hk_datasource* mydatasource= mydatabase->new_table("authors");
       if (mydatasource==NULL) {cout <<"error creating mydatasource"<<endl;exit(1);}
       mydatasource->enable();

       hk_column* mycolumn = mydatasource->column_by_name("name");
       if (mycolumn==NULL) {cout <<"error getting column"<<endl;exit(1);}

       mydatasource->goto_row(3);
       mydatasource->delete_actualrow();

       delete mydrivermanager;
    }

When you try this out you will be asked if you really want to delete the data. If this question is disturbing you switch it off. Use the function hk_class::set_showpedantic(false); for this.

## Chapter 8. Searching a column

The method unsigned int hk_column::find (const string& searchtext) searchs in a column whether there is a dataset which contains the needed value. There are different types of this method. See the documentation of hk_column for further details.

It returns the row number if it has found a row with the searchtext, otherwise max rows +1.

Example 8.1. Searching a column

    #define HAVE_SSTREAM 1
    #include <hk_classes.h>
    #include <iostream>
    int main()
    {
       hk_drivermanager* mydrivermanager = new hk_drivermanager();
       if (mydrivermanager==NULL) {cout <<"error creating mydrivermanager"<<endl;exit(1);}
       hk_connection* myconnection = mydrivermanager->new_connection("mysql");
       if (myconnection==NULL) {cout <<"error creating myconnection"<<endl;exit(1);}
       myconnection->set_host("localhost");
       myconnection->set_user("root");
       myconnection->set_password("mypasswd");
       myconnection->connect();

       hk_database* mydatabase=myconnection->new_database("exampledb");
       if (mydatabase==NULL) {cout <<"error creating mydatabase"<<endl;exit(1);}
       hk_datasource* mydatasource= mydatabase->new_table("authors");
       if (mydatasource==NULL) {cout <<"error creating mydatasource"<<endl;exit(1);}
       mydatasource->enable();

       hk_column* mycolumn = mydatasource->column_by_name("name");
       if (mycolumn==NULL) {cout <<"error getting column"<<endl;exit(1);}

       unsigned int result=mycolumn->find("searchtext");

       delete mydrivermanager;
    }

## Chapter 9. Use a query

A result query works like a table. Note: the SQL statement has no delimiter at the end, even if the used database needs one.

Example 9.1. Use a query

      #define HAVE_SSTREAM 1
      #include <hk_classes.h>
      #include <iostream>
      int main()
      {
      hk_drivermanager* mydrivermanager = new hk_drivermanager();
      if (mydrivermanager==NULL) {cout <<"error creating mydrivermanager"<<endl;exit(1);}
      hk_connection* myconnection = mydrivermanager->new_connection();
      if (myconnection==NULL) {cout <<"error creating myconnection"<<endl;exit(1);}
      myconnection->connect();

      hk_database* mydatabase=myconnection->new_database("exampledb");
      if (mydatabase==NULL) {cout <<"error creating mydatabase"<<endl;exit(1);}
      hk_datasource* mydatasource= mydatabase->new_resultquery();
      mydatasource->set_sql("SELECT * FROM literature");
      if (mydatasource==NULL) {cout <<"error creating mydatasource"<<endl;exit(1);}
      mydatasource->enable();
      //the following internal debugging command should not be used. It is used here for
      //demonstration purposes only!!!!
      mydatasource->dump_data(); // DON'T USE THIS COMMAND IN YOUR PROGRAMMS!!!

      delete mydrivermanager;
      }