Skip to content

Database API

Andrey Fedorov edited this page Jan 21, 2017 · 9 revisions

Plugin library for database

Current build working with PostgreSQL database.
Database module has name pg.so, it is dinamyc load plugin.
You must write library with two functions to use another database:

  • void *db_thread(void *arg)
  • void *timer_function(void *ptr)

Sorce file headers

The source file must contains three headers:

#include "glonassd.h"
#include "de.h"
#include "logger.h"

db_thread function

This function running in a separate thread and doing all the work:

  • open and close database connection
  • create a message queue
  • wait massage with decoded terminal data
  • write data to database

Main module call this function like this:

pthread_create(&db_thread, NULL, db_thread_func, &stConfigServer);

where stConfigServer is pointer to main configuration structure ST_CONFIG_SERVER (glonassd.h).
ST_CONFIG_SERVER contains database parameters, such as host, port, name, user, password, etc.

Message queue

Queue created with function mq_open and has name defined in constant QUEUE_WORKER (in glonassd.h).
Each terminal processing thread open this queue also and write decoded terminal data (messages) into it.
Messages for this queue described in file de.h (ST_RECORD stucture).

Each POSIX message queue has fixed size in Linux, known as "POSIX message queues" and you can use command "ulimit -a" to see it. This size is 819200 bytes for 64-bit system by default.
The ST_RECORD structure has size 224 bytes. Like this, queue can contain, in theory, 819200 / 224 = 3657 messages maximum (in fact less) at the same time.

This restriction may be lifted if the user on whose behalf the running daemon has root privilege or can change POSIX message queue size. System administrator can change default POSIX message queue size also by editing msgqueue value in /etc/security/limits.conf file.

Message queue created like this:

queue_workers = mq_open(QUEUE_WORKER, O_RDONLY | O_CREAT, S_IRUSR | S_IWUSR, &queue_attr);

After message queue was created, database thread must wait messages like this:

while( 1 ) {
	msg_size = mq_receive(queue_workers, msg_buf, buf_size, NULL);
	if( msg_size > 0 )
		write_data_to_db(db_connection, msg_buf, sql_insert_point);	// write message to database
}

where sql_insert_point is text of the SQL-operator for insert record in the database.

timer_function function

The timer_function is timer triggered function. It works in separate thread also and usually call script, specified in configuration file glonassd.conf in section server to parameter timer.
An argument ptr is pointer to a timer structure ST_TIMER (glonassd.h). This structure contains path to the fired script. Function can connect to the database before calling script if needed.

Log errors

To log errors you can call log-function like this:

logging("database thread[%ld]: error %d: %s\n", syscall(SYS_gettid), errno, strerror(errno));

Compile plugin library

Compile can be like this:

gcc -c -std=gnu99 -D_REENTERANT -m64 -fpic -Wall -Werror -O2 -flto -g0 -I/usr/include/nptl -lpq -lpthread -L/usr/lib/nptl -rdynamic -ldl -lrt -lm db.c -o db.o
gcc -shared -o db.so db.o

where db.c is source file and db.so is plugin library.

Use plugin library with daemon

To connect plugin library to daemon set parameter db_type in glonassd.conf file to the name of the .so file. E.g. db_type=pg for pg.so.

To be continued.