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