MySql úvod MySql je multiplatformní databázový systém (server a klient). Je napsán v C a C++. Ke stažení je na www.mysql.com pro různé platformy, ve zdrojových i binárních verzích. My se zde budeme zabívat konkrétně knihovnou libmysqlclient, která umožňuje komunikaci libovolného programu s mysql databází. Ještě než se pustíme do samotného popisu bych zmíníl, že u MySql se dají volit některé možnosti už při kompilaci, které lze změnit pouze další rekompilací. Zmíním zde některé volby configure skriptu, jde o optimalizaci, velikost a kódování:./configure --enable-assembler (povolí assembler, zvětší rychlost)./configure --with-client-ldflags=-all-static (zkompiluje mysqlclientlib ze statických knihoven, zvětší rychlost a velikost)./configure --with-mysqld-ldflags=-all-static (zkompiluje mysqld ze statických knihoven, zvětší rychlost a velikost)./configure --default-character-set=charset (zkompiluje jako defaulní znakovou sadu CHARSET, existuje zde volba czech)./configure --default-collation=collation (porovnávání řetězců, MySql používá jako default latin1_swedish_ci, existuje latin2_czech_ci)
MySql úvod a kompilace programu Binární verze pro linux stažené z www.mysql.com používají tyto flagy: CFLAGS ="-O3 -mpentiumpro" CXXFLAGS="-O3 -mpentiumpro -felide-constructors -fno-exceptions -fno-rtti" Kompilace programu s podporou mysql: Při Kompilaci programu s podporou mysql potřebujeme zahrnout hlavičkový soubor mysql.h: #include <mysql/mysql.h> a nalinkovat program s knihovnou (lib)mysqlclient (zjednodušeně - linux): gcc `mysql_config cflags` `mysql_config libs` test.c -o test
MySql C API Data typy Data typy používané v MySql: typedef char my_bool; Boolean (Pozor char!). typedef unsigned long long my_ulonglong; The type used for the number of rows and for mysql_affected_rows(), mysql_num_rows(), and mysql_insert_id(). This type provides a range of 0 to 1.84e19. On some systems, attempting to print a value of type my_ulonglong will not work. To print such a value, convert it to unsigned long and use a %lu print format. typedef char **MYSQL_ROW This is a type-safe representation of one row of data. It is currently implemented as an array of counted byte strings. (You cannot treat these as nullterminated strings if field values may contain binary data, because such values may contain null bytes internally.) Rows are obtained by calling mysql_fetch_row(). typedef unsigned int MYSQL_FIELD_OFFSET - This is a type-safe representation of an offset into a MySQL field list. (Used by mysql_field_seek().) Offsets are field numbers within a row, beginning at zero.
MySql C API Data typy (MYSQL) Data typy používané v MySql: typedef struct st_mysql {... MYSQL; This structure represents a handle to one database connection. It is used for almost all MySQL functions. Není třeba znát důkladně proměnné této struktury, pro nás reprezentuje handle k databázy. (Proměnné jsem neuvedl, protože by se sem nevlezly)
MySql C API Data typy (MYSQL_FIELD) Data typy používané v MySql: typedef struct st_mysql_field { char *name; /* Jméno pole, nulou ukončený řetězec */ char *org_name; /* Originální jméno pole (jestli jm.je alias) */ char *table; /* Jméno tabulky obsahující toto pole nebo NULL */ char *org_table; /* Originální jméno tabulky (jestli je tab alias) */ char *db; /* Database for table */ char *catalog; /* Catalog for table */ char *def; /* Default value (set by mysql_list_fields) */ unsigned long length; /* Width of column (create length) */ unsigned long max_length; /* Max width for selected set */ unsigned int name_length; unsigned int org_name_length; unsigned int table_length; unsigned int org_table_length; unsigned int db_length; unsigned int catalog_length; unsigned int def_length; unsigned int flags; /* Div flags */ unsigned int decimals; /* Počet čísel v poli */ unsigned int charsetnr; /* Character set */ enum enum_field_types type; /* Typ pole, typy popsány na následující stránce */ MYSQL_FIELD; This structure contains information about a field, such as the field's name, type, and size. Its members are described in more detail here. You may obtain the MYSQL_FIELD structures for each field by calling mysql_fetch_field() repeatedly. Field values are not part of this structure; they are contained in a MYSQL_ROW structure.
MySql C API Data typy (enum_field_types) Uvnitř struktury MYSQL_FIELD: enum enum_field_types; Enumerace použitá ve struktuře MYSQL_FIELD, určuje typ pole: Hodnota Popis FIELD_TYPE_TINY TINYINT field FIELD_TYPE_SHORT SMALLINT field FIELD_TYPE_LONG INTEGER field FIELD_TYPE_INT24 MEDIUMINT field FIELD_TYPE_LONGLONG BIGINT field FIELD_TYPE_DECIMAL DECIMAL or NUMERIC field FIELD_TYPE_FLOAT FLOAT field FIELD_TYPE_DOUBLE DOUBLE or REAL field FIELD_TYPE_TIMESTAMP TIMESTAMP field FIELD_TYPE_DATE DATE field FIELD_TYPE_TIME TIME field FIELD_TYPE_DATETIME DATETIME field FIELD_TYPE_YEAR YEAR field FIELD_TYPE_STRING CHAR field FIELD_TYPE_VAR_STRING VARCHAR field FIELD_TYPE_BLOB BLOB or TEXT field (use max_length to determine the maximum length) FIELD_TYPE_SET SET field FIELD_TYPE_ENUM ENUM field FIELD_TYPE_NULL NULL-type field FIELD_TYPE_CHAR Deprecated; use FIELD_TYPE_TINY instead
MySql C API Data typy (enum_field_types) Uvnitř struktury MYSQL_FIELD: Ve struktuře MYSQL_FIELD jsou ještě flagy, které je nutno popsat: unsigned int flags; Popis jednotlivých bitů (bity se můžou navzájem kombinovat) Hodnota Popis NOT_NULL_FLAG Pole nemůže být NULL PRI_KEY_FLAG Pole je část primárního klíče UNIQUE_KEY_FLAG Pole je část jedinečného (unique) klíče MULTIPLE_KEY_FLAG Pole je část non-unique klíče UNSIGNED_FLAG Pole má UNSIGNED atributu ZEROFILL_FLAG Pole má ZEROFILL atributu BINARY_FLAG Pole má BINARY atributu AUTO_INCREMENT_FLAG Pole má AUTO_INCREMENT atributu ENUM_FLAG Pole je ENUM (deprecated) SET_FLAG Pole je SET (deprecated) BLOB_FLAG Pole je BLOB or TEXT (deprecated) TIMESTAMP_FLAG Pole je TIMESTAMP (deprecated)
MySql C API Data typy (MYSQL_RES) Data typy používané v MySql: typedef struct st_mysql_res { my_ulonglong row_count; MYSQL_FIELD *fields; MYSQL_DATA *data; MYSQL_ROWS *data_cursor; unsigned long *lengths; /* column lengths of current row */ MYSQL *handle; /* for unbuffered reads */ MEM_ROOT field_alloc; unsigned int field_count, current_field; MYSQL_ROW row; /* If unbuffered read */ MYSQL_ROW current_row; /* buffer to current row */ my_bool eof; /* Used by mysql_fetch_row */ /* mysql_stmt_close() had to cancel this result */ my_bool unbuffered_fetch_cancelled; const struct st_mysql_methods *methods; MYSQL_RES; This structure represents the result of a query that returns rows (SELECT, SHOW, DESCRIBE, EXPLAIN). The information returned from a query is called the result set in the remainder of this section.
MySql C API Inicializace (otevření spojení) Inicializace: Abychom úspěšně otevřeli databázy, musíme se nejdřív spojit ze serverem. Funkce mysql_init() otevře spojení a při úspěchu vrátí ukazatel na strukturu MYSQL. Druhý krok je otevřít databázy pod uživatelským jménem, zadat heslo, apod..., to provedeme funkcí mysql_real_connect(). MYSQL* mysql_init(mysql *mysql); Tuto funkci voláme na začítku s parametrem NULL. MYSQL* mysql_real_connect(mysql *mysql, const char *host, const char *user, const char *passwd, const char *db, unsigned int port, const char *unix_socket, unsigned long clientflag); Poslední 3 parametry můžou být 0, NULL, 0 Příklad: MYSQL *mysql; mysql = mysql_init(null); mysql = mysql_real_connect(mysql, Host, User, Pass, Db, NULL, 0, NULL);
MySql C API Deinicializace (zavření spojení) Deinicializace: Jestli jsme úspěšně otevřeli spojení, udělali jsme co jsme potřebovali a teď chceme spojení ukončit, zavoláme mysql_close(). MYSQL* mysql_close(mysql *sock); Touto funkcí ukončíme spojení. Příklad: MYSQL *mysql; mysql = mysql_init(null); mysql = mysql_real_connect(mysql, Host, User, Pass, Db, NULL, 0, NULL); mysql_close(mysql);
MySql C API Požadavky (queries) a výsledky (results) Když je spojení aktivní, klient může poslat požadavek funkcí mysql_query() a mysql_real_query(). Rozdíl těchto funkcí je v tom, že funkcí mysql_query() posíláme nulou ukončený řetězec a funkcí mysql_real_query() můžeme poslat i binární data (posíláme i délku). int mysql_query(mysql *mysql, const char *query); int mysql_real_query(mysql *mysql, const char *query, unsigned long length); Je nutné znát výsledek našeho požadavku. MYSQL_RES *mysql_store_result(mysql *mysql); Každý výsledek vrácený funkcí mysql_store_result() musíme vyčistit funkcí: void mysql_free_result(mysql_res *result); MYSQL_ROW mysql_fetch_row(mysql_res *result); Retrieves the next row of a result set. When used after mysql_store_result(), mysql_fetch_row() returns NULL when there are no more rows to retrieve. When used after mysql_use_result(), mysql_fetch_row() returns NULL when there are no more rows to retrieve or if an error occurred.
MySql C API Požadavky (queries) a výsledky (results) Jednoduchý příklad funkce, která provede požadavek a vrátí MYSQL_ROW: static const char MySqlHost[] = "localhost"; static const char MySqlUser[] = "UserName"; static const char MySqlPass[] = "Password"; static const char MySqlDb[] = "Example"; my_bool GetMysql(char *query) { MYSQL *mysql = mysql_init(null); MYSQL_RES *res; MYSQL_ROW row; if (mysql!= mysql_real_connect(mysql, MySqlHost, MySqlUser, MySqlPass, MySqlDb, NULL, 0, NULL) ) { mysql_close(mysql); return FALSE; /* chyba při spojení */ if (mysql_query(mysql, query)) { mysql_close(mysql); return FALSE; /* chyba MySql serveru */ res = mysql_store_result(mysql); if (res) { row = mysql_fetch_row(res); /* tady něco co prošťourá row */ mysql_free_result(res); mysql_close(mysql); return TRUE; /* vše ok */
MySql C API Požadavky (queries) a výsledky (results) Jednoduchý příklad přímo z manuálu: pozor, tady je proměnná mysql deklarována takto: MYSQL mysql; MYSQL_RES *result; unsigned int num_fields; unsigned int num_rows; if (mysql_query(&mysql, query_string)) { /* error */ else { /* query succeeded, process any data returned by it */ result = mysql_store_result(&mysql); if (result) { /* there are rows */ num_fields = mysql_num_fields(result); /* retrieve rows, then call mysql_free_result(result) */ else { /* mysql_store_result() returned nothing; should it have? */ if (mysql_field_count(&mysql) == 0) { /* query does not return data */ /* (it was not a SELECT) */ num_rows = mysql_affected_rows(&mysql); else { /* mysql_store_result() should have returned data */ fprintf(stderr, "Error: %s\n", mysql_error(&mysql));
MySql C API Závěr Manuálové stránky MySQL mají přes 4mb a není v mé moci udělat jejich absolutní překlad. Celý smysl spočívá v tom, že klient MySQL otevře databázy (pomocí knihovny libmysqlclient), pošle požadavek, vrátí se mu výsledek, zhodnotí ho a uzavře spojení. Ještě před tím, než databázy otevřeme ji musíme nejdřív vytvořit, to můžeme udělat pomocí programu mysql: takto jsem to udělal já: /usr/local/bin/mysql Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 13 to server version: 4.0.22 create database Example; use Example; create TABLE Test(... ); quit Tady jsou odkazy, ze kterých jsem čerpal: www.mysql.com www.metalshell.com www.ousob.com www.root.cz