GSoC'20 progress : Week 2 & 3

Progress during the second and third week of the coding period

June 22, 2020 - 4 minute read -
GSoC 2020 KDE

GSoC 2020 with KDE

Greetings Reader,

The coding period began on June 1st. As listed in the previous post, the plan for the first phase is to complete the following tasks:

  • A script that generates the SQLite DB using blz datafile downloaded from the Deutsche Bundesbank :heavy_check_mark:
  • Modifications in the CMake build system to call this script at build time. :heavy_check_mark:
  • Replacing the part of code that uses the text datafile with the code that reads from this database.
  • Updating tests, documentations and benchmark to work with the new database.
  • Modifying the command-line tool to enable support for user-supplied database.

The ticked tasks have been completed till now.

Week 2

This week, my main aim was to link the SQLite library to use it in the code and start replacing some of the code that does reading from the text file.

Since, I did not have any previous experience with CMake build system, the linking part was a bit of a work. I carefully studied the existing build system to figure out how to achieve this. I looked up some of the examples on the internet and tried to fill in the gaps from my intuition.
Finally, victory! The CMake command ran successfully and the test source file executed the SQLite APIs.

With that done, now I was ready to write some C++.

Week 3

For this, I established the following flow. When the constructor is called, it checks the bankdata_dir path to see if the database is present. If it is, it calls the method

void AccountNumberCheck::readFile(const string &filename)

with the filename. This method establishes the connection with the database and executes a SELECT query using sqlite3_exec().

Now, there was a problem here.

The sqlite3_exec() calls a static function at every row of the result obtained from the query passed. But, I needed to use the results to insert new Record in the std::map data, which will be used for all the checking and finding of bank accounts. But since, these are members of the class, they cannot be accessed through a static function.

After spending a bit of time searching for a solution, I stumbled upon a way that was helpful. The trick was to pass the pointer to the current object into the static callback function which will cast it into the class pointer and call the required non-static method. So, the callback function looks like this:

int
AccountNumberCheck::callback(void *objPtr, int argc, char **argv, char **azColName){
    return ((AccountNumberCheck *)objPtr)->readDatabase(argv);
}

The method AccountNumberCheck::readFile() used to read from the text file; I modified it to read from the database.

int
AccountNumberCheck::readDatabase(char **argv){
    if(isEntryValidToday(argv[6])){
        char *blz = new char[BLZ_SIZE PLUSONE];
        char *method = new char[METHOD_SIZE PLUSONE];
        char *name = new char[NAME_SIZE PLUSONE];
        char *place = new char[PLACE_SIZE PLUSONE];

        memcpy(blz,argv[1],BLZ_SIZE);
        memcpy(method,argv[3],METHOD_SIZE);
        memcpy(name,argv[4],NAME_SIZE);
        memcpy(place,argv[5],PLACE_SIZE);

        Record* newRecord = new Record(blz,method,name,place); // Create new record
        data.insert(data.end(), banklist_type::value_type(newRecord->bankId, newRecord));

        delete[] blz;
        delete[] method;
        delete[] name;
        delete[] place;
    }
    return 0;
}

Here, the isEntryValidToday() method is used to compare the value of valid_upto field with today’s date.

static bool isEntryValidToday(char *valid_upto){
    if(valid_upto == NULL) return true;

    std::time_t now = time(0);
    struct tm t_struct;
    char today[20];
    t_struct = *localtime(&now);
    strftime(today, sizeof(today), "%Y-%m-%d", &t_struct);

    if(strcmp(today,valid_upto) > 0) return false;

    return true;
}

The SELECT query that I passed, extracts the date in the format YYYY-MM-DD so to compare it with today, I formatted today’s date in the same format, after which they could be compared simply using strcmp().

After a few more additions and changes, the code was successfully reading from the database and working well with the tests. However, the CTest benchmark fails due to incompatibility with the new code. So, next week’s plan is to fix this and make changes to the command-line tool to enable support for user-supplied database.

See you in the next post.

:wave:
Prasun.