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

Retornar