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; /* char *org_name; /* char *table; /* char *org_table; /* char *db; /* char *catalog; /* char *def; /* unsigned long length; /* unsigned long max_length; /* 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; /* unsigned int decimals; /* unsigned int charsetnr; /* enum enum_field_types type; /* } MYSQL_FIELD;
Jméno pole, nulou ukončený řetězec Originální jméno pole (jestli jm.je alias) Jméno tabulky obsahující toto pole nebo NULL Originální jméno tabulky (jestli je tab alias) Database for table Catalog for table Default value (set by mysql_list_fields) Width of column (create length) Max width for selected set
*/ */ */ */ */ */ */ */ */
Div flags Počet čísel v poli Character set Typ pole, typy popsány na následující stránce
*/ */ */ */
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 FIELD_TYPE_SHORT FIELD_TYPE_LONG FIELD_TYPE_INT24 FIELD_TYPE_LONGLONG FIELD_TYPE_DECIMAL FIELD_TYPE_FLOAT FIELD_TYPE_DOUBLE FIELD_TYPE_TIMESTAMP FIELD_TYPE_DATE FIELD_TYPE_TIME FIELD_TYPE_DATETIME FIELD_TYPE_YEAR FIELD_TYPE_STRING FIELD_TYPE_VAR_STRING FIELD_TYPE_BLOB FIELD_TYPE_SET FIELD_TYPE_ENUM FIELD_TYPE_NULL FIELD_TYPE_CHAR
TINYINT field SMALLINT field INTEGER field MEDIUMINT field BIGINT field DECIMAL or NUMERIC field FLOAT field DOUBLE or REAL field TIMESTAMP field DATE field TIME field DATETIME field YEAR field CHAR field VARCHAR field BLOB or TEXT field (use max_length to determine the maximum length) SET field ENUM field NULL-type field 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 NOT_NULL_FLAG PRI_KEY_FLAG UNIQUE_KEY_FLAG MULTIPLE_KEY_FLAG UNSIGNED_FLAG ZEROFILL_FLAG BINARY_FLAG AUTO_INCREMENT_FLAG ENUM_FLAG SET_FLAG BLOB_FLAG TIMESTAMP_FLAG
Popis Pole nemůže být NULL Pole je část primárního klíče Pole je část jedinečného (unique) klíče Pole je část non-unique klíče Pole má UNSIGNED atributu Pole má ZEROFILL atributu Pole má BINARY atributu Pole má AUTO_INCREMENT atributu Pole je ENUM (deprecated) Pole je SET (deprecated) Pole je BLOB or TEXT (deprecated) 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 static static static
const const const const
char char char char
MySqlHost[] MySqlUser[] MySqlPass[] MySqlDb[]
= = = =
"localhost"; "UserName"; "Password"; "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