| 1 | #pragma once | 
|---|
| 2 |  | 
|---|
| 3 | #include <mysqlxx/Connection.h> | 
|---|
| 4 | #include <mysqlxx/Transaction.h> | 
|---|
| 5 | #include <mysqlxx/Pool.h> | 
|---|
| 6 | #include <common/LocalDate.h> | 
|---|
| 7 | #include <common/LocalDateTime.h> | 
|---|
| 8 | #include <mysqlxx/Null.h> | 
|---|
| 9 |  | 
|---|
| 10 |  | 
|---|
| 11 | /** 'mysqlxx' - very simple library for replacement of 'mysql++' library. | 
|---|
| 12 | * | 
|---|
| 13 | * For whatever reason, in Yandex.Metrica, back in 2008, 'mysql++' library was used. | 
|---|
| 14 | * There are the following shortcomings of 'mysql++': | 
|---|
| 15 | * 1. Too rich functionality: most of it is not used. | 
|---|
| 16 | * 2. Low performance (when used for Yandex.Metrica). | 
|---|
| 17 | * | 
|---|
| 18 | * Low performance is caused by the following reasons: | 
|---|
| 19 | * | 
|---|
| 20 | * 1. Excessive copying: 'mysqlpp::Row' works like 'std::vector<std::string>'. | 
|---|
| 21 | *    Content of MYSQL_ROW is copied inside it. | 
|---|
| 22 | *    But MYSQL_ROW is a 'char**', that is allocated in single piece, | 
|---|
| 23 | *     where values are stored consecutively as (non-zero-terminated) strings. | 
|---|
| 24 | * | 
|---|
| 25 | * 2. Too slow methods for converting values to numbers. | 
|---|
| 26 | *    In mysql++, it is done through std::stringstream. | 
|---|
| 27 | *    This is slower than POSIX functions (strtoul, etc). | 
|---|
| 28 | *    In turn, this is slower than simple hand-coded functions, | 
|---|
| 29 | *     that doesn't respect locales and unused by MySQL number representations. | 
|---|
| 30 | * | 
|---|
| 31 | * 3. Too slow methods of escaping and quoting. | 
|---|
| 32 | *    In mysql++, 'mysql_real_escape_string' is used, that works correct | 
|---|
| 33 | *     even for charsets, that are not based on ASCII (examples: UTF-16, Shift-JIS). | 
|---|
| 34 | *    But when using charsets based on ASCII, as UTF-8, | 
|---|
| 35 | *     (in general, charsets, where escape characters are represented in same way as in ASCII, | 
|---|
| 36 | *      and where that codes cannot appear in representation of another characters) | 
|---|
| 37 | *     this function is redundant. | 
|---|
| 38 | * | 
|---|
| 39 | * 4. Too much garbage (dynamic_cast, typeid when converting values). | 
|---|
| 40 | * | 
|---|
| 41 | * Low performance cause the following effects: | 
|---|
| 42 | * 1. In sequential read from MySQL table, the client CPU becomes a bottleneck, while MySQL server is not loaded. | 
|---|
| 43 | *    When using bare MySQL C API, this doesn't happen. | 
|---|
| 44 | * 2. Sequential read from MySQL is lower than 30MB/s. | 
|---|
| 45 | * | 
|---|
| 46 | * Warning! | 
|---|
| 47 | * | 
|---|
| 48 | * mysqlxx is implemented as very simple wrapper around MySQL C API, | 
|---|
| 49 | *  and implements only limited subset of mysql++ interface, that we use. | 
|---|
| 50 | * And for the sake of simplicity, some functions work only with certain assumptions, | 
|---|
| 51 | *  or with slightly different semantic than in mysql++. | 
|---|
| 52 | * And we don't care about cross-platform usage of mysqlxx. | 
|---|
| 53 | * These assumptions are specific for Yandex.Metrica. Your mileage may vary. | 
|---|
| 54 | * | 
|---|
| 55 | * mysqlxx could not be considered as separate full-featured library, | 
|---|
| 56 | *  because it is developed from the principle - "everything that we don't need is not implemented", | 
|---|
| 57 | *  and also the library depends on some other libraries from Yandex.Metrica code. | 
|---|
| 58 | *  (dependencied could be easily removed if necessary). | 
|---|
| 59 | * It is assumed that the user will add all missing functionality that is needed. | 
|---|
| 60 | */ | 
|---|
| 61 |  | 
|---|