Um Exemplo Simples de Servidor Embutido
Este programa e makefile exemplo devem funcionar sem nenhuma alteração em um sistema Linux ou FreeBSD. Para outros sistemas operacionais, pequenas mudanças serão necessárias. Este exemplo é feito para dar detalhes suficientes para enteder o problema, sem a desordem que é uma parte necessária de uma aplicação real.
Para experimentar o exemplo, crie um diretório test_libmysqld no mesmo nível que o diretório fonte do mysql-4.0. Salve o fonte test_libmysqld.c e o GNUmakefile no diretório e execute GNU make de dentro do diretório test_libmysqld.
test_libmysqld.c
/*
* A simple example client, using the embedded MariaDB server library
*/
#include <mysql.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
MYSQL *db_connect(const char *dbname);
void db_disconnect(MYSQL *db);
void db_do_query(MYSQL *db, const char *query);
const char *server_groups[] = {
'test_libmysqld_SERVER', 'embedded', 'server', NULL
};
int main(int argc, char **argv)
{
MYSQL *one, *two;
/* mysql_server_init() devve ser chamado antes de qualquer
* função mysql.
*
* Você pode usar mysql_server_init(0, NULL, NULL), e iniciar
* o servidor usando os grupos = {
* 'server', 'embedded', NULL
* }.
*
* Em seu arquivo $HOME/.my.cnf file, você provavelmente deseja colocar:
[test_libmysqld_SERVER]
language = /path/to/source/of/mysql/sql/share/english
* É claro que você poderia modifcar argc e argv antes de passá-los
* a esta função. Ou poderá criar novos do modo que preferir. Mas
* todos os argumentos em argv (exceto argv[0], que é o nome do
* programa) devem ser opções válidas para o servidor MySQL.
*
* Se você ligar este cliente em um biblioteca mysqlclient
* normal, esta função não fará nada.
*/
mysql_server_init(argc, argv, (char **)server_groups);
one = db_connect('test');
two = db_connect(NULL);
db_do_query(one, 'SHOW TABLE STATUS');
db_do_query(two, 'SHOW DATABASES');
mysql_close(two);
mysql_close(one);
/* Isto deve ser chamado depois de todas outras funções mysql*/
mysql_server_end();
exit(EXIT_SUCCESS);
}
static void die(MYSQL *db, char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
(void)putc('\n', stderr);
if (db)
db_disconnect(db);
exit(EXIT_FAILURE);
}
MYSQL *
db_connect(const char *dbname)
{
MYSQL *db = mysql_init(NULL);
if (!db)
die(db, 'mysql_init failed: no memory');
/*
* Certifique-se que o cliente e o servidor utilizam grupos diferentes.
* Isto é critico pois o servidor não aceitará as opções do
* cliente e vice versa.
*/
mysql_options(db, MYSQL_READ_DEFAULT_GROUP, 'test_libmysqld_CLIENT');
if (!mysql_real_connect(db, NULL, NULL, NULL, dbname, 0, NULL, 0))
die(db, 'mysql_real_connect failed: %s', mysql_error(db));
return db;
}
void db_disconnect(MYSQL *db)
{
mysql_close(db);
}
void db_do_query(MYSQL *db, const char *query)
{
if (mysql_query(db, query) != 0)
goto err;
if (mysql_field_count(db) > 0)
{
MYSQL_RES *res;
MYSQL_ROW row, end_row;
int num_fields;
if (!(res = mysql_store_result(db)))
goto err;
num_fields = mysql_num_fields(res);
while ((row = mysql_fetch_row(res)))
{
(void)fputs('>> ', stdout);
for (end_row = row + num_fields; row < end_row; ++row)
(void)printf('%s\t', row ? (char*)*row : 'NULL');
(void)fputc('\n', stdout);
}
(void)fputc('\n', stdout);
mysql_free_result(res);
}
else
(void)printf('Affected rows: %lld\n', mysql_affected_rows(db));
return;
err:
die(db, 'db_do_query failed: %s [%s]', mysql_error(db), query);
}
GNUmakefile
# This assumes the MariaDB software is installed in /usr/local/mysql inc := /usr/local/mysql/include/mysql lib := /usr/local/mysql/lib # If you have not installed the MariaDB software yet, try this instead #inc := $(HOME)/mysql-4.0/include #lib := $(HOME)/mysql-4.0/libmysqld CC := gcc CPPFLAGS := -I$(inc) -D_THREAD_SAFE -D_REENTRANT CFLAGS := -g -W -Wall LDFLAGS := -static # You can change -lmysqld to -lmysqlclient to use the # client/server library LDLIBS = -L$(lib) -lmysqld -lz -lm -lcrypt ifneq (,$(shell grep FreeBSD /COPYRIGHT 2>/dev/null)) # FreeBSD LDFLAGS += -pthread else # Assume Linux LDLIBS += -lpthread endif # This works for simple one-file test programs sources := $(wildcard *.c) objects := $(patsubst %c,%o,$(sources)) targets := $(basename $(sources)) all: $(targets) clean: rm -f $(targets) $(objects) *.core