MySQL- Руководство разработчика
Отображение картинок в HTML из столбцов типа BLOB
Этот пример также очень короткий. Рассмотрим функцию, которую он выполняет. Хотя с версии 3.23.3 имеется команда для сброса данных из столбцов BLOB в двоичный файл, эта программа может использоваться не только клиентами, все еще использующими старые версии, но и теми, кто не хочет сбрасывать картинку на диск. #include
int main (int argc, char *argv[]) { if (argc < 2) { cerr << "Usage: cgi_image primary_key_value" << endl<< endl; return -1; } cout << "Content-type: image/jpeg" << endl; Connection con(use_exceptions); try { con.real_connect(MY_DATABASE,MY_HOST,MY_USER,MY_PASSWORD,3306, (int)0,60,NULL); Query query = con.query(); query << "SELECT" << MY_FIELD << "FROM " << MY_TABLE << " WHERE " << MY_KEY <<" = " << argv[1]; ResUse res = query.use(); Row row=res.fetch_row(); long unsigned int *jj = res.fetch_lengths(); cout << "Content-length:" << *jj << endl<< endl; fwrite(row.raw_data(0),1,*jj,stdout); return 0; } catch (BadQuery er) { cerr << "Error: " << er.error << " " << con.errnum() << endl; return -1; } }
Этот пример показывает обработку двоичных данных в MySQL++, которая появилась в версии 1.6. Гибкое использование потоков допускает легкое использование этого кода во многих прикладных программах.
Получение данных
Следующий пример показывает довольно интересное понятие, известное как Specialized SQL Structures (SSQLS). Имя файла для этого кода: custom1.cc. #include
sql_create_5 (stock, 1, 5, string, item, int, num, double, weight, double, price, Date, sdate)
// this is calling a very complex macro which will create a custom // struct "stock" which has the variables: // string item // int num // ... // Date sdate // defined as well methods to help populate the class from a mysql row // among other things that I'll get too in a latter example int main () { try { Connection con (use_exceptions); con.connect ("mysql_cpp_data"); Query query = con.query (); query << "select * from stock"; vector < stock > res; query.storein (res); // this is storing the results into a vector of the custom struct // "stock" which was created my the macro above. cout.setf (ios::left); cout << setw (17) << "Item" << setw (4) << "Num" << setw (7) << "Weight" << setw (7) << "Price" << "Date" << endl << endl; cout.precision(3); vector
Как Вы можете видеть, SSQLS очень мощная штука.
При выполнении запроса
Чтобы определять параметры, когда Вы хотите выполнять запрос, просто используйте Query::store(const SQLString &parm0, [..., const SQLString &parm11]) (или выражение Query::use или Query::execute). Здесь определение parm0 соответствует параметру 0 и так далее. Отсчет идет с нуля, так что первый параметр на самом деле нулевой. Вы можете определять от 1 до 12 различных параметров. Например: Result res = query.store("Dinner Roles", "item", "item", "price") Для описанного в разделе 3.6.2 шаблона запроса это выведет: select (item, price) from stock where item = " Dinner Roles" Причина того, почему я не сделал шаблон более логическим: select (%0:field1, %1:field2) from stock where %2: wheref = %q3:what Станет очевидным быстрее.
Простой пример
Следующий пример показывает, как открыть подключение, выполнить простой запрос и отобразить результаты. Код может быть найден в файле simple1.cc, который размещен в каталоге примеров пакета. #include
int main() { Connection con("mysql_cpp_data"); // The full format for the Connection constructor is // Connection(cchar *db, cchar *host="", cchar *user="", // cchar *passwd="") // You may need to specify some of them if the // database is not on // the local machine or you database username is // not the same as your // login name, etc..
Query query = con.query(); // This creates a query object that is bound to con.
query << "select * from stock"; // You can write to the query object // like you would any other ostrem
Result res = query.store(); // Query::store() executes the query // and returns the results
cout << "Query: " <
Struct BadConversion
Используется для создания исключительной ситуации, когда происходит плохое преобразование.
Загрузка двоичного файла в столбец типа BLOB
Эта функция появилась в MySQL version 3.23, но многие пользователи все еще используют старые версии. Пример показывает несколько свойств MySQL++. Эта программа требует одного параметра, который является полным путевым именем для двоичного файла. #include
extern int errno; const char MY_DATABASE[]="telcent"; const char MY_TABLE[]="fax"; const char MY_HOST[]="localhost"; const char MY_USER[]="root"; const char MY_PASSWORD[]=""; const char MY_FIELD[]="fax"; // BLOB field
int main(int argc, char *argv[]) { if (argc < 2) { cerr << "Usage: load_file full_file_path" << endl<< endl; return -1; } Connection con(use_exceptions); try { con.real_connect(MY_DATABASE,MY_HOST,MY_USER,MY_PASSWORD,3306, (int)0,60,NULL); Query query = con.query(); ostrstream strbuf; ifstream In (argv[1],ios::in| ios::binary); struct stat for_len; if ((In.rdbuf())->is_open()) { if (stat (argv[1],& for_len) == -1) return -1; unsigned int blen = for_len.st_size; if (!blen) return -1; char *read_buffer= new char[blen]; In.read(read_buffer,blen); string fill(read_buffer,blen); strbuf << "INSERT INTO " << MY_TABLE <<" (" << MY_FIELD << ") VALUES(\"" << escape << fill << "\")"; query.exec(strbuf.str()); delete[] read_buffer; } else cerr << "Your binary file " << argv[1] << "could not be open, errno = " << errno; return 0; } catch (BadQuery er) { cerr << "Error: " <
Добавление данных
SSQLS может также использоваться, чтобы добавить данные в таблицу. Имя файла для этого кода: custom2.cc. #include
sql_create_5(stock, 1, 5, string, item, int, num, double, weight, double, price, Date, sdate)
int main() { try { // its in one big try block Connection con(use_exceptions); con.connect("mysql_cpp_data"); Query query = con.query(); stock row; /* row.item = "Hot Dogs"; row.num = 100; row.weight = 1.5; row.price = 1.75; row.sdate = "1998-09-25"; */ row.set("Hot Dogs", 100, 1.5, 1.75, "1998-09-25"); // populate stock query.insert(row); // form the query to insert the row // the table name is the name of the struct by default cout << "Query : " << query.preview() << endl; // show the query about to be executed query.execute(); // execute a query that does not return a result set print_stock_table(query); // now print the new table; } catch (BadQuery er) { cerr << "Error: " <
Двинемся дальше
Это только общий обзор того, что SSQLS может делать. Для получения большего количества информации обратитесь к главе 3.7.
Использование значений по умолчанию
Вы можете также устанавливать параметры по одному посредством общего члена данных def. Чтобы сменить значения def, просто используйте подстановочные оператора. Вы можете обратиться к параметрам по номерам или по их именем. Например: query.def[0] = "Dinner Roles"; query.def[1] = "item"; query.def[2] = "item"; query.def[3] = "price"; Как и другой вариант: query.def["what"] = "Dinner Roles"; query.def["wheref"] = "item"; query.def["field1"] = "item"; query.def["field2"] = "price"; Имеют тот же самый эффект.
Как только все параметры установлены, просто выполните запрос так, как выполнили бы запрос без всяких шаблонов. Например так: Result res = query.store()
Немного более сложный пример
Этот пример почти подобен предыдущему, однако он использует исключительные ситуации и автоматическое свойство преобразования ColData. Файл с ним назван complic1.cc. #include
int main() { try { // its in one big try block Connection con(use_exceptions); con.connect("mysql_cpp_data"); // Here we broke making the connection into two calls. // The first one creates the Connection object with the // use exceptions option turned on and the second one // makes the connection
Query query = con.query(); query << "select * from stock"; Result res = query.store(); cout << "Query: " <
Все должно быть довольно очевидно. Приведу лишь несколько примечаний относительно исключительных ситуаций:
Когда флажок use_exceptions установлен для родительского объекта, он также установлен для всех потомков, созданных после того, как флажок был установлен. Например, когда флажок use_exceptions установлен для объекта con, он также установлено и для объекта query. Пожалуйста, обратите внимание, что флажок use_exceptions не компонуется, а копируется. Это означает, что, когда Вы изменяете флажок use_exceptions, это воздействует только на новые объекты, но не на старые.
Удаление или модификация из Select
Об этом свойстве просят многие пользователи, но пока оно не сделано на уровне ядра СУБД, эта программа может использоваться вместо него. Это маленькая программка, которая также показывает некоторые свойства MySQL++. #include
int main (void) { Connection con(use_exceptions); try { ostrstream strbuf; unsigned int i=0;
con.real_connect(MY_DATABASE,MY_HOST,MY_USER,MY_PASSWORD,3306, (int)0,60,NULL); Query query = con.query(); query << MY_QUERY; ResUse res = query.use(); Row row; strbuf << "delete from " << MY_TABLE << " where " << MY_FIELD << " in ("; // for UPDATE just replace the above DELETE FROM with UPDATE statement for (;row=res.fetch_row();i++) strbuf << row[0] << ","; if (!i) return 0; string output(strbuf.str()); output.erase(output.size()-1,1); output += ")"; query.exec((const string&)output); // cout << output << endl; return 0; } catch (BadQuery er) { cerr << "Error: " << er.error << " " << con.errnum() << endl; return -1; } }
Пожалуйста, сообщите в поле команды конструкции запроса MY_FIELD список значений для вставки. Значения поля будут цитироваться или нет в зависимости от их типа. Пользователи должны не должны ставить кавычки (или экранировать их символом escape), поскольку это приведет к ошибке. Этот метод требует несколько больше усилий от программиста. Программист может отключать это свойство, устанавливая соответствующую глобальную переменную переменную в false. Этот пример написан для выполнения DELETE. UPDATE требует изменений.
Все пользователи этих примеров должны быть осторожны: еще одна проверка требуется, чтобы выполнить этот запрос безопасно. А именно, в некоторых критических случаях размер запроса может превысить значение max_allowed. Эта проверка должна быть добавлна.
Манипуляторы
Следующие манипуляторы изменяют только следующий элемент направо от них в цепочке <<. Они могут использоваться с любым ostream (который включает SQLQuery и Query, поскольку они также ostream) или с SQLQueryParms. Когда используются с SQLQueryParms, они отменят любой набор параметров настройки шаблона запросов для этого элемента.
quote Цитирует и экранирует следующий элемент. Может использоваться с ostream или с SQLQueryParms. quote_only Цитирует, но не экранирует следующий элемент. Может использоваться с ostream или с SQLQueryParms. quote_only_double Цитирует, но не экранирует следующий элемент. Использует `` вместо '. escape Экранирует следующий элемент. do_nothing Не делает ничего. Используется как фиктивный манипулятор, когда надо применить некоторый манипулятор. Когда используется с SQLQueryParms, всегда удостоверится, что это не перекрывает параметры шаблона запросов. ignore Используется только с SQLQueryParms. Подобен do_nothing, но не будет отменять набор форматирований шаблона запросов.Начиная с версии 1.6, автоматическое цитирование и экранирование были добавлены в манипуляторы. Этот механизм применяется только к mysql_ColData. Автоматическое цитирование или экранирование используется только с оператором <<, и во всех классах, полученных потоками, объектах, включая strstream, а также в объектах запросов. Исключение составляют потоки cout, cerr и clog. Это было разработано именно так преднамеренно, поскольку внешние (для этих потоков) переменные не требует цитирования или экранирования. Но это свойство удобно при создании объекта запроса или объекта класса strstream.
Это свойство можно выключить, установив в Вашем коде переменную dont_quote_auto в значение true.
Формат шаблонов
Шаблон выглядит примерно так: select (%2:field1, %3:field2) from stock where %1:wheref = %q0:what
Числа представляют номер элемента в структуре SQLQueryParms (рассмотрена чуть ниже).
Формат параметров подстановки: %(modifier)##(:name)(:)
Здесь Modifier может быть любым из следующего перечня:
% Вывести знак "%". "" "" Не делает ничего. q Это цитирует и экранирует строку, применяя для этого mysql_escape_string, если это строка, char *, или другие специфические для Mysql типы, которые должны всегда цитироваться. Q Цитирует, но не экранирует строку, исходя из тех же правил. Это может сэкономить немного времени, если Вы знаете, что строки никогда не будут нуждаться в экранировке спецсимволов. r Обязательно цитирует и экранирует, даже если это число. R Обязательно цитирует, но не экранирует, даже если это число.## Представляет число длиной в две цифры.
``:name'' представляет собой факультативное имя, которое помогает в заполнении SQLQueryParms. Имя может содержать любые алфавитно-цифровые символы или символ подчеркивания. Если Вы используете имя, и должны ввести двоеточие, введите их два последовательно. Первый символ закончит имя, так что второй не будет обработан.
Специализированные структуры SQL
Специализированные структуры SQL (Specialized SQL Structures, SSQLS) позволяют Вам создавать свои структуры для хранения данных для запросов mysql с дополнительными функциональными возможностями. Эти структуры никоим образом не связаны с контейнерами и типами из Standard Template Library (STL). Это именно структуры (structs). Каждый элемент члена сохранен под уникальным именем внутри структуры. Вы никоим образом не можете использовать STL-алгоритмы или что-то еще из STL, чтобы работать с индивидуальными структурами. Однако Вы можете использовать эти структуры как value_type для контейнеров STL.
Изменение данных
Очень просто изменять данные с помощью SSQLS. Имя файла: custom3.cc. #include
sql_create_5(stock, 1, 5, string, item, int, num, double, weight, double, price, Date, sdate)
int main() { try { // its in one big try block Connection con(use_exceptions); con.connect("mysql_cpp_data"); Query query = con.query(); query << "select * from stock where item = \"Hotdogs' Buns\" "; Result res = query.store(); if (res.empty()) throw BadQuery("Hotdogs' Buns not found in table, run reset-db"); stock row = res[0]; stock row2 = row; row.item = "Hotdog Buns"; // now change item query.update(row2, row); // form the query to replace the row // the table name is the name of the struct by default cout << "Query : " << query.preview() << endl; // show the query about to be executed query.execute(); // execute a query that does not return a result set print_stock_table(query); // now print the new table; } catch (BadQuery er) { cerr << "Error: " << er.error << endl; return -1; } catch (BadConversion er) { cerr << "Error: Tried to convert \"" << er.data << "\" to a \"" << er.type_name << "\"." << endl; return -1; } }
Когда Вы выполняете пример, обратите внимание, что в предложении where проверено только поле item. Не забудьте выполнить reset-db после работы этого примера.
Комбинирование
Вы можете также объединять использование установки параметров во время выполнения и использование объекта def, просто применяя расширенную форму Query::store (можно также use или execute) без необходимых определенных параметров. Например: query.def["field1"] = "item"; query.def["field2"] = "price"; Result res1 = query.store("Hamburger Buns", "item"); Result res2 = query.store(1.25, "price"); Сохранит такой запрос: select (item, price) from stock where item = "Hamburger Buns" для res1 и select (item, price) from stock where price = 1.25 для res2.
Поскольку расширенная форма Query::store может работать только с начала списка (по номерам, но не по расположению параметров), более логично было бы сделать так: select (%0:field1, %1:field2) from stock where %2: wheref = %q3:what Но такой подход в этом случае не сработает. Более сложный вариант select (%2:field1, %3:field2) from stock where %1: wheref = %q0:what все же был необходим, чтобы Вы могли определять wheref и what.
Следует, однако, помнить, что Query::store(const char* q) также определена для выполнения запроса q. По этой причине, когда Вы используете Query::store (use или execute), только с одним элементом, и этот элемент const char*, Вы должны явно преобразовать это в SQLString. Например: Result res = query.store(SQLString("Hamburger Buns")).
Получение информации о полях
Следующий пример показывает, как получить некоторую базисную информацию относительно полей, включая имя поля и тип SQL. Файл назван fieldinfo1.cc. #include
int main() { try { // its in one big try block Connection con(use_exceptions); con.connect("mysql_cpp_data"); Query query = con.query(); query << "select * from stock"; Result res = query.store(); cout << "Query: " <
Less-Than-Comparable
SSQLS могут также быть сделаны less-than-comparable. Это означает, что структуры могут сортироваться и сохраняться в наборах результатов как показывается в следующем примере. Имя файла: custom4.cc. #include
sql_create_5(stock, 1, 5, string,item, int,num, double,weight, double,price, Date,sdate)
int main() { try { // its in one big try block Connection con(use_exceptions); con.connect("mysql_cpp_data"); Query query = con.query(); query << "select * from stock"; set
Обработка ошибок
Если по некоторым причинам Вы не определяли все параметры при выполнении запроса, и неопределенные параметры не имеют значений по умолчанию, заданных через объект def, объект запроса породит объект исключения SQLQueryNEParms. Вы можете выяснить, что же случилось, проверяя значение SQLQueryNEParms::string. Например: query.def["field1"] = "item"; query.def["field2"] = "price"; Result res = query.store(1.25); породит исключение SQLQueryNEParms по причине того, что wheref не был опеределен нигде.
В теории эта исключительная ситуация никогда не должна быть вызвана. Если она все же возникла, это, вероятно, логическая ошибка на Вашей стороне (например, как в вышеупомянутом примере).
Что планируется сделать
Что такое Mysql++
Mysql++ представляет собой полноценный C++ API для Mysql (а в скором времени и для других баз данных на SQL также). Цель этого API: сделать работу с запросами столь же простой, как работа с другими STL Контейнерами
Class BadNullConversion
Используется, когда значение Null пытаются преобразовать в тип, к которому оно не может быть преобразовано.
Class const_string
Специальная строка, которая создана из существующей const char *.
Class Fields
Вектор, подобный контейнеру с чистыми данными mysql о поле.
Class mysql_type_info
Класс, который хранит базисную информацию типа для ColData.
Class Row
Этот класс обрабатывает фактические строки интеллектуальным способом.
Class SQLQueryParms
Этот класс хранит значения параметров для заполнения шаблонов запроса.
Class SQLString
Специальная строка, которая преобразуется из чего-либо.
Детальное описание
Date представляет собой структуру данных для хранения типов дат mysql. Используется в приеме потоков и операциях вставки.
Этот класс подклассифицируется из SQLQuery. Этот класс в отличие от SQLQuery свободно присоединен к объекту Mysql так, чтобы он мог выполнять запросы.
Динамические полностью изменчивые наборы
Этот набор результатов будет выполнен, когда курсоры на стороне сервера будут поддерживаться в MySQL. Но, основываясь на приобретенном знании и опыте при проектирования MySQL++ и MySQLGUI, была сделана предварительная версия. Этот набор результатов полностью динамический в том смысле, что весь набор результатов сохранен в динамическом контейнере C++. Этот контейнер будет только кэшировать набор результатов, и он будет иметь заданный по умолчанию размер. Этот динамический контейнер будет окном в M строк из всего набора результатов в N строк, где N ограничено сервером MySQL. Этот набор результатов будет также полностью динамическим в том смысле, что имена столбцов и тип информации столбцов не должны быть определены во время компиляции. Но все существующие функциональные возможности статических и динамических наборов будут также доступны и в этом наборе. Этот набор будет также иметь методы для модифицирования, удаления и вставки строк, а также ряд специализированных макрокоманд для конструирования классов.
Динамический набор результатов
Динамический набор результатов представляет собой такой набор результатов, в котором имена столбцов и тип информации столбцов не должны быть определены во времени компиляции. Набор результатов может быть полностью постоянным, в нем жанные будут возвращены Вам в классе constant string link class, частично постоянным, тогда Вы можете изменять данные по одной строке за раз, или полностью переменным, в этом случае Вы можете менять данные как угодно.
Постоянный набор результатов почти аналогичен набору результатов в C API. Он обеспечивает наибольшие функциональные возможности. С этим набором результатов Вы можете выяснять детализированную информацию относительно типа информации, сохраненной в каждом из столбцов. Это также самое быстрое решение потому, что данные не должны быть скопированы вообще.
Частично постоянный набор результатов подобен постоянному набору результатов за исключением того, что Вы можете изменять данные по одной строке за раз. Данные, которые Вы изменяете, фактически копия данных, возвращенных сервером. Это означает, что изменение данных не изменяет фактический набор результатов.
Частично постоянный набор результатов почти то же самое, что и постоянный набор результатов. Единственное различие в том, что когда Вы запрашиваете строку из результата, Вы можете объявить ее изменяемой явно. Это означает, что Вы можете получать некоторые строки как постоянные, а другие как изменчивые.
Полностью изменяемый набор результатов подобен постоянному за исключением того, что данные полностью изменчивы в том смысле, что Вы можете изменять данные в фактическом наборе результатов. Однако, в отличие от первого, этот набор результатов не связан с набором результатов из C API. Взамен это создается копия данных, возвращенных C API в двухмерном векторе. Из-за этого детализированная информация относительно каждого из столбцов в настоящее время не доступна, только имена столбца и тип в C++, который наиболее близко соответствует оригинальному типу из SQL. Кроме того, поскольку это делает копию данных, возвращенных из C API, быстродействие будет чуть пониже.
Строки во всех динамических наборах результатов очень близки к контейнеру произвольного доступа из Standard Template Library (STL). Это означает, что они имеют iterator, который может использоваться для STL-алгоритмов. Имеется несколько специализированных сервисных функций, чтобы помочь в использовании наборов результатов в STL-алгоритмах.
Столбцы во всем динамическом результате также очень близки к контейнеру произвольного доступа из STL. Однако, в дополнение к доступу к столбцам по по их индексным числам, Вы можете также обращаться к столбцам через их имена полей.
Кроме того, поскольку строки и столбцы подобны контейнерам, Вы можете также обрабатывать набор результатов как двумерный массив. Например, Вы можете получить 5-ый элемент в 3-ей строке простым запросом result[3][5]. А так как Вы можете также использовать имена полей, Вы можете написать вместо номера поля его имя, например, result[3]["price"], чтобы получить элемент "price" в 3-ей строке.
Фактические данные, возвращаемые динамическим набором результатов, сохранены в специальной строке подобно классу, которая имеет некоторые дополнительные полезные свойства. А именно: данные столбца автоматически преобразуются во все базисные типы данных, также как некоторые дополнительные типы, которые разработаны, чтобы обработать типы mysql, которые включают типы для обработки дат, времен, наборов и величин со значением null. Если имеется проблема в преобразовании, будет установлена метка предупреждения или возвращена исключительная ситуация в зависимости от того, как пакет настроен. Относительно исключительных ситуаций: MySQL++ поддерживает два различных метода рассмотрения исключительных ситуаций. Первый работает по фиксированному типу, второй (новый) представляет собой стандартный тип C++, использующий метод what(). Выбор методов должен быть выполнен при формировании библиотеки. Если скрипт выбора конфигурации выполнен с опцией -enable-exception, то новый метод будет использоваться. Если никакая опция не обеспечивается, или используется -disable-exception, всегда используется старый метод исключений MySQL++.
Динамические наборы результатов могут даже использоваться, чтобы помочь формировать запросы с помощью некоторого дополнительного метода. Имеются методы для возвратов: 1) Разделенный запятыми список данных (например: 1.5, 10, "Dog", "Brown"), 2) Разделенный запятыми список имен полей (например: age, weight, what, color), 3) Список присваиваний (например: age = 1.5 AND weight = 10 AND what = "Dog" AND color = "Brown").
Изменчивые наборы результатов могут быть созданы так, чтобы Вы могли воспользоваться преимуществом этих методов во вставке данных в базу данных без необходимости писать дополнительные запросы.
Длинные имена
По умолчанию Mysql++ API использует как короткие имена без префиксов Mysql или mysql_, так и их длинные версии уже с префиксами Mysql или mysql_. Если это вызывает проблемы, определите макрос MYSQL_NO_SHORT_NAMES перед включением mysql++. После этого в принудительном порядке будут использоваться исключительно длинные имена. Их соответствие коротким такое:
| Короткое имя | Длинное имя |
| BadQuery | MysqlBadQuery |
| Connection | MysqlConnection |
| ResNSel | ResNSel |
| ResUse | ResUse MysqlResUse |
| Result | MysqlRes |
| Field | MysqlField |
| Fields | MysqlFields |
| ResIter | MysqlResIter |
| ResultIter | MysqlResIter |
| Row | MysqlRow |
| MutableRow | MysqlMutableRow |
| FieldNames | MysqlFieldNames |
| Query | MysqlQuery |
| BadConversion | MysqlBadConversion |
| ColData | MysqlColData |
| MutableColData | MysqlMutableColData |
| quote | mysql_quote |
| quote_only | mysql_quote_only |
| quote_double_only | mysql_quote_double_only |
| escape | mysql_escape |
| do_nothing | mysql_do_nothing |
| ignore | mysql_ignore |
| Date | MysqDate |
| Time | MysqlTime |
| DateTime | MysqlDateTime |
| Set | MysqlSet |
| Null | MysqlNull |
| null_type | mysql_null_type |
| null | mysql_null |
| NullisNull | MysqlNullisNull |
| NullisZero | MysqlNullisZero |
| NullisBlank | MysqlNullisBlank |
Добавление функциональных возможностей
Самый лучший способ добавлять функциональные возможности: через наследование. Даже при том, что Вы могли бы вставлять выводимый код из pretty.pl и изменять его, это не рекомендуется делать потому, что это не будет отражать будущие расширения.
Дополнение
В дополнение к материалу, упомянутому выше, хочу заметить, что есть много универсальных классов, которые могут использоваться с другими программами. Примеры этого включают специальный класс const string, адаптер произвольного доступа, который будет делать контейнер произвольного доступа из класса только с методом size() и определенным оператором subscript ([]), а также универсальный класс запроса SQL, который может использоваться любым SQL C или C++ API.
Начиная с версии 1.7, имеется новое дополнение к библиотекам. Добавилось несколько очень полезных функций для строк STL, которые могут применяться в любом приложении на C++, неважно, скомпоновано оно с MySQL++ или нет. Эти функции содержатся в исходных файлах string_util.hh и string_util.cc.
Дополнительные замечания
Макрокоманды определены для структур длиной до 25 элементов. Если Вы должны использовать больше, надо изменить основной скрипт perl (custom.pl). Этот скрипт на perl используется, чтобы генерировать файл заголовка. Он никоим образом не пробует анализировать код на C++.
Файл заголовка, который строит скрипт custom.pl занимает около мегабайта. Однако, пожалуйста обратите внимание, что заголовочный файл (custom-macros.hh) включает ТОЛЬКО макрокоманды. Так что компилятор должен делать очень малый объем работ при чтении файла.
Также, все включенное макрообращением выполнено таким способом, что Вы можете безопасно включать макрокоманду в файл заголовка и не должны волноваться относительно двойных обращений к функции или чего-то подобного.
Изменение имени таблицы
Вы не можете определять различные имена таблицы в фактическом макрообращении. Имя таблицы используется в SQLQuery::insert, replace и update. Однако Вы можете изменять заданное по умолчанию имя таблицы, которое является тем же самым, что и имя структуры, заменяя ссылку NAME::table() на другую const char *: stock::table() = "in_stock"
Это заменит имя таблицы на "in_stock" в примерах, используемых во всем этом руководстве.
Методы friend
Методы Protected
Методы public
возвращает success()
возвращает true, если соединение успешно установлено
послкднее сообщение об ошибке
Сохраняет результаты в TYPE. TYPE может быть любым типом контейнера STL.
возвращает true, если последний запрос был удачным
Создает новый список из данных в res.
Создает новый список с i именами полей.
Возвращает имя поля для указанного индекса в списке.
Возвращает имя поля для указанного индекса в списке.
Возвращает индекс поля с указанным именем.
Создает новый список, основанный на информации в res
Создает новый список с i полями.
Возвращает тип поля для поля со смещением i.
Возвращает тип поля для поля со смещением i.
Число полей. Возвращает поле со смещением i.
Дает Null значение null.
Создает новый объект запроса, связанный с подключением.
Сообщение об ошибке, если запрос не был успешным.
Выполняет запрос в буфере строк и возвращает структуру, которая содержит информацию о том, насколько успешным был запрос. Используйте это для запросов, которые не возвращают набор результатов, например, INSERT или UPDATE. Параметром может что-либо в имеющем силу SQLQuery.
Отображает строку, которая в настоящее время лежит в буфере. Аналогично string().
Если запрос был успешным.
Дополнительная информация о запросе.
Число обработанных строк.
Функция c api.
Функция c api field.
Функция c api.
Функция c api.
Возвращает поле со смещением i.
Возвращает поле-константу со смещением i.
Возвращает ссылку на основнорй класс FieldNames.
Возвращает ссылку на основнорй класс FieldNames.
Возвращает смещение регистрируемого поля, которое равняется str.
Функция c api field.
Возвращает ссылку на тип поля mysql для поля со смещением i.
Возвращает ссылку-константу на тип поля mysql для поля со смещением i.
Возвращает ссылку на основной FieldTypes.
Возвращает ссылку-константу на основной FieldTypes.
Возвращает ссылку на структуру Fields.
Возвращает ссылку на информацию mysql о поле для поля со смещением i.
Возвращает ссылку на основной класс FieldNames.
Возвращает ссылку-константу на основной класс FieldNames.
Возвращает смещение для объекта, который равняется str.
Возвращает поле со смещением i.
Возвращает поле со смещением i.
Функция c api field.
Сбрасывает имена полей к первоначальным значениям.
Сбрасывает field_types к первоначальным значениям.
Сбрасывает имена полей к первоначальным значениям.
Сбрасывает имена полей к первоначальным значениям.
Имя таблицы.
Имя таблицы.
Возвращает ссылку на основной FieldTypes.
Возвращает ссылку-константу на основной FieldTypes.
Возвращает ссылку на тип поля mysql для поля со смещением i.
Возвращает ссылку-константу на тип поля mysql для поля со смещением i.
Функция c api
Функция c api
Функция c api
Возвращает строку со смещением i.
Возвращает число строк.
Возвращает число строк.
Возвращает true, если имеются какие-либо данные в строке.
Возвращает значение поля с именем поля i. Этот метод не столь эффективен как использование индексного кода.
Возвращает значение поля с именем поля i. Этот метод не столь эффективен как использование индексного кода.
Возвращает значение поля с индексом поля i.
Возвращает число столбцов.
Заданный по умолчанию шаблон набора параметров.
Возвращает полную строку запроса, заменяя ее заданными по умолчанию параметрами шаблона в случае необходимости. Подобно str(query_reset), но устанавливает параметры запроса от 0 до 11. Здесь query_reset может быть DONT_RESET или RESET_QUERY. Если это установлено в RESET_QUERY, то reset() будет вызван после того, как запрос возвращен. Если не имеется достаточно параметров, то это возвратит пустую строку, а success() будет равно false. Если любой из требуемых параметров равен null, этот метод произведет ошибку и возвратит пустую строку.
Очищает весь список.
Устанавливает элементы списка: 0 в a, 1 в b и т.д. Может определять до дюжины элементов.
Добавляет элемент в список.
Добавляет элемент в список.
Обращается к значению элемента с ключом str.
Обращается к значению элемента с ключом str.
Обращается к элементу с кодом n.
Обращается к элементу с кодом n.
Также как const_iterator потому, что данные не могут быть изменены.
Наблюдение фактического кода
Увидеть фактический код, который используют макро вставки sql++pretty, довольно просто. Например так: sql++pretty < test.cc | less
Наборы результатов
Для запросов, которые возвращают набор результатов, имеются два различных пути обработки результатов: в динамическом наборе или в статическом.
Объект запроса
Этот объект представляет собой рекомендуемый путь выполнения запросов. Это подкласс от strstream, что означает, что Вы можете писать в него данные подобно любому другому потоку. Это сделано, чтобы помочь Вам в гибком и простом формировании запросов.
Вы можете также устанавливать запросы Template с этим классом. Запросы Template представляют собой путь установки запросов с заменяемыми параметрами, которые Вы можете изменять через Вашу программу.
Вы можете также использовать специализированные структуры и даже динамические (на сайте разработчиков они почему-то названы драматическими) наборы результатов, чтобы упростить создание и обработку запросов.
Объект Query возвращает объект с информацией относительно успеха запроса для запросов не-select (запросы, которые не возвращают набор результатов).
Обзор классов
Этот раздел документирует все классы для внешнего использования. Если некий класс не зарегистрирован здесь, не используйте кго, поскольку он представляет собой метод или класс для внутреннего пользования.
Обзор
Mysql++ API очень сложен и обладает большой мощностью. В этом разделе обеспечивается краткий обзор многих различных компонентов этой библиотеки.
Подобно работе с большинством других SQL API, процесс выполнения запросов тот же самый: 1) Вы открываете подключение, 2) Вы формируете и выполняете запросы, 3) Вы выполняете итерации через набор результатов. Однако имеется много дополнительных функциональных возможностей.
Основной дескриптор базы данных
Это тот класс, который обрабатывает подключение к серверу Mysql. Вы всегда нуждаетесь по крайней мере в одном из этих объектов, чтобы делать что-нибудь с сервером. Этот класс может создать отдельный объект запросов или непосредственно выполнять запросы. Отдельный объект запроса является рекомендуемым путем, поскольку это дает Вам гораздо больше мощности.
Основной формат sql_create_basic_c_order
Таким образом, общий формат для sql_create_basic такой: sql_create_basic_c_order_#(NAME, CMP, CNST, TYPE1, ITEM1, ORDER1, ... TYPE#, ITEM#, ORDER#)
# задает числом переменных в векторе.
Основной формат sql_create_basic
Основной формат для sql_create_basic следующий: sql_create_basic_#(NAME, CMP, CNST, TYPE1, ITEM1, ..., TYPE#, ITEM#)
Основной формат sql_create_c_names
Основной формат таков: sql_create_c_names_#(NAME, CMP, CNST, TYPE1, ITEM1, NAME1, ... TYPE#, ITEM#, NAME#)
Здесь NAME1 представляет собой имя первого поля. Все остальное так же, как и в формате sql_create_basic_c_order.
Подробное описание
Это также Random Access Container, который не LessThanComparable и не Assignable. Будучи контейнером произвольного доступа (Random Access Container), это может возвращать Random Access Iterator или обратный Random Access Iterator.
Это чистый класс запроса. Он используется для того, чтобы формировать запросы, которые планируется послать объекту Connection. Класс Query может использоваться, если Вы желаете также выполнить запросы без того, чтобы посылать их объекту Connection.
Этот класс подклассифицируется из strstream. Это означает, что Вы можете писать в него подобно потоку, чтобы избежать необходимости создавать свой strstream или применять sprintf. Хотя Вы можете читать из запроса (потому, что это поток), это не рекомендуется. Я не могу гарантировать предсказуемость класса. Однако, можно использовать любой из методов потока, чтобы писать в него. Только удостоверьтесь, что буферные точки Вашего запроса записаны прежде, чем Вы попробуете использовать любой из специфических методов SQLQuery, кроме error() и success().
Возникает, когда не задано достаточно параметров для шаблона запроса.
Получение Mysql++
Последняя версия Mysql++ лежит на web-сайте mysql++ по адресу http://www.mysql.com/download_mysql++.html
Предположения
Этот учебник предполагает, что Вы знаете C++ довольно хорошо. Считается, что Вы знакомы с исключениями и Standard Template Library (STL).
Сделаем еще лучше
При начале разработки MySQl++ 1.6 авторы представили три новых примера, чья цель состоит в том, чтобы показать некоторых из самых сильных свойств MySQL++, а также обеспечить решение некоторых из наиболее частых проблем. Эти примеры иллюстрируют превосходство C++ над другими существующими языками.
Поскольку эти примеры предполагаются к активному использованию (и применяются многими пользователями), константы, которые могут отличаться в разных ситуациях, были сгруппированы, чтобы упростить редактирование. Также, все эти примеры содержат полную ошибку, проверяющую код. Это один из тех редких случаев, в которых обработка исключительной ситуации, принятая в С++, полностью применена в MySQL++.
Шаблоны запросов
Другое мощное свойство Mysql++: можно устанавливать шаблоны запросов. Следующий пример показывает, как использовать их. Этот код представляет собой фактический код используемый, чтобы устанавливать и/или сбрасывать типовую базу данных. Этот код может быть найден в файле reset-db.cc. #include
Идея шаблонов сводится к тому, чтобы оснастить запрос такими параметрами для вызова, которые могут быть изменены между обращениями без необходимости преобразовывать сам запрос.
Список рассылки Mysql++
Инструкции по присоединению к списку рассылки (и архив списка рассылки) могут быть найдены на домашней страничке Mysql++ по адресу http://www.mysql.com/download_mysql++.html. Если Вы желаете только задать вопрос, можете писать на mysql-plusplus@lists.mysql.com.
Sql_create_basic_c_order
Вы можете также определять альтернативный порядок, когда mysql заполняет структуру. Например: sql_create_basic_c_order_5(stock, 2, 5, MysqlDate, date, 5, double, price, 4, string, item, 1, int, num, 2, double, weight, 3)
Это создаст структуру, схожую созданной в предыдущем примере за исключением того, что порядок элементов данных будет иным. С++ использует первые два элемента, чтобы сравнить с группой (date, price). Однако, так как определен заказной порядок, Вы можете использовать тот же самый запрос, чтобы заполнить набор. Это заполнит date 5-ым элементом набора результатов запроса, price соответственно 4-м и так далее.
Sql_create_basic с расширенным конструктором
Последний ноль в последнем примере предназначен для создания другого конструктора. Замените этот ноль на m, и это создаст конструктор, который заполнит первые n переменных. Например: sql_create_basic_5(stock, 1, 5, string, item, int, num, double, weight, double, price, MysqlDate, date) Также определит следующее: struct stock { ... stock(const string&, const int&, const double&, const double&, const MysqlDate&); set(const string&, const int&, const double&, const double&, const MysqlDate&); }
Sql_create_basic со сравнением
Вы можете также сделать структуру сравнимой, заменяя первый 0 в предыдущем примере на ненулевое значение. Это число сообщает, что если первые n чисел одинаковые, то и две структуры совпадают: sql_create_basic_5(stock, 1, 0, string, item, int, num, double, weight, double, price, MysqlDate, date) Создаст структуру, где только первый элемент будет проверен, чтобы увидеть являются ли две различных структуры действительно различными. Это также позволяет Вам сравнивать одну структуру с другой основываясь на значении элемента. Если n больше одного, это сравнит структуры в лексикографическом порядке. Например, если n=2, это сначала сравнило бы элемент item, и если он был тот же самый, затем будет сравниваться num. Если num был тот же самый, это объявит две структуры идентичными. struct stock ( ... stock (const string &p1); set (const string &p1); bool operator == (const stock &other) const; bool operator != (const stock &other) const; bool operator > (const stock &other) const; bool operator < (const stock &other) const; bool operator >= (const stock &other) const; bool operator <= (const stock &other) const; int cmp (const stock &other) const; int compare (const stock &other) const; } int compare (const stock &x, const stock &y); int compare (const stock &x, const stock &y) сравнивает x с y и возвращает значение <0, если x < y, 0 если x=y и значение >0, если x > y. stock::cmp и stock::compare действуют аналогично compare(*this, other).
stock::stock представляет собой конструктор, который установит элемент в p1 и оставит все другие переменные неопределенными. Это полезно для создания временных объектов, чтобы использовать для сравнений подобных такому: x <= stock("Hotdog")
Поскольку stock объявлена как less-then-comparable, Вы можете сохранять результаты запроса в наборе: set
Вы можете также теперь использовать любой STL-алгоритм который требует, чтобы все значения были less-then-comparable.
Общий формат таков: sql_create_base_#(NAME, CMP, 0, TYPE1, ITEM1, ... TYPE#, ITEM#)
Здесь CMP сообщает, что если первые cmp переменных являются теми же самыми, то две структуры одинаковы.
Sql_create_basic
Следующая команда создаст базисный запрос mysql для использования с типовой базой данных. sql_create_basic_5(stock, 0, 0, string, item, int, num, double, weight, double, price, MysqlDate, date) Это установит следующую структуру: struct stock { stock () {} stock (const MysqlRow &row); set (const MysqlRow &row); string item; int num; double weight; double price; MysqlDate date; }; Как Вы можете видеть, ничего фантастического в этих структурах нет. Основное преимущество этой простой структуры: конструктор stock (MysqlRow &row), который позволяет Вам легко заполнять вектор stock таким образом: vector
Общий формат структур: sql_create_basic_#(NAME, 0, 0, TYPE1, ITEM1, ... TYPE#, ITEM#)
Здесь # является числом переменных в векторе, NAME задает имя структуры, которую Вы желаете создать, TYPE1 определяет имя типа для первого элемента, а ITEM1 представляет собой имя переменной для первого элемента и т.д.
Sql_create_c_names
Вы можете также определять альтернативные имена поля так: sql_create_c_names_5(stock, 1, 5, string, item, "item", int, num, "quantity", double, weight, "weight", double, price, "price" MysqlDate, date, "shipment") Когда field_list или equal_list применены, это использует данные имена поля вместо имен переменных. Например: stock s("Dinner Roles",75,0.95,0.97,"1998-05-25"); cout << "Field List: " << s.field_list() << endl; cout << "Equal List: " << s.equal_list() << endl; вернет нечто вроде: Field List: item,quantity,weight,price,shipment Equal List: item = 'Dinner Roles',quantity = 75,weight = 0.95, price = 0.97,shipment = '1998-05-25'
Sql_create_c_order
Как в sql_create_basic_c_order Вы можете определять заказной порядок. Основная форма такая: sql_create_c_order_#(NAME, CMP, CNST, TYPE1, ITEM1, ORDER1, ... TYPE#, ITEM#, ORDER#)
Здесь все так же, как и в основном формате sql_create_basic_c_order.
Sql_create_complete
Вы можете также определять заказной порядок и заказные имена поля вместе. Основная форма такая: sql_create_complete_#(NAME, CMP, CNST, TYPE1, ITEM1, NAME1, ORDER1, ... TYPE#, ITEM#, NAME#, ORDER#)
Здесь все так же, как и в основном формате sql_create_c_order и sql_create_c_names.
Sql_create
В дополнение к базисным структурам Вы можете устанавливать расширенные структуры, которые также имеют методы определенные, чтобы помочь в создании запросов и во вставке данных в таблицах. Например: sql_create_5(stock, 1, 5, string, item, int, num, double, weight, double, price, MysqlDate, date) создаст определение, эквивалентное следующему: struct stock { ... static char *names[]; static char *table; template
field_list() возвращает специальный класс, который делает то же самое, но возвращает список полей, которые хранит структура. Имена полей не цитируются и не экранируются.
equal_list() возвращает разделенный запятыми список в формате имя поля=значение. Имена полей не цитируются и не экранируются, а значения цитируются и экранируются только по мере надобности. Например: stock s("Dinner Roles",75,0.95,0.97,"1998-05-25"); cout << "Value List: " << s.comma_list() << endl; cout << "Field List: " << s.field_list() << endl; cout << "Equal List: " << s.equal_list() << endl; вернет нечто вроде следующего: Value List: 'Dinner Roles',75,0.95,0.97,'1998-05-25' Field List: item,num,weight,price,date Equal List: item = 'Dinner Roles',num = 75,weight = 0.95, price = 0.97,date = '1998-05-25' Комбинация списков полей и значений может использоваться для запросов замены или вставки. Например: query << "insert into stock (" << s.field_list() ") values " << s.value_list(); вставит s в таблицу stock.
Вы можете также использовать SQLQuery::insert или SQLQuery::replace (и таким образом вызвать Query::insert или Query::replace), чтобы выполнить ту же самую задачу: query.insert(s); Это использует s.table для имени таблицы, которое задано по умолчанию в имени структуры.
Вы можете также определять различные разделители "d". Если ни один не определен явно, по умолчанию берется ",". Вы можете использовать разделитель " AND " для equal_list, чтобы помочь в запросах выбора и модификации. Например: stock s2 = s; s2.item = "6 Dinner Roles"; query << "UPDATE TABLE stock SET " << s2.equal_list() << " WHERE " << s.equal_list(" AND "); будет аналогично запросу: UPDATE TABLE stock SET item = '6 Dinner Roles',num=75,weight = 0.95, price = 0.97,date = '1998-05-25' WHERE item = 'Dinner Roles' AND num = 75 AND weight = 0.95 AND price = 0.97 AND date = '1998-05-25' который изменит запись в таблице так, чтобы элемент был теперь "6 Dinner Roles" вместо "Dinner Roles".
Вы можете использовать SQLQuery::update (и обратиться таким образом к Query::update) для выполнения той же самой задачи: stock s2 = s; s2.item = "6 Dinner Roles"; query.update(s,s2); Подобно SQLQuery::insert, это использует s.table для имени таблицы, который задан по умолчанию для имени структуры.
Вы можете также определять манипулятор, который методами c++ цитирует или экранирует значения. Это может быть любой имеющий силу манипулятор потока, который только обрабатывает элемент справа от манипулятора. Списки value_list и equal_list имеют значение по умолчанию escape, а field_list имеет do_nothing. Для equal_list манипулятор обрабатывает только часть value, но не трогает часть field name.
Это может быть полезным при экспорте в файл, где Вы не хотите получить кавычки вокруг строк. Например: table_out << q.value_list("\ t", mysql_escape) << endl; конкатенирует данные к файлу, который обрабатывается table_out.
Три не базисных формы позволяют Вам определять, которые элементы будут Вам возвращены. Например: cout << q.value_list(false,false,true,true,false) << endl; cout << q.value_list(stock_weight, stock_price) << endl; Оба варианта вернут: 0.95,0.97 bool form ожидает булевы параметры, где каждый бит представляет собой инструкцию, что именно надо показывать. Например: cout << q.value_list(false,false,true,true) << endl; выведет показанное в предыдущем примере.
list form позволяет Вам определять то, которые элементы будут показываться. Значения enum созданы для каждой переменной с именем структуры плюс символ подчеркивания в качестве префикса, например, item обозначается как stock_item.
Эти формы могут быть полезны в запросах выбора. Например: query << "SELECT * FROM stock WHERE " << q.equal_list(" AND ",stock_weight,stock_price); произведет такой запрос: SELECT * FROM stock WHERE weight=0.95 AND price=0.97 Который выберет все строки из stock, которые имеют weight и price, заданные в операторе как значение q.
vector form (не показанный выше) позволяет Вам передавать булев вектор, который экономит время, если Вы используете некоторый образец больше, чем однажды. Дело в том, что такой подохд позволяет обойти необходимость создавать вектор из параметров каждый раз. Если a представляет собой булев вектор, то a[0] хранит первую переменную, a[1] соответственно вторую и так далее. Например: vector
Статические наборы результатов
Результаты запроса могут также быть сохранены статически в специализированной структуре SQL. Эти структуры затем будут сохранены в некотором STL-контейнере, например, векторе или списке. В отличие от динамических наборов результатов принимается, что программист знает то, что набор результатов собирается вернуть. Из-за этого вся информация относительно столбцов, включая имена, будет потеряна.
Специализированные структуры являются термином C++ structs. Каждый элемент члена сохранен с уникальным именем внутри структуры. Вы никоим образом не можете использовать STL-алгоритмы или что-нибудь еще из STL, чтобы работать с индивидуальными элементами структур. Однако, поскольку эти структуры все равно затем будут сохранены в STL-контейнерах, Вы можете использовать STL-алгоритмы на контейнерах этих структур. Контейнеры представляют строки, а индивидуальные элементы структуры представляют столбцы. Например, Вы можете обращаться к элементу, именованному "price" в третьей строке как к result[3].price. В динамическом наборе результатов то же самое достигается записью result[3]["price"].
Если имеется проблема в преобразовании из набора результатов, возвращенного сервером, к специализированным структурам, возникает исключительная ситуация, которую нужно обработать.
Чтобы помочь в создании запросов, использующих эти специализированные структуры, тот же самый запрос, доступен для применения в динамических наборах результатов. Это включает методы для возврата списков данных.
Struct DateTime
Комбинация из Date и Time для хранения mysql-типа DateTime.
Struct NullisBlank
Тип нужный, чтобы использовать для параметра поведения для Null.
Struct NullisNull
Тип нужный, чтобы использовать для параметра поведения для Null.
Struct NullisZero
Тип нужный, чтобы использовать для параметра поведения для Null.
Struct ResNSel
Эта структура хранит информацию относительно успеха запросов, которые не возвращают наборы результатов.
Struct SQLQueryNEParms
Исключительная ситуация, когда не задано достаточно параметров.
Struct Time
Специальный тип для хранения времени в формате mysql.
Суперклассы
public mysql_date, public mysql_time, public MysqlDTbase DateTime
public ResUse, public const_subscript_container Result,Row,const Row
public const_subscript_container Row,ColData,const ColData, public RowTemplate Row, ResUse
public random_access_iterator ReturnType, SizeType
Текущие изменения
Template class const_subscript_container
Адаптер контейнера, чтобы сделать контейнер контейнером произвольного доступа (Random Access Container).
Template class mysql_ColData class Str
Основной класс для автопреобразований данных столбца. Не используйте непосредственно.
Template class Null class Type, class Behavior = NullisNull
Контейнерный класс для хранения типов с поддержкой null.
Template class Set class Container = set string
Специальный набор для хранения множеств в формате mysql.
Установка
Чтобы установить шаблон запроса, просто создайте обычным порядком нормальный запрос, например: query << "select (%2:field1, %3:field2) from stock where %1: wheref = %q0:what" А затем выполните метод Query::parse(). Например: query.parse()
Это описание, как предполагается, дает
Это описание, как предполагается, дает Вам начало использования Mysql++ API. Пакет этот сложный, с большим количеством свойств, так что начните с чего-то простого.
Задание параметров
Параметры могут заданы когда запрос выполнен, или раньше срока, используя заданные по умолчанию параметры.
Запуск примеров
Все коды примеров формируют полные программы. Однако, чтобы использовать их, Вы должны сначала откомпилировать их, для чего перейдите в каталог с примерами и наберите там make. Затем Вы должны установить базу данных запуском reset-db. Параметры здесь такие:
reset-db [host [user [password]]]Если Вы не указываете host, по умолчанию принимается localhost. Если Вы не указываете имя пользователя, по умолчанию принимается Ваше актуальное имя пользователя. Если Вы не указываете пароль, по умолчанию принимается, что Вы не нуждаетесь в нем.
Когда Вы выполняете программу, Вы должны иметь права доступа с разрешением создавать базы данных. Как только база данных создана, Вы можете использовать другие права доступа для полного доступа к базе данных mysql_cpp_data.
Вы должны также выполнить программу reset-db между примерами, которые изменяют данные, чтобы все работало как надо.
MySQL- Руководство разработчика
Базисные выражения
Базисные выражения в Lua такие: exp ::= `(' exp `)' exp ::= nil exp ::= number exp ::= literal exp ::= var exp ::= upvalue exp ::= function exp ::= functioncall exp ::= tableconstructor
Доступ к глобальной переменной x эквивалентен обращению getglobal("x"), а доступ к индексированной переменной t[i] эквивалентен обращению к gettable_event(t,i). Подробности в разделе 4.4.8, там есть описания этих функций (getglobal находится в базисной библиотеке).
Нетерминальный exp1 используется, чтобы указать, что значения, возвращенные выражением должны быть откорректированы к одному значению: exp1 ::= exp
Блоки
Блоком является список инструкций. Синтаксически блок равен составной части (chunk): block ::= chunk
Блок может быть явно разграничен: stat ::= do block end
Явные блоки полезны, чтобы управлять областью видимости (контекстом) локальных переменных. Явные блоки также иногда используются, чтобы добавить возврат или разрывать инструкцию в середине другого блока.
Арифметические операторы
Lua поддерживает комплект обычных арифметических операторов: двоичный + (сложение), - (вычитание), * (умножение), / (деление), ^ (возведение в степень), а также унарный - (обращение знака числа). Если операнды числа или строки, которые могут быть преобразованы в числа, (согласно правилам, данным в разделе 4.4.2), то все операции за исключением возведения в степень имеют обычное значение. Иначе будет вызван соответствующий метод тэга. Возведение в степень всегда вызывает метод тэга. Стандартная математическая библиотека переопределяет этот метод для чисел, давая ожидаемое значение (подробности в разделе 4.6.3).
Присваивания
Lua поддерживает такую удобную вещь, как многократные присваивания. Следовательно, синтаксис определяет список переменных с левой стороны и список выражений с правой сторона. Элементы в обоих списках отделяются запятыми: stat ::= varlist1 `=' explist1 varlist1 ::= var {`,' var} Эта инструкция сначала оценивает все значения справа и возможные индексы слева, а затем делает примваивание. Так, код: i = 3 i, a[i] = 4, 20 установит a[3] в 20, но не воздействует на a[4] потому, что i в a[i] оценен прежде, чем ему было присвоено значение 4. Многократное присваивание может использоваться, чтобы поменять местами два значения, например: x, y = y, x
Два списка в многократном присваивании могут иметь различные длины. Перед собственно присваиванием, список значений будет откорректирован к длине списка имеющихся переменных.
Одиночное имя может обозначать глобальную переменную, локальную переменную или формальный параметр: var ::= name
Квадратные скобки используются, чтобы индексировать таблицу: var ::= varorfunc `[' exp1 `]' varorfunc ::= var | functioncall varorfunc должен иметь в качестве результата значение из таблицы, где поле, индексированное значением выражения exp1, получает назначенное ему значение.
Синтаксис var.NAME представляет собой только синтаксический аналог для выражения var["NAME"]: var ::= varorfunc `.' name
Значение присваиваний, оценок глобальных переменных и индексированных переменных может быть изменено методами тэгов. Фактически, назначение x=val, где x представляет собой глобальную переменную, является эквивалентным обращению setglobal("x",val), а присваивание t[i]=val эквивалентно settable_event(t,i,val). В разделе 4.4.8 есть полное описание этих функций (setglobal находится в базисной библиотеке, settable_event используется только для объяснительных целей).
Реляционные операторы
Реляционные операторы в Lua: == ~= < > <= >= Эти операторы возвращают nil как ложь, или любое другое значение (но не nil) в качестве истины.
Равенство (==) сначала сравнивает тэги операндов. Если они различны, то результатом будет nil. Иначе сравниваются их значения. Числа и строки сравниваются обычным способом. Таблицы, userdata, и функции сравниваются как ссылки, то есть две таблицы рассматриваются равными только, если они реально та же самая таблица. Оператор ~= прямо противоположен оператору равенства (==).
Правила преобразования из раздела 4.4.2 НЕ применяются к сравнениям равенства. Таким образом, "0"==0 вернет false, а t[0] и t["0"] обозначают различные записи в таблице.
Операторы порядка работают следующим образом. Если оба параметра числа, то они сравниваются также. Иначе, если оба параметра строки, то их значения сравниваются, используя лексикографический порядок. Во всех остальных ситуациях будет вызван метод lt тэга (подробности в разделе 4.4.8).
Структуры управления
Структуры управления if, while и repeat имеют обычное значение и знакомый синтаксис: stat ::= while exp1 do block end stat ::= repeat block until exp1 stat ::= if exp1 then block {elseif exp1 then block} [else block] end Выражение exp1 условия структуры управления может возвращать любое значение. Все значения, отличные от nil, рассматриваются как истина, только nil считается ложью.
Инструкция return используется, чтобы возвратить значения из функции или из chunk. Поскольку функции или составные части могут возвращать больше, чем одно значение, синтаксис для инструкции return: stat ::= return [explist1]
Инструкция break может использоваться, чтобы завершить выполнение цикла, переходя к следующей инструкции сразу после цикла: stat ::= break
break заканчивает самый внутренний вложенный цикл (while, repeat или for).
По синтаксическим причинам инструкции return и break могут быть написаны только как последние инструкции блока. Если действительно необходимо вставить их в середину, надо применить явный внутренний блок, например, do return end потому, что теперь return в самом деле последняя инструкция во внутреннем блоке.
Инструкция For
Инструкция for имеет две формы, по одной для чисел и таблиц. Числовая версия цикла for имеет следующий синтаксис: stat ::= for name `=' exp1 `,' exp1 [`,' exp1] do block end Инструкция for, подобная: for var = e1 ,e2, e3 do block end является заменителем кода: do local var, _limit, _step = tonumber(e1), tonumber(e2), tonumber(e3) if not (var and _limit and _step) then error() end while (_step>0 and var<=_limit) or (_step<=0 and var>=_limit) do block var = var+_step end end Обратите внимание на следующее:
Таблица для инструкции for пересекает все пары (index,value) данной таблицы. Это имеет следующий синтаксис: stat ::= for name `,' name in exp1 do block end Инструкция for, подобная: for index, value in exp do block end равносильна такому коду: do local _t = exp local index, value = next(t, nil) while index do block index, value = next(t, index) end end Обратите внимание на следующее:
Логические операторы
Логические операторы в Lua: and or not Подобно структурам управления, все логические операторы рассматривают nil как false (ложь), а все остальное как истину (true).
Оператор конъюнкции and вернет nil, если первый параметр nil, иначе это возвращает второй параметр. Оператор дизъюнкции or вернет первый параметр, если он отличается от nil, в противном случае это возвращает второй параметр. Операторы and и or используют краткое вычисление, то есть второй операнд оценен только в случае необходимости. Имеются две полезных идиомы в Lua, которые используют логические операторы. Первая идиома: x = x or v Которая является эквивалентной: if x == nil then x = v end Эта идиома устанавливает x к значению по умолчанию v, когда x не установлен.
Вторая идиома такая: x = a and b or c Которая должна читаться как x=(a and b) or c. Эта идиома эквивалентна: if a then x = b else x = c end При условии, что b не nil.
Объединения
Оператор объединения строк в Lua обозначен двумя точками (`..'). Если оба операнда строки или числа, они будут преобразованы в строки согласно правилам в разделе . Иначе будет вызван метод concat тэга.
Обращения к функции как инструкции
Из-за возможных побочных эффектов, обращения к функции могут быть выполнены как инструкции: stat ::= functioncall В этом случае все возвращенные значения утрачены. Обращения к функции объясняются в разделе 4.4.5.8.
Локальные объявления
Локальные переменные могут быть объявлены где-нибудь внутри блока. Объявление может включать начальное присваивание: stat ::= local declist [init] declist ::= name {`,' name} init ::= `=' explist1 Если представлено начальное назначение, то оно имеет ту же самую семантику многократного назначения. Иначе все переменные инициализированы nil.
Сhunk также блок, так что локальные переменные могут быть объявлены снаружи любого явного блока.
Область действия (контекст) локальных переменных начинается после объявления и продолжается до конца блока. Таким образом, код local print=print создает локальную переменную, названную print, чье начальное значение будет взято из глобальной переменной с тем же самым именем.
Старшинство
Порядок старшинства в Lua следует из таблицы ниже. Операторы в ней перечислены в порядке от низкого к более высокому приоритету: and or < > <= >= ~= == .. + - * / not - (unary) ^ Все двоичные операторы ассоциативны слева, кроме возведения в степень, который является ассоциативным справа. Прекомпилятор может перестраивать порядок оценки ассоциативных операторов (типа .. или +), пока эти оптимизация не изменяют нормальные результаты. Однако, эти оптимизация могут изменять некоторые результаты, если Вы определяете не ассоциативные методы тэгов для этих операторов.
Конструкторы таблиц
Конструкторы таблиц представляют собой выражения, которые создают таблицы: каждый раз конструктор оценен, и новая таблица создана. Конструкторы могут использоваться, чтобы создать пустые таблицы или создать таблицу и инициализировать некоторые из полей (необязательно все). Общий синтаксис для конструкторов: tableconstructor ::= `{' fieldlist `}' fieldlist ::= lfieldlist|ffieldlist|lfieldlist `;' ffieldlist|ffieldlist `;' lfieldlist lfieldlist ::= [lfieldlist1] ffieldlist ::= [ffieldlist1]
Форма lfieldlist1 используется, чтобы инициализировать списки: lfieldlist1 ::= exp {`,' exp} [`,'] Выражения в списке назначены последовательным числовым индексам, начиная с 1 (но не с 0!). Например, код: a = {"v1", "v2", 34} является эквивалентным коду: do local temp = {} temp[1] = "v1" temp[2] = "v2" temp[3] = 34 a = temp end
Форма ffieldlist1 инициализирует другие поля в таблице: ffieldlist1 ::= ffield {`,' ffield} [`,'] ffield ::= `[' exp `]' `=' exp | name `=' exp Например такая запись: a = {[f(k)] = g(y), x = 1, y = 3, [0] = b+c} эквивалентна такому коду: do local temp = {} temp[f(k)] = g(y) temp.x = 1 -- or temp["x"] = 1 temp.y = 3 -- or temp["y"] = 3 temp[0] = b+c a = temp end Выражения, подобные {x=1, y=4} фактически синтаксический аналог для выражения вида {["x"]=1, ["y"]=4}.
Обе формы могут иметь факультативную конечную запятую и могут использоваться в том же самом конструкторе, разделенные точкой с запятой. Например, все формы ниже правильны: x = {;} x = {"a", "b",} x = {type="list"; "a", "b"} x = {f(0), f(1), f(2),; n=3,}
Вызовы функций
Вызовы функций в Lua имеют синтаксис: functioncall ::= varorfunc args Сначала вычисляется varorfunc. Если значение имеет тип function, то эта функция будет вызвана с данными параметрами. Иначе вызывается метод function тэга, имея первым параметром значение varorfunc с перечисленными затем первоначальными параметрами обращения. Подробности в разделе 4.4.8.
Форма functioncall ::= varorfunc `:' name args Может использоваться, чтобы вызвать methods. Обращение v:name(...) синтаксически аналогично v.name(v, ...), за исключением того, что v будет оценен только однажды. Параметры имеют следующий синтаксис: args ::= `(' [explist1] `)' args ::= tableconstructor args ::= literal explist1 ::= {exp1 `,'} exp Все выражения параметра оценены перед обращением. Обращение в форме f{...} синтаксически аналогично f({...}), то есть список параметров представляет собой одиночную новую таблицу. Обращение в форме f'...' (f"..." или f[[...]]) синтаксически аналогично f('...'), то есть список параметров представляет собой одиночную строку литералов.
Потому, что функция может возвращать любое число результатов, число результатов должно быть откорректировано прежде, чем они используются. Если функция вызвана как инструкция, то список возврата откорректирован к 0, таким образом отбрасывая все возвращенные значения. Если функция вызвана в месте, которое нуждается в одиночном значении (синтаксически обозначенном нетерминальным exp1), то список возврата откорректирован к 1, таким образом отбрасывая все возвращенные значения, но не первый. Если функция вызвана в месте, которое может использовать много значений (синтаксически обозначено нетерминальным exp), то никакая корректировка не будет сделана. Единственные места, которые могут обрабатывать много значений, это последние (или единственные) выражения в присваивании, в списке параметров или в инструкции return. Имеются примеры: f() -- 0 результатов g(f(), x) -- f() 1 результат g(x, f()) -- g получает x и все значения, возвращенные f() a,b,c = f(), x -- f() скорректирован к 1 результату (и c получает nil) a,b,c = x, f() -- f() 2 результата a,b,c = f() -- f() 3 результата return f() -- возвращает все значения, возвращенные f() return x,y,f() -- вернет a, b и все, что вернет f()
Определение функций
Синтаксис для определения функций такой: function ::= function `(' [parlist1] `)' block end stat ::= function funcname `(' [parlist1] `)' block end funcname ::= name | name `.' name | name `:' name Инструкция function f () ... end является только синтаксическим аналогом для f = function () ... end а инструкция function v.f () ... end является синтаксическим аналогом для v.f = function () ... end
Функциональное определение представляет собой выполнимое выражение, чье значение имеет тип function. Когда Lua прекомпилирует chunk, все функциональные тела также прекомпилируются. Затем, всякий раз, когда Lua выполняет функциональное определение верхние переменные (upvalues) фиксируются, и функция выполняется. Этот функциональный образец (или замкнутое выражение) представляет собой конечное значение выражения. Различные образцы той же самой функции могут иметь различные верхние переменные.
Параметры действуют как локальные переменные, инициализированные со значениями параметра: parlist1 ::= `...' parlist1 ::= name {`,' name} [`,' `...'] Когда функция вызвана, список параметров будет откорректирован к длине списка параметров, если функция не vararg-функция, которая обозначена тремя точками (`...') в конце списка параметра. Функция vararg не корректирует список параметров, вместо этого она собирает все лишние параметры в неявный параметр, названный arg. Значением arg является таблицы из n полей, чьим значением является число параметров дополнительного пространства и сами эти параметры, перечисленные в полях 1, 2, ..., n.
Как пример, рассмотрите следующие определения: function f(a, b) end function g(a, b, ...) end function r() return 1,2,3 end Имеем следующее отображение параметров: ВЫЗОВ ПАРАМЕТРЫ
f(3) a=3, b=nil f(3, 4) a=3, b=4 f(3, 4, 5) a=3, b=4 f(r(), 10) a=1, b=10 f(r()) a=1, b=2 g(3) a=3, b=nil, arg={n=0} g(3, 4) a=3, b=4, arg={n=0} g(3, 4, 5, 8) a=3, b=4, arg={5, 8; n=2} g(5, r()) a=5, b=1, arg={2, 3; n=2}
Результаты возвращены, используя инструкцию return. Если управление достигает конца функции без того, чтобы столкнуться с инструкцией return, то функция будет завершена без результатов.
Синтаксис funcname ::= name `:' name используется для определения методов, то есть функции, которые имеют неявный дополнительный параметр self .
Инструкция function v:f (...) ... end является только синтаксическим аналогом для v.f = function (self, ...) ... end
Обратите внимание, что функция получает дополнительный формальный параметр self.
_ALERT (message)
Печатает только строковый аргумент на stderr. Все сообщения об ошибках в Lua напечатаны через функцию, сохраненную в глобальной переменной _ALERT. Следовательно, программа может назначать другую функцию к этой переменной, и изменять путь, которым такие сообщения показываются (например, для систем без stderr).
API
Этот раздел описывает API для Lua, то есть набор функций C, доступных ведущей программе, чтобы связаться с Lua. Все функции API, связанные типы и константы объявлены в файле заголовка lua.h.
Даже когда используем термин "функция", любое средство в API можно обеспечить как макрокоманду. Все такие макрокоманды используют каждый из параметров точно однажды и не генерируют скрытые побочные эффекты.
Appendto (filename)
Открывает файл, именованный filename и устанавливает это как значение _OUTPUT. В отличие от операции writeto, эта функция не стирает предыдущее содержание файла, вместо этого все, что пишется в файл, будет конкатенировано к концу. Если эта функция получила сбой, она вернет nil плюс строку, описывающую ошибку.
Assert (v [, message])
Выдает ошибку assertion failed!, когда параметр v равен nil. Эта функция эквивалентна следующей функции Lua: function assert(v, m) if not v then m = m or "" error("assertion failed! " .. m) end end
Базисные функции
Базисная библиотека обеспечивает некоторые основные функции для Lua. Следовательно, если Вы не включаете эту библиотеку в Вашей прикладной программе, Вы должны тщательно проверить, должны ли Вы обеспечить какую-то альтернативную реализацию для некоторых средств. Например, без функции _ERRORMESSAGE Lua не способен показать сообщения об ошибках.
Благодарности
Авторы пакета хотели бы поблагодарить CENPES/PETROBRAS, который, совместно с TeCGraf, использовал ранние версии этой системы и дал ценные комментарии. Авторы также хотели бы отблагодарить Carlos Henrique Levy за найденное имя для проекта. Lua на португальском означает луну.
Call (func, arg [, mode [, errhandler]])
Вызывает функцию func с параметрами, заданными таблицей arg. Обращение эквивалентно func(arg[1], arg[2], ..., arg[n])
где n представляет собой результат getn(arg). Все результаты из func просто возвращены call.
По умолчанию, если ошибка происходит в течение обращения к func, она объясняется подробно. Если строка mode включает "x", то обращение защищено. В этом режиме обращение к функции не call не объясняет ошибку подробно, независимо от того, что случается в течение обращения. Вместо этого, это возвращает nil, чтобы сообщить об ошибке (помимо вызова приспособленного драйвера ошибки).
Если errhandler обеспечивается, функция ошибки _ERRORMESSAGE временно установлена к errhandler на время выполнения func. В частности, если errhandler равен nil, никакие сообщения об ошибках не будут выданы в течение выполнения вызванной функции вообще.
Что такое Lua?
Сайт языка Lua: http://www.lua.org/.
Lua представляет собой ядро языка, которое Вы можете внедрять в Вашу прикладную программу. Это означает, что, помимо синтаксиса и семантики, Lua имеет API, который позволяет прикладной программе обмениваться данными с программами на Lua и расширять Lua функциями на C. В этом смысле, Lua может быть расценен как некий базисный метаязык для формирования проблемно-зависимых языков программирования.
Lua был предоставлен первый приз (технологическая категория) в Second Compaq Award for Research and Development in Computer Science в 1997. Это вознаграждение было объединенным предприятием Compaq Computer Brazil, the Brazilian Ministry of Science and Technology и the Brazilian Academy of Sciences.
Lua использовался во многих различных проектах во всем мире. Краткий перечень есть на http://www.lua.org/uses.html.
Lua объединяет простой процедурный синтаксис (подобный Паскалю) с мощными конструкциями описания данных, основанными на ассоциативных массивах и расширяемой семантике. Lua имеет динамические типы, интерпретируется из байт-кода и имеет автоматическое управление памятью.
Lua представляет собой мощный, легкий язык программирования расширений разработанный, чтобы поддерживать общее процедурное программирование для средств описания данных. Lua предназначен, чтобы использоваться как мощный и легкий язык конфигураций для любой программы, которая нуждается в этом, и для расширения прикладных программ. Lua также часто используется как автономный язык общего назначения.
Цели реализации: простота, эффективность, мобильность и низкая объемлющая стоимость. Результат: быстрое ядро языка с маленькими требованиями, что делает его идеальным также и во встроенных системах.
Lua написан как библиотека на C, написан на ANSI C и компилирует неизменяемый на всех известных платформах код. Будучи языком расширений, Lua не имеет никакого понятия главной программы: это работает только как вложение в некую ведущую программу. Эта ведущая программа может вызывать функции, чтобы выполнить часть кода в Lua, может писать и читать переменные Lua, и может регистрировать функции C, которые будут вызваны Lua-кодом. С помощью функций C, Lua может быть расширена, чтобы справиться с широким диапазоном различных областей, таким образом создавая настроенные языки программирования, совместно использующие синтаксические рамки.
Clock ()
Возвращает приближение количество времени CPU, используемое программой (в секундах).
Closefile (handle)
Эта функция закрывает файл. Это не изменяет _INPUT или _OUTPUT.
Collectgarbage ([limit])
Устанавливает порог для мусоросборщика в данное значение (в Kbytes). Если новый порог меньше, чем счетчик байтов, то Lua немедленно выполняет уборку мусора в памяти. Если limit отсутствует, значением по умолчанию является ноль (таким образом уборка мусора запустится сразу).
Copytagmethods (tagto, tagfrom)
Копирует все методы тэга из одного тэга в другой, возвращает tagto.
Date ([format])
Возвращает строку, содержащую дату и время, форматируемую согласно данному формату format. Формат задается по тем же самым правилам, что и в функции ANSI C strftime. Когда вызвана без параметров, возвращает приемлемое представление даты и времени, которое зависит от ведущей системы и от текущего региона.
Диагностика
Сообщения пакета об ошибках должны быть самодостаточными.
Dofile (filename)
Получает имя файла, открывает именованный файл и выполняет его содержимое как Lua-код или как прекомпилируемый код. Когда вызвано без параметров, dofile выполняет содержание стандартного ввода (stdin). Если имеется любая ошибка, dofile вернет nil. Иначе это возвращает значения, возвращенные кодом, или значение не-nil, если блок кода не возвращает никаких значений. Это выдает ошибку, когда вызвано не со строчным параметром.
Dostring (string [, chunkname])
Выполняет данную строку как код на Lua. Если имеется любая ошибка, то dostring вернет nil. Иначе это возвращает значения, возвращенные кодом, или значение не-nil, если код не возвращает никакие значения. Факультативный параметр chunkname имя кода, используемого для информации об ошибках и отладочных сообщений.
Доступность
Lua свободно доступен для академических и коммерческих целей и может быть скачан с различных сайтов в сети: Базовый сайт: http://www.lua.org/
Зеркала: Brazil: http://www.lua.org/ftp/
Germany: http://ftp.gwdg.de/pub/languages/lua/
Germany: ftp://ftp.gwdg.de/pub/languages/lua/
Greece: ftp://ftp.ntua.gr/pub/lang/lua/
Japan: ftp://ftp.u-aizu.ac.jp/pub/lang/lua/
Denmark: ftp://ftp.ucore.com/lua/dist
Россия: http://ftp.chg.ru/pub/lang/lua/
Lua распространяется свободно. Реализация, описанная в этом руководстве, доступна по адресам: http://www.lua.org/home.html
Error (message)
Вызывает драйвер ошибки и затем завершает последнюю защищенную вызванную функцию (в C: lua_dofile, lua_dostring, lua_dobuffer или lua_callfunction, в Lua: dofile, dostring или call в защищенном режим). Если message равно nil, то драйвер ошибки не будет вызван. Функция error никогда ничего не возвращает.
Execute (command)
Эта функция эквивалентна функции C system. Это передает команду command, которая будет выполнена оболочкой операционной системы. Возвращает код состояния, который является зависимым от системы.
Exit ([code])
Вызывает C-функцию exit с факультативным кодом завершения программы code. Значение по умолчанию для code: код успешного завершения.
Flush ([filehandle])
Сохраняет любые записанные данные в заданный файл. Если filehandle не определен, то flush сбросит на диск все открытые файлы. Если эта функция получила сбой, она вернет nil плюс строку с описанием ошибки.
Foreach (table, func)
Выполняется данную func над всеми элементами таблицы table. Для каждого элемента, функция вызвана с индексом и соответствующим значением как параметрами. Если функция возвращает любое значение не-nil, то цикл завершается, и это значение будет возвращено как конечное значение foreach. Эта функция могла бы быть определена в Lua так: function foreach (t, f) for i, v in t do local res = f(i, v) if res then return res end end end
Поведение foreach неопределено, если Вы изменяете таблицу t в ходе работ.
Foreachi (table, func)
Выполняет данную func над числовыми индексами таблицы table. Для каждого индекса функция вызвана с индексом и соответствующим значением как параметрами. Индексы обрабатываются в последовательном порядке, от 1 до n, где n представляет собой результат getn(table). Если функция возвращает любое значение не-nil, то цикл прерывается, а это значение будет возвращено как конечное значение foreachi. Эта функция могла бы быть определена в Lua таким образом: function foreachi (t, f) for i=1,getn(t) do local res = f(i, t[i]) if res then return res end end
end
Format (formatstring, e1, e2, ...)
Возвращает форматированную версию переменного числа параметров после применения описания, заданного в первом параметре (который должен быть строкой). Строка формата следует тем же самым правилам, что и семейство стандартных функций printf в C. Единственное различие состоит в том, что параметры *, l, L, n, p и h тут не работают, зато имеется дополнительная опция q. Опция q форматирует строку в форме, подходящей, чтобы безопасно читаться обратно Lua интерпретатором. Строка записана между двойными кавычками, а все двойные кавычки и спецсимволы будут правильно экранированы при записи. Например, обращение format('%q', 'a string with "quotes" and \n new line')
произведет такую строку: "a string with \"quotes\" and \ new line"
Преобразования могут применяться к энному параметру в списке параметров вместо следующего неиспользуемого параметра. В этом случае символ % заменен последовательностью %d$, где d десятичная цифра в диапазоне [1,9], определяет позицию параметра в списке. Например, обращение format("%2$d -> %1$03d", 1, 34) выдаст результат "34 -> 001". Тот же самый параметр может использоваться больше, чем в одном преобразовании.
Опции c, d, E, e, f, g, G, i, o, u, X и x все ожидают число как параметр, в то время как q и s ожидают строку. Модификатор * может применяться, формируя соответствующую строку формата. Например, "%*g" может соответствовать "%"...что-то-внутри..."g".
Ни строка формата, ни значения строки, которые нужно форматировать с %s, не могут содержать вложенные ноли. Но %q обрабатывает значения строк с вложенными нолями.
MySQL- Руководство разработчика
Возвращает значение системной переменной процесса varname или nil, если эта переменная не определена.
MySQL- Руководство разработчика
Получает значение глобальной переменной или вызывает метод тэга для события getglobal. Полная семантика объясняется в разделе 4.4.8 . Строка name задает имя переменной.
MySQL- Руководство разработчика
Эта функция возвращает таблицу с информацией относительно функции. Вы можете давать функцию непосредственно, или Вы можете давать число как значение function, что означает функциональное управление в уровне стека function. Уровень 0 считается текущей функцией (непосредственно getinfo), уровень 1: функция, которая вызвала getinfo и так далее. Если function представляет собой число большее, чем число активных функций, то getinfo сразу вернет nil.
Возвращенная таблица содержит все поля, возвращенные lua_getinfo со строкой what описывающий, что нужно получить. Значение по умолчанию для what: нужно получить всю доступную информацию.
Например, выражение getinfo(1,"n").name вернет имя текущей функции, если приемлемое имя может быть найдено, и getinfo(print) возвращает таблицу со всей доступной информацией относительно функции print.
MySQL- Руководство разработчика
Эта функция возвращает имя и значение локальной переменной с индексом, local на уровне level стека. Первый параметр или локальная переменная имеет индекс 1 и так далее до последней активной локальной переменной. Функция вернет nil, если не имеется никакой локальной переменной с данным индексом, и поднимает ошибку когда вызвана с level вне диапазона. Вы можете вызывать getinfo, чтобы проверить, имеет ли этот уровень силу.
MySQL- Руководство разработчика
Возвращает размер таблицы, представленной как список. Если таблица имеет n полей с числовым значением, это количество и будет размером таблицы. Иначе размером является самый большой числовой индекс со значением не-nil в таблице. Эта функция могла бы быть определена в Lua так: function getn (t) if type(t.n) == "number" then return t.n end local max = 0 for i, _ in t do if type(i) == "number" and i>max then max=i end end return max end
MySQL- Руководство разработчика
Возвращает текущий метод тэга для данной пары (tag, event). Эта функция не может использоваться, чтобы получить метод тэга для события gc. Такие методы тэга могут управляться только C-кодом.
MySQL- Руководство разработчика
Возвращает текущую таблицу глобальных переменных. Если параметр table задан, то это также устанавливает его как новую таблицу глобальных переменных.
MySQL- Руководство разработчика
Возвращает копию s, в которой все местонахождения образца pat были заменены строкой замены, определенной в repl. Функция gsub также возвращает, как второе значение, общее количество сделанных замен.
Если repl является строкой, то значение используется для замены как есть. Любая последовательность в repl в форме %n с n от 1 до 9 предназначена для n-й зафиксированной подстроки.
Если repl представляет собой функцию, то эта функция будет вызвана каждый раз, когда соответствие происходит, со всеми зафиксированными подстроками, переданными как параметры. Если значение, возвращенное этой функцией, является строкой, то это используется как строка для замены, иначе берется пустая строка.
Последний факультативный параметр n ограничивает максимальное число замен. Например, когда n равно 1, только первое местонахождение pat будет обработано.
Имеются некоторые примеры: x = gsub("hello world", "(%w+)", "%1 %1") --> x="hello hello world world" x = gsub("hello world", "(%w+)", "%1 %1", 1) --> x="hello hello world" x = gsub("hello world from Lua", "(%w+)%s*(%w+)", "%2 %1") --> x="world hello Lua from" x = gsub("home = $HOME, user = $USER", "%$(%w+)", getenv) --> x="home = /home/roberto, user = roberto" (for instance) x = gsub("4+5 = $return 4+5$", "%$(.-)%$", dostring) --> x="4+5 = 9" local t = {name="lua", version="4.0"} x = gsub("$name - $version", "%$(%w+)", function (v) return %t[v] end) --> x="lua - 4.0" t = {n=0} gsub("first second word", "(%w+)", function (w) tinsert(%t, w) end) --> t={"first", "second", "word"; n=3}
Информация стека и функций
Основная функция, чтобы получить информацию относительно стека интерпретатора: int lua_getstack (lua_State *L, int level, lua_Debug *ar);
Это заполняет части структуры lua_Debug с идентификацией записи активации функции, выполняющейся в заданном уровне. Уровень 0 текущая функция управления, в то время как уровень n+1 функция, которая вызвала уровнем n. Обычно lua_getstack вернет 1, когда вызвана с уровнем больше, чем глубина стека, она возвращает 0.
Структура lua_Debug используется, чтобы нести различные части информации относительно активной функции: typedef struct lua_Debug { const char *event; /* "call", "return" */ int currentline; /* (l) */ const char *name; /* (n) */ const char *namewhat; /* (n) поля, глобальные и локальные переменные, методы тэгов */ int nups; /* (u) количество upvalues */ int linedefined; /* (S) */ const char *what; /* (S) "Lua" функция, "C" функция, Lua "main" */ const char *source; /* (S) */ char short_src[LUA_IDSIZE]; /* (S) */ /* private part */ ... } lua_Debug;
lua_getstack заполняет только одну из частей этой структуры для будущего использования. Чтобы заполнить другие поля lua_Debug полезной информацией, надо вызвать: int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);
Эта функция возвращает 0 на ошибке (например, недопустимая опция в what). Каждый символ в строке what указывает некоторые поля ar, которые будет заполнены, как обозначено символом в круглых скобках в определении lua_Debug: S заполняет поле исходником (source), linedefined и what, l заполняет поле текущей строкой (currentline) и так далее. Кроме того, f помещает в стек функцию, которая работает в данном уровне.
Чтобы добираться до информации относительно функции, которая не активна (то есть она не в стеке), Вы помещаете функцию в стек и начинаете строку what с символа >. Например, чтобы знать, в которой строке функция f была определена, Вы можете писать: lua_Debug ar; lua_getglobal(L, "f"); lua_getinfo(L, ">S", &ar); printf("%d\n", ar.linedefined);
Поля lua_Debug имеют следующее значение:
source Если функция была определена в строке, source как раз и будет этой строкой, а если функция была определена в файле, source начинается с @, а дальше имя файла. short_src Пригодная к печати версия source, чтобы использоваться в сообщениях об ошибке. linedefined Код строки, где было начато определение функции. what Строка "Lua", если это функция Lua, "C", если это функция C или "main", если это основная часть chunk. currentline Текущая строка, где данная функция выполняется. Когда никакая информация о строке недоступна, currentline установлен в -1. name Приемлемое имя для данной функции. Так как функции в Lua значения первого класса, они не имеют фиксированных имен. Именем функции может быть значение многих глобальных переменных, в то время как другие функции могут быть сохранены только в поле таблицы. Функция lua_getinfo проверяет, является ли данная функция методом тэга или значением глобальной переменной. Если данная функция представляет собой метод тэга, name указывает на имя события. Если данная функция является значением глобальной переменной, то name указывает на имя переменной. Если данная функция не является ни методом тэга, ни глобальной переменной, то name установлен в NULL. namewhat Объясняет предыдущее поле. Если функция глобальная переменная, namewhat равен "global". Если функция метод тэга, namewhat равен "tag-method", иначе namewhat равен "" (пустой строке). nups Число upvalues в функции.
Инструкции
Lua поддерживает почти стандартный набор инструкций, подобных таким же наборам на Pascal или C. Стандартные команды включают присваивание, контроль выполнения и вызовы процедур. Нестандартные команды включают конструкторы таблицы и объявления локальных переменных.
Интерфейс отладки
Lua не имеет никаких встроенных средств отладки. Вместо этого, это предлагает специальный интерфейс, посредством функций и обработчиков прерываний, который позволяет создание различных видов отладчиков, профилировщиков и других инструментальных средств, которые нуждаются во внутренней информации из интерпретатора. Этот интерфейс объявлен в файле заголовков luadebug.h.
Использование таблиц как массивов
API имеет функции, которые помогают использовать таблицы Lua как массивы, то есть таблицы, индексированные только числами:
void lua_rawgeti(lua_State *L, int index, int n); void lua_rawseti(lua_State *L, int index, int n); int lua_getn(lua_State *L, int index);
lua_rawgeti получает значение энного элемента таблицы в позиции index стека.
lua_rawseti устанавливает значение энного элемента таблицы в позиции index стека к значению наверху стека.
lua_getn возвращает число элементов в таблице в позиции index. Это число представляет собой значение поля n таблицы, если это имеет числовое значение, или самый большой числовой индекс со значением non-nil в таблице.
Изменения в API
Изменения в библиотеках
Изменения в языке
Язык
Этот раздел описывает лексику, синтаксис и семантику Lua.
Элемент образца:
Элементом образца может быть:
Корректировка
Функции в Lua могут возвращать много значений. Потому, что не имеется никаких объявлений типа когда функция вызвана, система не знает, сколько значений вернется, или сколько параметры требуется. Следовательно, иногда список значений должен быть откорректирован во время выполнения к данной длине. Если имеется большее количество значений, чем необходимы, то лишние значения отбрасываются. Если имеется меньшее количество значений, чем необходимы, то список расширен добавлением потребного количества nil. Эта корректировка происходит в многократных назначениях (подробности в разделе 4.4.4.2) и в обращениях к функции (подробности в разделе 4.4.5.8).
Лексические соглашения в языке
Идентификатором в Lua может быть любая строка символов, цифр и символов подчеркивания, не начинающаяся цифрой. Это совпадает с определением идентификаторов в большинстве языков, за исключением того, что определение символа зависит от текущего региона. Любой символ, который считается алфавитным в текущем языке, может использоваться в идентификаторе. То есть, алфавитные символы берутся из настроек текущей системной локали. Замечу, что для лучшей переносимости программ и их применения в разных регионах лучше все же ограничиться латинским алфавитом, цифрами и символом подчеркивания: они применимы везде. Следующие слова зарезервированы, и не могут использоваться как идентификаторы: and break do else elseif return end for function if in then local nil not or repeat until while
Lua представляет собой язык, чувствительный к регистру символов: and является зарезервированным словом, но And и AND (если региональный язык разрешает) не одно и то же. Значит, приведенные варианты уже можно использовать как имена переменных. Кроме того, идентификаторы, начинающиеся с символа подчеркивания, сопровождаемого прописными буквами (типа _INPUT) зарезервированы для внутренних переменных. Их не стоит применять в своих программах.
Следующие строки обозначают другие лексемы (tokens): ~= <= >= < > == = + - * ( ) { } [ ] ; , . .. ... /
Литеральные строки могут быть разграничены одиночными или двойными кавычками, и могут содержать C-подобные управляющие последовательности: \a (bell), \b (backspace), \f (form feed), \n (newline), \r (carriage return), \t (horizontal tab), \v (vertical tab), \\ (backslash), \" (double quote), \' (single quote), и \newline (то есть, наклонная черта влево, сопровождаемая реальным newline, который приводит к переводу строки). Символ в строке может также быть определен числовым значением, через управляющую последовательность \ddd, где ddd последовательность до трех десятичных цифр. Строки в Lua могут содержать любое 8-разрядное значение, включая вложенные нули, которые могут быть определены как \000.
Литеральные строки могут также быть разграничены парами [[ ... ]]. Литералы в этой форме в скобках могут занимать по несколько строк, содержать вложенные пары скобок [[ ... ]] и не интерпретировать управляющие последовательности. Эта форма особенно удобна для записи строк, которые содержат части программы или другие цитируемые строки. Как пример, в системе использующей ASCII-кодировку, следующие три литерала эквивалентны: 1) "alo\n123\"" 2) '\97lo\10\04923"' 3) [[alo 123"]]
Комментарии начинаются с двойного тире (--) и выполняются до конца строки. Кроме того, первая строка составной части всегда пропущена, если начинается с символа #. Это средство позволяет использование Lua как интерпретатора скриптов в Unix-системах.
Числовые константы могут быть написаны с факультативной целой частью и тоже факультативным дробной частями. Допустимо применение экспоненциальной формы запитси. Примеры имеющих силу числовых констант: 3 3.0 3.1416 314.16e-2 0.31416E1
Lua в автономном режиме
Хотя Lua был разработан как язык расширений, чтобы быть вложенным в ведущую программу на C, это часто используется как автономный язык. Интерпретатор для Lua, как автономного языка, называется просто lua. Эта программа может быть вызвана с любой последовательностью следующих параметров:
-sNUM Устанавливает размер стека в NUM (если используется, должно быть первой опцией). - Выполняет stdin как файл. -c Вызывает lua_close после обработки всех параметров. -e \rmstat Выполняет строку stat. -f filename Выполняет файл filename с параметрами для таблицы arg. -i Вводит интерактивный режим с подсказкой. -q Вводит интерактивный режим без подсказки. -v Информация о версии пакета. var=value Устанавливает глобальную переменную var в строку "value". filename Выполняет файл filename.
Когда вызван без параметров, lua ведет себя как lua -v -i, когда stdin представляет собой терминал, или аналогично lua - в противном случае.
Все параметры обработаны по порядку, за исключением -c. Например, обращение, подобное: $ lua -i a=test prog.lua
Сначала взаимодействует с пользователем до EOF в stdin, затем установит a в "test" и в заключение выполнит файл prog.lua. Здесь под $ понимается подсказка оболочки. Ваша подсказка может быть иной.
Когда используется опция -f filename, все параметры в командной строке переданы программе Lua filename в таблице, названной arg. В этой таблице поле n получает индекс последнего параметра, а поле 0 получает "filename". Например, $ lua a.lua -f b.lua t1 t3
интерпретатор сначала выполняет файл a.lua, затем создает таблицу: arg = {"t1", "t3"; n = 2, [0] = "b.lua"}
а в заключение выполняет файл b.lua. Автономный интерпретатор также обеспечивает функцию getargs, которая может использоваться, чтобы обратиться ко всем параметрам командной строки. Например, если Вы вызываете Lua строкой: $ lua -c a b
то обращение к getargs в a или в b возвратит такую таблицу: {[0] = "lua", [1] = "-c", [2] = "a", [3] = "b", n = 3}
В интерактивном режиме может быть написана многострочная инструкция. Для этого надо заканчивать промежуточные строки наклонной чертой влево (\). Если глобальная переменная _PROMPT определена как строка, то ее значение используется как подсказка. Следовательно, подсказка может быть изменена непосредственно в командной строке. Например: $ lua _PROMPT='myprompt> ' -i
Или в программе Lua, назначая новое значение переменной _PROMPT.
В Unix Lua-скрипты могут быть переделаны в выполнимые программы, используя chmod +x и форму #! как в #!/usr/local/bin/lua или #!/usr/local/bin/lua -f, чтобы получить другие параметры.
Манипуляции со стеком
API предлагает следующие функции для базисного манипулирования стеком:
void lua_settop(lua_State *L, int index); void lua_pushvalue(lua_State *L, int index); void lua_remove(lua_State *L, int index); void lua_insert(lua_State *L, int index);
lua_settop принимает любые приемлемые индексы или 0 и устанавливает верхнюю часть стека к этому индексу. Если новая верхняя часть больше, чем старая, то новые элементы заполнены nil. Если index равен 0, то все элементы из стека будут удалены. Полезная макрокоманда, определенная в API: #define lua_pop(L,n) lua_settop(L, -(n)-1)
выталкивает n элементов из стека.
lua_pushvalue помещает в стек копию элемента в данном индексе. lua_remove удаляет элемент в данной позиции, сдвигая элементы вверх от этой позиции, чтобы заполнить промежуток. lua_insert перемещает верхний элемент в данную позицию, сдвигая элементы вверх от позиции на открытое место. Эти функции принимают только имеющие силу индексы. Как пример, если стек хранит значения (снизу вверх) 10 20 30 40 50: lua_pushvalue(L, 3) --> 10 20 30 40 50 30 lua_pushvalue(L, -1) --> 10 20 30 40 50 30 30 lua_remove(L, -3) --> 10 20 30 40 30 30 lua_remove(L, 6) --> 10 20 30 40 30 lua_insert(L, 1) --> 30 10 20 30 40 lua_insert(L, -1) --> 30 10 20 30 40 (никакого эффекта нет) lua_settop(L, -3) --> 30 10 20 lua_settop(L, 6) --> 30 10 20 nil nil nil
Математические функции
Эта библиотека предоставляет интерфейс к некоторым функциям стандартной математической библиотеки C. Кроме того, это регистрирует метод тэга для двоичного оператора ^, который возвращает x^y, когда применяется к числам x^y.
Библиотека обеспечивает следующие функции: abs acos asin atan atan2 ceil cos deg exp floor log log10 max min mod rad sin sqrt tan frexp ldexp random randomseed
Плюс глобальная переменная PI. Большинство из них представляют собой только интерфейсы к функциям в C-библиотеке, за исключением того, что для тригонометрических функций все углы выражены в градусах, а не в радианах. Функции deg и rad могут использоваться для того, чтобы преобразовывать данные между радианами и градусами.
Функция max возвращает максимальное значение числовых параметров. Точно так же min вычисляет минимум. Обе они могут использоваться с 1, 2 или большим количеством параметров.
Функции random и randomseed представляют собой интерфейсы к простому генератору случайных чисел, предоставляемому ANSI C (соответвенно функции rand и srand). Не может быть дпно никаких гарантий касательно их статистических свойств. Функция random при вызове без параметров возвращает псевдослучайное вещественное число в диапазоне [0,1). При вызове с параметром n, random вернет псевдослучайное целое число в диапазоне [1,n]. При вызове с двумя параметрами l и u, random вернет псевдослучайное целое число в диапазоне [l,u]. Границы всегда входят в диапазон.
Методы тэгов
Lua обеспечивает мощный механизм, чтобы расширить семантику, названный методами тэгов. Это определенная программистом функция, которая вызвана в специфических точках в течение выполнения программы Lua, позволяя программисту изменить стандартное поведение Lua в этих точках. Каждая из этих точек названа событием (event).
Метод тэга для некоего специфического события выбран согласно тэгу значения. Функция settagmethod изменяет метод тэга, связанный с данной парой (tag, event). Первый параметр представляет собой тэг, второй строку (имя события), а третий параметр (функция) задает новый метод или nil, чтобы восстановить заданное по умолчанию поведение для пары. Функция settagmethod возвращает предыдущий метод тэга для этой пары. Функция-компаньон gettagmethod получает тэг и имя события и возвращает текущий метод, связанный с парой.
Методы тэгов вызваны при соответствующих событиях, которые идентифицированы данными именами. Семантика методов лучше объяснена функцией Lua, описывающей поведение интерпретатора в каждом событии. Эта функция не только показывает, когда метод вызван, но также параметры, результаты и заданное по умолчанию поведение. Код, показанный здесь, только иллюстративен: реальное поведение сложно закодировано в интерпретаторе и намного более эффективно, чем это моделирование. Все функции, используемые в этих описаниях (rawget, tonumber, call и т.д.), описаны подробно в разделе 4.6.1.
``add'': Вызван, когда операция + применяется к не числовым операндам.
Функция getbinmethod ниже определяет, как Lua выбирает метод для двоичной операции. Сначала Lua пробует первый операнд. Если тэг не определяет метод для операции, то Lua пробует второй операнд. Если это также терпит неудачу, то Lua получает метод из тэга 0. function getbinmethod (op1, op2, event) return gettagmethod(tag(op1), event) or gettagmethod(tag(op2), event) or gettagmethod(0, event) end При использовании этой функции, метод события ``add'' такой: function add_event (op1, op2) local o1, o2 = tonumber(op1), tonumber(op2) if o1 and o2 then -- both operands are numeric return o1+o2 -- '+' here is the primitive 'add' else -- at least one of the operands is not numeric local tm = getbinmethod(op1, op2, "add") if tm then -- call the method with both operands and an extra -- argument with the event name return tm(op1, op2, "add") else -- no tag method available: default behavior error("unexpected type at arithmetic operation") end end end
``sub'': Вызван, когда операция - применяется к не числовым операндам. Поведение подобно событию ``add''.
``mul'': Вызван, когда операция * применяется к не числовым операндам. Поведение подобно событию ``add''.
``div'': Вызван, когда операция / применяется к не числовым операндам. Поведение подобно событию ``add''.
``pow'': Вызван, когда операция ^ (возведение в степень) применяется к числовым операндам. function pow_event (op1, op2) local tm = getbinmethod(op1, op2, "pow") if tm then -- call the method with both operands and an extra -- argument with the event name return tm(op1, op2, "pow") else -- no tag method available: default behavior error("unexpected type at arithmetic operation") end end
``unm'': Вызван, когда одноместная операция - применяется к не числовому операнду. function unm_event (op) local o = tonumber(op) if o then -- operand is numeric return -o -- '-' here is the primitive 'unm' else -- the operand is not numeric. -- Try to get a tag method from the operand; -- if it does not have one, try a "global" one (tag 0) local tm = gettagmethod(tag(op), "unm") or gettagmethod(0, "unm") if tm then -- call the method with the operand, nil, and an extra -- argument with the event name return tm(op, nil, "unm") else -- no tag method available: default behavior error("unexpected type at arithmetic operation") end end end
``lt'': Вызван, когда операция порядка применяется к не числовому или не строчному операнду. Это соответствует оператору <. function lt_event (op1, op2) if type(op1) == "number" and type(op2) == "number" then return op1 < op2 -- numeric comparison elseif type(op1) == "string" and type(op2) == "string" then return op1 < op2 -- lexicographic comparison else local tm = getbinmethod(op1, op2, "lt") if tm then return tm(op1, op2, "lt") else error("unexpected type at comparison"); end end end Другие операторы порядка используют этот метод согласно обычным эквивалентностям: a>b <=> b not (b=b <=> not (a
``concat'': Вызван, когда конкатенация применяется к не строчным операндам. function concat_event (op1, op2) if (type(op1) == "string" or type(op1) == "number") and (type(op2) == "string" or type(op2) == "number") then return op1..op2 -- primitive string concatenation else local tm = getbinmethod(op1, op2, "concat") if tm then return tm(op1, op2, "concat") else error("unexpected type for concatenation") end end end
``index'': Вызван, когда Lua пробует найти значение индекса, не представленного в таблице.
``getglobal'': Вызван всякий раз, когда Lua нуждается в значении глобальной переменной. Этот метод может быть установлен только для nil и для тэгов, порожденных вызовом newtag. Обратите внимание, что тэг представляет собой текущее значение глобальной переменной. function getglobal (varname) -- access the table of globals local value = rawget(globals(), varname) local tm = gettagmethod(tag(value), "getglobal") if not tm then return value else return tm(varname, value) end end Функция getglobal определена в базисной библиотеке. ``setglobal'': Вызван всякий раз, когда Lua присваивает значение глобальной переменной. Этот метод не может быть установлен для чисел, строк, таблиц и userdata с заданным по умолчанию тэгом. function setglobal (varname, newvalue) local oldvalue = rawget(globals(), varname) local tm = gettagmethod(tag(oldvalue), "setglobal") if not tm then rawset(globals(), varname, newvalue) else tm(varname, oldvalue, newvalue) end end Функция setglobal определена в базисной библиотеке.
``gettable'': Вызван всякий раз, когда Lua обращается к индексированной переменной. Этот метод не может быть установлен для таблиц с заданным по умолчанию тэгом. function gettable_event (table, index) local tm = gettagmethod(tag(table), "gettable") if tm then return tm(table, index) elseif type(table) ~= "table" then error("indexed expression not a table"); else local v = rawget(table, index) tm = gettagmethod(tag(table), "index") if v == nil and tm then return tm(table, index) else return v end end end
``settable'': Вызван, когда Lua присваивает значение индексированной переменной. Этот метод не может быть установлен для таблиц с заданным по умолчанию тэгом. function settable_event (table, index, value) local tm = gettagmethod(tag(table), "settable") if tm then tm(table, index, value) elseif type(table) ~= "table" then error("indexed expression not a table") else rawset(table, index, value) end end
``function'': Вызван, когда Lua пробует вызывать не функциональное значение. function function_event (func, ...) if type(func) == "function" then return call(func, arg) else local tm = gettagmethod(tag(func), "function") if tm then for i=arg.n,1,-1 do arg[i+1] = arg[i] end arg.n = arg.n+1 arg[1] = func return call(tm, arg) else error("call expression not a function") end end end
``gc'': Вызван, когда Lua начинает уборку мусора в userdata. Этот метод может быть установлен только из C, и не может быть установлен для userdata с заданным по умолчанию тэгом. Для каждого объекта userdata, который будет собран, Lua делает эквивалент следующей функции в цикле уборки мусора: function gc_event (obj) local tm = gettagmethod(tag(obj), "gc") if tm then tm(obj) end end В цикле уборки мусора методы тэгов для userdata вызываются в порядке, обратном созданию тэгов, то есть первые методы, которые будут вызваны, связаны с последним тэгом, созданным в программе. Кроме того, в конце цикла Lua делает эквивалент обращения gc_event(nil).
Несовместимость с предыдущими версиями
Lua 4.0 представляет собой значительное изменение языка. Была проделана большая работа, чтобы избежать несовместимости с предыдущими общими версиями Lua, но некоторые различия нужно представлять. Есть список несовместимостей.
Next (table, [index])
Позволяет программе пересекать все поля таблицы. Первый параметр: таблица, а второй параметр задает индекс в этой таблице. next вернет следующий индекс таблицы и значение, связанное с индексом. Когда вторым параметром является nil, next вернет первый индекс таблицы и связанное значение. При вызове с последним индексом или с nil в пустой таблице, next вернет nil. Если второй параметр отсутствует, то это интерпретируется как указание nil.
Lua не имеет никакого объявления полей: семантически не имеется никакого различия между полем, не представленным в таблице, или полем со значением nil. Следовательно, next рассматривает только поля со значениями не-nil. Порядок, в котором индексы перечислены, не определен даже для числовых индексов. Чтобы обработать таблицу в числовом порядке, надо использовать функцию foreachi.
Поведение next неопределено, если Вы изменяете таблицу в ходе работ.
Обработчики прерываний
Lua-интерпретатор предлагает два обработчика прерываний для целей отладки: call и line. Оба обработчика имеют тот же самый тип: typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
Вы можете устанавливать их со следующими функциями: lua_Hook lua_setcallhook (lua_State *L, lua_Hook func); lua_Hook lua_setlinehook (lua_State *L, lua_Hook func);
Обработчик прерываний заблокирован, когда значение NULL, что и является начальным значением обоих обработчиков прерываний. Функции lua_setcallhook и lua_setlinehook устанавливают соответствующие обработчики прерываний и возвращают их предыдущие значения.
Обработчик прерываний call вызван всякий раз, когда интерпретатор вызывает или оставляет функцию. Поле события event записи ar имеет строки "call" или "return". Этот ar может затем использоваться в обращениях для lua_getinfo, lua_getlocal и lua_setlocal, чтобы получить большее количество информации относительно функции и управлять локальными переменными.
Обработчик прерываний line вызван каждый раз, когда интерпретатор изменяет строку кода, которую выполняет. Поле event в ar имеет строку "line", а поле currentline хранит код строки. Вы можете использовать этот ar в других обращениях к отладочному API.
В то время как Lua управляет обработчиком прерываний, это отключает другие обращения к обработчикам прерываний. Следовательно, если обработчик прерываний вызывает Lua, чтобы выполнить функцию или chunk, это выполнение идет без обращений к обработчикам прерываний.
Обработка ошибок
Поскольку Lua язык расширений, все действия Lua начинаются из C-кода в ведущей программе, вызывающей функцию из Lua-библиотеки. Всякий раз, когда ошибка происходит в течение Lua-трансляции или выполнения, вызывается функция _ERRORMESSAGE и затем соответствующая функция из библиотеки (lua_dofile, lua_dostring, lua_dobuffer или lua_call) завершена, возвращая условие ошибки.
Ошибки распределения памяти представляют собой исключительную ситуацию из предыдущего правила. Когда происходит сбой распределения памяти, Lua не может выполнить функцию _ERRORMESSAGE. Так что, для этого вида ошибки, Lua не вызывает функцию _ERRORMESSAGE. Вместо этого соответствующая функция из библиотеки немедленно завершится со специальным кодом ошибки (LUA_ERRMEM). Это и другие коды ошибки определено в заголовочном файле lua.h, подробности в разделе 4.5.8.
Единственный параметр _ERRORMESSAGE: строка, описывающая ошибку. Заданное по умолчанию определение для этого: обращение к функции _ALERT, которая печатает сообщение на stderr. Стандартная библиотека ввода-вывода переопределяет _ERRORMESSAGE и использует средства отладки, чтобы печатать некоторую дополнительную информацию, типа расположения обращений в стеке.
Lua-код может явно генерировать ошибку, вызывая функцию error (подробности в разделе 4.6.1). Lua-код может перехватить ошибку, используя обращение к функции call (подробности в разделе 4.6.1).
Опции
Тире (-) загрузить стандартный ввод как файл, то есть не в интерактивном режиме, даже когда стандартный ввод является терминалом.
-c Закрыть Lua перед выходом.
-e "stat" выполнить инструкцию stat. Вы должны цитировать stat, если она содержит пробелы или кавычки.
-f "file" собрать все последующие параметры как строку в глобальную таблицу arg, а затем выполнить файл file. Параметры в arg начинаются с 0, который содержит строку file. Индекс последнего параметра сохранен в arg.n.
-i ввести интерактивный режим, показывая подсказку. В этом режиме lua читает строки из стандартного ввода и выполняет их как они читаются. Каждая строка должна содержать полную инструкцию. Чтобы записать инструкцию, охватывающую несколько строк, закончите каждую строку наклонной чертой влево (\). Показываемая подсказка представляет собой значение глобальной переменной _PROMPT, если это значение строка. Чтобы изменить подсказку, задайте нужное значение _PROMPT. Вы можете делать это после вызова интерпретатора или в командной строке с помощью "_PROMPT=\'lua: \'". Обратите внимание на потребность в кавычках потому, что строка содержит пробел. Заданная по умолчанию подсказка: >.
-q ввести интерактивный режим, но не показывая подсказку.
-sn установить размер стека в n. Если представлено, это должно быть первой опцией. Обратите внимание, что n находится в том же самом параметре, что и -s. Например, чтобы определить размер стека в 2000, используйте -s2000.
-v вывести информацию о версии.
Параметры должны быть отделены друг от друга. -l производит распечатку компилируемого байт-кода для виртуальной машины Lua. Если никакие файлы не даны, то luac загружает luac.out и вносит в список его полное
Openfile (filename, mode)
Эта функция открывает файл в режиме, определенном в строке mode. Это возвращает новый дескриптор файла или, в случае ошибок, nil плюс строку, описывающую ошибку. Эта функция не изменяет _INPUT или _OUTPUT.
Строка mode может быть любой из следующего списка:
r Режим чтения. w Режим записи. a Режим добавления к концу. r+ Режим обновления, все ранее записанные данные сохраняются. w+ Режим обновления, все ранее записанные данные уничтожаются. a+ Режим модификации, предыдущие данные сохраняются, запись позволяется только в конце файла.
Строка mode может также иметь в конце b, что необходимо в некоторых системах, чтобы открыть файл в двоичном режиме. Эта строка аналогична той, что используется в стандартной функции C fopen.
lua представляет собой автономный интерпретатор
lua представляет собой автономный интерпретатор языка Lua. Он загружает и выполняет программы на Lua, как в текстовой исходной форме, так и в виде прекомпилированных модулей, созданных компилятором luac. lua может использоваться как пакетный интерпретатор, а также в интерактивном режиме.
arguments могут быть параметрами, назначениями или именами файлов. Они будут обработаны слева направо.
Параметры начинаются с тире (-) и описаны ниже.
Назначение представляет собой параметр формы a=b, который назначает b глобальной переменной a. Обратите внимание, что никакие кавычки не нужны вокруг строки, если она не содержит пробелы или другие символы, специальные для оболочки. Вообще, Вы должны быть внимательны при использовании кавычек и пробелов в командной строке потому, что они обычно обрабатываются оболочкой непосредственно.
Если параметр не является ни опцией, ни назначением, то это имя файла, который затем будет загружен и выполнен.
Если никакие параметры не заданы, то принято -v -i, когда стандартный ввод представляет собой терминал, в противном случае используется -.
luac представляет собой компилятор Lua. Он транслирует программы, написанные на языке программирования Lua в двоичные файлы, которые могут быть загружены и выполнен с помощью lua_dofile в C или dofile в Lua.
Основные преимущества прекомпилированных программ: они быстрее при загрузке, исходный текст защищен от изменений пользователя и недоступно обнаружение ошибок синтаксиса.
Прекомпиляция не подразумевает более быстрое выполнение потому, что в Lua блоки всегда компилируются в байт-код прежде, чем выполняются. luac просто позволяет этому байт-коду быть сохраненным в файле.
luac производит одиночный выходной файл, содержащий байт-код для всех заданных исходных файлов. По умолчанию выходной файл именован luac.out, но Вы можете изменять это опцией -o.
Двоичные файлы, созданные luac, переносимы на любую архитектуру с тем же самым размером слова. Это означает, что двоичные файлы, созданные на 32-разрядной платформе (типа Intel) могут читаться без изменений на другой 32-разрядной платформе (типа Sparc), даже если порядок байт различен. С другой стороны, двоичные файлы, созданные на 16-разрядной платформе, не могут читаться на 32-разрядной платформе.
В командной строке Вы можете смешивать текстовые файлы, содержащие код на Lua, и двоичные файлы, содержащие прекомпилированные блоки. Это полезно: чтобы объединить несколько прекомпилированных блоков даже с различных (но совместимых) платформ в один блок.
Вы можете использовать "-", чтобы указать stdin как исходный файл.
Внутренний формат двоичных файлов, произведенных luac, может изменяться, когда выпущена новая версия Lua. Так что храните исходные файлы всех прекомпилированных программ Lua.
Определение функций C
Чтобы зарегистрировать функцию C в Lua, имеется следующая макрокоманда:
#define lua_register(L, n, f) (lua_pushcfunction(L,f),lua_setglobal(L,n)) /* const char *n; */ /* lua_CFunction f; */
Которая получает имя, которое функция будет иметь в Lua, и указатель на функцию. Этот указатель должен иметь тип lua_CFunction, который определен так; typedef int (*lua_CFunction) (lua_State *L);
То есть, это указатель на функцию с целочисленным результатом и одиночным параметром, Lua-средой.
Чтобы связываться правильно с Lua, функция C должна следовать следующему протоколу, который определяет путь, которым параметры и результаты переданы: функция C получает параметры от Lua в стеке, в прямом порядке (первый параметр помещен первым). Чтобы возвращать значения Lua, функция C только помещает их в стек в прямом порядке и возвращает число результатов. Подобно функции Lua, функция C, вызванная Lua, может возвращать много результатов.
Как пример, следующая функция получает переменное число числовых параметров, а возвращает их среднее и сумму: static int foo (lua_State *L) { int n = lua_gettop(L); /* number of arguments */ double sum = 0; int i;
for (i = 1; i <= n; i++) { if (!lua_isnumber(L, i)) lua_error(L, "incorrect argument to function `average'"); sum += lua_tonumber(L, i); } lua_pushnumber(L, sum/n); /* первый результат */ lua_pushnumber(L, sum); /* второй результат */ return 2; /* сколько всего результатов */ }
Эта функция может быть зарегистрирована в Lua как average таким вызовом: lua_register(L, "average", foo);
Когда функция C создана, возможно сопоставить с ней некоторые upvalues, таким образом создавая замкнутое выражение C; эти значения будут переданы функции всякий раз, когда она вызвана, как обычные параметры. Чтобы сопоставить upvalues с функцией C, сначала эти значения должны быть помещены в стек. Затем функция void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);
используется, чтобы поместить функцию C в стек с параметром n означающим, сколько upvalues должно быть связан с функцией (эти upvalues берутся из стека). Фактически, макрокоманда lua_pushcfunction определена как lua_pushcclosure с n установленным в 0. Затем, всякий раз, когда функция C вызвана, эти upvalues вставлены как последние параметры функции, после фактических параметров, переданных в обращении. Это избавляет от необходимости выяснять, сколько параметров было передано фактически. Так i-th upvalue находится в стеке в индексе i-(n+1), где n задает номер upvalues.
Для большего количества примеров функций C и замкнутых выражений изучите файлы lbaselib.c, liolib.c, lmathlib.c и lstrlib.c в дистрибутиве Lua.
Помещение значений в стек
API имеет следующие функции, чтобы поместить значения C в стек: void lua_pushnumber(lua_State *L, double n); void lua_pushlstring(lua_State *L, const char *s, size_t len); void lua_pushstring(lua_State *L, const char *s); void lua_pushusertag(lua_State *L, void *u, int tag); void lua_pushnil(lua_State *L); void lua_pushcfunction(lua_State *L, lua_CFunction f);
Эти функции получают значение C, преобразовывают его в соответствующее значение Lua, и помещают результат в стек. В частности, lua_pushlstring и lua_pushstring делают внутреннюю копию данной строки. lua_pushstring может использоваться только, чтобы поместить соответствующие C-строки (то есть, такие строки, которые заканчиваются нолем и не содержат вложенные ноли), иначе Вы должны использовать более общую функцию lua_pushlstring, которая принимает явный размер данных.
Print (e1, e2, ...)
Получает любое число параметров, и печатает их значения, используя строки, возвращенные tostring. Эта функция не предназначена для форматируемого вывода, ее следует рассматривать только как быстрый способ показать значение, например для отладки.
Приведение
Lua обеспечивает некоторые автоматические преобразования между значениями во время выполнения. Любая арифметическая операция, примененная к строке, пробует преобразовывать эту строку в соответствующее число, следуя обычным правилам. Наоборот, всякий раз, когда используется число, а ожидается строка, это число будет преобразовано в строку в приемлемом формате. Формат выбран так, чтобы преобразование из числа в строку было таким, чтобы обратное преобразование из строки в число было точным. Таким образом, преобразование не обязательно генерирует хороший текст для некоторых чисел. Для полного управления тем, как числа будут преобразованы в строки, используйте функцию format (подробности в разделе 4.6.2).
Rawget (table, index)
Получает реальное значение table[index] без того, чтобы вызвать любой метод тэга. Таблица должна быть задана как table, а index представляет собой любое значение, отличное от nil.
Rawset (table, index, value)
Устанавливает реальное значение table[index] в value без того, чтобы вызвать любой метод тэга. Параметр table должен быть таблицей, index представляет собой любое значение, отличное от nil, а value задает любое значение Lua.
Read ([filehandle,] format1, ...)
Читает файл _INPUT или filehandle, если этот параметр задан, согласно данным форматам, которые определяют, что читать. Для каждого формата, функция возвращает строку или число с прочитанными данными или nil, если не может читать данные с определенным форматом. Когда вызвана без форматов, эта функция использует заданный по умолчанию формат, который читает следующую строку.
Доступные форматы такие:
*n Читает число. Это единственный формат, который возвращает число вместо строки. *l Читает следующую строку (обходя концы строк) или nil в конце файла. Это и есть заданный по умолчанию формат. *a Читает целый файл, начинающийся в текущей позиции. На конце файла, возвращает пустую строку. *w Читает следующее слово (максимальная последовательность символов без пробелов. Пробелы обходит в случае необходимости. Замечу, что под пробелом здесь понимается не только собственно пробел, но и спецсимволы. В конце файла функция вернет nil. Число Читает строку до указанного числа символов в длину или nil на конце файла.
Readfrom (filename)
Эта функция может быть вызвана двумя путями. Когда она вызвана с именем файла, открывает именованный файл, устанавливает дескриптор как значение _INPUT и возвращает это значение. Это не закрывает текущий файл input. При вызове без параметров, она закрывает файл _INPUT и восстанавливает stdin как значение _INPUT. Если эта функция где-то не сработала, она возвращает nil плюс строку описания.
Если filename начинается с символа трубопровода |, открывается поточный ввод через функцию popen. Не все системы его выполняют. Кроме того, число файлов, которые могут быть открыты в то же самое время, обычно ограничивается и зависит от системы.
Рефлексивный интерфейс отладки
Библиотека ldblib обеспечивает функциональные возможности интерфейса отладки программам Lua. Если Вы хотите использовать эту библиотеку, Ваша ведущая прикладная программа должна открыть ее вызовом lua_dblibopen.
Вы должны проявить большую осторожность при использовании этой библиотеки. Функции, обеспеченные здесь, должны использоваться исключительно для отладки и подобных задач (например, профилирования). Пожалуйста, сопротивляйтесь искушению использовать их как обычный инструмент программирования. Они медленны и нарушают некоторые аспекты языка (например, секретность локальных переменных). Как общее правило, если Ваша программа не нуждается в этой библиотеке, не открывайте ее вообще.
Remove (filename)
Удаляет файл с данным именем. Если эта функция получила сбой, она вернет nil плюс строку с описанием ошибки.
Rename (name1, name2)
Переименовывает файл name1 в name2. Если эта функция получила сбой, она вернет nil плюс строку с описанием ошибки.
Сборы данных:
Образец может содержать подобразцы, включенные в круглые скобки, они описывают сборы данных. Когда соответствие выполнено, подстроки подчиненной строки, которые соответствуют сборам данных, сохранены для будущего использования. Сборы данных пронумерованы согласно их левым круглым скобкам. Например, в образце "(a*(.)%w(%s*))", часть соответствия строки "a*(.)%w(%s*)" сохранена как первый сбор данных (а, следовательно, имеет номер 1), символьное соответствие . зафиксировано с номером 2, а часть, соответствующая %s*, конечно, имеет номер 3.
Образец не может содержать вложенные ноли. Используйте вместо этого %z.
Seek (filehandle [, whence] [, offset])
Получает позицию файла, измеряемую в байтах от начала файла, и меняет ее на позицию, данную смещением offset плюс ядром, определенным как строка whence следующим образом:
set Позиция 0 (начало файла). cur Текущая позиция. end Конец файла.
В случае успеха функция seek возвращает конечную позицию файла, измеряемую в байтах от начала файла. Если эта функция получила сбой, она вернет nil плюс строку, описывающую эту ошибку.
Значение по умолчанию для whence равно cur, а для offset это 0. Следовательно, вызов seek(file) возвращает текущую позицию файла без того, чтобы изменить это. Вызов seek(file, "set") устанавливает позицию на начало файла (и возвращает 0), а seek(file, "end") устанавливает позицию в конец файла и возвращает его размер.
Setcallhook (hook)
Устанавливает функциональный обработчик прерываний hook как обработчик прерываний call. Этот обработчик прерываний будет вызван каждый раз при начале и завершении интерпретации функции. Единственный параметр на обработчик прерываний call: имя события ("call" или "return"). Вы можете вызывать getinfo с уровнем 2, чтобы получить большее количество информации относительно функции (уровень 0 соответствует функции getinfo, а уровень 1 задает функцию обработчика прерываний. Когда вызвана без параметров, эта функция выключает обработчики прерываний call. setcallhook вернет старый обработчик прерываний.
Setglobal (name, value)
Устанавливает именованную глобальную переменную к данному значению, или вызывает метод тэга для события setglobal. Полная семантика объясняется в разделе 4.4.8.
Setlinehook (hook)
Устанавливает функциональный обработчик прерываний hook как обработчик прерываний line. Этот обработчик прерываний будет вызван каждый раз, когда интерпретатор изменяет обрабатываемую строку кода. Единственный параметр на обработчике прерываний line: код строки, которую интерпретатор собирается выполнять. Когда вызвана без параметров, эта функция выключает обработчики прерываний line. Вызов setlinehook возвращает старый обработчик прерываний.
Setlocal (level, local, value)
Эта функция назначает значение value локальной переменной с индексом local функции на уровне level стека. Функция вернет nil, если не имеется никакой локальной переменной с данным индексом, и поднимает ошибку когда вызвана с уровнем level вне диапазона.
Setlocale (locale [, category])
Эта функция предоставляет интерфейс к функции ANSI C setlocale. locale представляет собой строку, определяющую регион, category факультативная строка, описывающая которую категорию изменить: "all", "collate", "ctype", "monetary", "numeric" или "time", заданная по умолчанию категория: "all". Функция возвращает имя нового региона или nil, если этот запрос не может быть выполнен.
Settag (t, tag)
Устанавливает тэг данной таблицы. Тэг (tag) должен быть значением, созданным через newtag. settag вернет значение первого параметра (таблицу). Для безопасности ведущих программ невозможно изменить тэг userdata прямо из Lua.
Settagmethod (tag, event, newmethod)
Устанавливает новый метод тэга к данной паре (tag, event) и возвращает старый метод. Если newmethod равно nil, то settagmethod восстанавливает заданное по умолчанию поведение для данного события. Эта функция не может использоваться, чтобы установить метод для события gc. Такие методы могут управляться только C-кодом.
Символьный класс:
Символьный класс используется, чтобы представить набор символов. Следующие комбинации позволяются в описании символьного класса:
x Здесь x любые волшебные символы: ^$()%.[]*+-?. Представляет непосредственно символ x. . (точка) Представляет все символы. %a Представляет все буквы. %c Представляет все спецсимволы. %d Представляет все цифры. %l Представляет все буквы в нижнем регистре. %p Представляет все символы пунктуации. %s Представляет все пробелы. %u Представляет все буквы в верхнем регистре. %w Представляет все алфавитно-цифровые символы. %x Представляет все шестнадцатеричные цифры. %z Представляет символ с представлением 0. %x Здесь x задает любой не алфавитно-цифровой символ. Представляет символ x. Это стандартный способ экранировки управляющих спецсимволов. Лучше следить за тем, чтобы любому символу пунктуации (даже не управляющему!) предшествовал %, когда символ применен в образце. [char-set] Представляет класс, который является объединением всех символов в char-set. Диапазон символов может быть определен, отделяя конечные символы диапазона тире (-). Все классы %x, описанные выше, могут также использоваться как компоненты в char-set. Все другие символы в char-set представляются как есть. Например, [%w_] (или [_%w]) представляет все алфавитно-цифровые символы плюс символ подчеркивания, [0-7] представляет восьмеричные цифры, а [0-7%l%-] представляет восьмеричные цифры плюс символы строчных букв плюс символ тире. Взаимодействие между диапазонами и классами не определено. Следовательно, образцы, подобные [%a-z] или [a-%%] не имеют никакого значения. [^char-set] Представляет дополнение char-set, где char-set интерпретируется как выше.
Для всех классов, представляемых одиночными символами (%a, %c, ...), соответствующая прописная буква представляет дополнение класса. Например, %S представляет все не пробелы.
Определения символа, пробела и т.д. зависят от текущего региона. В частности, класс [a-z] не может быть эквивалентен %l. Вторая форма должна быть предпочтительней для переносимости.
Системный реестр
При своем запуске Lua регистрируют таблицу в позиции LUA_REFREGISTRY. К этому можно обращаться через макрокоманду: #define lua_getregistry(L) lua_getref(L, LUA_REFREGISTRY)
Эта таблица может использоваться C-библиотеками как общий механизм системного реестра. Любая C-библиотека может сохранять данные в этой таблице, пока она выбирает ключ регистрации, отличный от других библиотек.
Sort(table [, comp])
Сортирует элементы таблицы в данном порядке, данные берутся из table[1] и помещаются в table[n], где n представляет собой результат getn(table). Если comp задан, то это должно быть функцией, которая получает два элемента таблицы и возвращает истину (то есть значение, отличное от nil), когда первый меньше, чем второй (так, чтобы not comp(a[i+1], a[i]) был истиной после сортировки). Если comp не задано, то вместо этого используется стандартный оператор < языка Lua.
Алгоритм сортировки неустойчив (то есть элементы, рассматриваемые как равные, могут изменить свои относительные позиции после сортировки).
Состояния
Библиотека Lua полностью повторно используема: она не имеет никаких глобальных переменных. Все состояние интерпретатора Lua (глобальные переменные, стек, методы тэгов и т.д.) сохранено в динамически распределенной структуре типа lua_State. Это состояние должно быть передано как первый параметр каждой функции в библиотеке (за исключением lua_open).
Перед вызовом любой функции API, Вы должны создать состояние вызовом: lua_State *lua_open (int stacksize); Единственный параметр этой функции: размер стека для интерпретатора. Каждое обращение к функции нуждается в одной позиции стека для каждого параметра, локальной переменной и временного значения, плюс по одной позиция для бухгалтерии. Стек должен также иметь приблизительно 20 позиций дополнительного пространства доступными. Для очень маленьких реализаций, без применения рекурсивных функций, размер стека в 100 должен быть достаточным. Если параметр stacksize равен 0, то используется заданный по умолчанию размер в 1024.
Чтобы освободить состояние, созданное lua_open, вызовите: void lua_close (lua_State *L); Эта функция уничтожает все объекты в данной среде Lua (вызывая соответствующие методы тэгов для уборки мусора, если они есть) и освобождает всю динамическую память, используемую этим состоянием. Обычно Вы не должны вызвать эту функцию потому, что все ресурсы естественно освобождены, когда Ваша программа заканчивается. С другой стороны, долго работающие программы должны бы освобождать ресурсы как только они становятся ненужными, чтобы не становиться слишком большими.
За исключением lua_open все функции в Lua API нуждаются в состоянии как в первом параметре.
Среда и составные части
Все инструкции в Lua выполнены в глобальной среде. Эта среда будет инициализирована обращением к lua_open и сохранится до обращения к lua_close или до завершения ведущей программы. В случае необходимости программист может создавать много независимых глобальных сред и свободно переключаться между ними.
Глобальная среда может управляться Lua-кодом или ведущей программой, которая может читать и писать глобальные переменные, используя функции API из библиотеки, которая предоставлена Lua.
Глобальные переменные в Lua не должны быть объявлены. Любая переменная считается глобальной, пока не объявлена явно как локальная. Перед первым назначением, значение глобальной переменной nil (это значение по умолчанию может быть изменено, подробности в разделе 4.4.8). Таблица используется, чтобы хранить все глобальные имена и значения (таблицы объясняются в разделе 4.3).
Модуль выполнения Lua назван составной частью. Это просто последовательность инструкций, которые выполнены последовательно. Каждая инструкция может факультативно сопровождаться точкой с запятой: chunk ::= {stat [`;']} Инструкции описаны в разделе 4.4.4. Запись выше представляет собой обычный расширенный BNF, в котором {a} соответствует 0 или более объектов a [a] означает факультативный a, а (a)+ задает один или большее количество a.
Составная часть (chunk) может быть сохранена в файле или в строке в ведущей программе. Когда chunk выполняется, сначала проводится прекомпиляция в байт-код для реальной машины, а затем инструкции будут выполнены в последовательном порядке, моделируя действительную машину. Все модификации глобальной среды сохраняются после окончания работы кода.
Chunk также может быть прекомпилирован в двоичную форму и сохранен в файле. Текстовые файлы с кодом и их двоичные прекомпилированные формы взаимозаменяемы. Lua автоматически обнаруживает тип файла и действует соответственно.
Средства ввода-вывода
Все операции ввода-вывода в Lua реализованы через два
дескриптора файла, по одному на ввод и вывод. Эти дескрипторы сохранены в двух глобальных переменных Lua, названных _INPUT и _OUTPUT. Глобальные переменные _STDIN, _STDOUT и _STDERR инициализированы с описателями файлов для stdin, stdout и stderr. Первоначально Initially, _INPUT=_STDIN и _OUTPUT=_STDOUT.
Дескриптор файла представляет собой объект userdata, содержащий поток файла (FILE*) с отличительным тэгом, созданным библиотекой ввода-вывода (I/O).
Если иное не установлено, все функции I/O возвращают nil на сбое и некоторое значение, отличное от nil, при успехе.
Ссылки к Lua-объектам
Если C-код должен хранить значение Lua вне продолжительности жизни функции C, то надо создать ссылку к значению. Функции, чтобы управлять ссылками, следующие: int lua_ref(lua_State *L, int lock); int lua_getref(lua_State *L, int ref); void lua_unref(lua_State *L, int ref);
lua_ref выталкивает значение из стека, создает ссылку к нему и возвращает эту ссылку. Для значения nil ссылка всегда LUA_REFNIL. lua.h также определяет константу LUA_NOREF, которая отличается от любой имеющей силу ссылки. Если lock не равно 0, то объект блокирован: это означает, что объект не будет обработан мусоросборщиком. Разблокированные ссылки могут быть удалены в порядке уборки мусора на общих основаниях.
Всякий раз, когда вызванный объект необходим в C, обращение к lua_getref помещает тот объект в стек; если объект был убран, lua_getref вернет 0 (и не поместит ничего в стек).
Когда ссылка больше не нужна, ее надо освободить вызовом lua_unref.
Стандартные библиотеки
Стандартные библиотеки обеспечивают полезные функции, которые выполнены непосредственно через стандартный API. Следовательно, они не так уж и необходимы для самого языка, а обеспечиваются как отдельные C-модули. В настоящее время, Lua имеет следующие стандартные библиотеки:
Чтобы иметь доступ к этим библиотекам, ведущая C-программа должна вызвать функции lua_baselibopen, lua_strlibopen, lua_mathlibopen и lua_iolibopen, которые объявлены в файле заголовков lualib.h.
Стек и индексы
Lua использует стек (stack), чтобы передавать значения в и из C. Каждый элемент в этом стеке представляет значение Lua (nil, число, строка).
Для удобства большинство операций запроса в API не следует за строгой дисциплиной стека. Вместо этого они могут обратиться к любому элементу в стеке, используя индекс: положительный индекс представляет абсолютную позицию стека (начиная с 1, а не с 0, как в C). Отрицательный индекс представляет смещение от верхней части стека. Более определенно, если стек имеет n элементов, индекс 1 представляет первый элемент (то есть, первый элемент, помещенный в стек), а индекс n представляет последний элемент. Индекс -1 также представляет последний элемент (то есть, элемент наверху), и индекс -n представляет первый элемент. Мы говорим, что индекс имеет силу, если он находится между 1 и верхней частью стека (то есть, если 1 <= abs(index) <= top).
В любое время Вы можете получать индекс верхнего элемента вызовом: int lua_gettop (lua_State *L); Потому, что начало индексов в 1, результат lua_gettop равно числу элементов в стеке (0 стало быть означает пустой стек).
Когда Вы взаимодействуете с Lua API, Вы ответственны за контроль переполнения стека. Функция int lua_stackspace (lua_State *L); возвращает число доступных позиций стека. Всякий раз, когда Lua вызывается C, это гарантирует, что по крайней мере LUA_MINSTACK позиций все еще доступны. LUA_MINSTACK определен в файле заголовка lua.h и по крайней мере 16, так что Вы должны позаботиться о месте в стеке только, когда Ваш код имеет циклы, помещающие элементы в стек.
Большинство функций запроса принимает как индексы любое значение внутри доступного места в стеке. Такие индексы названы приемлемыми индексами . Более формально можно определять приемлемый индекс таким образом: (index < 0 && abs(index) <= top) (index > 0 && index <= top + stackspace)
Обратите внимание, что 0 не является приемлемым индексом.
Strbyte (s [, i])
Возвращает внутренний числовой код i-го символа строки s. Если i отсутствует, то принято 1. i может быть отрицателен.
Числовые коды не обязательно переносимы между платформами.
Strchar (i1, i2, ...)
Получает 0 или большее количество целых чисел. Возвращает строку с длиной, равной числу параметров, в которой каждый символ имеет внутренний числовой код, заданный соответствующим параметром.
Числовые коды не обязательно переносимы между платформами.
Strfind (s, pattern [, init [, plain]])
Ищет первое соответствие образцу pattern в s. Если это найдено, strfind вернет индексы s, где эти вхождения начинаются и заканчивается, иначе это возвращает nil. Если образец определяет набор данных (подробности в описании gsub ниже), зафиксированные строки возвращены как дополнительные результаты. Факультативный числовой параметр init определяет, где запустить поиск: значение по умолчанию 1, и оно может быть отрицательным. Четвертый факультативный аргумент plain выключает средства поиска образца, так что функция просто ищет подстроку без символов в pattern, обрабатываемых особым образом. Обратите внимание, что если задана опция plain, должна быть задана и init.
Strlen (s)
Получает строку и возвращает ее длину. Пустая строка ("") имеет длину 0. Вложенные ноли в строке считаются, так что строка "a\000b\000c" имеет длину 5 символов.
Strlower (s)
Получает строку и возвращает ее копию со всеми символами верхнего регистра, измененными на строчные буквы. Все другие символы оставлены прежними. Определение того, какие буквы прописные, зависит от настроек региона.
Строковые манипуляции в Lua
Эта библиотека обеспечивает универсальные функции для манипулирования строками, типа нахождения и извлечения соответствия образца и подстрок. При индексации строки в Lua, первый символ находится в позиции 1 (не в 0, как в C!). Также, индексам позволено быть отрицательными, что понимается как индексация в обратном направлении, с конца строка к началу. Таким образом, последний символ находится в позиции -1 и так далее.
Strrep (s, n)
Возвращает строку, которая является суммой n копий строки s.
Strsub (s, i [, j])
Возвращает другую строку, которая является подстрокой s, начинающегося в i и продолжающейся до j. i и j могут быть отрицательными, Если j отсутствует, то оно считается равным -1 (длине строки). В частности, обращение strsub(s,1,j) возвращает префикс s длиной j, а вызов strsub(s, -i) вернет суффикс s длиной i.
Strupper (s)
Получает строку и возвращает копию со всеми символами строчных букв, измененными на верхний регистр. Все другие символы оставлены как есть. Что такое строчные буквы, читается из настроек региона.
Связь с авторами
Lua был разработан и выполнен Waldemar Celes, Roberto Ierusalimschy и Luiz Henrique de Figueiredo. С ними можно входить в контакт по e-mail lua@tecgraf.puc-rio.br.
Шлите Ваши комментарии, вопросы и отчеты об ошибках на . Для сообщений об ошибках попробуйте также список рассылки . Для получения большего количества информации относительно этого списка, включая инструкции о том, как на него подписаться, обратитесь на http://www.lua.org/mirrors.html.
Lua разработан в TeCGraf, the Computer Graphics Technology Group of PUC-Rio (the Pontifical Catholic University of Rio de Janeiro in Brazil). TeCGraf является лабораторией отдела информатики. Множество индустриальных программ, разработанных в TeCGraf, используют Lua.
Tag (v)
Позволяет программам Lua проверять тэг значения. Это получает один параметр и возвращает тэг (число).
Tinsert (table [, pos] , value)
Вставляет значение элемента value в позицию pos таблицы, сдвигая другие элементы в случае необходимости на открытое место. Значение по умолчанию для pos равно n+1, где n является результатом getn(table) так, чтобы обращение tinsert(t,x) вставило x в конец таблицы t. Эта функция также устанавливает или увеличивает поле n таблицы, превращая его в n+1. Эта функция эквивалентна следующей функции Lua, за исключением того, что доступ к таблице прямой (без методов тэгов): function tinsert (t, ...) local pos, value local n = getn(t) if arg.n == 1 then pos, value = n+1, arg[1] else pos, value = arg[1], arg[2] end t.n = n+1; for i=n,pos,-1 do t[i+1] = t[i] end t[pos] = value end
Типы и тэги
Lua представляет собой dynamically typed language. Это означает, что переменные не имеют типов, а только значения. Следовательно, не имеется никаких определений типов на языке. Все значения несут их собственный тип. Помимо типа все значения также имеют тэг.
Имеются шесть базисных типов в Lua: nil, number (число), string (строка), function (функция), userdata (пользовательские данные) и table (таблица). Nil тип значения nil, чье основное свойство должно отличаться от любого другого значения. Number представляет реальные (двойная точность с плавающей запятой) числа, в то время как string имеет обычное значение. Lua нормально понимает 8-разрядные символы, так что строки могут содержать любой 8-разрядный символ, включая вложенные нули ('\0'). Подробности в разделе 4.4.1. Функция type возвращает строку, описывающую тип данного значения (подробности в разделе 4.6.1).
Функции рассматриваются как значения первого класса (first-class values) в Lua. Это означает, что функции могут быть сохранены в переменных, переданы как параметры другим функциям и возвращены как результаты. Lua может вызывать и управлять как функциями, написанными на Lua, так и функциями, написанными на C. Два вида функций могут различаться их тэгами: все функции Lua имеют тот же самый тэг, и все функции C имеют свой тэг, который отличается от тэга функций Lua. Функция tag возвращает тэг данного значения (подробности в разделе 4.6.1).
Тип userdata обеспечивается, чтобы позволить произвольным C-указателям быть сохраненными в Lua-переменных. Этот тип соответствует void* и не имеет никаких предопределенных операций в Lua, за исключением теста равенства и назначения. Однако, используя методы тэгов, программист может определять операции для значений userdata. Подробности в разделе 4.4.8.
Тип table осуществляет ассоциативные массивы, то есть массивы, которые могут быть индексированы не только числами, а любыми значениями (за исключением nil). Следовательно, этот тип может использоваться не только, чтобы представить обычные массивы, но также и символные таблицы, наборы, записи, графы, деревья и т.д. Таблицы представляют собой основной механизм, структурирующий данные в Lua. Чтобы представлять записи (records), Lua использует имя поля как индекс. Язык поддерживает это представление, обеспечивая a.name как синтаксический аналог для a["name"]. Таблицы могут также нести методы: поскольку функции представляют собой значения первого класса, поля таблицы могут содержать функции. Форма t:f(x) синтаксический аналог для t.f(t,x), который вызывает метод f из таблицы t прохождением таблицы непосредственно как первый параметр (подробности в разделе 4.4.5.9).
Обратите внимание, что таблицы представляют собой объекты, а не значения. Переменные не содержат таблицы, только ссылаются на них. Назначение, обработка параметра и возврат всегда управляют ссылками на таблицы и не подразумевают никакого вида копирования. Кроме того, таблицы должны быть явно созданы прежде, чем используются. Подробности в разделе 4.4.5.7.
Каждый из типов nil, number и string имеет свой тэг. Вообще, очень многое в Lua построено именно вокруг тэгов. Все значения каждого из этих типов имеют тот же самый предопределенный тэг. Как объяснено выше, значения типа function могут иметь два различных тэга в зависимости от того, являются ли они функциями Lua или функциями C. В заключение, значения типов userdata и table могут иметь переменные тэги, назначенные программистом (подробности в разделе 4.4.8). Функция tag возвращает тэг данного значения. Пользовательские тэги могут быть созданы функцией newtag. Функция settag используется, чтобы изменить тэг таблицы (подробности в разделе 4.6.1). Тэг значений userdata может быть установлен из C (подробности в разделе 4.5.7). Тэги главным образом используются, чтобы выбрать соответствующие методы тэгов, когда происходят некоторые события. Методы тэгов представляют собой основной механизм для распространения семантики Lua (подробности в разделе 4.4.8).
Tmpname ()
Возвращает строку с именем файла, которое может безопасно использоваться для временного файла. Файл должен быть явно открыт перед использованием и удален, когда больше не нужен.
Tonumber (e [, base])
Пробует преобразовывать параметр в число. Если параметр уже число или строка, обратимая в число, то tonumber вернет это число, иначе это всегда возвращает nil.
Факультативный параметр определяет ядро, чтобы интерпретировать цифру. Ядром может быть любое целое число между 2 и 36 включительно. В базах более, чем 10, символ A (заглавные или строчные буквы) представляет 10, B соответствует 11 и так далее до символа Z, соответствующему 35. В ядре 10 (значение по умолчанию) число может иметь десятичную часть, также как и факультативную часть экспоненты. В других базах только целые числа без знака.
Tostring (e)
Получает параметр любого типа и преобразовывает его в строку в приемлемом формате. Для полного управления тем, как числа будут преобразованы, используйте функцию format.
Tremove (table [, pos])
Удаляет из таблицы table элемент в позиции pos, сдвигая в случае необходимости другие элементы, чтобы закрыть образовавшуюся дырку. Возвращает значение удаленного элемента. Значение по умолчанию для pos равно n, где n является результатом getn(table), чтобы обращение tremove(t) удалило последний элемент из таблицы t. Эта функция также устанавливает поле n таблицы в значение n-1.
Эта функция эквивалентна следующей функции Lua, за исключением того, что доступ к таблице прямой (без использования методов тэгов): function tremove (t, pos) local n = getn(t) if n<=0 then return end pos = pos or n local value = t[pos] for i=pos,n-1 do t[i] = t[i+1] end t[n] = nil t.n = n-1 return value end
Уборка мусора
Lua использует два числа, чтобы управлять совокупностью мусора. Одно число рассчитывает, сколько байтов динамической памяти Lua использует, а другое задает порог. Это внутренний счетчик байтов, сохраняемый Lua не полностью аккуратно: это может отклоняться на 10% от реального положения дел в памяти. Когда число байтов пересекает порог, Lua выполняет цикл зачистки мусора, который исправляет память и стирает оттуда все отработавшие свое, но забытые там объекты (то есть объекты, больше доступные из Lua). Счетчик байтов будет исправлен, а затем порог сброшен к двойному значению счетчика байтов.
Вы можете обращаться к текущим значениям этих двух чисел через следующие функции: int lua_getgccount (lua_State *L); int lua_getgcthreshold (lua_State *L);
Оба возвращают их соответствующие значения в килобайтах. Вы можете изменять пороговое значение с помощью: void lua_setgcthreshold (lua_State *L, int newthreshold);
Снова значение newthreshold задано в килобайтах. Когда Вы вызываете эту функцию, Lua устанавливает новый порог и проверяет счетчик байтов. Если новый порог меньше, чем счетчик байтов, то Lua немедленно выполняет уборку мусора. После нее новый порог будет установлен согласно предыдущему правилу.
Если Вы хотите изменять поведение коллектора мусора адаптивно, Вы можете использовать метод тэга мусоросборщика для nil, чтобы установить ваш собственный порог (метод тэга будет вызван после того, как Lua сбрасывает порог).
Управление глобальными переменными в Lua
Чтобы прочитать значение глобальной переменной Lua, надо: void lua_getglobal (lua_State *L, const char *varname);
Это помещает в стек значение данной переменной. Как в Lua эта функция может вызывать метод тэга для события getglobal. Чтобы читать реальное значение глобальной переменной без того, чтобы вызывать любой метод тэга, используют lua_rawget над таблицей глобальных переменных.
Чтобы записать значение в глобальнукю переменную: void lua_setglobal (lua_State *L, const char *varname);
Это извлекает из стека значение, которое будет сохранено в данной переменной. Как в Lua эта функция может вызывать метод тэга для события setglobal. Чтобы устанавливать реальное значение глобальной переменной без того, чтобы вызывать любой метод тэга, используют lua_rawset над таблицей глобальных переменных (подробности приведены ниже).
Все глобальные переменные сохраняются в обычной Lua-таблице. Вы можете получать ее вызовом: void lua_getglobals (lua_State *L);
Это помещает текущую (актуальную) таблицу глобальных переменных в стек. Чтобы устанавливать другую таблицу глобальных переменных, используйте вызов: void lua_setglobals (lua_State *L);
Таблица, которую нужно использовать, извлекается из стека.
Управление локальными переменными
Для манипулирования локальными переменными luadebug.h использует индексы: первый параметр или локальная переменная имеет индекс 1 и так далее до последней активной локальной переменной.
Следующие функции позволяют манипулировать локальными переменными данной активной записи. const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n); const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n);
Параметр ar должен быть имеющей силу записью активации, заполненной предыдущим обращением к lua_getstack или данный как параметр обработчика прерываний. Функция lua_getlocal получает индекс локальной переменной (n), помещает значение в стек и возвращает имя. Для lua_setlocal Вы помещаете новое значение в стек, а функция назначает это значение переменной и возвращает имя. Обе функции возвращают NULL при сбое. Это случается, если заданный индекс больше, чем число активных локальных переменных.
Как пример, следующая функция вносит в список имена всех локальных переменных функции в данном уровне стека: int listvars (lua_State *L, int level) { lua_Debug ar; int i = 1; const char *name;
if (lua_getstack(L, level, &ar) == 0) return 0; /* failure: no such level in the stack */ while ((name = lua_getlocal(L, &ar, i++)) != NULL) { printf("%s\n", name); lua_pop(L, 1); /* remove variable value */ } return 1; }
Управление таблицами в Lua
Lua-таблицы могут также управляться через API.
Чтобы читать значение в таблице, таблица должна находиться где-нибудь в стеке. Теперь вызовите void lua_gettable (lua_State *L, int index);
где index относится к таблице. lua_gettable извлекает ключ из стека и возвращает (через стек) содержание таблицы для заданного ключа. Как в Lua эта операция может вызывать метод тэга для события gettable. Получать реальное значение любого ключа таблицы, без того, чтобы вызывать любой метод тэга, можно, используя void lua_rawget (lua_State *L, int index);
Чтобы сохранять значение в таблицу, которая находится где-нибудь в стеке, Вы помещаете ключ и значение в стек (именно в этом порядке!), а затем вызываете такое обращение: void lua_settable (lua_State *L, int index);
здесь index относится к таблице. lua_settable извлекает из стека ключ и значение. Как и все в Lua, эта операция может вызывать метод тэга для события settable. Чтобы устанавливать реальное значение любого индекса таблицы без того, чтобы вызывать любой метод тэга, используют raw-версию: void lua_rawset (lua_State *L, int index);
В заключение, еще одна функция void lua_newtable (lua_State *L);
создает новую, пустую, таблицу и помещает ее в стек.
Userdata и тэги
Поскольку userdata представляют собой объекты, функция lua_pushusertag может создавать новые userdata. Если Lua имеет userdata с данным значением (void*) и тэг, то этот объект размещен. Иначе создается новый userdata с данным значением и тэгом. Если эта функция вызвана с тэгом, равным LUA_ANYTAG , то Lua пробует находить любой объект userdata с данным значением, независимо от его тэга. Если не имеется никакого userdata с этим значением, то новый объект будет создан с тэгом, равным 0.
Userdata может иметь различные тэги, чья семантика известна только ведущей программе. Тэги создаются функцией: int lua_newtag (lua_State *L);
Функция lua_settag меняет тэг объекта в верхней части стека (без того, чтобы получить его): void lua_settag (lua_State *L, int tag);
Объект должен быть userdata или таблицей, данный тэг должен быть значением, созданным с помощью функции lua_newtag.
Выполнение Lua-кода
Ведущая программа может выполнять Lua-chunk, записанные в файле или в строке, используя следующие функции:
int lua_dofile(lua_State *L, const char *filename); int lua_dostring(lua_State *L, const char *string); int lua_dobuffer(lua_State *L, const char *buff, size_t size, const char *name);
Эти функции возвращают 0 в случае успеха, или один из следующих кодов ошибки, если они терпят неудачу:
Эти константы определены в lua.h.
Когда функция lua_dofile вызвана с параметром NULL, она выполняет поток stdin. lua_dofile и lua_dobuffer способны выполнить прекомпилируемые объекты кода. Они автоматически обнаруживают, является ли кусок кода текстовым или двоичным, и загружают его соответственно. lua_dostring выполняет только исходный текст, заданный в простой текстовой форме.
Третий параметр для lua_dobuffer задает имя chunk, который используется сообщениях об ошибках и отладочных сообщениях. Если имя name равно NULL, то Lua дает заданное по умолчанию имя этому chunk.
Эти функции помещают в стек любые значения, в конечном счете возвращенные кодом. Код может возвращать любое число значений; Lua соблюдает осторожность, в том плане, что эти значения вписываются в размер стека, но после обращения ответственность переходит к Вам. Если Вы должны поместить другие элементы после вызова любой из этих функций, и Вы хотите работать спокойно, Вы должны или проверить место в стеке с помощью lua_stackspace, или удалять возвращенные элементы из стека (если Вы не нуждаетесь в них). Например, следующий код загружает код в файле и отбрасывает все результаты, возвращенные этим кодом: { int oldtop = lua_gettop(L); lua_dofile(L, filename); lua_settop(L, oldtop); }
Вызов функций Lua
Функции, определенные в Lua (и функции C, зарегистрированные в Lua), могут быть вызваны из ведущей программы. Это выполнено, используя следующий протокол: сначала, функция, которая будет вызвана, помещена в стек, затем, параметры функции помещены в прямом порядке, то есть первый параметр помещен в стек первым. В заключение, функция вызвана: int lua_call (lua_State *L, int nargs, int nresults);
Эта функция возвращает те же самые коды ошибки, что и lua_dostring и другие (подробности в разделе
4.5.8). Если Вы хотите исследовать ошибку, вместо того, чтобы возвратить код ошибки, используйте: void lua_rawcall(lua_State *L, int nargs, int nresults);
В обеих функциях nargs задает число параметров, которые Вы поместили в стек. Все параметры и функциональное значение берутся из стека, а функциональные результаты помещены туда. Число результатов будет откорректировано до nresults, если nresults не LUA_MULTRET. В этом случае все результаты функции будут помещены в стек. Функциональные результаты помещены в прямом порядке (первый результат и помещен первым), чтобы после обращения последний результат оказался на самой вершине стека.
Следующий пример показывает, как ведущая программа может делать эквивалент коду на Lua: a,b = f("how", t.x, 4)
Here it is inC:
/* глобальная `t' (потом пригодится) */ lua_getglobal(L, "t"); /* функция, которая будет вызвана */ lua_getglobal(L, "f"); /* 1-ый параметр */ lua_pushstring(L, "how"); /* помещает в стек строку `x' */ lua_pushstring(L, "x"); /* помещает в стек результат t.x (2-ой аргумент) */ lua_gettable(L, -4); /* 3-ий параметр */ lua_pushnumber(L, 4); /* вызывает функцию с 3 параметрами и 2 результатами */ lua_call(L, 3, 2); /* устанавливает глобальную переменную `b' */ lua_setglobal(L, "b"); /* устанавливает глобальную переменную `a' */ lua_setglobal(L, "a"); /* удаляет из стека `t' */ lua_pop(L, 1);
Обратите внимание, что код выше сбалансированный: в конце стек обратен к первоначальной конфигурации. Это считается хорошей практикой.
Некоторые специальные функции Lua имеют собственные интерфейсы C. Ведущая программа может генерировать ошибку Lua, вызывая функцию: void lua_error (lua_State *L, const char *message);
Эта функция никогда не возвращает ничего. Если lua_error вызвана из функции C, которая была вызвана из Lua, то соответствующий блок кода Lua завершается так, как будто ошибка произошла внутри кода Lua. Иначе вся ведущая программа завершается обращением exit(EXIT_FAILURE). Перед завершением выполнения, сообщение message будет передано функции драйвера ошибки _ERRORMESSAGE. Если message равно NULL, то _ERRORMESSAGE не вызывается.
Методы тэгов могут быть изменены с void lua_settagmethod (lua_State *L, int tag, const char *event);
Второй параметр задает тэг, а третий представляет собой имя события. Новый метод берется из стека. Чтобы получить текущее (актуальное) значение метода тэга используйте функцию void lua_gettagmethod(lua_State *L, int tag, const char *event);
Также возможно копировать все методы из одного тэга в другой: int lua_copytagmethods (lua_State *L, int tagto, int tagfrom);
Эта функция вернет tagto.
Вы можете пересекать таблицу с функцией: int lua_next (lua_State *L, int index);
здесь index относится к таблице, которая будет пересечена. Функция берет ключ из стека и помещает туда пару "значение-ключ" из таблицы (следующую после данного ключа). Если не имеется больше элементов, то функция возвращает 0 (и не помещает в стек ничего). Типичный пример использования выглядит следующим образом: lua_pushnil(L); /* first key */ while (lua_next(L, t) != 0) { /* `key' is at index -2 and `value' at index -1 */ printf("%s - %s\n", lua_typename(L, lua_type(L, -2)), lua_typename(L, lua_type(L, -1))); lua_pop(L, 1); /* removes `value'; keeps `index' for next iteration */ }
Функция void lua_concat (lua_State *L, int n);
конкатенирует n значений сверху стека, извлекает их и оставляет результат наверху. Здесь n должно быть по крайней мере равно 2. Конкатенация выполнена по правилам обычной семантики Lua
Пишет значение каждого из параметров в файл _OUTPUT или в filehandle, если этот параметр задан. Параметры должны быть строками или числами. Чтобы писать другие значения, используйте tostring или format перед write. Если эта функция нарвалась на ошибку, она вернет nil и строку с описанием данной ошибки.
Writeto (filename)
Эта функция может быть вызвана двумя путями. Когда она вызвана с именем файла, открывает именованный файл, устанавливает дескриптор как значение _OUTPUT и возвращает это значение. Это не закрывает текущий выходной файл. Обратите внимание, что если файл уже существует, то он будет полностью уничтожен этой операцией. Когда функция вызвана без параметров, она закрывает файл _OUTPUT и восстанавливает stdout как значение _OUTPUT. В случае ошибки функция возвращает nil плюс строку, описывающую ошибку.
Если filename начинается с символа трубопровода |, открывается поточный ввод через функцию popen. Не все системы его выполняют. Кроме того, число файлов, которые могут быть открыты в то же самое время, обычно ограничивается и зависит от системы.
Запросы к стеку
Чтобы проверять тип элемента стека, следующие функции доступны: int lua_type(lua_State *L, int index); int lua_tag(lua_State *L, int index); int lua_isnil(lua_State *L, int index); int lua_isnumber(lua_State *L, int index); int lua_isstring(lua_State *L, int index); int lua_istable(lua_State *L, int index); int lua_isfunction(lua_State *L, int index); int lua_iscfunction(lua_State *L, int index); int lua_isuserdata(lua_State *L, int index);
Эти функции могут быть вызваны с любым приемлемым индексом.
lua_type возвращает одну из следующих констант, согласно типу данного объекта: LUA_TNIL, LUA_TNUMBER, LUA_TSTRING, LUA_TTABLE, LUA_TFUNCTION, LUA_TUSERDATA. Если индекс не имеет силу (то есть, если та позиция стека пуста), то lua_type возвращает LUA_TNONE. Эти константы могут быть преобразованы в строки с помощью вызова: const char *lua_typename(lua_State *L, int t);
здесь t представляет собой тип, возвращенный lua_type. Строки, возвращаемые lua_typename: "nil", "number", "string", "table", "function", "userdata" и "no value",
lua_tag возвращает тэг значения или LUA_NOTAG для не имеющего силу индекса.
Функция lua_is* возвращает 1, если объект совместим с данным типом, и 0 в противном случае. Всегда возвращается 0 для не имеющего силу индекса. lua_isnumber принимает числа и числовые строки. lua_isstring берет строки и числа и lua_isfunction воспринимает функции Lua и C. Чтобы различать между функциями Lua и функциями C, Вы должны использовать lua_iscfunction. Чтобы различать между числами и числовыми строками, Вы можете использовать lua_type.
API также имеет функции, чтобы сравнить два значения в стеке: int lua_equal(lua_State *L, int index1, int index2); int lua_lessthan(lua_State *L, int index1, int index2);
Эти функции эквивалентны их дубликатам в Lua. Определенно, lua_lessthan эквивалентна lt_event. Обе функции возвращают 0, если любой из индексов не имеет силу.
Чтобы транслировать значение в стеке к специфическому типу C, Вы можете использовать следующие функции преобразования: double lua_tonumber(lua_State *L, int index); const char *lua_tostring(lua_State *L, int index); size_t lua_strlen(lua_State *L, int index); lua_CFunction lua_tocfunction(lua_State *L, int index); void *lua_touserdata(lua_State *L, int index);
Эти функции могут быть вызваны с любым приемлемым индексом. Когда вызваны с не имеющим силу индексом, они действуют так, как будто переданное им значение имело неправильный тип.
lua_tonumber преобразовывает значение в данном индексе к числу с плавающей запятой. Это значение должно быть числом или строкой, обратимой в число (подробности в разделе
4.4.2). Иначе lua_tonumber возвращает 0.
lua_tostring преобразовывает значение Lua в строку (const char*). Это значение должно быть числом или строкой, иначе будет возвращен NULL. Эта функция возвращает указатель на строку внутри Lua-среды. Эти строки всегда имеют ноль ('\0') после их последнего символа (как в C), но могут содержать другие ноли в их теле. Если Вы не знаете, может ли строка содержать ноли, Вы должны использовать lua_strlen, чтобы получить фактическую длину. Потому, что Lua имеет мусороуборщик, не имеется никакой гарантии, что указатель, возвращенный lua_tostring, будет иметь силу после того, как соответствующее значение удалено из стека.
lua_tocfunction преобразовывает значение в стеке к функции C. Это значение должно быть функцией C, иначе lua_tocfunction возвращает NULL. Тип lua_CFunction рассмотрен более подробно в отдельном разделе 4.5.13.
lua_touserdata преобразовывает значение в void*. Это значение должно иметь тип userdata, иначе lua_touserdata вернет NULL.
MySQL- Руководство разработчика
Cursor.rollback() всегда падает!
MySQLdb теперь поддерживает транзакции, если сервер поддерживает транзакционно-безопасные таблицы (TST), и Вы используете их. Если Ваш сервер не поддерживает их, rollback всегда будет терпеть неудачу потому, что система не в состоянии выполнить Ваши инструкции. Даже если Ваш сервер поддерживает транзакционно-безопасные таблицы, rollback будет терпеть неудачу, если Вы изменили любую не-TST таблицу.
cursor.commit(), который пытается завершить транзакцию всегда работает нормально потому, что MySQL по существу всегда в режиме auto-commit mode (если Вы не его не выключили).
ImportError: libmysqlclient.so.6: cannot open shared object file: No such file or directory
Вы имеете динамические библиотеки MySQL, и по умолчанию Ваш компилятор линкует _mysql.so с ними, но они не в пути загрузчика, когда Вы запускаете Python. Вы имеете два базисных параметра:
Я установил MySQLdb, но ZMySQLDA его не видит
Вероятно, Вы установили двоичную версию Zope, которая приходит со своим собственным интерпретатором Python. Вы должны компилировать MySQLdb с той специфической установкой Python. Выясните, где находятся двоичные модули python и используйте это, чтобы выполнить setup.py.
ImportError: ./_mysql.so: undefined symbol: PyLong_FromUnsignedLongLong
PyLong_FromUnsignedLongLong() сначала появляется в Python 1.5.2, так что Вы компонуете с более старой версией. Вы можете также иметь больше, чем одну установленную версию. Получите Python 1.5.2 (а лучше посвежее) с python.org.
Я получаю буквы L в столбцах INTEGER
Вообще-то они должны быть преобразованы в длинные целых числа, чтобы избежать переполнения на столбцах UNSIGNED INT. Решения: используйте атрибут fmt=%d на элементах dtml-var или поставьте Zope 2.4, который приходит с Python 2.1, который не добавляет L.
Как я могу использовать некоторые из специальных свойств СУБД MySQL?
С одной стороны, никак. Не делайте этого, если Вы можете избежать этого. Ваша программа не будет переносима к другим базам данных.
Но если Вас эта переносимость не интересует, то почти все специальные обращения API выполнены в объекте _mysql, и объект связи в MySQLdb может также вызывать их.
ImportError: ./_mysql.so: undefined symbol: uncompress
Библиотеки пользователей MySQL-3.23 требуют libz для сжатия gzip. Скрипт setup.py должен бы добавить это автоматически.
Я получаю синтаксическую ошибку SQL на предложениях LIMIT, но я не помещал в запрос слово LIMIT!
Z метода SQL имеют параметр max_rows. Если это установлено к значению, отличному от нуля, ZMySQLDA автоматически добавляет предложение LIMIT к инструкции SELECT. Это сильно повышает эффективность, особенно, если набор результатов мог бы быть большим. Если это сталкивается с чем-то, установите max_rows в ноль, и это не будет добавлять предложение LIMIT. В частности, Вы, вероятно, должны будете сделать это при вставке строк со столбцами AUTO_INCREMENT, поскольку обычно Вы используете SELECT, чтобы получить LAST_INSERT_ID(), а LIMIT может блокировать это.
Я все еще хочу использовать _mysql
Хорошо, это может быть необходимо в каком-то случае. ZMySQLDA делает это потому, что Zope-модуль ZRDB сам по себе API, а слишком много уровней API имеют тенденцию к разброду и шатанию. С этим поделать что-либо трудно. Кроме того, было фактически довольно просто сделать это именно таким способом, да и эффективность малость повысилась.
Mysql.c:33: mysql.h: No such file or directory
Путь для include-файлов (-I) к Вашим MySQL include-файлам ошибочен. Поправьте скрипт setup.py. Другой вариант: Вы не имеете набора разработчика для MySQL. Если Вы используете Red Hat RPM, Вы нуждаетесь в RPM-пакете MySQL-devel, чтобы откомпилировать _mysql.so. Однако, если Вы компонуетесь со статическими библиотеками MySQL, Вы можете устанавливать _mysql.so на системе, которая не имеет библиотек пользователей MySQL (libmysqlclient).
MySQLmodule
MySQLmodule, старый интерфейс MySQL, разработанный Joe Skinner, является также интерфейсом C/Python. MySQL, C-часть, имеет интерфейс, подобный perl DBI. Кроме того, имеется часть Python, Mysqldb, которая обеспечивает интерфейс DB API v1.0, написанный James Henstridge. MySQLdb-0.2.2 и выше включает CompatMysqldb, который является адаптацией Mysqldb к _mysql. Это должно рассмотреться экспериментальным решением.
Напротив, C-часть MySQLdb, _mysql, разработана в соответствии с MySQL C API объектно-ориентированным способом. MySQLdb обеспечивает интерфейс DB API v2.0, который имеет некоторые отличия от v1.0, в частности такие изменения:
| Действие | Mysqldb | MySQLdb |
| Соединение | db=Mysqldb.Mysqldb("db@host user pass") | db=MySQLdb.connect(db='db', host='host', user='user', passwd='pass') |
| Неявный курсор | db.execute(SQL) | Неявные курсоры удалены из DB API v2.0. Всегда используйте c=db.cursor() |
| Строка выборок как словарь | c.fetchDict(), ключи: "table.column" | Не стандарт: альтернативный класс DictCursor предоставляет интерфейс словаря, ключи являются "column" или "table.column , если имеются два столбца с одним именем. Используйте SQL-оператор AS для переименования полей. |
| Транзакции | db.commit() и db.rollback() мирно сосуществуют вместе и тихо не делают ничего (опасно!) | db.commit() и db.rollback() работают, если сервер MySQL может выполнять транзакции, иначе db.rollback() всегда терпит неудачу. |
Модуль _mysql
Если Вы хотите писать прикладные программы, которые переносимы между базами данных, избегайте использовать этот модуль непосредственно. Модуль _mysql обеспечивает интерфейс, который обычно осуществляет MySQL C API. Для получения большего количества информации обратитесь к документации на пакет MySQL. Документация для этого модуля преднамеренно слаба потому, что Вы, вероятно, должны использовать более высокий уровень (модуль MySQLdb).
MySQLdb: интерфейс DB API
MySQLdb представляет собой тонкую обертку на Python вокруг _mysql. MySQLdb делает его совместимым с интерфейсом Python DB API (version 2). В действительности код, который осуществляет API, находится в _mysql ради эффективности.
Использование и расширение
Базы данных, даже SQL-базы данных, изменяются по возможностям очень сильно и могут иметь ненормативные свойства. DB API делает хорошую работу по обеспечению приемлемо переносимого интерфейса, но некоторых методов там нет. Специфические параметры для connect()полностью зависимы от реализации.
Если Вы полагаете, что Ваша прикладная программа должна выполниться на нескольких различных базах данных, автор рекомендует следующий подход, основанный на персональном опыте: пишите упрощенный API для Вашей прикладной программы, который осуществляет специфические запросы и операции, которые Ваша прикладная программа должна выполнить. Выполните этот API как основной класс, который должен иметь немного зависимостей от базы данных, а затем получите подкласс, который осуществляет необходимые зависимости. Таким образом, перенос Вашей прикладной программы к новой базе данных должен быть относительно простым вопросом создания нового подкласса для базы данных.
В качестве примера рекомендую изучить модуль SQLDict (http://dustman.net/andy/python), который позволяет стандартным запросам работать, используя объект, который напоминает словарь, а также читать и писать определяемые пользователем дополнительные объекты.
Поскольку объекты MySQLdb Connection и Cursor написаны на Python, Вы можете легко получать Ваши собственные подклассы. Имеются несколько классов Cursor в MySQLdb.cursors:
BaseCursor Основной класс для объектов Cursor. Не вызывает Warning. CursorWarningMixIn Создает исключительную ситуацию Warning на запросах, которые производят предупреждения. CursorStoreResultMixIn Заставляет Cursor использовать функцию mysql_store_result(), чтобы получить результат запроса. Весь набор результатов сохранен на стороне пользователя. CursorUseResultMixIn Заставляет курсор использовать функцию mysql_use_result(), чтобы получить результат запроса. Набор результатов сохранен на стороне сервера и передается построчно. CursorTupleRowsMixIn Заставляет cursor возвращать строки как блоки значений столбца. CursorDictRowsMixIn Заставляет cursor возвращать строки как как словарь, где ключи имена столбца, а значения представляют значения столбца. Обратите внимание, что, если имена столбца не уникальны, то есть, Вы выбираете из двух таблиц, которые совместно используют имена столбца, некоторые из них будут переделаны в table.column. Этого можно избежать, используя ключевое слово SQL AS Cursor Заданный по умолчанию класс курсора. Этот класс составлен из CursorWarningMixIn, CursorStoreResultMixIn, CursorTupleRowsMixIn и BaseCursor, то есть он создает исключительную ситуацию Warning, использует mysql_store_result() и возвращает строки как блоки. DictCursor Аналогичен Cursor за исключением того, что возвращает строки как словари. SSCursor Серверный курсор. Похож на Cursor, но использует CursorUseResultMixIn. Используйте только, если Вы имеете дело с потенциально большими наборами результатов. SSDictCursor Аналогичен SSCursor за исключением того, что возвращает строки как словари. XXXCursorNW Курсоры с суффиксом NW не создают исключительную ситуацию Warning.
Я использую только Windows...
А я не использую Windows. Скрипт setup.py, как предполагается, работает. Может также быть связь с каким-либо сторонним пакетом.
DateTime
Если Вы имеете установленный пакет mx.DateTime , MySQLdb использует его для связанных с датой объектов. Иначе они будут возвращены как строки. Вы можете также изменять словарь преобразования типов, чтобы возвратить их как другие объектные классы.
FAQ
FAQ доступны на http://dustman.net/andy/python/MySQLdb/faq/MySQLdb-FAQ.html.
Функции и атрибуты
Только несколько высокопоставленных функций и атрибутов определены внутри MySQLdb.
connect(parameters...) Конструктор для создания подключения. Возвращает объект подключения (Connection Object). Параметры те же, как и для MySQL C API. Кроме того, имеются несколько дополнительных ключевых слов, которые соответствуют тому, что Вы передали бы как mysql_options() перед соединением. Обратите внимание, что некоторые параметры должны быть определены как параметры ключевого слова! Значение по умолчанию для каждого параметра: NULL или 0, зависит от типа. Важные параметры:
host Имя компьютера, с которым надлежит соединиться Значение по умолчанию: используйте локальный компьютер. user Пользователь, чтобы авторизоваться на сервере. Значение по умолчанию: текущий эффективный пользователь. passwd Пароль, чтобы авторизоваться на сервере. Значение по умолчанию: никакого пароля (пустой пароль). db База данных, которую надо использовать. Значение по умолчанию: никакой заданной по умолчанию базы данных. port TCP-порт сервера MySQL. Значение по умолчанию: стандартный порт (3306). unix_socket Расположение сокета UNIX. Значение по умолчанию: использование TCP. conv Словать преобразования типов. Значение по умолчанию: копия MySQLdb.converters.conversions. compress Включить сжатие протокола. Значение по умолчанию: никакого сжатия. connect_timeout Аварийное прекращение работы, если соединение не завершено в рамках данного числа секунд. Значение по умолчанию: нет тайм-аута. named_pipe Использовать именованный канал (только под Windows). Значение по умолчанию: не делать этого. init_command Начальная команда, которую надо выдать на сервер при подключении. Значение по умолчанию: нет. read_default_file Файл настроек MySQL. Отсюда берутся mysql_options(). read_default_group Заданная по умолчанию группа в файле настроек. Отсюда берутся mysql_options(). cursorclass Класс курсора, который использует cursor(), если не перекрыт. Значение по умолчанию: MySQLdb.cursors.Cursor. Это должно быть параметром ключевого слова.
apilevel Строковая константа, задающая поддерживаемый уровень DB API: '2.0'. threadsafety Константа типа Integer, устанавливающая уровень поточной безопасности, который поддерживает интерфейс. С MySQLdb version 0.9.0 это установлено в 1, что означает: потоки могут совместно использовать модуль.
Протокол MySQL не может обрабатывать много потоков, использующих то же самое подключение, сразу. Более ранние версии MySQLdb использовали блокировку, чтобы достигнуть threadsafety=2. Несмотря на то, что это не должно активно использовать стандартный класс Cursor (который используется в mysql_store_result()), это усложнено SSCursor (который используется в mysql_use_result(). Здесь Вы должны гарантировать, что все строки прочитались прежде, чем другой запрос сможет быть выполнен. Это далее усложнено добавлением транзакций, начинающихся когда курсор выполняет запрос, и завершающихся выполнением COMMIT или ROLLBACK объектом Connection. Два потока не могут совместно использовать подключение, в то время как транзакция происходит, в дополнение к неспособности совместно использовать его в течение выполнения запроса. К сожалению, это чрезмерно усложнило код.
Общий результат этого: совместно не используйте подключения разными потоками. Это не стоит прилагаемых усилий и в результате, вероятно, причинит вред эффективности, так как сервер MySQL выполняет отдельный поток для каждого подключения. Вы можете, конечно, делать кэширование подключений через специальный пул, и давать подключения с одним потоком одновременно. Если Вы позволяете двум потокам использовать подключение одновременно, библиотека пользователей MySQL, вероятно, будет сваливаться.
paramstyle Строковая константа, устанавливающая тип маркера параметра, форматирующего ожидаемое интерфейсом. Установите в 'format'=ANSI C printf-коды формата, например '...WHERE name=%s'. Если объект отображения используется для conn.execute(), то интерфейс фактически использует 'pyformat'= расширенные форматные коды Python, например, '...WHERE name=%(name)s'. Однако, API теперь не позволяет спецификацию больше, чем одного стиля в paramstyle.
Примечание о совместимости: старые версии MySQLmodule используют подобную схему задания параметра, но требуют, чтобы кавычки были помещены вокруг строк формата, которые будут содержать строки, даты и подобные символьные данные. Это не требуется для MySQLdb. Рекомендуется, чтобы %s (но не '%s') использовался для всех параметров, независимо от типа. Интерфейс выполняет все необходимое цитирование сам.
conv Словарь, отображающий типы MySQL (из FIELD_TYPE.*) к вызываемым объектам Python (обычно функциям), которые преобразовываются из строк в нужные типы. Это инициализировано с приемлемыми значениями по умолчанию для большинства типов. При создании объекта Connection Вы можете передать Ваш собственный словарь конвертера типа как параметр ключевого слова. Иначе это использует копию MySQLdb.converters.conversions. Словарь включает некоторые из функций модуля DateTime, если это доступно. Несколько ненормативных типов возвращены как строки,
Начиная с MySQL-3.23, MySQL поддерживает различные наборы символов на клиенте и сервере, а также новую функцию цитирования mysql_real_escape_string(). Это требует, чтобы функция цитирования строки была методом, связанным с объектом connection. MySQLdb обрабатывает это для Вас автоматически. Однако, если Вы чувствуете потребность сделать что-то особое со строками, Вы должны изменить словарь после открытия подключения.
Использование MySQLdb
MySQLdb представляет собой модуль, соответствующий спецификации Python Database API 2.0 (http://www.python.org/topics/database/DatabaseAPI-2.0.html), так что Вы должны быть знакомы с этой спецификацией. Здесь указаны отличия: http://dustman.net/andy/python/MySQLdb/doc/MySQLdb.html.
Компиляция _mysql.so
Имеются некоторые общие ошибки, которые случаются в ходе построения пакета. Этот раздел покрывает только проблемы UNIX/Linux, поскольку я не делаю пакетов под Windows. Файлы типа .so представляют собой динамические библиотеки в Linux и большинстве других вариантов UNIX. Windows использует расширение .dll.
Linux/UNIX
Этот модуль разработан на RedHat Linux (в настоящее время 7.1) для Intel. Это должно формироваться без больших трудностей на большинстве платформ, используя скрипт setup.py. Возможно этот модуль работает и под MacOS X. Вы нуждаетесь в пакете Distutils, который поставляется с Python 2.0. Если Вы не имеете его (то есть Вы имеете Python 1.5.2), Вы можете скачать пакет с сайта http://www.python.org/.
и выше. Некоторые старые версии
Гарантируется работа версии 3.22.32 и выше. Некоторые старые версии могут работать, если Вы имеете старшую версию, Вы должны серьезно подумать об апгрейде в целях исправления ошибок и дыр в защите.
MySQL-3.22 имеет проблему при попытке вставить значения TIME с дробными секундами. Значения, подобные 12:56:13.00, возвращены как 344:13:00, очевидно интерпретируя первоначальный ввод как 12 дней, 56 часов, 13 минут и 0 секунд (12 дней и 56 часов=344 часа). Чтобы избежать этой проблемы, используйте тип DateTimeDelta.
MySQLdb поддерживает транзакции, если их
MySQLdb поддерживает транзакции, если их поддерживает сервер. Но не гарантирует, что транзакции будут работать. Для этого Вы должны использовать транзакционно-безопасную таблицу (TST). Текущие TST: BDB и InnoDB. Таблицы GEMINI намечены для MySQL-4.0. Обратите внимание, что MySQL функционирует в режиме AUTOCOMMIT по умолчанию, и MySQLdb считает, что AUTOCOMMIT включен. Чтобы изменить это, используйте инструкции SQL SET AUTOCOMMIT=0.
MySQLdb: Python-интерфейс для MySQL
MySQLdb представляет собой поточно-совместимый интерфейс с популярной СУБД MySQL, который обеспечивает Python API для баз данных. Здесь рассматривается его версия 0.9.1 (автор Andy Dustman, andy@dustman.net). Пакет распространяется по лицензии GPL и доступен для закачки с http://sourceforge.net/projects/mysql-python. Цели проекта:
Требования:
Python 1.5.2 или выше:
Distutils 1.0.2 или выше:
MySQL 3.22.19 или выше.
Некоторые примеры использования
Метод connect() работает почти также, как и с _mysql: import MySQLdb db=MySQLdb.connect(passwd="moonpie",db="thangs") Чтобы выполнить запрос, Вы сначала нуждаетесь в курсоре, а затем Вы можете выполнять запросы на нем. c=db.cursor() max_price=5 c.execute("""SELECT spam, eggs, sausage FROM breakfast WHERE price < %s""", (max_price,))
В этом примере max_price=5. Почему затем в строке использована опция %s? Потому, что MySQLdb преобразует это в литеральное значение SQL, которое является строкой '5'. Когда это закончено, запрос будет фактически таким: "...WHERE price < 5".
Так, а теперь результаты: >>> c.fetchone() (3L, 2L, 0L) В отличие от примера с _mysql, это возвращает одиночный блок результатов, который является строкой, и значения правильно преобразованы.
Как упомянуто ранее, в то время как столбец MySQL INTEGER транслируется в Python integer, UNSIGNED INTEGER может вызвать переполнение, так что эти значения преобразованы в Python long integer. До Python 1.6 long integer сохраняли L, когда были преобразованы в строки с помощью str(). В 1.6 и позже str() не включает L. Конечно, L всегда выводится при использовании repr().
Когда Вы закончили работу с транзакцией, Вы должны выполнить db.commit() или db.rollback(). Если сервер и таблицы не поддерживает транзакции, commit() будет работать, но rollback() вызовет исключительную ситуацию. Обратите внимание, что это методы connection, а не cursor, даже при том, что транзакция запускается через c.execute(...).
Если Вы хотели получить большее количество строк, Вы могли бы использовать c.fetchmany(n) или c.fetchall(). На c.fetchmany(n) параметр n факультативный и имеет значение по умолчанию c.arraysize (обычно 100). Оба этих метода возвращают последовательность строк, или пустую последовательность, если строки уже кончились.
Обратите внимание, что в отличие от вышеупомянутого, c.fetchone() вернет None, когда не имеется больше строк для выборки.
Единственный другой метод, который Вы, очень вероятно, используете, это многострочная вставка: c.execute("""INSERT INTO breakfast (name, spam, eggs, sausage, price) VALUES (%s, %s, %s, %s, %s)""", [ ("Spam and Sausage Lover's Plate", 5, 1, 8, 7.95 ), ("Not So Much Spam Plate", 3, 2, 0, 3.95 ), ("Don't Wany ANY SPAM! Plate", 0, 4, 3, 5.95 )])
Здесь мы вставляем три строки по пять значений в каждой. Обратите внимание, что имеется смесь типов (строки, int, float), хотя все еще используется только %s. А также обратите внимание, что включили только строки формата для одной строки. MySQLdb выбирает и дублирует их для каждой строки.
Объекты Connection
Объекты Connection возвращены функцией connect().
commit() Если база данных и таблица поддерживают транзакции, это передает текущую транзакцию, Иначе этот метод успешно не делает ничего. rollback() Если база данных и таблица поддерживают транзакции, это отменяет текущую транзакцию, Иначе этот метод вызывает исключение NotSupportedError.
Примечание совместимости: старые версии MySQLmodule определяют этот метод, так что он не далет ничего. Это опасное поведение, поскольку успешная обратная перемотка указывает, что текущая транзакция отменена.
cursor([cursorclass]) MySQL не поддерживает курсоры, однако, курсоры легко эмулируются. Вы можете обеспечивать альтернативный класс курсора как факультативный параметр. Если это не представлено, берется значение по умолчанию данное при создании объекта подключения или стандартного класса Cursor. begin() Явно запускает транзакции. Обычно Вы не должны использовать это: выполнение запроса начинает новую транзакцию, если ни одной работающей нет. Если включен AUTOCOMMIT, Вы можете использовать begin() для его временного отключения. AUTOCOMMIT продолжит работу после следующего вызова commit() или rollback.
Объекты Cursor
callproc() Не реализован. close() Закрывает курсор. Будущие операции вызывают исключение ProgrammingError. Если Вы используете курсоры стороны сервера, очень важно закрыть курсор, когда Вы с ним закончили, но перед созданием нового курсора. insert_id() Возвращает последнее значение поля AUTO_INCREMENT, вставленное в базу данных. info() Возвращает некоторую информацию относительно последнего запроса. Обычно Вы не должны проверять это. С заданным по умолчанию курсором любое предупреждение MySQL вызовет исключение Warning. Если Вы используете класс курсора без предупреждений, рекомендую проверять info(). Подробности в документации MySQL на mysql_info(). setinputsizes() Не делает ничего. setoutputsizes() Не делает ничего.
ы использования _mysql
Допустим, что Вы хотите использовать _mysql. Имеются некоторые примеры.
Самое простое подключение к базе данных: import _mysql db=_mysql.connect()
Это создает подключение к серверу MySQL на локальной машине, используя стандартый сокет UNIX, Ваше имя входа в систему (из системной переменной USER), пустой пароль и не применяет команду USE. Возможно, это будет работать у Вас, если Вы установили файл конфигурации (~/.my.cnf ). Но скорее всего Вы должны обеспечить большее количество информации: db=_mysql.connect("localhost","joebob","moonpie","thangs")
Это создает подключение к серверу MySQL на локальной машине, используя TCP на стандартном порте (3306), имя пользовател joebob, пароль moonpie и выбирает начальную базу данных thangs.
Конечно, Вы должны использовать TCP, если работаете с удаленной системой. Здесь я не рассмотрел часть параметров connect(), и Вы обратите внимание, что, если Вы используете позиционные параметры, настроить связь по TCP не так-то просто. Кроме того, сокеты UNIX быстрее. Я предпочитаю использовать параметры ключевого слова: db=_mysql.connect(host="localhost",user="joebob", passwd="moonpie",db="thangs") Это делает точно то же, что делал последний пример, но проще для чтения. Теперь, если Вы действительно хотели использовать сокет UNIX, и Ваше имя входа в систему joebob, Вы могли бы сократить этот пример до: db=_mysql.connect(passwd="moonpie",db="thangs") Имеются некоторые другие параметры, которые Вы можете использовать, и большинство их не так уж и необходимо, кроме одного, о котором чуть ниже. Во всем остальном обратитесь к встроенной документации. Модуль Python 2.1 pydoc представляет собой хороший справочник.
Теперь Вы имеете открытое подключение db и хотите сделать запрос. Не имеется никаких курсоров в MySQL и никакой подстановки параметров, так что Вы должны передать полную строку запроса db.query(): db.query("""SELECT spam, eggs, sausage FROM breakfast WHERE price < 5""") Не имеется никакого значения возврата, но исключительные ситуации могут быть вызваны. Исключительные ситуации определены в отдельном модуле, _mysql_exceptions, но _mysql экспортирует их. Читайте спецификацию DB API (http://www.python.org/topics/database/DatabaseAPI-2.0.html), чтобы выяснить то, чем они являются, или Вы можете использовать MySQLError.
В этой точке Ваш запрос был выполнен, и Вы должны получить результаты. Вы имеете два параметра: r=db.store_result() # ...или... r=db.use_result() Оба метода возвращают объект результата. В чем же разница? А в том, что store_result() возвращает весь набор результатов пользователю немедленно. Если Ваш набор результатов действительно большой, это станет проблемой. Один путь обхода этого состоит в том, чтобы добавить предложение LIMIT к Вашему запросу, чтобы ограничить число возвращенных строк. Но можно использовать use_result(), который хранит набор результатов на сервере и посылает его построчно, когда Вы выбираете. Это связывает ресурсы сервера и подключение: Вы не можете делать больше запросов, пока Вы не выбрали все строки. Вообще я рекомендую использовать store_result(), если Ваш набор результатов не огромен, и Вы не можете использовать LIMIT.
Теперь для фактического получения реальных результатов надо: >>> r.fetch_row() (('3','2','0'),) Первая вещь, которую Вы должны знать: fetch_row() берет некоторые дополнительные параметры. Первый задает, сколько строк (maxrows) должны быть возвращены. По умолчанию, это возвращает одну строку. Это может возвращать меньшее количество строк, чем Вы просите, но никогда не больше. Если Вы устанавливаете maxrows=0, это возвращает все строки набора результатов. Если Вы когда-либо получаете пустой набор, значит Вы исчерпали строки.
Второй параметр (how) сообщает как строка должна представиться. По умолчанию, это ноль, что означает вернуть как набор. how=1 значит вернуть данные как словарь, где ключи представляют собой имена столбца или table.column, если имеются два столбца с тем же самым именем. how=2 аналогично how=1, кроме того, что ключи всегда table.column, это для совместимости со старым модулем Mysqldb.
Другая причуда: известно, что обрабатываются числовые столбцы, почему они возвращены как строки? Потому, что MySQL возвращает все данные как строки просто по определению и ожидает, что Вы преобразуете их непосредственно. Как я понимаю, все данные в базе хранятся именно как строки, как бы они не выглядели снаружи. Это было бы реальной проблемой, но фактически _mysql может делать это для Вас. MySQLdb делает это для Вас сам. Чтобы иметь автоматическое выполненное преобразование типов, Вы должны создать словарь конвертера типов и передать его в connect() как параметр ключевого слова conv.
Ключи в conv должны быть типами столбцов MySQL, которые в C API являются FIELD_TYPE_*. Вы можете получать эти значения так: from MySQLdb.constants import FIELD_TYPE
По умолчанию любой тип столбца, который не может быть найден в conv, возвращен как строка, которая пригодна для самых разных применений. Для наших целей нужно: my_conv = {FIELD_TYPE.LONG: int} Это означает, если это FIELD_TYPE_LONG, обработать это встроенной int(). Обратите внимание, что FIELD_TYPE_LONG представляет собой столбец INTEGER, который соответствует C long, который является также типом, используемым для нормального целого числа в Python. Но остерегайтесь: если это столбец UNSIGNED INTEGER, это может вызвать переполнение. По этой причине MySQLdb фактически использует long(), чтобы сделать преобразование.
Затем, если Вы используете db=_mysql.connect(conv=my_conv...), результаты возвратятся в виде ((3, 2, 0),), который является тем, что и ожидается.
Python
MySQLdb требует Python 1.5.2 или новее. Более ранние версии не будут работать потому, что MySQL нужна поддержка для C long long. Если Вы имеете более раннюю версию Python, обновитесь хотя бы до 1.5.2. Текущая разработка выполнена в Python 2.1, но старый Python 1.5.2 все еще будет поддержан в обозримом будущем.
Трансляция MySQL C API
MySQL C API был обернут объектно-ориентированным способом. Единственные MySQL структуры данных, которые выполнены в данном интерфейсе, это MYSQL (дескриптор подключения базы данных) и MYSQL_RES (дескриптор результата). Вообще, любая функция, которая берет как параметр MYSQL *mysql, теперь представляет собой метод объекта подключения, и любая функция, которая берет MYSQL_RES *result, теперь метод объекта результата. Функции, не требующие ни одной структуры MySQL, выполнены как функции в модуле. Функции, требующие какую-то из других структур данных MySQL, вообще не выполнены. Во всех случаях префикс mysql_ удален из имени. Большинство перечисленных методов conn также доступно как методы объекта MySQLdb Connection. Их использование не переносимо между базами данных.
| C API | _mysql |
| mysql_affected_rows() | conn.affected_rows() |
| mysql_close() | conn.close() |
| mysql_connect() | _mysql.connect() |
| mysql_data_seek() | result.data_seek() |
| mysql_debug() | _mysql.debug() |
| mysql_dump_debug_info | conn.dump_debug_info() |
| mysql_escape_string() | _mysql.escape_string() |
| mysql_fetch_row() | result.fetch_row() |
| mysql_get_client_info() | _mysql.get_client_info() |
| mysql_get_host_info() | conn.get_host_info() |
| mysql_get_proto_info() | conn.get_proto_info() |
| mysql_get_server_info() | conn.get_server_info() |
| mysql_info() | conn.info() |
| mysql_insert_id() | conn.insert_id() |
| mysql_list_dbs() | conn.list_dbs() |
| mysql_list_fields() | conn.list_fields() |
| mysql_list_processes() | conn.list_processes() |
| mysql_list_tables() | conn.list_tables() |
| mysql_num_fields() | result.num_fields() |
| mysql_num_rows() | result.num_rows() |
| mysql_options() | _mysql.connect() |
| mysql_ping() | conn.ping() |
| mysql_query() | conn.query() |
| mysql_real_connect() | _mysql.connect() |
| mysql_real_query() | conn.query() |
| mysql_real_escape_string() | conn.escape_string() |
| mysql_row_seek() | result.row_seek() |
| mysql_row_tell() | result.row_tell() |
| mysql_select_db() | conn.select_db() |
| mysql_stat() | conn.stat() |
| mysql_store_result() | conn.store_result() |
| mysql_thread_id() | conn.thread_id() |
| mysql_use_result() | conn.use_result() |
| CLIENT_* | MySQLdb.constants.CLIENT.* |
| CR_* | MySQLdb.constants.CR.* |
| ER_* | MySQLdb.constants.ER.* |
| FIELD_TYPE_* | MySQLdb.constants.FIELD_TYPE.* |
| FLAG_* | MySQLdb.constants.FLAG.* |
что Вы будете делать, редактирование
Первое, что Вы будете делать, редактирование скрипта setup.py. Имеются некоторые переменные, которые сообщают где искать MySQL include-файлы и библиотеки. Значения корректны для стандартной установки MySQL в Red Hat Linux (6.2) RPM. Если Вы имеете другую платформу, Вы должны будете вычислить нужные значения самостоятельно. Вам почти никогда не придется изменять это. Если Вы имеете старую версию distutils (до 1.0.2), обновитесь или удалите параметры, относительно которых система возражает.
Обратите внимание, что недавние двоичные дистрибутивы с www.mysql.com включают два набора библиотек пользователей: mysqlclient и mysqlclient_r. Последний хранит поточно-безопасные библиотеки, так что используйте именно его, если потоки Вам нужны.
Если Вы имеете динамические библиотеки пользователей (в Linux .so-файлы), они будут использоваться по умолчанию. Если они не в Вашем стандартном пути загрузчика, Вы должны будете установить или откорректировать системную переменную LD_LIBRARY_PATH (в Linux) или ту, которую Ваша платформа требует. Иначе Вы можете скорректировать setup.py, чтобы компоновать со статической библиотекой. Если Вы используете стандартный пакет RPM, с этим не должно быть особых проблем.
ПРЕДУПРЕЖДЕНИЕ: Если Вы используете двоичный пакет Zope, Вы нуждаетесь в выполнении скрипта setup.py программой python из Zope. Иначе Zope (ZMySQLDA) не может найти _mysql.
Если Вы предпочитаете RPM, Вы можете использовать команду bdist_rpm с setup.py. Это только формирует RPM, но не устанавливает его.
Этот модуль должен быть совместим с более старым интерфейсом, написанным Joe Skinner. Однако, старая версия:
MySQLdb полностью новый модуль, распространяемый бесплатно согласно GNU Public License. Никакой код из той версии не используется в MySQLdb.
Zope и ZMySQLDA
Был написан пакет ZMySQLDA для использования с MySQLdb. Это адаптируется из ZOracleDA Digital Creations разработчиков системы Zope.
MySQL- Руководство разработчика
Как я могу получить уникальный ID для последней вставленной строки?
Если Вы вставляете запись в таблицу, содержащую столбец, который имеет атрибут AUTO_INCREMENT, Вы можете получать последнее значение ID вызовом mysql_insert_id().
Вы можете также получать ID, используя функцию LAST_INSERT_ID() в строке запроса, которую Вы передаете mysql_query().
Вы можете проверять, используется ли индекс AUTO_INCREMENT, выполняя следующий код. Это также проверит, был ли запрос INSERT с индексом AUTO_INCREMENT:
if (mysql_error(pmysql)[0]=0) && (mysql_num_fields(result)=0) && (mysql_insert_id(pmysql) != 0) then begin used_id := mysql_insert_id(pmysql); end;
Недавно сгенерированный ID хранится на сервере с привязкой к подключению. Это не будет изменено другим пользователем. Это не будет даже изменено, если Вы модифицируете другой столбец AUTO_INCREMENT не со специальным значением (то есть значением, которое не NULL и не 0).
Если Вы хотите использовать ID, который был сгенерирован для одной таблицы и вставлять его во вторую таблицу, Вы можете использовать инструкции SQL подобно этому: INSERT INTO foo (auto,text) VALUES(NULL,'text'); # generate ID by inserting NULL INSERT INTO foo2 (id,text) VALUES(LAST_INSERT_ID(),'text'); # use ID in second table
Какой результаты я могу получить из запроса?
В дополнение к набору результатов, возвращенному запросом, Вы можете также получать следующую информацию:
Mysql_affected_rows()
tmy_ulonglong mysql_affected_rows(mysql:PMYSQL):TMY_ULONGLONG; stdcall;
Mysql_change_user()
mysql_change_user(mysql: PMYSQL; const user,passwd, db:pchar):TMY_BOOL;stdcall;
Mysql_connect()
mysql_connect(mysql: PMYSQL; const host,user,passwd:pchar):PMYSQL; stdcall;
Mysql_create_db()
mysql_create_db(mysql:PMYSQL; const db:pchar):integer;stdcall;
Mysql_data_seek()
mysql_data_seek(res:PMYSQL_RES;offset:TMY_ULONGLONG); stdcall;
MySQL DELPHI API
Пользователь имеет максимальный размер буфера связи. Размер буфера, который распределен первоначально (16 килобайт), автоматически увеличивается до максимального размера (максимум 16 мегабайт). Поскольку размеры буфера растут только по запросу, просто увеличивая заданное по умолчанию максимальное ограничение, Вы не заставите большее количество ресурсов использоваться. Эта проверка размера обычно применяется в сложных ситуациях.
Буфер связи должен быть достаточно большим, чтобы хранить одиночную инструкцию SQL (для трафика "клиент-на сервер") и одну строку возвращенных данных (для трафика "сервер-на-клиент"). Буфер связи каждого потока будет динамически расширен до максимального ограничения, чтобы обработать любой запрос или строку. Например, если Вы имеете значения BLOB, которые содержат до 16M данных, Вы должны иметь ограничение буфера связи по крайней мере в 16M (на клиенте и на сервере сразу). Заданный по умолчанию максимум пользователя равен 16M, но заданный по умолчанию максимум сервера равен всего 1M. Вы можете увеличивать это, меняя значение параметра max_allowed_packet при запуске сервера.
Сервер MySQL сокращает каждый буфер связи до net_buffer_length байт после каждого запроса. Для клиентуры размер буфера, связанного с подключением, не будет уменьшен, пока подключение не будет закрыто.
Mysql_drop_db()
mysql_drop_db(mysql:PMYSQL; const db:pchar):integer;stdcall;
Mysql_dump_debug_info()
mysql_dump_debug_info(mysql:PMYSQL):integer;stdcall;
Mysql_escape_string()
Это идентично mysql_real_escape_string() за исключением того, что требуется подключение как первый параметр. mysql_real_escape_string() обработает строку согласно текущему (актуальному) набору символов, в то время как mysql_escape_string() игнорирует установку charset.
Mysql_fetch_field()
mysql_fetch_field(res:PMYSQL_RES):PMYSQL_FIELD;stdcall;
Mysql_fetch_field_direct()
mysql_fetch_field_direct(res:PMYSQL_RES; fieldnr:integer):PMYSQL_FIELD;stdcall;
Mysql_fetch_fields()
mysql_fetch_fields(res:PMYSQL_RES):PMYSQL_FIELDS;stdcall;
Mysql_fetch_lengths()
mysql_fetch_lengths(res:PMYSQL_RES):longword;stdcall;
Mysql_fetch_row()
mysql_fetch_row(res:PMYSQL_RES):PMYSQL_ROW;stdcall;
Mysql_field_count()
mysql_field_count(mysql:PMYSQL):longword;stdcall;
Если Вы используете версию MySQL ранее, чем Version 3.22.24, Вы должны вместо этого использовать mysql_num_fields(res:PMYSQL_RES):longword; stdcall;.
Mysql_field_seek()
mysql_field_seek(res:PMYSQL_RES; offset:TMYSQL_FIELD_OFFSET): TMYSQL_FIELD_OFFSET; stdcall;
Mysql_field_tell()
mysql_field_tell(res:PMYSQL_RES):longword;stdcall;
Mysql_get_proto_info()
mysql_get_proto_info(mysql:PMYSQL):longword;stdcall;
Mysql_get_server_info()
mysql_get_server_info(mysql:PMYSQL):pchar;stdcall;
Mysql_insert_id()
mysql_insert_id(mysql:PMYSQL):TMY_ULONGLONG;stdcall;
Mysql_kill()
mysql_kill(mysql:PMYSQL;pid:longword):integer;stdcall;
Mysql_list_dbs()
mysql_list_dbs(mysql:PMYSQL;const wild:pchar):PMYSQL_RES;stdcall;
Mysql_list_fields()
mysql_list_fields(mysql:PMYSQL;const table,wild:pchar):PMYSQL_RES; stdcall;
Mysql_list_processes()
mysql_list_processes(mysql:PMYSQL):PMYSQL_RES;stdcall;
Mysql_list_tables()
mysql_list_tables(mysql:PMYSQL;const wild:pchar):PMYSQL_RES;stdcall;
Mysql_num_fields()
mysql_num_fields(res:PMYSQL_RES):longword;stdcall;
Mysql_num_rows()
mysql_num_rows(res:PMYSQL_RES):TMY_ULONGLONG;stdcall;
Mysql_options()
mysql_options(mysql: PMYSQL; option: TMYSQL_OPTION; const arg: pchar): integer ;stdcall;
Mysql_query()
mysql_query(mysql:PMYSQL; const q:pchar):integer;stdcall;
Mysql_real_connect()
mysql_real_connect(mysql: PMYSQL; const host,user,passwd,db:pchar; port:longword; const unix_socket:pchar; clientflag:longword):PMYSQL;stdcall;
Mysql_real_escape_string()
mysql_real_escape_string(mysql:PMYSQL; wto:pchar; const wfrom:pchar; wfromlength:longword):longword;stdcall;
Mysql_real_query()
mysql_real_query(mysql:PMYSQL; const q:pchar; length:longword):integer;stdcall;
Mysql_row_seek()
mysql_row_seek(res:PMYSQL_RES; offset:PMYSQL_ROW_OFFSET):PMYSQL_ROW_OFFSET;stdcall;
Mysql_row_tell()
mysql_row_tell(res:PMYSQL_RES):PMYSQL_ROWS;stdcall;
Mysql_select_db()
mysql_select_db(mysql:PMYSQL; const db:pchar):integer;stdcall;
Mysql_store_result()
mysql_store_result(mysql:PMYSQL):PMYSQL_RES;stdcall;
Mysql_use_result()
mysql_use_result(mysql:PMYSQL):PMYSQL_RES;stdcall;
Обзор функций Delphi API
Функции, доступные в Delphi API, перечислены ниже и описаны более подробно в следующем разделе. Подробности в разделе "Описание функций Delphi API".
| mysql_affected_rows() | Возвращает число строк измененных последним запросом UPDATE, DELETE или INSERT. |
| mysql_close() | Закрывает подключение к серверу. |
| mysql_connect() | Соединяется с сервером. |
| mysql_change_user() | Меняет пользователя и базу данных на открытом подключении. |
| mysql_create_db() | Создает базу данных. Аналог команды SQL CREATE DATABASE. |
| mysql_data_seek() | Ищет произвольную строку в наборе результатов запросов. |
| mysql_debug() | Делает DBUG_PUSH для заданной строки. |
| mysql_drop_db() | Удаляет базу данных. Эта функция аналогична команде SQL DROP DATABASE. |
| mysql_dump_debug_info() | Заставляет сервер писать информацию отладки в файл регистрации. |
| mysql_eof() | Определяет, читалась или нет последняя строка набора результатов. |
| mysql_errno() | Возвращает код ошибки для вызванной недавно функции MySQL. |
| mysql_error() | Возвращает текстовое сообщение об ошибке для вызванной недавно функции MySQL. |
| mysql_real_escape_string() | Выходит из специальных символов в строке для использования в инструкции SQL, принимающей во внимание текущий набор символов данного подключения. |
| mysql_escape_string() | Выходит из специальных символов в строке для использования в обычной инструкции SQL. |
| mysql_fetch_field() | Возвращает тип следующего поля таблицы. |
| mysql_fetch_field_direct() | Возвращает тип поля таблицы, по номеру поля. |
| mysql_fetch_fields() | Возвращает массив всех структур поля. |
| mysql_fetch_lengths() | Возвращает длины всех столбцов в текущей (актуальной) строке. |
| mysql_fetch_row() | Выбирает следующую строку из набора результатов. |
| mysql_field_seek() | Помещает курсор столбца в определенный параметром столбец. |
| mysql_field_count() | Возвращает число столбцов результата для последнего запроса. |
| mysql_field_tell() | Возвращает позицию курсора поля, используемого для последнего вызова mysql_fetch_field(). |
| mysql_free_result() | Освобождает память, используемую набором результатов. |
| mysql_get_client_info() | Возвращает информацию о версии программы-клиента. |
| mysql_get_host_info() | Возвращает строку, описывающую подключение. |
| mysql_get_proto_info() | Возвращает версию протокола, используемую подключением. |
| mysql_get_server_info() | Возвращает номер версии сервера. |
| mysql_info() | Возвращает информацию относительно недавно выполненного запроса. |
| mysql_init() | Получает или инициализирует структуру MYSQL. |
| mysql_insert_id() | Возвращает ID, сгенерированный для столбца с поддержкой AUTO_INCREMENT предыдущим запросом. |
| mysql_kill() | Уничтожает заданный поток. |
| mysql_list_dbs() | Возвращает имена баз данных, соответствующие простому регулярному выражению. |
| mysql_list_fields() | Возвращает имена полей, соответствующие простому регулярному выражению. |
| mysql_list_processes() | Возвращает список текущих потоков сервера. |
| mysql_list_tables() | Возвращает имена таблиц, соответствующие простому регулярному выражению. |
| mysql_num_fields() | Возвращает число столбцов в наборе результатов. |
| mysql_num_rows() | Возвращает число строк в наборе результатов. |
| mysql_options() | Устанавливает опции связи для вызова mysql_connect(). |
| mysql_ping() | Проверяет работает или нет подключение с сервером, повторно соединяется по мере необходимости. |
| mysql_query() | Выполняет запрос SQL, определенный как строка с нулевым символом в конце. |
| mysql_real_connect() | Соединяется с сервером. |
| mysql_real_query() | Выполняет запрос SQL, определенный как рассчитанная строка. |
| mysql_reload() | Сообщает, чтобы сервер перезагрузил таблицы предоставления привилегий. |
| mysql_row_seek() | Переходит к строке в наборе результатов, используя значение, возвращенное из mysql_row_tell(). |
| mysql_row_tell() | Возвращает позицию курсора строки. |
| mysql_select_db() | Выбирает базу данных. |
| mysql_shutdown() | Закрывает сервер. |
| mysql_stat() | Возвращает состояние сервера. |
| mysql_store_result() | Возвращает полный набор результатов пользователю. |
| mysql_thread_id() | Возвращает ID потока. |
| mysql_thread_safe() | Возвращает 1, если клиент компилируется как поточно-безопасный. |
| mysql_use_result() | Инициализирует копию результата строка в строку. |
Чтобы соединиться с сервером, вызовите mysql_init(), чтобы инициализировать драйвер подключения, затем вызовите mysql_real_connect() с этим драйвером (наряду с другой информацией типа hostname, имени пользователя и пароля). При подключении mysql_real_connect() устанавливает флажок reconnect (часть структуры MYSQL) в значение 1. Этот флажок указывает, что когда запрос не может выполняться из-за потерянного подключения, надо попробовать повторно соединиться с сервером перед отказом. Когда Вы закончите работу с подключением, вызовите mysql_close() для его закрытия.
В то время как подключение активно, пользователь может посылать запросы SQL серверу, применяя функции mysql_query() или mysql_real_query(). Различие между ними в том, что mysql_query() ожидает, что запрос будет определен как строка с нулевым символом в конце, в то время как mysql_real_query() ожидает рассчитанную строку. Если несет в себе двоичные данные (которые сами по себе могут включать нулевые байты), Вы должны использовать только mysql_real_query().
Для каждого запроса не-SELECT (например, INSERT, UPDATE, DELETE), Вы можете выяснить, сколько строк были изменены, вызывая mysql_affected_rows().
Для запросов SELECT Вы получаете выбранные строки в наборе результатов. Обратите внимание, что некоторые инструкции подобны SELECT в том плане, что они возвращают строки. Сюда входят SHOW, DESCRIBE и EXPLAIN. Они должны обработаться тем же самым методом, что и обычный SELECT.
Имеются два пути для пользователя, чтобы обработать наборы результатов. Один путь состоит в том, чтобы получить весь набор результатов, вызывая mysql_store_result(). Эта функция получает с сервера все строки, возвращенные запросом и сохраняет их на клиенте. Второй путь инициализировать построчный набор результатов, вызывая mysql_use_result(). Эта функция инициализирует поиск, но фактически не получает никаких строк.
В обоих случаях Вы обращаетесь к строкам, вызывая mysql_fetch_row(). В случае mysql_store_result() mysql_fetch_row() обращается к строкам, которые уже были выбраны из сервера. В случае же mysql_use_result() mysql_fetch_row() фактически получает строку с сервера самостоятельно. Информация относительно размера данных в каждой строке доступна через вызов mysql_fetch_lengths().
После того, как Вы закончите работу с набором результатов, вызовите mysql_free_result(), чтобы освободить используемую память.
Два механизма поиска дополняют друг друга. Программы пользователя должны выбрать подход, который является наиболее подходящим для их требований. Практически же, клиентура имеет тенденцию обычно использовать mysql_store_result().
Преимущество mysql_store_result() в том, что, поскольку все строки были переданы пользователю, Вы не только можете обращаться к строкам последовательно, Вы можете также двигаться обратно в наборе результатов, используя mysql_data_seek() или mysql_row_seek(), чтобы изменить текущую (актуальную) позицию строки внутри набора результатов. Вы можете также выяснять, сколько там строк, вызывая mysql_num_rows(). С другой стороны, требования к памяти для mysql_store_result() могут быть очень высоки для больших наборов результатов, и Вы, вероятно, столкнетесь с проблемами нехватки памяти.
Преимущество mysql_use_result() в том, что пользователь требует меньшего количества памяти для набора результатов потому, что это поддерживает только одну строку одновременно (и потому, что имеется меньшее количество дополнительных распределений для заголовков, так что mysql_use_result() может быть быстрее). Недостаток: Вы должны обработать каждую строку быстро, чтобы не держать занятым сервер. Вы не имеете произвольного доступа к строкам внутри набора результатов (Вы можете только обращаться к строкам последовательно), и Вы не знаете, сколько строк находится в наборе результатов, пока Вы не получите их все. Кроме того, Вы должны принять все строки, даже если Вы определяете в середине поиска, что уже нашли ту информацию, которую Вы искали.
API позволяет клиентам ответить соответственно на запросы (получая строки только по мере необходимости) без того, чтобы знать, является или нет запрос SELECT. Вы можете делать это, вызывая mysql_store_result() после каждого mysql_query() (или mysql_real_query()). Если обращение к набору результатов прошло успешно, запросом был SELECT, и Вы можете читать строки. Если произошел сбой, вызовите mysql_field_count(), чтобы определить, должен или нет фактически ожидаться результат. Если mysql_field_count() возвращает ноль, запрос не возвратил никаких данных (это показывает, что это был INSERT, UPDATE, DELETE или что-то в этом роде) и не возвратит строки. Если mysql_field_count() отличен от нуля, запрос должен был возвратить строки, но не сделал этого. Это указывает, что запросом был SELECT, который потерпел неудачу.
Вызовы mysql_store_result() и mysql_use_result() позволяют Вам получать информацию относительно полей, которые составляют набор результатов (число полей, их имена, типы и т.п.). Вы можете обращаться к информации поля последовательно внутри строки, вызывая mysql_fetch_field() неоднократно, или по номеру поля внутри строки, вызывая mysql_fetch_field_direct() напрямую. Текущая (актуальная) позиция курсора поля может быть изменена вызовом mysql_field_seek(). Установка курсора поля воздействует на последующие обращения к mysql_fetch_field(). Вы можете также получать информацию для полей в любой момент, вызывая mysql_fetch_fields().
Для обнаружения и сообщения об ошибках MySQL обеспечивает доступ к информации ошибки посредством функций mysql_errno() и mysql_error(). Они возвращают код ошибки или сообщение об ошибке для последней вызванной функции, позволяя Вам определить, когда ошибка произошла, и что это было.
Возвращает число строк, измененных последним
Возвращает число строк, измененных последним UPDATE, удаленных последним DELETE или вставленных последней инструкцией INSERT. Может быть вызвана немедленно после mysql_query() для UPDATE, DELETE или INSERT. Для инструкции SELECT mysql_affected_rows() работает подобно mysql_num_rows().
Пытается устанавливать подключение с сервером MySQL на компьютере host. mysql_connect() должна завершиться успешно прежде, чем Вы сможете выполнить любую из функций API, за исключением mysql_get_client_info().
Значения параметров такие же, как для соответствующих параметров mysql_real_connect() с тем различием, что параметр подключения может быть NULL. В этом случае API распределяет память для структуры подключения автоматически и освобождает ее, когда Вы вызываете mysql_close(). Недостаток этого подхода в том, что Вы не можете получить сообщение об ошибке, если подключение терпит неудачу. Чтобы получать информацию об ошибке из mysql_errno() или mysql_error(), Вы должны обеспечить имеющий силу указатель на структуру MYSQL.
Меняет пользователя и заставляет базу данных, определенную как db, стать заданной по умолчанию (текущей) базой данных на подключении, определенном mysql. В последующих запросах эта база данных будет значением по умолчанию для ссылок на таблицы, которые не включают явный спецификатор базы данных.
Эта функция впервые была представлена в MySQL Version 3.23.3.
mysql_change_user() терпит неудачу, если указанный пользователь не может быть использован, или если он не имеет разрешения использовать эту базу данных. В этом случае пользователь и база данных не будут изменены вообще.
Параметр db может быть установлен в NULL, если Вы не хотите иметь заданную по умолчанию базу данных.
Переходит к произвольной строке в наборе результатов запроса. Это требует, чтобы структура набора результата содержала весь результат запроса, так что mysql_data_seek() может использоваться только в конъюнкции с mysql_store_result(), но никак не с mysql_use_result().
Смещение должно быть значением в диапазоне от 0 до mysql_num_rows(result)-1.
Делает DBUG_PUSH с заданной строкой. Вызов mysql_debug() использует библиотеку отладки Fred Fish. Чтобы использовать эту функцию, Вы должны компилировать библиотеку клиентов так, чтобы поддерживать отладку.
Инструктирует сервер, чтобы писать некоторую информацию отладки в файл регистрации. Отдавший команду пользователь должен иметь привилегию process, чтобы работать.
mysql_eof() определяет, читалась или нет последняя строка набора результатов.
Если Вы приобретаете результат из успешного обращения к mysql_store_result(), клиент получает весь набор в одной операции. В этом случае возврат NULL из mysql_fetch_row() всегда означает, что конец набора результатов был достигнут и не нужно вызвать mysql_eof().
С другой стороны, если Вы используете mysql_use_result(), чтобы инициализировать поиск набора результата, строки набора получены с сервера по одной, поскольку Вы вызываете mysql_fetch_row() неоднократно. Потому что ошибка может происходить на подключении в течение этого процесса, значение NULL из функции mysql_fetch_row() не обязательно означает, что конец набора результатов был достигнут. В этом случае, Вы можете использовать mysql_eof(), чтобы определить, что там случилось. Функция mysql_eof() возвращает значение, отличное от нуля, если конец набора результатов был достигнут и ноль, если произошла ошибка.
Исторически mysql_eof() предшествует стандартной функции MySQL mysql_errno() и mysql_error(). Так как те функции ошибки обеспечивают ту же самую информацию, их использование предпочтительнее mysql_eof(). Фактически, они обеспечивают большее количество информации потому, что mysql_eof() возвращает только булево значение, в то время как функции ошибки указывают причину.
Для подключения, определенного в mysql, mysql_errno() возвращает код ошибки для вызванной функции API, которая может сработать нормально или потерпеть неудачу. Значение возврата 0 означает, что никакой ошибки не произошло. Числа сообщений об ошибках клиента перечислены в файле заголовка MySQL errmsg.h. Серверные ошибки перечислены в mysqld_error.h. В дистрибутиве исходного кода MySQL Вы можете найти полный список сообщений об ошибках и их кодов в файле Docs/mysqld_error.txt.
Для подключения, определенного в mysql, mysql_error() возвращает сообщение об ошибках для вызванной функции API, которая может сработать нормально или потерпеть неудачу. Пустая строка вернется, если никакой ошибки не произошло. Это означает, что следующие тесты эквивалентны:
if (mysql_errno(&mysql)) { // an error occurred } if (mysql_error(&mysql)[0] != '\0') { // an error occurred }
Язык сообщений об ошибках пользователя может быть изменен перекомпиляцией библиотеки клиента MySQL. В настоящее время Вы можете выбирать сообщения об ошибках на нескольких различных языках.
Возвращает определение одного столбца набора результатов как структуру MYSQL_FIELD. Вызовите эту функцию неоднократно, чтобы собрать информацию относительно всех столбцов в наборе результатов. mysql_fetch_field() возвращает NULL, когда все поля уже обработаны или их не было вовсе.
mysql_fetch_field() будет сброшен так, чтобы возвратить информацию относительно первого поля каждый раз, когда Вы выполняете новый запрос SELECT. На поле, возвращенное mysql_fetch_field() также воздействуют обращения к mysql_field_seek().
Если Вы вызвали mysql_query() чтобы выполнить SELECT на таблице, но не вызвали mysql_store_result(), MySQL возвращает заданную по умолчанию длину blob (8K), если Вы вызываете mysql_fetch_field(), чтобы спросить о длине поля типа BLOB. Размер в 8K выбран потому, что MySQL не знает максимальную длину для BLOB. Это должно быть сделано с перестраиваемой конфигурацией когда-нибудь. Как только Вы получили набор результатов, field.max_length хранит длину самого большого значения для этого столбца в специфическом запросе.
Возвращает массив всех структур MYSQL_FIELD для набора результатов. Каждая структура обеспечивает определение поля для одного столбца набора результатов.
Получает код поля fieldnr для столбца внутри набора результатов, возвращает определение поля столбца как структура MYSQL_FIELD. Вы можете использовать эту функцию, чтобы получить описание для произвольного столбца. Значение fieldnr должно быть в диапазоне от 0 до mysql_num_fields(result)-1.
Возвращает длины столбцов текущей (актуальной) строки внутри набора результатов. Если Вы планируете копировать значения поля, эта информация также полезна для оптимизации потому, что Вы можете избежать вызова strlen(). Кроме того, если набор результатов содержит двоичные данные, Вы должны использовать эту функцию, чтобы определить размер данных потому, что функция strlen() возвращает неправильные результаты для любого поля, содержащего символы пробела.
Длина для пустых столбцов и для столбцов, содержащих значения NULL, равна нулю. Чтобы видеть, как отличить эти два случая, обратитесь к описанию mysql_fetch_row().
Получает следующую строку набора результатов. Когда используется после mysql_store_result(), mysql_fetch_row() возвращает NULL, когда не имеется больше строк, чтобы получить. Когда используется после mysql_use_result(), mysql_fetch_row() вернет NULL, когда не имеется больше строк, чтобы получить, или произошла ошибка.
Число значений в строке задано mysql_num_fields(result). Если row хранит значение возврата от обращения к mysql_fetch_row(), указатели на значения меняются с row[0] на row[mysql_num_fields(result)-1]. Значения NULL в строке обозначены указателями NULL.
Длины значений полей в строке могут быть получены, вызывая mysql_fetch_lengths(). Пустые поля и поля, содержащие NULL имеют длину 0. Вы можете отличать их, проверяя указатель для значения поля. Если указатель равен NULL, поле NULL, иначе поле пустое.
Возвращает число столбцов для самого последнего запроса на подключении.
Нормальное использование этой функции: когда mysql_store_result() возвращает NULL (и таким образом Вы не имеете никакого указателя на набор результатов). В этом случае Вы можете вызывать mysql_field_count(), чтобы определить, должен или нет mysql_store_result() произвести не пустой результат. Это позволяет программе пользователя выбрать соответствующее действие без того, чтобы знать, был или нет запрос SELECT (или SELECT-подобным). Пример, показанный ниже иллюстрирует, как это может быть выполнено.
Устанавливает курсор поля к данному смещению. Следующее обращение к mysql_fetch_field() получит определение поля столбца, связанного именно с этим смещением.
Чтобы перейти к началу строки, передайте 0 как значение offset.
Возвращает позицию курсора поля, используемого для последнего mysql_fetch_field(). Это значение может использоваться как параметр для mysql_field_seek().
Освобождает память, распределенную для набора результатов mysql_store_result(), mysql_use_result(), mysql_list_dbs() и другими подобными функциями. Когда Вы закончили работу с набором результатов, Вы должны освободить память, которую он использует, вызывая mysql_free_result().
Возвращает строку, которая представляет версию клиентской библиотеки.
Возвращает строку, описывающую тип используемого подключения, включая имя главного компьютера сервера.
Возвращает код версии протокола, используемой текущим подключением.
Возвращает строку, которая представляет номер версии сервера.
Возвращает строку, обеспечивающую информацию относительно недавно выполненного запроса, но только для инструкций, перечисленных ниже. Для других инструкций mysql_info() всегда возвращает NULL. Формат строки изменяется в зависимости от типа запроса, как описано ниже. Числа только иллюстративны: строка будет содержать значения, соответствующие запросу.
INSERT INTO ... SELECT ... Формат строки: Records: 100 Duplicates: 0 Warnings: 0 INSERT INTO ... VALUES (...),(...),(...)... Формат строки: Records: 3 Duplicates: 0 Warnings: 0 LOAD DATA INFILE ... Формат строки: Records: 1 Deleted: 0 Skipped: 0 Warnings: 0 ALTER TABLE Формат строки: Records: 3 Duplicates: 0 Warnings: 0 UPDATE Формат строки: Rows matched: 40 Changed: 40 Warnings: 0
Обратите внимание, что mysql_info() возвращает значение не-NULL для инструкции INSERT ... VALUES только, если много списков значений было определено в инструкции.
Распределяет или инициализирует объект MYSQL, подходящий для mysql_real_connect(). Если mysql является указателем NULL, функция распределяет память, инициализирует и возвращает новый объект. Иначе объект будет просто инициализирован, и адрес объекта возвращен. Если mysql_init() распределяет новый объект, место будет освобождено, когда будет вызвана mysql_close().
Возвращает ID, сгенерированный предыдущим запросом для столбца с поддержкой AUTO_INCREMENT. Используйте эту функцию после того, как Вы выполнили запрос INSERT для таблицы, которая содержит поле AUTO_INCREMENT.
Обратите внимание, что mysql_insert_id() возвращает 0, если предыдущий запрос не генерирует значение AUTO_INCREMENT. Если Вы должны сохранить значение для последующего неспешного потребления убедитесь, что вызвали mysql_insert_id() немедленно после того запроса, который генерирует значение.
mysql_insert_id() модифицируется после инструкций INSERT и UPDATE, которые генерируют значение AUTO_INCREMENT, или установки значения столбца с помощью LAST_INSERT_ID(expr).
Также обратите внимание, что значение функции SQL LAST_INSERT_ID() всегда содержит самое последнее сгенерированное значение AUTO_INCREMENT, и оно не будет сброшено между запросами потому, что значение этой функции поддерживается сервером.
Просит, чтобы сервер уничтожил поток, определенный как pid.
Возвращает набор результатов, состоящий из имен баз данных на сервере, которые соответствуют простому регулярному выражению, определенному параметром wild. Здесь wild может содержать групповые символы % или _, или может быть NULL, чтобы соответствовать всем базам данных. Вызов mysql_list_dbs() подобен выполнению запроса SHOW databases [LIKE wild].
Вы должны освободить набор результатов с помощью mysql_free_result().
Возвращает набор результатов, состоящий из имен полей в данной таблице, которые соответствуют простому регулярному выражению, определенному параметром wild. Здесь wild может содержать групповые символы % или _, или может быть NULL, чтобы соответствовать всем полям. Вызов mysql_list_fields() подобен выполнению запроса SHOW COLUMNS FROM tbl_name [LIKE wild].
Обратите внимание, что рекомендуется, чтобы Вы использовали SHOW COLUMNS FROM tbl_name вместо mysql_list_fields().
Вы должны освободить набор результатов с помощью mysql_free_result().
Возвращает набор результатов, описывающий текущие потоки сервера. Это тот же самый вид информации, что и сообщаемый командой mysqladmin processlist или запросом SHOW PROCESSLIST.
Вы должны освободить набор результатов с помощью mysql_free_result().
Возвращает набор результатов, состоящий из имен таблиц в текущей базе данных, которые соответствуют простому регулярному выражению, определенному параметром wild. Здесь wild может содержать групповые символы % или _, или может быть NULL, чтобы соответствовать всем таблицам. Вызов mysql_list_tables() подобен выполнению запроса SHOW tables [LIKE wild].
Вы должны освободить набор результатов с помощью mysql_free_result().
Возвращает число столбцов в наборе результатов.
Обратите внимание, что Вы можете получать число столбцов из указателя набора результатов или от дескриптора подключения. Вы используете дескриптор подключения, если mysql_store_result() или mysql_use_result() возвращает NULL (и таким образом Вы не имеете никакого указателя набора результата). В этом случае Вы можете вызывать mysql_field_count() чтобы определить, должен или нет mysql_store_result() произвести непустой результат. Это позволяет программе пользователя выбрать соответствующее действие без того, чтобы знать, был или нет запрос SELECT (или SELECT-подобным). Пример, показанный ниже иллюстрирует, как это может быть выполнено.
Возвращает число строк в наборе результатов.
Использование mysql_num_rows() зависит от того, используете ли Вы mysql_store_result() или mysql_use_result(), чтобы получить набор результатов. Если Вы используете mysql_store_result(), mysql_num_rows() может быть вызван немедленно. Если Вы используете mysql_use_result(), mysql_num_rows() не будет возвращать правильное значение, пока все строки в наборе результатов не будут получены.
Может использоваться, чтобы установить дополнительные параметры связи и действует на поведение подключения. Эта функция может быть вызвана несколько раз, чтобы установить несколько параметров.
mysql_options() должна быть вызвана после mysql_init(), но перед mysql_connect() или mysql_real_connect().
Параметр option представляет собой опцию, которую Вы хотите устанавливать, arg задает значение для опции. Если опция целое число, то arg должен указывать на значение целого числа.
Возможные значения параметров:
| Опция | Тип аргумента | Действие |
| MYSQL_OPT_CONNECT_TIMEOUT | longword | Время ожидания в секундах. |
| MYSQL_OPT_COMPRESS | TMY_BOOL | Использовать сжатый протокол клиент-сервер. |
| MYSQL_OPT_NAMED_PIPE | TMY_BOOL | Использовать именованные каналы, чтобы соединиться с сервером MySQL под NT. |
| MYSQL_INIT_COMMAND | PCHAR | Команда, чтобы выполнить при соединении с сервером MySQL. Будет автоматически выполнена при повторном соединении. |
| MYSQL_READ_DEFAULT_FILE | PCHAR | Читать параметры из указанного файла опций вместо my.cnf. |
| MYSQL_READ_DEFAULT_GROUP | PCHAR | Читать параметры из именованной группы из файла опций my.cnf или файла, определенного в MYSQL_READ_DEFAULT_FILE. |
Обратите внимание, что группа client всегда читается, если Вы используете MYSQL_READ_DEFAULT_FILE или MYSQL_READ_DEFAULT_GROUP.
Определенная группа в файле опций может содержать следующие параметры:
| connect_timeout | Время ожидания в секундах. В Linux это время ожидания также используется для ожидания первого ответа. |
| compress | Использовать сжатый протокол клиент-сервер. |
| database | Соединиться с этой базой данных, если никакая база данных не была определена в команде подключения. |
| debug | Опции для отладки. |
| host | Имя сервера по умолчанию. |
| init-command | Команда, чтобы выполнить при соединении с сервером MySQL. Будет автоматически заново выполнена при повторном соединении, если связь прервалась. |
| interactive-timeout | Аналогично указанию опции CLIENT_INTERACTIVE в mysql_real_connect(). |
| password | Пароль по умолчанию. |
| pipe | Использовать именованные каналы, чтобы соединиться с сервером MySQL, работая под NT. |
| port | Порт по умолчанию. |
| return-found-rows | Сообщить mysql_info() о том, что нужно возвратить найденные строки вместо модифицируемых строк при использовании UPDATE. |
| socket | Сокет по умолчанию. |
| user | Пользователь по умолчанию. |
Обратите внимание, что timeout был заменен на connect_timeout, но timeout будет все еще работать некоторое время для совместимости.
Проверяет работает или нет подключение. В случае неработоспособности будет предпринято автоматическое переподключение.
Эта функция может использоваться клиентом, который долго простаивает, чтобы определить, закрыл или нет сервер подключение, и повторно соединиться с ним в случае необходимости.
Выполняет запрос SQL, указанный строкой с нулевым символом в конце. Запрос должен состоять из одиночной инструкции SQL. Вы не должны добавлять точку с запятой (;) или \g для завершения запроса.
mysql_query() не может использоваться для запросов, которые содержат двоичные данные, взамен Вы должны использовать mysql_real_query(). Двоичные данные могут содержать в себе символ \0, который mysql_query() интерпретирует как конец строки запроса. Если Вы хотите знать, возвратил ли запрос набор результатов или нет, Вы можете использовать mysql_field_count(), чтобы проверить это.
mysql_real_connect() пытается установить подключение с сервером MySQL, запущенным на машине host. mysql_real_connect() должен завершиться успешно прежде, чем Вы сможете выполнить любую из других функций API, за исключением mysql_get_client_info().
Параметры определены следующим образом:
| Имя флажка | Что он делает |
| CLIENT_COMPRESS | Использовать протокол сжатия. |
| CLIENT_FOUND_ROWS | Возвратить число найденных, а не обработанных строк. |
| CLIENT_IGNORE_SPACE | Позволить использовать пробелы после имен функций. Делает все зарезервированные слова именами функций. |
| CLIENT_INTERACTIVE | Позволить interactive_timeout секунд (вместо wait_timeout секунд) бездеятельности перед закрытием подключения. |
| CLIENT_NO_SCHEMA | Не позволять синтаксис db_name.tbl_name.col_name. Это сделано для ODBC. Это заставляет синтаксический анализатор генерировать ошибку, если Вы используете тот синтаксис, который является полезным для заманивания в ловушку ошибок в некоторых программах ODBC. |
| CLIENT_ODBC | Работает клиент ODBC. |
| CLIENT_SSL | Использовать шифрованный протокол SSL. |
Эта функция используется, чтобы создать допустимую строку, которую Вы можете использовать в инструкции SQL.
Строка в from бужет закодирована до экранированной строки SQL, принимая во внимание текущий (актуальный) набор символов подключения. Результат будет помещен в to и завершающий байт пустого указателя допишется автоматически. Символы NUL (ASCII 0), \n, \r, \, ', ", а также Control-Z, будуь экранированы.
Строка, указанная в from должна быть length байтов длины. Вы должны распределить буфер по крайней мере length*2+1 байт. В худшем случае каждый символ должен быть закодирован как использование двух байтов, и Вы нуждаетесь в участке памяти для завершающего байта пустого указателя. Когда mysql_escape_string() завершится, в to будет строка с нулевым байтом в конце. Значение возврата: длина закодированной строки, не включая символ завершения.
Выполняет запрос SQL, указанный в query, который должен быть строкой длиной в length байт. Запрос должен состоять из одиночной инструкции SQL. Вы не должны добавлять точку с запятой (`;') или \g для завершения запроса.
Вы должны использовать mysql_real_query() вместо mysql_query() для запросов, которые содержат двоичные данные, потому, что двоичные данные могут сами содержать символ \0. Кроме того, mysql_real_query() быстрее, чем mysql_query() потому, что не вызывает strlen().
Если Вы хотите знать, возвратил ли запрос набор результатов или нет, Вы можете использовать mysql_field_count(), чтобы проверить это.
Описание функций API
В описаниях ниже параметр или значение возврата NULL означает NULL в смысле языка программирования C, а не MySQL-значение NULL.
Функции, которые возвращают значение, возвращают указатель или целое число. Если не определено иное, функции, возвращающие указатель, возвращают значение не-NULL, чтобы указать успех, или значение NULL, чтобы указать ошибку, а функции, возвращающие число, возвращают целочисленный ноль, чтобы указать успех, или отличное от нуля значение, чтобы указать ошибку. Обратите внимание, что "отличное от нуля" означает только это. Если функциональное описание не говорит иного, не надо проверять результат на соответствие каким-либо числам, кроме нуля.
if (result) /* правильно */ ... error ...
if (result < 0) /* неправильно */ ... error ...
if (result = -1) /* неправильно */ ... error ...
Когда функция возвращает ошибку, подраздел Ошибки описания функции вносит в список возможные типы ошибок. Вы можете выяснить, который из них произошел, вызывая mysql_errno(). Представление строки ошибки может быть получено, вызывая mysql_error().
Ошибки
Аналогично mysql_real_connect().
CR_COMMANDS_OUT_OF_SYNC Команды были выполнены в неподходящем порядке. CR_SERVER_GONE_ERROR Сервер MySQL занят. CR_SERVER_LOST Подключение было потеряно в течение запроса. CR_UNKNOWN_ERROR Произошла неизвестная ошибка. ER_UNKNOWN_COM_ERROR Сервер MySQL не выполняет эту команду (вероятно, старая версия). ER_ACCESS_DENIED_ERROR Пользователь или пароль ошибочен. ER_BAD_DB_ERROR База данных не существует. ER_DBACCESS_DENIED_ERROR Пользователь не имеет прав доступа к базе данных. ER_WRONG_DB_NAME Имя базы данных слишком длинное.
CR_COMMANDS_OUT_OF_SYNC Команды были выполнены в неподходящем порядке. CR_SERVER_GONE_ERROR Сервер MySQL занят. CR_SERVER_LOST Подключение было потеряно в течение запроса. CR_UNKNOWN_ERROR Произошла неизвестная ошибка.
CR_COMMANDS_OUT_OF_SYNC Команды были выполнены в неподходящем порядке. CR_SERVER_GONE_ERROR Сервер MySQL занят. CR_SERVER_LOST Подключение было потеряно в течение запроса. CR_UNKNOWN_ERROR Произошла неизвестная ошибка.
CR_COMMANDS_OUT_OF_SYNC Команды были выполнены в неподходящем порядке. CR_SERVER_GONE_ERROR Сервер MySQL занят. CR_SERVER_LOST Подключение было потеряно в течение запроса. CR_UNKNOWN_ERROR Произошла неизвестная ошибка.
mysql_fetch_lengths() имеет силу только для текущей строки набора результатов. Этот вызов возвращает NULL, если Вы вызываете его перед mysql_fetch_row() или после получения всех строк в результате.
CR_SERVER_LOST Подключение было потеряно в течение запроса. CR_UNKNOWN_ERROR Произошла неизвестная ошибка.
Почему при успехе mysql_query() вызов mysql_store_result() иногда возвращает NULL?
Когда это случается, это означает, что одно из следующего произошло:
Вы можете всегда проверить, должна или нет инструкция произвести непустой результат, вызывая mysql_field_count(). Если mysql_field_count() вернет ноль, результат пуст, и последний запрос был инструкцией, которая не возвращает значения (например, INSERT или DELETE). Если mysql_field_count() вернет не ноль, инструкция должна была произвести не пустой результат.
Вы можете проверить наличие ошибки вызовом mysql_error() или mysql_errno().
показанное ниже, заставляет библиотеку клиентов
Обращение, показанное ниже, заставляет библиотеку клиентов генерировать файл трассировки /tmp/client.trace на машине пользователя:
mysql_debug("d:t:O,/tmp/client.trace");
Типы данных в DELPHI API
TMYSQL Эта структура представляет дескриптор на одно подключение базы данных. Это используется почти для всех функций MySQL. TMYSQL_RES Эта структура представляет результат запроса, который возвращает строки (SELECT, SHOW, DESCRIBE, EXPLAIN). Информация, возвращенная из запроса, названа набором результатов в остатках от этого раздела. TMYSQL_ROW Это тип-безопасное представление одной строки данных. Это в настоящее время выполнено как массив байтовых строк. Вы не можете обрабатывать их как обычные строки с нулевым символом в конце, если значения поля могут содержать двоичные данные потому, что такие значения могут содержать нулевые символы в себе. Строки получены, вызывая функцию mysql_fetch_row(). TMYSQL_FIELD Эта структура содержит информацию относительно поля, например, имя поля, тип и размер. Члены описаны более подробно ниже. Вы можете получать структуры TMYSQL_FIELD для каждого поля, неоднократно вызывая mysql_fetch_field(). Значения полей не являются частью этой структуры, они содержатся в структуре TMYSQL_ROW. TMYSQL_FIELD_OFFSET Это тип-безопасное представление смещения в списке полей MySQL. Используются в вызове mysql_field_seek(). Смещения представляют собой номера полей внутри строки, начиная с нуля. Tmy_ulonglong Тип, используемый для числа строк и для функций mysql_affected_rows(), mysql_num_rows() и mysql_insert_id(). Этот тип обеспечивает диапазон от 0 до 1.84e19. На некоторых системах попытка печатать значение типа Tmy_ulonglong не будет работать. Чтобы отпечатать такое значение, преобразуйте его к типу longint.
Структура TMYSQL_FIELD содержит члены, перечисленные ниже:
name:pchar; Имя поля, как строка с нулевым символом в конце. table:pchar; Имя таблицы, содержащей это поле, если это не расчетное поле. Для расчетных полей, значение table представлено пустой строкой. def:pchar; Значение по умолчанию этого поля, как строка с нулевым символом в конце. Это установлено только, если Вы используете mysql_list_fields(). typ:TFIELD_TYPES; Тип поля. Значение typ может быть один из следующего:
| Значение Typ | Используемый тип |
| FIELD_TYPE_TINY | TINYINT |
| FIELD_TYPE_SHORT | SMALLINT |
| FIELD_TYPE_LONG | INTEGER |
| FIELD_TYPE_INT24 | MEDIUMINT |
| FIELD_TYPE_LONGLONG | BIGINT |
| FIELD_TYPE_DECIMAL | DECIMAL или NUMERIC |
| FIELD_TYPE_FLOAT | FLOAT |
| FIELD_TYPE_DOUBLE | DOUBLE или REAL |
| FIELD_TYPE_TIMESTAMP | TIMESTAMP |
| FIELD_TYPE_DATE | DATE |
| FIELD_TYPE_TIME | TIME |
| FIELD_TYPE_DATETIME | DATETIME |
| FIELD_TYPE_YEAR | YEAR |
| FIELD_TYPE_STRING | Строка (CHAR или VARCHAR) |
| FIELD_TYPE_BLOB | BLOB или TEXT (используйте max_length, чтобы определить максимальную длину поля) |
| FIELD_TYPE_SET | SET |
| FIELD_TYPE_ENUM | ENUM |
| FIELD_TYPE_NULL | NULL |
| FIELD_TYPE_CHAR | Не рекомендуется: используйте FIELD_TYPE_TINY |
length:longword; Ширина поля, как она определена в описании таблицы. max_length:longword; Максимальная ширина поля для набора результатов (длина самого длинного поля для строк в наборе результатов). Если Вы используете mysql_store_result() или mysql_list_fields(), это содержит максимальную длину поля. Если Вы используете mysql_use_result(), значение этой переменной нулевое. flags:longword; Различные биты задают флажки для поля. Значение flags может иметь ноль или большее количество из следующего набора битов:
| Значение Flags | Что это значит |
| NOT_NULL_FLAG | Поле не может быть NULL |
| PRI_KEY_FLAG | Поле часть первичного ключа |
| UNIQUE_KEY_FLAG | Поле часть уникального ключа |
| MULTIPLE_KEY_FLAG | Поле часть неуникального ключа |
| UNSIGNED_FLAG | Поле имеет атрибут UNSIGNED |
| ZEROFILL_FLAG | Поле имеет атрибут ZEROFILL |
| BINARY_FLAG | Поле имеет атрибут BINARY |
| AUTO_INCREMENT_FLAG | Поле имеет атрибут AUTO_INCREMENT |
| ENUM_FLAG | Поле имеет тип ENUM |
| BLOB_FLAG | Поле имеет тип BLOB или TEXT |
| TIMESTAMP_FLAG | Поле имеет тип TIMESTAMP |
| IS_NOT_NULL(flags) | Истина, если это поле определено как NOT NULL |
| IS_PRI_KEY(flags) | Истина, если это поле первичный ключ |
| IS_BLOB(flags) | Истина, если это поле BLOB или TEXT |
Возвращаемые значения
Целое число, большее, чем ноль, указывает количество обработанных строк. Ноль указывает, что никакие записи обработаны не были. -1 указывает, что запрос возвратил ошибку или то, что для запроса SELECT mysql_affected_rows() был вызван до вызова mysql_store_result().
Если определен флажок CLIENT_FOUND_ROWS, при соединение с mysqld mysql_affected_rows() возвратит число строк, согласованных инструкцией WHERE для UPDATE.
Обратите внимание, что, когда использована команда REPLACE, mysql_affected_rows() вернет 2 потому, что в этом случае одна строка была вставлена, а затем дубликат был удален.
Ноль для успеха. Отличное от нуля, если произошла ошибка.
Ноль, если база данных была создана успешно. Отличное от нуля, если в процессе произошла ошибка.
Ноль, если база данных была удалена успешно. Отличное от нуля, если в процессе произошла ошибка.
Ноль, если команда была успешно выполнена. Отличное от нуля, если в процессе произошла ошибка.
Функция mysql_eof() возвращает значение, отличное от нуля, если конец набора результатов был достигнут и ноль, если произошла ошибка.
Значение кода ошибки. 0, если никакая ошибка не произошла.
Символьная строка, которая описывает ошибку. Пустая строка, если никакой ошибки не произошло.
Структура типа MYSQL_FIELD для текущего (актуального) столбца. NULL, если никакие столбцы не обработаны.
Массив структур MYSQL_FIELD для всех столбцов набора результатов.
MySQL- Руководство разработчика
DBI с DBD::mysql
DBI представляет собой универсальный интерфейс для многих баз данных. Это означает, что Вы можете написать скрипт, который работает с многими серверами баз данных без изменений. Вы нуждаетесь в драйвере базы данных (DBD) для каждого типа базы данных. Для MySQL этот драйвер назван DBD::mysql.
Для получения большего количества информации относительно Perl5 DBI, пожалуйста, посетите Web-страницу DBI и прочтите документацию на ней по адресу http://dbi.perl.org/docs/.
Для получения большего количества информации относительно объектно-ориентированного программирования (OOП) как оно определено в Perl5, обратитесь по адресу http://www.perl.com/pub/q/documentation.
Обратите внимание, что, если Вы хотите использовать транзакции с Perl, Вы должны иметь Msql-Mysql-modules версии 1.2216 или новее.
Интерфейс DBI
Портируемые методы DBI
| connect | Устанавливает подключение к серверу. |
| disconnect | Закрывает подключение к серверу. |
| prepare | Готовит инструкцию SQL для выполнения. |
| execute | Выполняет подготовленные инструкции. |
| do | Готовит и выполняет инструкцию SQL. |
| quote | Цитирует строку или значения BLOB, которые будут вставлены. |
| fetchrow_array | Выбирает следующую строку как массив полей. |
| fetchrow_arrayref | Выбирает следующую строку как массив ссылок на поля. |
| fetchrow_hashref | Выбирает следующую строку как ссылку на hashtable. |
| fetchall_arrayref | Выбирает все данные как массив массивов. |
| finish | Заканчивает инструкцию и позволяет системе освободить ресурсы. |
| rows | Возвращается число строк, на которые воздействовал данный запрос. |
| data_sources | Возвращает массив баз данных, доступных на localhost. |
| ChopBlanks | Указывает методам fetchrow_* урезать ли пробелы. |
| NUM_OF_PARAMS | Число параметров в подготовленной инструкции. |
| NULLABLE | Которые столбцы могут быть NULL. |
| trace | Выполнить трассировку для отладки. |
MySQL-специфичные методы
| insertid | Последнее занчение AUTO_INCREMENT. |
| is_blob | Которые столбцы являются значениями BLOB. |
| is_key | Которые столбцы являются ключами. |
| is_num | Которые столбцы являются числовыми. |
| is_pri_key | Которые столбцы являются первичными ключами в данной таблице. |
| is_not_null | Которые столбцы не могут быть NULL. |
| length | Максимально возможные размеры столбца. |
| max_length | Максимальные размеры столбца, фактически представленные в результате. |
| NAME | Имена столбцов. |
| NUM_OF_FIELDS | Число возвращенных полей. |
| table | Имена таблицы в возвращенном наборе. |
| type | Все типы столбцов. |
Методы Perl описаны более подробно в следующих разделах. Переменные, используемые для значений возврата метода, имеют эти значения:
$dbh Дескриптор базы данных $sth Дескриптор оператора Statement handle $rc Код возврата (часто состояние) $rv Значение возврата (часто число строк)
Портируемые методы DBI
connect($data_source, $username, $password) Используйте метод connect, чтобы сделать подключение к базе с источником данных. Значение $data_source должно начинаться с DBI:driver_name:. Пример connect с драйвером DBD::mysql: $dbh = DBI->connect("DBI:mysql:$database", $user, $password); $dbh = DBI->connect("DBI:mysql:$database:$hostname", $user, $password); $dbh = DBI->connect("DBI:mysql:$database:$hostname:$port", $user, $password); Если имя пользователя и/или пароль не определены, DBI использует значения системных переменных DBI_USER и DBI_PASS соответственно. Если Вы не определяете hostname, по умолчанию берется localhost. Если Вы не определяете номер порта, это выставляется в порт MySQL по умолчанию (3306). Начиная с Msql-Mysql-modules Version 1.2009, значение $data_source позволяет модификаторы:
mysql_read_default_file= file_name Читать файл опций filename. mysql_read_default_group=group_name Заданная по умолчанию группа при чтении файла опций, обычно это группа [client]. Если опция mysql_read_default_group определена, группой в файле опций будет [group_name]. mysql_compression=1 Использовать сжатую связь между пользователем и сервером (доступно только в MySQL Version 3.22.3 или позже). mysql_socket=/path/to/socket Определяет имя Unix-сокета, который используется, чтобы подключиться к серверу (доступно только в MySQL Version 3.21.15 или позже).Может быть задано много модификаторов каждому должна предшествовать точка с запятой. Например, если Вы хотите избежать прямого указания имени пользователя и пароля в скрипте DBI, Вы можете брать их из пользовательского файла опций ~/.my.cnf переделав connect следующим образом: $dbh = DBI->connect("DBI:mysql:$database" . ";mysql_read_default_file=$ENV{HOME}/.my.cnf", $user, $password); Это обращение будет читать параметры, определенные для группы [client] в файле опций. Если Вы хотите сделать то же самое, но опции брать из секции [perl], Вы могли бы использовать это: $dbh = DBI->connect("DBI:mysql:$database" . ";mysql_read_default_file=$ENV{HOME}/.my.cnf" . ";mysql_read_default_group=perl", $user, $password);
disconnect Метод disconnect отсоединяет дескриптор базы данных от собственно базы данных. Это надлежит сделать перед завершением программы: $rc = $dbh->disconnect;
prepare($statement) Готовит инструкцию SQL для выполнения ядром базы данных и возвращает операторный дескриптор ($sth), который Вы можете использовать, чтобы вызвать метод execute. Обычно Вы обрабатываете инструкции SELECT (а также SELECT-подобные инструкции, вроде SHOW, DESCRIBE и EXPLAIN) посредством prepare и execute. Например так: $sth = $dbh->prepare($statement) or die "Can't prepare $statement: $dbh->errstr\n";
execute Метод execute выполняет подготовленную инструкцию. Для инструкций не-SELECT, execute возвращает число строк, на которые воздействовал оператор. Если ни на какие строки метод не воздействовал, он вернет 0E0, который Perl обрабатывает как ноль, но расценивает как истину. Если происходит ошибка, execute вернет undef. Для инструкций SELECT execute только запускает запрос SQL в базе данных. Вы должны использовать один из методов fetch_*, описанных ниже, чтобы получить сами данные. Пример: $rv = $sth->execute or die "can't execute the query: $sth->errstr;
do($statement) Метод do готовит и выполняет инструкцию SQL и возвращает число строк , на которые воздействовал оператор. Если ни на какие строки метод не воздействовал, он вернет 0E0, который Perl обрабатывает как ноль, но расценивает как истину. Если происходит ошибка, do вернет undef. Этот метод вообще используется для инструкций не-SELECT, которые не могут быть подготовлены заранее (из-за ограничений драйвера) или тех инструкций, которые не должны быть выполнены больше, чем однажды (вставки, удаления и т.п.). Например: $rv = $dbh->do($statement) or die "Can't execute $statement: $dbh- >errstr\n"; Вообще инструкция do НАМНОГО быстрее, чем prepare/execute для инструкций, которые не содержат параметров. quote($string) Метод quote используется, чтобы обойти любые специальные символы, содержащиеся в строке, и добавить требуемые внешние метки цитирования. Конкретный пример: $sql = $dbh->quote($string)
fetchrow_array Этот метод выбирает следующую строку данных и возвращает ее как массив значений полей. Пример: while(@row = $sth->fetchrow_array) { print qw($row[0]\t$row[1]\t$row[2]\n); }
fetchrow_arrayref Этот метод выбирает следующую строку данных и возвращает ее как ссылку на массив значений полей. Пример: while($row_ref = $sth->fetchrow_arrayref) { print qw($row_ref->[0]\t$row_ref->[1]\t$row_ref->[2]\n); }
fetchrow_hashref Этот метод выбирает строку данных и возвращает ссылку на хэш-таблицу, содержащую пары имя/значение поля. Этот метод не столь эффективен как использование ссылок на массив, как показывается выше. Пример: while($hash_ref = $sth->fetchrow_hashref) { print qw($hash_ref->{firstname}\t$hash_ref->{lastname}\t\ $hash_ref-> title}\n); }
fetchall_arrayref Этот метод используется, чтобы получить все данные (строки), которые будут возвращены из инструкции SQL. Это возвращает ссылку на массив, хранящий ссылки на массивы для каждой строки. Вы обращаетесь к ним или печатаете данные, используя вложенный цикл. Пример: my $table = $sth->fetchall_arrayref or die "$sth->errstr\n"; my($i, $j); for $i (0 .. $#{$table}) { for $j (0 .. $#{$table->[$i]}) { print "$table->[$i][$j]\t"; } print "\n"; }
finish Указывает максимальное количество данных, которое будет выбрано из этого операторного дескриптора. Вы вызываете этот метод, чтобы освободить операторный дескриптор и любые ресурсы системы, связанные с этим. Пример: $rc = $sth->finish;
rows Возвращает число измененных последней командой строк (возможно, удаленных, а не модифицированных). Это обычно используется после того, как выполнена команда не-SELECT через execute. Пример: $rv = $sth->rows;
NULLABLE Возвращает ссылку на массив булевых значений: для каждого элемента массива значение TRUE указывает, что этот столбец может содержать значение NULL. Пример: $null_possible = $sth->{NULLABLE};
NUM_OF_FIELDS Этот атрибут указывает число полей, возвращенных инструкциями SELECT или SHOW FIELDS. Вы можете использовать это для проверки, возвратила ли инструкция результат: нулевое значение указывает на инструкцию не-SELECT, типа INSERT, DELETE или UPDATE. Например: $nr_of_fields = $sth->{NUM_OF_FIELDS};
data_sources($driver_name) Этот метод возвращает массив, содержащий имена баз данных, доступных серверу MySQL на машине localhost. Например: @dbs = DBI->data_sources("mysql");
ChopBlanks Этот атрибут определяет, уберут ли методы fetchrow_* конечные пробелы из возвращенных ими значений. Пример: $sth->{'ChopBlanks'} =1;
trace($trace_level)
trace($trace_level, $trace_filename) Метод trace включает или отключает трассировку. Когда он вызывается как метод класса DBI, это воздействует на трассировку для всех дескрипторов. Когда он вызывается как метод базы данных или инструкции, это воздействует на трассировку для данного дескриптора и любых будущих потомков дескриптора. Установка $trace_level равным 2 обеспечивает детализированную информацию. Установка $trace_level в 0 отключает трассировку. Вывод идет на стандартный вывод ошибки по умолчанию. Если $trace_filename определен, файл будет открыт в режиме дополнения, и вывод для всех прослеженных дескрипторов будет записан в этот файл. Например: # Трассировать все DBI->trace(2); # Регистрировать все в /tmp/dbi.out DBI->trace(2,"/tmp/dbi.out"); # Трассировать этот дескриптор базы данных $dth->trace(2); # Трассировать этот операторный дескриптор $sth->trace(2);Вы можете также допускать трассировку DBI, устанавливая системную переменную DBI_TRACE. Установка ее к числовому значению эквивалентна вызову DBI->(value). Установка ее к имени пути эквивалентна вызову DBI->(2,value).
MySQL-специфичные методы
Методы, показанные ниже, MySQL-специфические, а не часть стандарта DBI. Несколько из них теперь осуждаются: is_blob, is_key, is_num, is_pri_key, is_not_null, length, max_length и table. Где существуют варианты в стандарте DBI, они обязательно отмечены ниже:
insertid Если Вы используете свойство MySQL AUTO_INCREMENT, новые значения будут сохранены здесь. Пример: $new_id = $sth->{insertid}; Как вариант, Вы можете использовать $dbh->{'mysql_insertid'}. is_blob Возвращает ссылку на массив булевых значений: для каждого элемента массива, значение TRUE указывает, что соответствующий столбец имеет тип BLOB. Так, например: $keys = $sth->{is_blob};
is_key Возвращает ссылку на массив булевых значений: для каждого элемента массива, значение TRUE указывает, что соответствующий столбец является ключом (не всегда первичным). Например: $keys = $sth->{is_key};
is_num Возвращает ссылку на массив булевых значений: для каждого элемента массива, значение TRUE указывает, что соответствующий столбец хранит только числовые значения. Пример: $nums = $sth->{is_num};
is_pri_key Возвращает ссылку на массив булевых значений: для каждого элемента массива, значение TRUE указывает, что соответствующий столбец является первичным ключом. Пример: $pri_keys = $sth->{is_pri_key};
is_not_null Возвращает ссылку на массив булевых значений: для каждого элемента массива, значение FALSE указывает, что соответствующий столбец может хранить (но не обязательно хранит в настоящий момент) значения NULL: $not_nulls = $sth->{is_not_null}; Метод is_not_null осуждается, предпочтительно использовать атрибут NULLABLE (описанный выше) потому, что это стандарт DBI. length
max_length Каждый из этих методов возвращает ссылку на массив размеров столбца. Массив length указывает максимальные возможные размеры, которые каждый столбец может иметь (как объявлено в описании таблицы). Массив max_length указывает максимальные размеры, фактически представленные в таблице. Пример: $lengths = $sth->{length}; $max_lengths = $sth->{max_length};
NAME Возвращает ссылку на массив имен столбцов. Пример: $names = $sth->{NAME};
table Возвращает ссылку на массив имен таблиц. Пример: $tables = $sth->{table};
type Возвращает ссылку на массив типов столбцов. Пример: $types = $sth->{type};
MySQL Perl API
Этот раздел документирует интерфейс Perl DBI. Вышеупомянутый интерфейс ранее был назван mysqlperl. Ныне рекомендуемым является DBI/DBD, так что mysqlperl здесь не рассматривается.
Подробности по DBI/DBD
Вы можете использовать команду perldoc, чтобы получить большее количество информации относительно DBI:
perldoc DBI perldoc DBI::FAQ perldoc DBD::mysql
Вы можете также использовать инструментальные средства pod2man, pod2html и им подобные, чтобы транслировать справочник к другим форматам.
Вы можете находить последнюю информацию по DBI на Web-странице DBI по адресу http://dbi.perl.org/docs/.
Проблемы с интерфейсом Perl DBI/DBD
Если Perl сообщает, что не может найти модуль ../mysql/mysql.so, то проблема, вероятно, в том что Perl не может найти общедоступную библиотеку libmysqlclient.so.
Вы можете исправить это любым из следующих методов:
Если Вы получаете следующие ошибки из DBD-mysql, Вы, вероятно, используете gcc (или используете старый двоичный дистрибутив, собранный с помощью gcc):
/usr/bin/perl: can't resolve symbol '__moddi3' /usr/bin/perl: can't resolve symbol '__divdi3'
Добавьте -L/usr/lib/gcc-lib/... -lgcc к команде компоновки, когда библиотека mysql.so собрана (проверьте вывод из make для mysql.so, когда Вы компилируете клиента Perl). Опция -L должна определить имя пути каталога, где файл libgcc.a размещен на Вашей системе.
Другой причиой этой проблемы может быть то, что Perl и MySQL не вместе компилируются gcc. В этом случае, Вы можете устранить несоответствие, компилируя оба пакета gcc.
Если Вы получаете следующую ошибку из Msql-Mysql-modules, когда Вы выполняете тесты: t/00base............install_driver(mysql) failed: Can't load '../blib/arch/auto/DBD/mysql/mysql.so' for module DBD::mysql: ../blib/arch/auto/DBD/mysql/mysql.so: undefined symbol: uncompress at /usr/lib/perl5/5.00503/i586-linux/DynaLoader.pm line 169.
Это означает, что Вы должны включить библиотеку сжатия -lz в строку компновки. Это может сделать следующее изменение в файле lib/DBD/mysql/Install.pm: $sysliblist .= " -lm"; надо поменять на $sysliblist .= " -lm -lz";
После этого, Вы ДОЛЖНЫ выполнить make realclean и затем продолжить установку с самого начала.
Если Вы хотите использовать Perl- модуль на системе, которая не поддерживает динамическую связь (подобно SCO), Вы можете сгенерировать статическую версию Perl, которая включает DBI и DBD-mysql. Соберите версию Perl с модулем DBI и установите поверх текущей версии Perl. Затем Вы используете это, чтобы сформировать версию Perl, которая дополнительно имеет встроенный код DBD, и вот ее-то и надо установить как окончательную.
На SCO Вы должны иметь следующий набор системных переменных:
shell> LD_LIBRARY_PATH=/lib:/usr/lib:/usr/local/lib: /usr/progressive/lib или shell> LD_LIBRARY_PATH=/usr/lib:/lib:/usr/local/lib: /usr/ccs/lib:/usr/progressive/lib:/usr/skunk/lib shell> LIBPATH=/usr/lib:/lib:/usr/local/lib:/usr/ccs/lib: /usr/progressive/lib:/usr/skunk/lib shell> MANPATH=scohelp:/usr/man:/usr/local1/man: /usr/local/man:/usr/skunk/man:
Сначала, создайте Perl, который включает статически связанный DBI, применяя эти команды в каталоге, где размещен Ваш дистрибутив пакета DBI:
shell> perl Makefile.PL -static -config shell> make shell> make install shell> make perl
Затем Вы должны установить новый Perl. Вывод из make perl укажет точную команду make, которую Вы должны выполнить, чтобы осуществить установку. На SCO это make -f Makefile.aperl inst_perl MAP_TARGET=perl.
Затем используйте только что созданный Perl, чтобы создать другой Perl, который также включает и статически связанный модуль DBD::mysql этими командами в каталоге, где размещен Ваш дистрибутив Msql-Mysql-modules:
shell> perl Makefile.PL -static -config shell> make shell> make install shell> make perl
В заключение Вы должны установить этот новый Perl. Снова вывод из команды make perl указывает команду, которую Вам надлежит использовать для выполнения установки.
Установка ActiveState Perl под Windows
Чтобы установить модуль MySQL DBD под ActiveState Perl под Windows, Вы должны сделать следующее:
Вышеупомянутое должно работать по крайней мере с ActiveState Perl Version 5.6.
Если Вы не можете заставить это работать, Вы должны взамен установить драйвер MyODBC и соединяться с сервером MySQL через ODBC: use DBI; $dbh=DBI->connect("DBI:ODBC:$dsn","$user","$password") die "Got error $DBI::errstr when connecting to $dsn\n";
Установка дистрибутива MySQL Perl под Windows
Дистрибутив MySQL Perl включает в себя DBI, DBD:MySQL и DBD:ODBC.
Установка Perl на Unix
Perl-поддержка для MySQL обеспечивается посредством интерфейса пользователя DBI/DBD. Код пользователя Perl DBD/DBI требует Perl Version 5.004 или выше. Интерфейс не будет работать, если Вы имеете старую версию!
MySQL Perl-поддержка также требует, чтобы Вы установили MySQL-поддержку программирования пользователя. Если Вы установили MySQL из файлов RPM, программы пользователя находятся в клиентском RPM, но поддержка программирования пользователя находится в RPM для разработчика. Удостоверьтесь, что Вы в самом деле установили последний RPM.
Начиная с Version 3.22.8, поддержка Perl поставляется отдельно от главного дистрибутива MySQL. Если Вы хотите устанавливать поддержку Perl, нужные файлы можно найти на http://www.mysql.com/Downloads/Contrib.
Дистрибутивы Perl поставляются как сжатые архивы в формате tar и имеют имена подобные MODULE-VERSION.tar.gz, где MODULE представляет собой имя модуля, а VERSION задает номер версии. Вы должны получить пакеты Data-Dumper, DBI и Msql-Mysql-modules и устанавливать их в этом порядке. Процедура установки показывается ниже. Показанный пример подходит для модуля Data-Dumper, но процедура та же самая для всех трех нужных Вам модулей:
Команда make test важна потому, что она проверяет что модуль работает. Обратите внимание, что когда Вы выполняете эту команду в течение установки Msql-Mysql-modules, чтобы проверить код интерфейса, сервер MySQL должен работать, или тест будет терпеть неудачу.
Стоит пересобрать и повторно установить Msql-Mysql-modules всякий раз, когда Вы устанавливаете новый выпуск MySQL, особенно, если Вы обращаете внимание на нехорошие признаки типа того, что все Ваши скрипты DBI после апгрейда MySQL падают.
Если Вы не имеете права установить модули Perl в системный каталог, или чтобы установить локальные модули Perl, следующая ссылка может помочь:
http://www.bluehill.com/support/perl_modules.html
Смотрите под заголовком Installing New Modules that Require Locally Installed Modules.
MySQL- Руководство разработчика
Соглашения по вызову UDF
Основная функция должна быть объявлена как показано ниже. Обратите внимание, что тип возврата и параметры отличаются в зависимости от того, объявите ли Вы тип возврата функции SQL XXX() как STRING, INTEGER или REAL в вызове CREATE FUNCTION:
Для функций типа STRING:
char *xxx(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length, char *is_null, char *error);
Для функций типа INTEGER:
long long xxx(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error);
Для функций типа REAL:
double xxx(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error);
Функции инициализации и деинициализации объявлены подобно этому:
my_bool xxx_init(UDF_INIT *initid, UDF_ARGS *args, char *message); void xxx_deinit(UDF_INIT *initid);
Параметр initid передан всем трем функциям. Он указывает на структуру UDF_INIT, которая используется, чтобы передать информацию между функциями. Члены структуры UDF_INIT перечислены ниже. Функция инициализации должна заполнить любые члены, которые она желает изменить. Чтобы использовать значение по умолчанию для члена, оставьте его неизменным. Перейдем к описанию:
my_bool maybe_null xxx_init() должна установить maybe_null в 1, если xxx() может возвращать NULL. Значение по умолчанию 1, если любой из параметров объявлен как maybe_null. unsigned int decimals Число десятичных цифр. Значение по умолчанию: максимальное количество десятичных цифр в параметрах, переданных основной функции. Например, если функции переданы 1.34, 1.345 и 1.3, значением по умолчанию будет 3, поскольку 1.345 имеет 3 десятичных цифры. unsigned int max_length Максимальная длина результата-строки. Значение по умолчанию отличается в зависимости от типа результата функции. Для строчных функций значение по умолчанию равно длине самого длинного параметра. Для целочисленных функций значение по умолчанию соответствует 21 цифре. Для реальных функций значение по умолчанию 13+количество десятичных чисел, обозначенных как initid->decimals. Для числовых функций длина включает любой знак или десятичные символы отметки. char *ptr Указатель, который функция может использовать для собственных целей. Например, функции могут использовать initid->ptr, чтобы передать распределенную память между функциями. В xxx_init() как обычно распределите память и назначьте ее этому указателю: initid->ptr=allocated_memory; В xxx() и xxx_deinit() обратитесь к initid->ptr, чтобы использовать или освободить память.
Запуск набора тестов MySQL
Система теста состоит из интерпретатора языков тестов (mysqltest), скрипта оболочки, чтобы выполнить все тесты (mysql-test-run), фактических случаев тестов, написанных на специальном языке тестов и их ожидаемых результатов. Чтобы выполнить набор теста на Вашей системе после построения, введите make test или mysql-test/mysql-test-run из корневого каталога исходных текстов. Если Вы установили двоичный дистрибутив, перейдите в корень установки (например, /usr/local/mysql) и скомандуйте scripts/mysql-test-run. Все тесты должны выполниться. Если этого не произошло, пропобуйте выяснить почему и сообщите о проблеме, если это ошибка в пакете MySQL.
Если Вы имеете копию mysqld на машине, где Вы хотите выполнить набор тестов, Вы не должны останавливать ее, если она не использует порты 9306 и 9307. Если один из этих портов применяется, Вы должны отредактировать mysql-test-run и изменить значения главного или подчиненного порта к тому, которое является доступным.
Вы можете запустить индивидуально каждый тест командой mysql-test/mysql-test-run test_name.
Если один тест свалился, проверьте работу mysql-test-run с опцией --force, чтобы проверить, сбоят ли любые другие тесты.
Обработка параметров
Параметр args указывает на структуру UDF_ARGS, члены которой приведены ниже:
unsigned int arg_count Число параметров. Проверьте это значение в функции инициализации, если Вы хотите, чтобы Ваша функция была вызвана со специфическим числом параметров. Например, таким кодом: if (args->arg_count != 2) { strcpy(message,"XXX() requires two arguments"); return 1; }
enum Item_result *arg_type Типы для каждого параметра. Возможные значения типов: STRING_RESULT, INT_RESULT и REAL_RESULT. Чтобы удостовериться, что параметры имеют данный тип и возвращают ошибку, если они к нему не принадлежат, проверьте массив arg_type в функции инициализации. Например: if (args->arg_type[0] != STRING_RESULT args->arg_type[1] != INT_RESULT) { strcpy(message,"XXX() requires a string and an integer"); return 1; } Вы можете использовать функцию инициализации, чтобы установить элементы arg_type к типам, которые Вы хотите получить. Это заставляет MySQL привести параметры к тем типам для каждого обращения к xxx(). Например, чтобы определить первые два элемента как строку и число, сделайте следующее в xxx_init(): args->arg_type[0] = STRING_RESULT; args->arg_type[1] = INT_RESULT;
char **args args->args сообщает информацию функции инициализации относительно общего характера параметров, с которыми Ваша функция была вызвана. Для постоянного параметра (константы) i args->args[i] указывает на значение параметра. Для непостоянного параметра args->args[i] равно 0. Постоянный параметр представляет собой выражение, которое использует только константы, типа 3, 4*7-2 или SIN(3.14). Непостоянный параметр представляет собой выражение, которое обращается к значениям, которые могут изменяться, типа имени столбца или функций, которые вызваны с непостоянными параметрами. Для каждого обращения основной функции args->args хранит фактические параметры, которые переданы для в настоящее время обрабатываемой строки. Функции могут обратиться к параметру i следующим образом:
unsigned long *lengths Для функции инициализации, массив lengths указывает максимальную длину строки для каждого параметра. Для каждого обращения к основной функции lengths хранит фактические длины любых строковых параметров, которые переданы для строки, обрабатываемой в настоящее время. Для параметров типов INT_RESULT или REAL_RESULT lengths хранит максимальную длину параметра (как для функции инициализации).
Расширение набора тестов MySQL
Вы можете использовать язык mysqltest, чтобы писать Ваши собственные случаи теста. К сожалению, авторы пакета еще не написали полную документацию для него. Вы можете, однако, рассматривать текущие случаи теста и использовать их как пример. Следующие пункты должны помочь Вам:
Как сообщать об ошибках в наборе тестов MySQL
Если Ваша версия MySQL не выполняет набор тестов, Вы должны сделать так:
Возвращаемые значения и обработка ошибок
Функция инициализации возвратит 0, если никакая ошибка не произошла, и 1 в противном случае. Если ошибка происходит, xxx_init() должна сохранить сообщение об ошибке с нулевым символом в конце в параметре message. Сообщение будет возвращено пользователю. Буфер сообщений имеет длину в MYSQL_ERRMSG_SIZE символов, но Вы должны попробовать сохранить сообщение в 80 символах так, чтобы это удовлетворило ширине стандартного экрана терминала.
Значение возврата основной функции xxx() зависит от типа. Для функций типов long long и double оно представляет собой собственно функциональное значение. Строковые функции должны возвратить указатель на результат и сохранить длину строки в параметрах length. Здесь result представляет собой буфер длиной в 255 байт. Установите их к содержанию и длине значения. Например:
memcpy(result, "result string", 13); *length=13;
Если Ваши функции строки должны возвратить строку длиннее, чем 255 байт, распределите память для результата через malloc() в функции xxx_init() или в xxx(), а затем освободите память в xxx_deinit(). Вы можете сохранять распределенную память в слоте ptr структуры UDF_INIT для повторного использования в будущем обращении xxx().
Чтобы указывать значение возврата NULL в основной функции, установите is_null в 1:
*is_null=1;
Чтобы указать возврат ошибки в основной функции, установите параметр ошибки (error) в значение 1:
*error=1;
Если xxx() устанавливает *error в 1 для любой строки, функциональное значение NULL для текущей строки и для любых последующих строк, обработанных инструкцией, в которой вызывалась XXX(). Причем, xxx() не будет даже запрашиваться для последующих строк. ПРИМЕЧАНИЕ: В MySQL до версии 3.22.10 Вы должны установить *error и *is_null:
*error=1; *is_null=1;
Компиляция и установка определяемых пользователем функций
Файлы, выполняющие UDF, должны компилироваться и устанавливаться на сервере. Этот процесс описан ниже для примерного UDF-файла udf_example.cc, который включен в дистрибутив исходников MySQL. Этот файл содержит следующие функции:
Динамически загружаемый файл должен компилироваться как разделяемый объектный файл, используя команду:
shell> gcc -shared -o udf_example.so myfunc.cc
Вы можете легко выяснять правильные параметры компилятора для Вашей системы, запуская такую команду в каталоге sql Вашего дерева исходных текстов MySQL:
shell> make udf_example.o
Вы должны выполнить команду компиляции, подобную одной из тех, что отображает make, за исключением того, что Вы должны удалить опцию -c близко к концу строки и добавить -o udf_example.so в самый конец строки. На некоторых системах удалять -c не надо, пробуйте.
Как только Вы скомпилируете общедоступный объект, содержащий UDF, Вы должны установить его и сообщить MySQL о расширении функциональности. Компиляция общедоступного объекта из udf_example.cc производит файл с именем udf_example.so (точное имя может изменяться от платформы к платформе). Скопируйте этот файл в некоторый каталог, где ищет файлы ld, например, в /usr/lib. На многих системах Вы можете устанавливать системную переменную LD_LIBRARY или LD_LIBRARY_PATH, чтобы указать каталог, где Вы имеете Ваши файлы функции UDF. Руководство на dlopen сообщает Вам, которую переменную Вы должны использовать на Вашей системе. Вы должны установить это в mysql.server или в safe_mysqld и перезапустить mysqld.
После того, как библиотека установлена, сообщите mysqld относительно новых функций этими командами:
mysql> CREATE FUNCTION metaphon RETURNS STRING SONAME "udf_example.so"; mysql> CREATE FUNCTION myfunc_double RETURNS REAL SONAME "udf_example.so"; mysql> CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "udf_example.so"; mysql> CREATE FUNCTION lookup RETURNS STRING SONAME "udf_example.so"; mysql> CREATE FUNCTION reverse_lookup RETURNS STRING SONAME "udf_example.so";
Функции могут быть удалены, используя DROP FUNCTION:
mysql> DROP FUNCTION metaphon; mysql> DROP FUNCTION myfunc_double; mysql> DROP FUNCTION myfunc_int; mysql> DROP FUNCTION lookup; mysql> DROP FUNCTION reverse_lookup;
Инструкции CREATE FUNCTION и DROP FUNCTION модифицируют системную таблицу func в базе данных mysql. Имя функции, тип и общедоступное библиотечное имя будут сохранено в таблице. Вы должны иметь привилегии insert и delete для базы данных mysql, чтобы создавать и удалять свои функции.
Вы не должны использовать CREATE FUNCTION, чтобы добавить функцию, которая уже была создана. Если Вы должны повторно установить функцию, сначала удалите ее через вызов DROP FUNCTION и затем повторно установите ее с помощью CREATE FUNCTION. Вы должны сделать это, например, если Вы откомпилировали новую версию Вашей функции, чтобы mysqld обновил используемую им версию. Иначе сервер продолжит применять старую версию.
Активные функции будут перезагружены при каждом перезапуске сервера, если Вы не запускаете mysqld с опцей --skip-grant-tables. В этом случае инициализация UDF будет пропущена, а UDF-функции станут недоступными. Активная функция представляет собой функцию, загруженную через CREATE FUNCTION, но не удаленную DROP FUNCTION.
Анализ процедур
analyse([max elements,[max memory]])
Эта процедура определена в sql/sql_analyse.cc. Она исследует результат, полученный из Вашего запроса, и возвращает анализ результатов:
SELECT ... FROM ... WHERE ... PROCEDURE ANALYSE([max elements,[max memory]])
Добавление новой функции, определяемой пользователем
Для работы механизма UDF функции должны быть написаны на C или C++, а Ваша операционная система должна поддерживать динамическую загрузку. Дистрибутив исходников MySQL включает файл sql/udf_example.cc, который определяет 5 новых функций. Консультируйтесь с этим файлом, чтобы видеть, как работают соглашения о вызовах UDF.
Чтобы mysqld мог использовать UDF, Вы должны конфигурировать MySQL с опцией --with-mysqld-ldflags=-rdynamic. Причина этого в том, что на многих платформах (включая Linux) Вы можете загружать динамическую библиотеку (вызовом dlopen()) из статически скомпонованной программы, которая собрана с опцией --with-mysqld-ldflags=-all-static, но если Вы хотите использовать UDF, который должен обратиться к символам из mysqld (подобно примеру methaphone в sql/udf_example.cc, который использует default_charset_info), Вы должны компоновать программу с -rdynamic. Подробности на man dlopen.
Для каждой функции, которую Вы хотите использовать в инструкциях SQL, Вы должны определить соответствующую функцию на C или на C++. В обсуждении ниже имя ``xxx'' используется для имени функции примера. Здесь XXX() (верхний регистр) указывает SQL-обращение к функции, и xxx() (нижний регистр) указывает C/C++-обращение к функции.
Функции, которые Вы пишете на C/C++ для реализации интерфейса с XXX():
xxx() (обязательна) Основная функция. Это то место, где функциональный результат вычислен. Соответствие между типом SQL и типом возврата Вашей функции на C/C++ показывается ниже:
| SQL-тип | C/C++-тип |
| STRING | char * |
| INTEGER | long long |
| REAL | double |
xxx_init() (опциональна) Функция инициализации для xxx(). Это может использоваться для:
xxx_deinit() (опционально) Функция деинициализации для xxx(). Это должно освободить любую память, распределенную функцией инициализации.
Когда инструкция SQL вызывает XXX(), MySQL вызывает функцию инициализации xxx_init(), чтобы позволить ей выполнить любую требуемую настройку, типа проверки параметра или распределения памяти. Если xxx_init() возвращает ошибку, инструкция SQL будет прервана с сообщением об ошибке, причем главная и деинициализационная функции не будут вызваны, что стоит иметь в виду при распределении памяти. Иначе основная функция xxx() будет вызвана один раз для каждой строки. После того, как все строки были обработаны, вызывается функция xxx_deinit(), так что она может выполнить требуемую очистку.
Все функции должны быть безопасны для потоков (не только основная функция, но и остальные: инициализация и деинициализация идут в поточном режиме!). Это означает, что Вам не позволят распределить любые глобальные или менять статические переменные! Если Вы нуждаетесь в памяти, Вы должны распределить ее в xxx_init() и непременно освободить в xxx_deinit().
Добавление новых функций в MySQL
Есть два способа добавить новую функцию в MySQL:
Каждый метод имеет свои проблемы:
Независимо от метода, который Вы используете, чтобы добавить новые функции, они могут использоваться точно так же как местные функции типа ABS() или SOUNDEX().
Добавление новых процедур в MySQL
В MySQL Вы можете определять процедуру на C++, которая может обращаться и изменять данные в запросе прежде, чем они отправятся к пользователю. Модификация может быть выполнена на уровне строки или GROUP BY.
Авторы пакета создали процедуру примера в MySQL Version 3.23, чтобы показать Вам, что там может быть выполнено.
Дополнительно авторы рекомендуют Вам посмотреть файл mylua, который Вы можете найти в каталоге Contrib. Вы можете использовать язык LUA, чтобы загрузить процедуру в mysqld прямо во время выполнения.
Добавление новых встроенных функций
Процедура для добавления новой встроенной функции описана ниже. Обратите внимание, что Вы не можете добавлять встроенные функции к двоичному дистрибутиву потому, что процедура включает изменение исходного текста MySQL. Вы должны скомпилировать MySQL самостоятельно из исходников. Также обратите внимание, что, если Вы мигрируете на другую версию MySQL (например, когда новая версия выпущена), Вы будете должны повторить процедуру с новой версией.
Чтобы добавить новую встроенную функцию MySQL, нужно:
Все функции должны быть поточно-безопасными (другими словами, не используйте любые глобальные или статические переменные в функциях без того, чтобы защитить их через mutex).
Если Вы хотите возвращать NULL из ::val(), ::val_int() или ::str() Вы должны установить null_value в 1 и вернуть из функции 0.
Для объектной функции ::str() имеются некоторые дополнительные хитрости, которые надо знать:
Набор тестов MySQL
До недавнего времени основной набор теста был основан на составляющих собственность данных заказчика и по этой причине не был публично доступен. Единственный публично доступная часть процесса тестирования состояла из теста crash-me, эталонного теста Perl DBI/DBD, находящегося в каталоге sql-bench, и разнообразных тестов, размещенных в каталоге tests. Отсутствие стандартизированного публично доступного набора тестов сделало трудным для пользователей и разработчиков тестирование кода MySQL. Чтобы исправить эту ситуацию, авторы пакета создали совершенно новую систему тестов, которая теперь включена в исходные и двоичные дистрибутивы, начиная с Version 3.23.29.
Текущий набор тестов не проверяет все в MySQL, но должен охватить наиболее очевидные ошибки в обработка кода SQL, OS/library проблемы и тестирование репликации. Конечная цель состоит в том, чтобы иметь тесты, покрывающие 100% кода. Вы можете предоставить тесты, которые исследуют функциональные возможности, критичные для Вашей системы, поскольку это гарантирует, что все будущие выпуски MySQL будут хорошо работать с Вашими прикладными программами.
Начинка MySQL
Эта глава описывает много вещей, которые Вы должны знать при работе на коде MySQL. Если Вы планируете способствовать MySQL разработке, иметь доступ к коду отлаживаемых версий или хотите только следить за разработкой, поставьте дерево исходников для разработки. Если Вы заинтересованы внутренней организацией MySQL, Вы должны также подписаться на специальный список рассылки internals@lists.mysql.com.
Написание процедур
На сегодняшний день единственной документацией для этого является исходный код пакета.
Вы можете найти всю информацию относительно процедур, исследуя файлы:
Потоки в MySQL
Сервер MySQL создает следующие потоки:
mysqladmin processlist показывает только подключения, потоки репликации и INSERT DELAYED.
Синтаксис CREATE FUNCTION/DROP FUNCTION
CREATE [AGGREGATE] FUNCTION function_name RETURNS {STRING|REAL|INTEGER} SONAME shared_library_name DROP FUNCTION function_name
Определяемые пользователем функции (user-definable function, UDF) представляют собой способ расширить MySQL новой функцией, которая работает подобно местным (встроенным) функциям MySQL типа ABS() или CONCAT().
AGGREGATE новая опция для MySQL Version 3.23. Функция с AGGREGATE работает точно так же, как и встроенная функция GROUP, подобно SUM или COUNT().
CREATE FUNCTION сохраняет имя функции, тип и общедоступное библиотечное имя в таблице mysql.func системы. Вы должны иметь привилегии insert и delete для базы данных mysql, чтобы создавать и удалять функции.
Все активные функции перезагружаются при каждом запуске сервера, если Вы не запускаете mysqld с опцией --skip-grant-tables. В этом случае инициализация пропущена, и UDF станут недоступны. Активная функция представляет собой такую функцию, которая была загружена с помощью CREATE FUNCTION, но не была удалена через вызов DROP FUNCTION.
Для работы механизма UDF функции должны быть написаны на C или C++, Ваша операционная система должна поддерживать динамическую загрузку, и mysqld должен быть откомпилирован динамически (не статически).
MySQL- Руководство разработчика
Использование данного интерфейса
Имена методов базируются на C API без префикса mysql_. Если метод породил некую ошибку, возникает исключительная ситуация MysqlError. Загрузка модуля mysql выполняется указанием require "mysql".
Класс Mysql. Методы:
Используется для Mysql#options()
Псевдонимы: connect(), new()
Псевдоним: quote()
Псевдоним: client_info()
Объектные методы:
Псевдоним: connect()
Псевдоним: quote()
Псевдоним: host_info()
Псевдоним: proto_info()
Псевдоним: server_info()
Объектные переменные:
Если true, query() действует как store_result() и возвращает объект MysqlRes. Значение по умолчанию: true.
Класс MysqlRes. Методы:
Итераторы:
x представляет собой массив значений столбца.
x представляет собой хэш значений столбца, а ключ является именем столбца.
Класс MysqlField. Объектные переменные (только для чтения):
Объектные методы в классе:
Возвращает строку в формате "#".
Класс MysqlError. Объектные переменные (только для чтения):
Это MySQL Ruby API. Он
Это MySQL Ruby API. Он отвечает за реализацию ряда функций, аналогичных MySQL C API.
Для исправной работы интерфейса требуются, как минимум:
Автор: TOMITA Masahiro (, http://www.tmtm.org/mysql).
Порядок установки интерфейса
Сначала введите команды: # ruby extconf.rb # make
Скрипт extconf.rb понимает следующие опции:
Каталог заголовков MySQL. По умолчанию это /usr/local/include.
Каталог библиотек MySQL. По умолчанию это /usr/local/lib.
Аналогично заданию параметров --with-mysql-include=dir/include и --with-mysql-lib=dir/lib
Теперь введите команду: # ruby -I. ./test.rb hostname user passwd
Скрипт test.rb имеет несколько аргументов: имя хоста сервера MySQL, имя пользователя MySQL и его пароль.
Теперь введите команду: # make install
Если Вы получили ошибку, например, libmysqlclient not found, при тестировании, следует в явном виде задать каталог библиотек в вызове make: # env LD_RUN_PATH=каталог_с_libmysqlclient.so # make
Если используется статическая библиотека libmysqlclient.a, понадобятся некоторые дополнительные библиотеки. Подправьте скрипт extconf.rb и включите в нем "have_library('m')" и "have_library('z')".
Библиотека-оболочка mysql для C++
Автор: Roland Haenel (rh@ginster.net). Эта программа является public domain. Распространять и использовать ее можно совершенно свободно.
Это маленькая оболочка для C++, которая написана вокруг базисной клиентской библиотеки mysql. Целью было создание единого универсального интерфейса для следующих баз данных:
Но потому, что mysql намного лучше прочих, контекст этой реализации немного изменился. Теперь стало нужно обеспечить удобный в работе и безопасный интерфейс доступа к mysql.
Программа примера может быть найдена в example.cc. Некоторые слова относительно классов библиотеки:
Класс Database обеспечивает интерфейс связи с базой данных mysqld. Следующие методы выполнены:
Фактически это не делает ничего в настоящее время, но вызовите его перед выполнением чего-нибудь еще. Это может быть важно для будущих выпусков.
Может быть вызван в любое время. Возвращает состояние подключения: DB_CONNECTION_NONE, DB_CONNECTION_OK или DB_CONNECTION_BAD.
Если произошла ошибка, возвращает текст, описывающий ошибку
Соединяется с базой данных db на машине host. Обратите внимание, что параметр port в настоящее время еще не задействован.
Закрывает текущее подключение.
Пока не реализовано.
void Database::exec(DBResult *res, char *sqlFormat, ...);
Выполнить произвольную команду SQL. Первая форма возвращает экземпляр класса DBResult (даже если имелся сбой). Последняя форма повторно использует уже созданный экземпляр класса DBResult.
Возвращает состояние транзакции, связанное с экземпляром класса. Значения могут быть следующими: #define DB_COMMAND_OK 0 // OK: команда выполнена #define DB_EMPTY_QUERY 1 // Запрос не вернул данных #define DB_TUPLES_OK 2 // Запрос вернул данные #define DB_ERROR 5 // Ошибка в команде #define DB_BAD_RESPONSE 6 // Неправильный ответ сервера #define DB_UNEXPECTED 7 // Непонятная ошибка
Возвращает число выбранных записей (если status() == DB_TUPLES_OK).
Возвращает число полей в записи (если status() == DB_TUPLES_OK).
Возвращает имя поля n.
Возвращает размер в байтах поля с номером n.
Возвращает размер в байтах поля с именем name.
Устанавливает внутренний курсор на запись tuple. Она будет возвращена следующим вызовом getTuple().
Возвращает одну запись. Вызов getTuple()[0] вернет значение первого поля и т.д.
Прямой доступ к записи. Для последовательного доступа, пожалуйста, не используйте этот метод. Применяйте вместо него сочетание seekTuple()/getTuple().
MySQL- Руководство разработчика
Хитрости в реализации
def DateFromTicks(ticks): return apply(Date,time.localtime(ticks)[:3])
def TimeFromTicks(ticks): return apply(Time,time.localtime(ticks)[3:6])
def TimestampFromTicks(ticks): return apply(Timestamp,time.localtime(ticks)[:6])
class Error(exceptions.StandardError): pass
class Warning(exceptions.StandardError): pass
class InterfaceError(Error): pass
class DatabaseError(Error): pass
class InternalError(DatabaseError): pass
class OperationalError(DatabaseError): pass
class ProgrammingError(DatabaseError): pass
class IntegrityError(DatabaseError): pass
class DataError(DatabaseError): pass
class NotSupportedError(DatabaseError): pass На C Вы можете использовать API PyErr_NewException(fullname,base,NULL), чтобы создать объекты исключительной ситуации.
Интерфейс модулей
Доступ к базе данных сделан доступным через объекты подключения. Модуль должен обеспечивать конструктор для них:
connect(parameters...) Конструктор для создания подключения с базой данных. Возвращает объект подключения. Требуется ряд параметров, которые являются зависимыми от базы данных.
Эти глобальные переменные модуля должны быть определены:
apilevel Строковая константа, устанавливающая поддержанный уровень DB API. В настоящее время допустимы только строки '1.0' и '2.0'. Если не задана, предполагается уровень интерфейса Database API 1.0. threadsafety Целочисленная константа, устанавливающая уровень безопасности потоков, который интерфейс поддерживает. Возможные значения:
| 0 | Потоки не могут совместно использовать модуль. |
| 1 | Потоки могут совместно использовать модуль, но не подключения. |
| 2 | Потоки могут совместно использовать модуль и подключения. |
| 3 | Потоки могут совместно использовать модуль, курсоры и подключения. |
Совместное использование в вышеупомянутом контексте означает, что два потока могут использовать ресурс без того, чтобы применять mutex-семафор, чтобы выполнить блокировку ресурса. Обратите внимание, что Вы не можете всегда делать внешние ресурсы поточно-безопасными управляя доступом, использующим mutex: ресурс может полагаться на глобальные переменные или другие внешние источники данных, которые находятся вне Вашего управления!
paramstyle Строковая константа. Устанавливает тип маркера параметра, форматирующего ожидаемый интерфейсом. Возможные значения:
| 'qmark' | Стиль метки запроса, например, '...WHERE name=?' |
| 'numeric' | Числовой, позиционный стиль, например, '...WHERE name=:1' |
| 'named' | Именованный стиль, например, '...WHERE name=:name' |
| 'format' | Формат кодов ANSI C printf, например, '...WHERE name=%s' |
| 'pyformat' | Расширенные форматные коды языка Python, например, '...WHERE name=%(name)s' |
Модуль должен делать всю информацию об ошибках доступной через эти исключительные ситуации или через подклассы от них:
Warning Исключительная ситуация для важных предупреждений подобно усечениям данных при вставке и т. д. Это должно быть подклассом от Python StandardError. Error Исключительная ситуация, которая является основным классом для всех других исключительных ситуаций ошибки. Вы можете использовать это, чтобы захватить все ошибки с одиночной частью 'except'. Предупреждения не считаются ошибками и таким образом не должны использовать этот класс как ядро. Это обязательно должно быть подклассом Python StandardError. InterfaceError Исключительная ситуация для ошибок, которые связаны с интерфейсом базы данных, а не с самой базой данных. Это должно быть подклассом Error. DatabaseError Исключительная ситуация для ошибок, которые связаны с самой базой данных. Это должно быть подклассом Error. DataError Исключительная ситуация для ошибок, которые появляются из-за проблем с обработанными данными, подобно делению на ноль, числовое значение вне диапазона и т.д. Это должно быть подклассом DatabaseError. OperationalError Исключительная ситуация для ошибок, которые связаны с работой с базой данных и не обязательно подконтрольны программисту, например, непредвиденное разъединение, имя источника данных не найдено, транзакция не могла быть обработана, ошибка распределения памяти произошла в течение обработки и т.д. Это должно быть подклассом от DatabaseError. IntegrityError Исключительная ситуация вызывается, когда воздействуют на реляционную целостность базы данных, например, произошла ошибка проверки внешних ключей. Это должно быть подклассом от DatabaseError. InternalError Исключительная ситуация для случаев, когда база данных сталкивается с внутренней ошибкой, например, курсор больше не имеет силу, транзакция вышла из синхронизации, либо случилось что-то в этом роде. Это должно быть подклассом от DatabaseError. ProgrammingError Исключительная ситуация для ошибок программирования, например, таблица не найдена или уже существует, ошибка синтаксиса в инструкции SQL, неправильное число определенных параметров и т.д. Это должно быть подклассом DatabaseError.
NotSupportedError Исключительная ситуация для ситуации, когда использовался метод или API базы данных, который не поддержан базой данных, например, запрашивается rollback() на подключении, которое не поддерживает транзакции или имеет выключенные транзакции. Это должно быть подклассом DatabaseError.
Если база данных не поддерживает функциональные возможности, требуемые методом, интерфейс должен породить исключительную ситуацию в случае, если метод используется.
Можно также не реализовывать метод вообще, тогда Python сам сгенерирует исключительную ситуацию AttributeError в случае, если метод запрошен. Это позволяет программисту проверять возможности базы данных, используя функцию hasattr().
Это размещение наследования исключительной ситуации: StandardError |__Warning |__Error |__InterfaceError |__DatabaseError |__DataError |__OperationalError |__IntegrityError |__InternalError |__ProgrammingError |__NotSupportedError
Обратите внимание: значения этих исключительных ситуаций не определены. Они должны дать пользователю информацию о том, что пошло не так.
представляет несколько важных нововведений
Python Database API 2. 0 представляет несколько важных нововведений по сравнению с версией 1.0. Некоторые из этих изменений делают невозможным применять старые скрипты с новой версией DB API.
Известные проблемы
Хотя спецификация версии 2.0 разъясняет много вопросов, которые были оставлены открытыми в версии 1.0, некоторые все еще остаются проблемами:
Объекты курсоров
Эти объекты представляют курсор базы данных, который используется, чтобы управлять контекстом операции выборки.
Объекты курсоров должны отвечать на следующие методы и атрибуты:
description Этот атрибут только для чтения: последовательность последовательностей с 7 элементами. Каждая из этих последовательностей содержит информацию, описывающую один столбец результата: (name, type_code, display_size, internal_size, precision, scale, null_ok). Этот атрибут будет None для операций, которые не возвращают строки, или если курсор не имел операции, вызываемой через метод executeXXX().
Код type_code может интерпретироваться, сравнивая его с Type Objects, определенными в разделе ниже.
rowcount Этот атрибут только для чтения определяет число строк, обработанных последним вызовом executeXXX() (для SQL-инструкций, вроде select) или затронутых запросом (для SQL-инструкций, подобных update или insert). Атрибут равен -1 в случае, если никакой executeXXX() не выполнился на курсоре. callproc(procname[,parameters]) Этот метод факультативный: все базы данных обеспечивают хранимые процедуры. Вызывает хранимую процедуру базы данных с данным именем. Последовательность параметров должна содержать одну запись для каждого параметра, который процедура ожидает. Результат обращения будет возвращен как изменяемая копия входной последовательности. Входные параметры оставлены нетронутыми, выводимые и вводимо-выводимые параметры будут заменены на возможно новые значения. Процедура может также обеспечивать набор результатов как вывод. Это затем должно быть сделано доступным через стандартные методы fetchXXX(). close() Закрывает курсор немедленно и делает его непригодным, начиная с текущего момента. При попытке что-либо с ним сделать еще, будет вызвана исключительная ситуация Error (или ее подкласс). execute(operation[,parameters]) Препарирует и выполняет операцию базы данных (запрос или команду). Параметры можно обеспечивать как последовательность или отображение. Переменные определены в специфической для базы данных записи. Значения возврата не определены.
Ссылка на операцию будет сохраняться курсором. Если тот же самый объект операции передан снова, то курсор может оптимизировать поведение. Это наиболее эффективно для алгоритмов, где много раз используется та же самая операция, но с разными параметрами. Для достижения максимальной эффективности при многократном использовании операции, самое лучшее использовать метод setinputsizes(), чтобы определить типы параметра и размеры. Для параметра допустимо не соответствовать предопределенной информации: реализация должна это скомпенсировать, возможно, с потерей эффективности.
Параметры могут быть также определены как список, чтобы, например, вставить много строк в одной операции, но этот вид использования не рекомендуется: лучше пользуйтесь executemany().
executemany(operation,seq_of_parameters) Готовит операцию базы данных (запрос или команду), а затем выполняет это для всех последовательностей параметров или отображений, найденных в последовательности seq_of_parameters.
Модули могут выполнить этот метод, используя многократные обращения к методу execute() или используя операции массива, чтобы база данных обработала всю последовательность в целом в одном обращении.
Те же самые комментарии, что касаются execute(), также применяются к этому методу. Значения возврата не определены.
fetchone() Выбирает следующую строку набора результатов запросов, возвращая одиночную последовательность или None, когда больше нет доступных данных. Исключительная ситуация Error (или ее подкласс) произойдет, если предыдущее обращение к executeXXX() не производило никакого набора результатов. fetchmany([size=cursor.arraysize]) Выбирает следующую строку набора результатов запросов, возвращая последовательность последовательностей (например, список tuples). Пустая последовательность будет возвращена, когда больше нет доступных строк. Число строк, которое надо выбрать за обращение, определено параметром. Если это не задано, arraysize курсора определяет число строк, которые будут выбраны. Метод должен пробовать выбирать так много строк, как уаазано параметром. Если это невозможно из-за определенного числа строк, меньшее количество строк может быть возвращено.
Исключительная ситуация Error ( или ее подкласс) произойдет, если предыдущее обращение к executeXXX() не производило никакого набора результатов.
Обратите внимание, что имеются сложности с эффективностью, включаемые с параметром размера. Для достижения оптимальной эффективности, обычно самое лучшее использовать arraysize.
fetchall() Выбирает все оставшиеся строки результата запроса, возвращая их как последовательность последовательностей (например, список tuples). Обратите внимание, что атрибут arraysize курсора может воздействовать на эффективность этой операции. Исключительная ситуация Error (или ее подкласс) произойдет, если предыдущее обращение к executeXXX() не производило никакого набора результатов. nextset() Этот метод факультативный, поскольку не все базы данных поддерживают многократные наборы результатов.
Этот метод будет переводить курсор к следующему доступному набору, отбрасывая любые остающиеся строки из текущего (актуального) набора.
Если не имеется больше никаких наборов, метод возвращает None. Иначе он возвращает значение true, и последующие обращения к методам выборки возвратят строки из следующего набора результатов.
Исключительная ситуация Error (или ее подкласс) произойдет, если предыдущее обращение к executeXXX() не производило никакого набора результатов.
Обратите внимание, что интерфейс может выполнять выборку строки, используя массивы и другие оптимизацию. Не гарантируется, что обращение к этому методу только переместит связанный курсор вперед.
arraysize Этот атрибут для чтения-записи определяет число строк, которое надо выбрать с помощью fetchmany() за раз. Значение по умолчанию 1 (выбрать одиночную строку результатов)
Реализации должны отслеживать это значение применительно к методу fetchmany(), но никто не запрещает реально работать с базой данных каким-либо иным способом. Это может также использоваться в реализации метода executemany().
setinputsizes(sizes) Это может использоваться перед обращением для executeXXX() к предопределенным областям памяти для параметров операции. sizes определен как последовательность: один элемент для каждого входного параметра. Элемент должен быть Type Object, который соответствует вводу, который будет использоваться, или это должно быть целым числом, определяющим максимальную длину параметра строки. Если элемент равен None, то никакая предопределенная область памяти не будет зарезервирована для этого столбца (это полезно, чтобы избегать предопределенных областей для больших вводов). Метод не является обязательным для использования и реализации. setoutputsize(size[,column]) Устанавливает размер буфера столбца для выборок больших столбцов (например, LONG, BLOB и им подобных). Столбец определен как индекс в последовательности результатов. Отсутствие определения column установит заданный по умолчанию размер для всех больших столбцов в курсоре. Метод не является обязательным для использования и реализации.
Объекты подключения
Объекты подключения должны отвечать на следующие методы:
close() Закрыть подключение немедленно. Подключение будет непригодным, начиная с этого момента. Если с ним попытаться что-то сделать, будет вызвана исключительная ситуация Error (или подкласс от нее). То же самое применяется ко всем объектам курсора, пробующим использовать подключение. commit() Передать любую ждущую обработки транзакцию на базу данных. Обратите внимание, что если база данных поддерживает auto-commit, это свойство надо заранее выключить. Метод интерфейса можно обеспечивать, чтобы иметь возможность отмены изменений.
Модули баз данных, которые не поддерживают транзакции, должны выполнить этот метод с не имеющими силу функциональными возможностями.
rollback() Этот метод факультативный, поскольку не все базы данных обеспечивают поддержку транзакции. В случае если база данных обеспечивает транзакции, этот метод заставляет базу данных откатиться обратно к началу любой ждущей обработки транзакции. Закрытие подключения без того, чтобы завершить транзакцию, сначала заставит выполниться неявную обратную перемотку. cursor() Возвращает новый объект курсора, использующий подключения. Если база данных не обеспечивает прямое понятие (концепцию) курсора, модуль должен будет подражать курсорам, используя другие средства для соответствия спецификации.
Параметры конструктора подключения должны быть выполнены как параметры ключевого слова для более интуитивного использования и следовать этому порядку параметров:
| dsn | Источник данных как строка | обязательно |
| user | Имя пользователя как строка | опционально |
| password | Пароль пользователя как строка | опционально |
| host | Имя хоста | опционально |
| database | Имя базы данных | опционально |
Например, конструктор подключения мог бы выглядеть следующим образом: connect(dsn='myhost:MYDB',user='guido',password='234+$').
Этот API был определен, чтобы
Этот API был определен, чтобы привести к одному знаменателю модули Python, которые используются, чтобы обратиться к базам данных. Этот документ описывает Python Database API 2.0. Спецификация интерфейса состоит из нескольких разделов:
Комментарии и вопросы относительно этой спецификации могут быть направлены на .
Для получения большего количества информации относительно связи с помощью интерфейса базы данных с Python и о доступных пакетах изучите руководство на http://www.python.org/topics/database.
Типы конструкторов и объектов
Многие базы данных должны иметь ввод в специфическом формате для связывания с входными параметрами операции. Например, если ввод предназначен для столбца DATE, то это будет связано с базой данных в специфическом формате строки. Подобные проблемы существуют для столбцов "Row ID" или больших двоичных элементов (например, столбцов blob или RAW). Это представляет проблемы для Python, начиная с параметров для метода без контроля типов executeXXX(). Когда модуль базы данных видит строковый объект, он не знает сходу, как с ним быть.
Чтобы преодолеть эту проблему, модуль должен обеспечить конструкторы, определенные ниже, чтобы создать объекты, которые могут хранить специальные значения. При передаче к методам курсора, модуль может затем обнаружить соответствующий тип входного параметра и обработать его соответственно.
Атрибут description объекта курсора возвращает информацию относительно каждого из столбцов результата запроса. Здесь type_code должен быть равен одному из Type Objects, определенных ниже. Эти самые Type Objects могут быть равны больше, чем одному коду типа (например, DATETIME может быть равен кодам типа для столбцов даты, времени и метки времени).
Модуль экспортирует следующие конструкторы:
Date(year,month,day) Эта функция создает объект, хранящий значение даты. Time(hour,minute,second) Эта функция создает объект, хранящий значение времени. Timestamp(year,month,day,hour,minute,second) Эта функция создает объект, хранящий значение метки времени. DateFromTicks(ticks) Эта функция создает объект, хранящий значение даты с данного значения импульсов сигнала времени (число секунд, начиная с epoch, согласно стандартному модулю Python time). TimeFromTicks(ticks) Эта функция создает объект, хранящий значение времени с данного значения импульсов сигнала времени (число секунд, начиная с epoch, согласно стандартному модулю Python time). TimestampFromTicks(ticks) Эта функция создает объект, хранящий значение метки времени с данного значения импульсов сигнала времени (число секунд, начиная с epoch, согласно стандартному модулю Python time). Binary(string) Эта функция создает объект, способный хранить строковое двоичное значение типа long. STRING Этот объект используется, чтобы описать столбцы в базе данных, которые являются основанными на строках (например, типа CHAR). BINARY Этот объект используется, чтобы описать двоичные (long) столбцы в базе данных (например, LONG, RAW, BLOB). NUMBER Этот объект используется, чтобы описать числовые столбцы в базе данных. DATETIME Этот объект используется, чтобы описать столбцы даты/времени в базе данных. ROWID Этот объект используется, чтобы описать "Row ID" столбец в базе данных.
SQL-значение NULL представляется на вводе и выводе как Python None.
Обратите внимание: использование Unix-импульсов сигнала времени для связи с помощью интерфейса базы данных может вызвать проблемы из-за ограниченного диапазона даты, который они покрывают.
Интерфейс базы данных может поддерживать
Интерфейс базы данных может поддерживать именованные курсоры, позволяя задавать методу параметр-строку. Это свойство пока не является частью спецификации, так как оно сильно усложняет семантику методов fetchXXX().
Модуль использует метод __getitem__ объекта параметров, чтобы отобразить позиции (целые числа) или имена (строки) к значениям параметра. Это учитывает последовательности и отображения, которые нужно использовать как ввод.
Значение передается базе данных напрямую. В практических условиях это означает, что входное значение непосредственно используется как значение в операции. Пользователь не должен требоваться, чтобы экранировать значение так, чтобы оно могло использоваться: значение должно быть равно фактическому параметру для базы данных.
Атрибут rowcount может быть реализован так, что модифицирует значение динамически. Это может быть полезно для баз данных, которые возвращают используемые значения rowcount только после первого обращения к методу fetchXXX().
MySQL- Руководство разработчика
Доступ к данным
К данным в текущей строке в наборе результатов можно обращаться, вызывая GetField или GetFieldN. GetField вызывается с именем поля как параметр и возвращает символьный указатель на данные или символьный указатель на EOF в случае сбоя. GetFieldN работает подобным способом, за исключением того, что GetFieldN вызывается с номером желательного поля (отсчет начинается с 0).
Файлы заголовков
В настоящее время все подпрограммы MyC включены в один файл заголовков database.h. Имя этого файла не критическое и может быть изменено в любое время, чтобы удовлетворить потребности специфического проекта.
Этот файл должен быть включен первым, также нужно включить stdio.h и stdlib.h. Если директива #define MYC_DEBUG помещена перед включением database.h, то обширный код отладки будет записан в поток stderr.
Инициализация
При вызове OpenDatabase() с именем базы данных, которая будет открыта, именем хоста, именем пользователя и паролем функция инициализирует прикладную программу и открывает выбранную базу данных. EOF возвращен при сбое, NULL возвращен при успехе.
Вызов OpenRecordset() со строкой представляющей собой корректный запрос SQL, открывает набор результатов, который содержит результаты запроса. OpenRecordset() возвращает EOF при ошибке и NULL при успехе. Число записей в наборе результатов может быть получено вызовом RecordCount(), который возвращает число записей в наборе результатов как целое число без знака.
Компиляция
Программы MyC компилируются аналогично любым другим программам, использующим MySQL C API.
Ограничения
MyC не предназначен, чтобы открывать больше, чем один набор результатов за раз. Поддержка нескольких наборов результатов будет в следующем выпуске.
Если набор результатов не имеет уникального ключа, связанного с каждой записью, то Delete() удалит только первое соответствие названной записи. Это отличие от модели DAO, в которой удаляется только в настоящий момент указанная запись, неважно первая она или нет.
Сейчас MyC работает только под Linux, но планируется перенос на другие версии UNIX. Попыток переноса на платформу Windows не было.
Никаких тестов на утечки памяти пока не проводилось для MyC.
Пожалуйста не забудьте, что этот код ALPHA, так что он постоянно будет меняться. В коде почти наверняка есть ошибки, так что будьте осторожны с применением его в ответственных участках своих программ. У автора все работает должным образом, должно бы и у Вас работать, но никаких гарантий пока дать не могу.
Перемещение внутри набора результатов
Набор результатов может быть пройден и изучен с помощью вызовов MoveNext, MovePrev, MoveFirst и MoveLast, которые перемещают в следующий, предыдущий, первый и в последний результат в наборе результатов соответственно. Если набор результатов некорректен, эти подпрограммы возвращают значение EOF, иначе они возвращают NULL.
Получение информации
В настоящее время поддерживаются следующие информационные подпрограммы, RecordCount(), FieldCount(), AbsolutePosition() и RecordsetEOF(). RecordCount возвращает целое число без знака, указывающее текущее число записей в наборе результатов. FieldCount возвращает число полей в строке набора результатов. FieldValue вызывается с номером поля и возвращает его значение, в то время как FieldName тоже вызывается с номером поля, но возвращает уже его имя. AbsolutePosition возвращает номер строки текущей строки в наборе результатов. RecordsetEOF возвращает TRUE, если не имеется никаких имеющих силу записей в наборе результатов, или если текущая строка в конце или начале набора результатов, и никаких имеющих силу записей не осталось, чтобы прочитать их из набора записей. MoveLast и MoveFirst устанавливают RecordsetEOF в TRUE.
Разработчик пакета
Автор этого пакета: Ed Carp. Связаться с ним можно по erc@pobox.com. Есть и веб-страница www.pobox.com/~erc. Он технический администратор и коммерческий программный разработчик, с обширным опытом в управлении проектами от начала до конца, а также в разработке программ на C и VB.
Удаление данных
Вызов Delete() с именем таблицы удалит текущую строку из таблицы. Если имеются строки с двойными данными, только первая строка будет удалена.
Все и сразу
Прикладные программы очень просто писать с MyC. В следующих примерах существует таблица test в базе данных mysql, а в ней есть 5 записей заданных следующим образом:
+--------+-----+ | name | num | +--------+-----+ | item 0 | 0 | | item 1 | 1 | | item 2 | 2 | | item 3 | 3 | | item 4 | 4 | +--------+-----+
Предположим, например, что прикладная программа должна сделать запрос к базе данных и записать все данные в поток stdout:
#include "database.h" main () { int i;
OpenDatabase("mysql", NULL, NULL, NULL); OpenRecordset("select * from test"); while(RecordsetEOF () != EOF) { for (i = 0; i < FieldCount(); i++) printf("%s\t", GetFieldN(i)); puts(""); MoveNext(); } CloseRecordset(); CloseDatabase(); exit(0); }
Немного более сложный пример иллюстрирует добавление, изменение и удаление данных. Этот пример будет формировать таблицу test, вносить в список все данные в таблице, затем просматривать таблицу, заменяя item 3 на item 5 и попутно удаляя item 4:
#include "database.h" main () { int i; char buf[10], buf2[5];
OpenDatabase("mysql", NULL, NULL, NULL); OpenRecordset("delete from test"); CloseRecordset(); OpenRecordset("select * from test"); for (i = 0; i < 5; i++) { AddNew(); sprintf(buf, "item %d", i); sprintf(buf2, "%d", i); SetField("name", buf); SetField("num", buf2); Update("test"); } Refresh(); MoveFirst(); while (RecordsetEOF () != EOF) { for (i = 0; i < FieldCount (); i++) printf("%s\t", GetFieldN(i)); puts(""); MoveNext(); } MoveFirst (); while (RecordsetEOF () != EOF) { printf ("Looking at '%s'\n", GetField ("name")); if (strcmp(GetField("name"), "item 3") == 0) { puts("Changing data"); Edit(); SetField("name", "item 5"); Update("test"); } if (strcmp(GetField("name"), "item 4") == 0) { puts("Deleting data"); Delete("test"); } MoveNext(); } CloseRecordset(); CloseDatabase(); exit(0); }
MyC представляет собой набор простых
MyC представляет собой набор простых подпрограмм C, предназначенных, чтобы сделать создание прикладных программ для использования с базой данных MySQL проще, особенно для тех, кто знаком с Microsoft DAO engine model (используемой в пакетах Microsoft Access и Microsoft Visual Basic).
MyC использует подобную модель, чтобы обратиться к данным внутри базы данных: OpenDatabase, чтобы открыть базу данных, OpenRecordset, чтобы открыть набор результатов, Move, чтобы двигаться внутри набора результатов, AddNew/Edit и Update/Delete, чтобы добавлять, редактировать или удалять данные внутри базы данных.
Запись данных
Данные могут быть записаны в таблицу одним из двух путей: вызовом OpenRecordset() с запросом INSERT INTO или UPDATE (или любой другой имеющей силу в этом отношении инструкцией SQL), или использованием встроенных функций AddNew или Edit.
AddNew() вызывается без параметров и устанавливает внутренние флажки так, что последующее обращение к Update() генерирует инструкцию SQL INSERT INTO. Точно так же Edit() вызывается без параметров и устанавливает внутренние флажки так, что последующее обращение к функции Update() сгенерирует инструкцию SQL UPDATE.
Чтобы устанавливать индивидуальные поля используются SetField, SetFieldN или SetFieldB. SetField вызывается с двумя параметрами: именем поля, которое будет установлено, и значением для него. Точно так же вызывается и SetFieldN, но первый параметр задает номер поля, а не его имя. SetFieldB используется с двоичными данными, и преобразует двоичные данные и NULL в форму, которая может быть сохранена. Обратите внимание, что SetFieldB перезаписывает указанные строки. Никакого средства пока не сделано для преобразования чистых двоичных данных, хотя можно вызывать mysql_escape_string() и передавать возвращенный указатель функциям SetField или SetFieldN.
Важно обратить внимание, что SetField и подобные подпрограммы сохраняют только указатель на данные, которые будут записаны, а не сами данные.
В конце концов поля установлены, Update() вызван с именем таблицы, которую нужно модифицировать. Update() вернет EOF при ошибке или NULL при успехе.
После того, как данные добавлены или модифицированы в таблице, иногда полезно иметь текущий (актуальный) набор записей, отражающий измененные данные. Вызов Refresh() заново выполнит запрос, выполненный последним OpenRecordset() (до 4096 байт) и эквивалентен вызову OpenRecordset(), за исключением того, что текущая строка та же, что и перед вызовом Refresh().
MySQL- Руководство разработчика
MyDAO: библиотека-оболочка для C++
Версия v0.1 (19-Feb-2000). Автор: Satish (spitfire@pn3.vsnl.net.in). Лицензия: Feel free to use/copy/modify/add bugs/find bugs, but keep the author informed.
Руководство программиста
dbconnect class: Один объект подключения должен быть создан. Это ответственно за соединение с сервером MySQL и открытие базы данных. Свойства:
Connected равно true, если подключение к серверу MySQL работает.
DBase является указателем на структуру MYSQL. Это требуется, чтобы открыть набор результатов.
Методы:
Пытается соединиться с сервером MySQL, используя указанные параметры хоста, порта, имени пользователя и пароля. Если подключение успешно установлено, свойство Connected будет true.
Разъединяет текущее подключение с сервером MySQL.
Открывает базу данных db. Если все в порядке, вернет true.
Пример: dbconnect MyConnect; char host[]="localhost"; char port[]="3306"; char name[]="satish"; char pwd[]=""; char db[]="orders";
MyConnect.Connect(host, port, name, pwd); if (MyConnect.Connected) cout << "Connected" << endl; else { cout << "Connection failed" << endl; return; } if (!MyConnect.OpenDB(db)) { cout << "Can not open selected database" << endl; return; } else { cout << "Opened datbase: " << db << endl; // open recorset(s)... // Manipulate data... } MyConnect.Disconnect();
recordset class: Любое количество наборов результатов может быть создано из этого класса. Он имеет много свойств для простого манипулирования данными.
Свойства:
Источник записей, из которых данные должны обрабатываться. Это должна быть SQL-инструкция SELECT, возвращающая записи.
Число строк в открытом наборе результатов.
Может использоваться только с Update, AddNew или Delete. Число строк фактически обработанных сервером.
Конец набора результатов. True, если Вы двигаетесь в последнюю строку.
Начало набора результатов. True, если Вы двигаетесь первую строку. Замечание: EOR и BOR вместе будут равны true, если RecordCount=0.
Методы:
Открывает набор результатов основанный на SQL-инструкции select.
Закрывает набор результатов. Он должен быть закрыт, чтобы освободить память, используемую им.
Перемещается в следующую строку набора результатов. Если уже достигнута последняя строка, в ней и останется.
Перемещается в предыдущую строку набора результатов. Если уже достигнута первая строка, в ней и останется.
Перемещается в первую строку набора результатов.
Перемещается в последнюю строку набора результатов.
Возвращает содержание поля FName.
Устанавливает содержание поля FName в значение Value. Изменения будут отброшены, если после установки значения не используется метод Update/AddNew.
Должен использоваться перед методами SetField и Update, иначе все изменения будет отброшены.
Используется, чтобы добавить новую строку в набор результатов. Для работы этого метода набор результатов должен быть основан на таблице. Метод Update должен использоваться после установки всех значений поля. Определение WHERE не должно использоваться в методе Update, если оно уже используется с методом AddNew. Свойство AffectedRows выдаст число добавленных строк.
Используется, чтобы редактировать или добавить строку вместе с методами Edit/AddNew. Определение WHERE не должно использоваться с AddNew.
Применяется, чтобы удалить строки из набора результатов.
Изменения, сделанные методом Update, невидимы, если метод Refresh не используется. Обновите набор результатов немедленно после Update.
Аналогично GetField, но вместо имени поля используется его код (номер).
Аналогично SetField, но вместо имени поля используется его код (номер).
Пример 1: // Продолжение примера из dbconnect. // Откроем таблицу заказчиков (customers) и распечатаем // все записи из нее. recordset MySet; char sql[]="SELECT * FROM customers";
MySet.OpenRecordset(MyConnect.DBase, sql); if (MySet.EOR && MySet.BOR){ cout << "No records found" << endl; return; } else { // Show number of records cout << "No. of records: " << MySet.RecordCount << endl; // Show all records while (!MySet.EOR) { cout << MySet.GetField("or_id") << "\t"; cout << MySet.GetField("customers") << "\t"; cout << MySet.GetField("city") << endl; MySet.MoveNext(); } }
Пример 2: // Добавление новой строки в таблицу заказчиков. MySet.AddNew(); MySet.SetField("cs_id", "7"); MySet.SetField("name", "Satish"); MySet.SetField("city", "Pune"); MySet.Update(""); // where не используется! MySet.Refresh(); // Сделаем изменения видимыми.
Пример 3: // Изменение имени заказчика. MySet.Edit(); MySet.SetField("cs_id", "7"); MySet.SetField("name", "Suresh"); MySet.SetField("city", "Pune"); MySet.Update("or_id=7"); // where здесь необходимо использовать. MySet.Refresh(); // Сделаем изменения видимыми.
Пример 4: // Удаление записи. MySet.Delete("name='Suresh'"); MySet.Refresh(); // Сделаем изменения видимыми.
Пример 5: // Закроем набор результатов после употребления. Это ОБЯЗАТЕЛЬНО! MySet.CloseRecordset();
Что еще надо сделать:
MySQL- Руководство разработчика
Модуль MySQLDataset
Этот модуль содержит все классы необходимые, чтобы поддерживать основной класс TMySQLDataset.
Компонент: TMySQLDataset.
Типы: TMySQLEvent, TMySQLLocateOptions.
Константы: DefaultMacroChar='|', DefaultTermChar=';'.
TMySQLDataset
Модуль: MySQLDataset.
Описание
Это основной класс, используемый в Вашей прикладной программе. Он был назван именно Dataset, а не Query или Table потому, что он может легко использоваться как стандартный TTable или TQuery. Поскольку этот класс связывается и работает с сервером MySQL, он делает доступными для использования все инструкции SQL. По умолчанию используется концепция макросов (Macros) в командах SQL. Эти макрокоманды очень легко могут быть заблокированы или удалены из значения по умолчанию SQL.
Кроме того, являясь прямым поточным подключением к серверу MySQL, класс был получен непосредственно из TDataset и таким образом поддержан всеми компонентами для работы с базами данных, включая TDatasource. Этот компонент имеет все стандартные свойства и методы.
Из-за отсутствия поддержки курсоров на стороне сервера в MySQL, этот компонент полагается на хорошо разработанные таблицы по умолчанию, то есть Ваши таблицы должны по крайней мере иметь первичный ключ. Если Вы отменяете заданные по умолчанию инструкции SQL, Вы можете сами определять, когда, что и над чем будет выполнено.
Компонент TMySQLDataset
Свойства
Active!AL("Active_Property") AffectedRows AfterCancel!AL("AfterCancel_Property") AfterClose!AL("AfterClose_Property") AfterDelete!AL("AfterDelete_Property") AfterEdit!AL("AfterEdit_Property") AfterInsert!AL("AfterInsert_Property") AfterOpen!AL("AfterOpen_Property") AfterPost!AL("AfterPost_Property") AfterRefresh!AL("AfterRefresh_Property") AfterScroll!AL("AfterScroll_Property") BeforeCancel!AL("BeforeCancel_Property") BeforeClose!AL("BeforeClose_Property") BeforeDelete!AL("BeforeDelete_Property") BeforeEdit!AL("BeforeEdit_Property") BeforeInsert!AL("BeforeInsert_Property") BeforeOpen!AL("BeforeOpen_Property") BeforePost!AL("BeforePost_Property") BeforeRefresh!AL("BeforeRefresh_Property") BeforeScroll!AL("BeforeScroll_Property") AllFieldValues CachedUpdates DatabaseName FieldName Filter Filtered MacroChar MacroCount Macros MacrosEnabled MasterFields MasterSource MultiKeyFields MySQLFields MySQLRecords MySQLTables PrimaryKeyFields ReadOnly RealSQL Records Server ShareConnection SQL SQLBatch SQLDelete SQLInsert SQLUpdate TableName UniqueKeyFields
Методы
Create!AL("Create_Method") Destroy!AL("Destroy_Method") BookmarkValid!AL("BookmarkValid_Method") CompareBookmarks!AL("CompareBookmarks_Method") CreateBlobStream!AL("CreateBlobStream_Method") EscapeStr ExecBatch ExecSQL ExecSQLBatch GetFieldData!AL("GetFieldData_Method") GetMacroValue HexStr Locate!AL("Locate_Method") LocateRecord LocateRecordOption Lookup!AL("Lookup_Method") MacroByName ParseSQL QuoteStr ClearMacros ConnectEvent
События
OnCalcFields!AL("OnCalcFields_Event") OnDeleteError!AL("OnDeleteError_Event") OnEditError!AL("OnEditError_Event") OnExecSQL OnNewRecord!AL("OnNewRecord_Event") OnPostError!AL("OnPostError_Event")
Свойство AffectedRows
Применимо к TMySQLDataset
Определение
property AffectedRows : string;
Описание
Число строк, на которые воздействует последняя инструкция SQL, которая будет выполнена. Только для Run-time. Read-only.
Свойство CachedUpdates
Применимо к TMySQLDataset
Определение
property CachedUpdates : boolean;
Описание
Установка этого свойства в True заставит все инструкции SQL, SQLUpdate, SQLInsert, SQLDelete и SQLBatch кэшироваться на локальной системе и реально выполняться только тогда, когда методы Close или Refresh в очередной раз обращаются к этому набору данных.
Свойство DatabaseName
Применимо к TMySQLDataset
Определение
property DatabaseName : string;
Описание
В настоящее время выбранная база данных, устанавливая это свойство вызовет "USE Database" на активной поточной связи этого набора данных с сервером MySQL. Это значение заменит все макросы $DATABASENAME в Ваших запросах SQL.
Свойство FieldName
Применимо к TMySQLDataset
Определение
property FieldName : string;
Описание
В настоящее время выбранное имя поля (возможно, нескольких полей). Это может содержать список полей, разделенных запятыми, и необязательный первичный ключ для текущей (актуальной) таблицы. Это заменит все макросы $FIELDNAME в Ваших запросах SQL.
Свойство AllFieldValues
Применимо к TMySQLDataset
Определение
property AllFieldValues : boolean;
Описание
Установите это свойство в True, если Вы хотите, чтобы набор данных использовал "show columns from table", чтобы получить расширенную информацию относительно каждого поля, например, значения по умолчанию, перечни допустимых значений для полей типов ENUM и SET и так далее.
Свойство MacroChar
Применимо к TMySQLDataset
Определение
property MacroChar : Char;
Описание
Текущий (актуальный) символ, используемый для определенных макрокоманд в Ваших инструкциях SQL.
Свойство Filter
Применимо к MySQLDataset
Определение
property Filter : string;
Описание
Установите это свойство к любому имеющему силу определению MySQL WHERE, например, AccountName like "J%". Это значение будет автоматически включено в макрокоманду $WHERE, если Filtered установлено в значение True.
Свойство MacroCount
Применимо к TMySQLDataset
Определение
property MacroCount : Word;
Описание
Число существующих макрокоманд. Только Run-time. Read-only.
Свойство Filtered
Применимо к TMySQLDataset
Определение
property Filtered : boolean;
Описание
Установите это свойство в True, если Вы хотите, чтобы текущий (актуальный) Filter применялся со следующей командой Open к набору данных.
Свойство MasterFields
Применимо к TMySQLDataset
Определение
property MasterFields : string;
Описание
Установите это свойство к любой имеющей силу комбинации Name=Value так, чтобы получилась пара DetailField=MasterField, например, MasterFields:='AccountID=AccountID,AccountName=FirstName', или используйте компоновку, чтобы связать Ваш набор данных с полями MasterSource.
AccountID и AccountName берутся из текущего детального набора данных, а AccountID и Firstname берутся из главного набора данных, определенного свойством MasterSource.
Поля, определенные свойством MasterFields, автоматически анализируются и будут вставлены в предложение $WHERE, набор данных будет закрыт и вновь открыт, уже используя новую инструкцию SQL, которая отразит изменения в наборе данных MasterSource.
Свойство Macros
Применимо к TMySQLDataset
Определение
property Macros : TMySQLMacros;
Описание
TParams представляет собой совокупность макрокоманд, найденных в инструкциях SQL.
Свойство MasterSource
Применимо к TMySQLDataset
Определение
property MasterSource : string;
Описание
Установите это свойство к любому имеющему силу доступному источнику данных. Если это свойство установлено, оно автоматически модифицирует подробный набор данных для макроса $WHERE, когда происходят изменения в наборе данных.
Свойство MacrosEnabled
Применимо к TMySQLDataset
Определение
property MacrosEnabled : boolean;
Описание
Если установлено в True, допускает использование макрокоманд в Ваших инструкциях SQL.
Свойство MultiKeyFields
Применимо к TMySQLDataset
Определение
property MultiKeyFields : string;
Описание
Список строк всех полей, которые являются частью ключа, доступного в текущем (актуальном) наборе результатов. Только Run-time. Read-only.
Свойство MySQLFields
Применимо к TMySQLDataset
Определение
property MySQLFields : TStringList;
Описание
Список строк всех полей, используемых в текущем наборе результатов. Только Run-time. Read-only.
Свойство MySQLRecords
Применимо к TMySQLDataset
Определение
property MySQLRecords : TList;
Описание
Необработанные записи из текущего (актуального) набора результатов. Только Run-time. Read-only.
Свойство MySQLTables
Применимо к TMySQLDataset
Определение
property MySQLTables : TStringList;
Описание
Список всех таблиц, используемых в текущем наборе результатов. Только Run-time. Read-only.
Свойство PrimaryKeyFields
Применимо к TMySQLDataset
Определение
property PrimaryKeyFields : string;
Описание
Строковый список всех полей первичных ключей, доступных в текущем наборе результатов. Только Run-time. Read-only.
Свойство ReadOnly
Применимо к TMySQLDataset
Определение
property ReadOnly : boolean;
Описание
Изменение этого свойства включит или отключит редактирование текущего наборе результатов.
Свойство RealSQL
Применимо к TMySQLDataset
Определение
property RealSQL : string;
Описание
Последняя полная инструкция SQL, которая будет послана серверу MySQL. Только Run-time. Read-only.
Свойство Records
Применимо к TMySQLDataset
Определение
property Records[Index : Integer] : PRecInfo;
Описание
Необработанные записи текущего набора результатов. Только Run-time. Read-only.
Свойство Server
Применимо к MySQLDataset
Определение
property Server : TMySQLServer;
Описание
TMySQLServer, используемый этим набором данных.
Свойство ShareConnection
Применимо к TMySQLDataset
Определение
property ShareConnection : boolean;
Описание
Если True, этот набор данных совместно использует поточное подключение, обеспеченное TMySQLServer с TMySQLServer.
Обратите внимание: Соблюдайте осторожность при использовании этого, так как каждый набор данных может использовать любую базу данных, но разделяемое подключение может использовать в один момент времени только единственную базу данных. Если выставить значение в False, этот набор данных будет иметь собственное поточное подключение к серверу MySQL, организованное TMySQLServer. Все операции будут локальными и не смогут влиять на другой экземпляр TMySQLDataset или TMySQLServer.
Свойство SQL
Применимо к TMySQLDataset
Определение
property SQL : TStrings;
Описание
Тип SELECT SQL-запроса. Эти инструкции будут выполнены, каждый раз, когда Вы выполняете операцию Open или Active на наборе данных. Этот набор строк может содержать несколько инструкций, разделеных точкой с запятой (;). Последняя инструкция должна будет произвести набор результатов.
Свойство SQLBatch
Применимо к TMySQLDataset
Определение
property SQLBatch : TStrings;
Описание
Общая команда SQL. Эти инструкции будут выполнены каждый раз, когда Вы выполняете ExecBatch на наборе данных. Этот список строк может содержать несколько инструкций, разделеных точкой с запятой (;).
Свойство SQLDelete
Применимо к TMySQLDataset
Определение
property SQLDelete : TStrings;
Описание
DELETE-тип SQL-команды. Эти инструкции будут выполнены каждый раз, когда Вы выполняете Delete на наборе данных. Этот список строк может содержать несколько инструкций, разделеных точкой с запятой (;).
Свойство SQLInsert
Применимо к TMySQLDataset
Определение
property SQLInsert : TStrings;
Описание
INSERT-тип SQL-команды. Эти инструкции будут выполнены каждый раз, когда Вы выполняете Insert или Append на наборе данных. Этот список строк может содержать несколько инструкций, разделеных точкой с запятой (;).
Свойство SQLUpdate
Применимо к TMySQLDataset
Определение
property SQLUpdate : TStrings;
Описание
UPDATE-тип SQL-команды. Эти инструкции будут выполнены каждый раз, когда Вы выполняете Edit и Post на наборе данных. Этот список строк может содержать несколько инструкций, разделеных точкой с запятой (;).
Свойство TableName
Применимо к TMySQLDataset
Определение
property TableName : string;
Описание
Имя в настоящее время выбранной таблицы. Это заменит макросы $TABLENAME в Ваших инструкциях SQL.
Свойство UniqueKeyFields
Применимо к TMySQLDataset
Определение
property UniqueKeyFields : string;
Описание
Список всех уникальных полей, используемых в текущем наборе результатов. Только Run-time. Read-only.
Метод EscapeStr
Применимо к TMySQLDataset
Определение
function EscapeStr(const Value : string) : string;
Описание
Создает экранированную строку для сервера MySQL, используя функцию mysql_escape_string.
Метод ExecBatch
Применимо к TMySQLDataset
Определение
function ExecBatch : boolean;
Описание
Выполняет инструкции SQLBatch, использующие подключение набора данных и текущие параметры настройки.
Метод ExecSQL
Применимо к TMySQLDataset
Определение
function ExecSQL(SQL : string; EnableMacros, Cached : boolean) : boolean;
Описание
Выполнит любую инструкцию SQL, использующую подключение набора данных. Если EnableMacros равно True, SQL будет анализироваться, используя макрокоманды. Если Cached равно True, SQL-запрос будет послан серверу со следующим обращением к методу Close или Refresh.
Метод ExecSQLBatch
Применимо к TMySQLDataset
Определение
function ExecSQLBatch(SQL : TStrings; EnableMacros, Cached, AutoRefresh : boolean): boolean;
Описание
Выполнит любую инструкцию SQL, использующую подключение набора данных. Если EnableMacros равно True, SQL будет анализироваться, используя макрокоманды. Если Cached равно True, SQL-запрос будет послан серверу со следующим обращением к методу Close или Refresh. AutoRefresh не используется.
Метод GetMacroValue
Применимо к TMySQLDataset
Определение
function GetMacroValue(Name : string) : string;
Описание
Возвратит текущее значение макрокоманды Name как строку.
Метод HexStr
Применимо к TMySQLDatasetCVYCG0
Определение
function HexStr(S : PChar; L : longint) : string;
Описание
Применяется для полей типов BLOB и MEMO. Двоичные данные, указанные в S с длиной L возвратятся как строка, наподобие "0x623E63F...".
Метод LocateRecord
Применимо к TMySQLDataset
Определение
function LocateRecord(const KeyFields : string; const KeyValues : Variant; Options : TLocateOptions; SyncCursor : Boolean): Boolean;
Описание
Стандартный метод реализации Locate.
Метод LocateRecordOption
Применимо к TMySQLDatasetCVYCG0
Определение
function LocateRecordOption(const KeyFields : string; const KeyValues : Variant; Options : TLocateOptions; SyncCursor : Boolean; MySQLOptions : TMySQLLocateOptions; var MatchedField : TField) : Boolean;
Описание
Расширенная версия Locate. Это учитывает полный текстовый поиск на всех полях текущего набора результатов. Параметры KeyFields, KeyValues и Options работают так же, как и со стандартным методом Delphi Locate. Если SyncCursor равно True, набор данных будет установлен в первую согласованную запись. MySQLOptions определяет направление и тип поиска. MatchedField возвращает компонент TField, который соответствует критериям. Эта функция вернет True, если соответствие было найдено.
Метод MacroByName
Применим к TMySQLDataset.
Определение
function MacroByName(const Value : string) : TParam;
Описание
Дает Вам доступ во время выполнения ко всем макрокомандам, используемым в любых инструкциях SQL. TMySQLDataset может применяться без того, чтобы использовать любую макрокоманду.
Макросы
Макросы дают возможность Вам что-то задать в Вашем SQL-запросе однажды, а затем факультативно устанавливать части инструкций SQL позже.
Рассмотрим такую SQL-команду:
"select * from |$TABLENAME |JOIN |WHERE |GROUPBY |ORDER |LIMIT;"
Эта инструкция имеет 6 определенных макрокоманд, первая специальна, но посмотрим на макрос |WHERE.
По умолчанию это будет пустая строка, если не задано иное. Но если Вы факультативно хотите устанавливать это, Вы можете:
A) Используя Object Inspector:
Выбрать макрос, нажать на WHERE и ввести значение, подобно "WHERE AccountID=1".
Теперь закройте и снова откройте набор данных, текст будет помещен в Вашу инструкцию SQL и послан на сервер без того, чтобы заменить SQL-свойство.
B) В коде указать:
MySQLDataset1.MacroByName('WHERE').AsString := 'WHERE AccountID=1';
MySQLDataset1.Open;
В обоих случаях заключительная инструкция SQL, посланная серверу, будет выглядеть следующим образом:
"select * from Accounts WHERE AccountID=1;"
Вы можете устанавливать макрокоманды, даже если Ваш набор данных открыт. Они будут использоваться только, если инструкция SQL должна анализироваться и выполняться снова.
ОБРАТИТЕ ВНИМАНИЕ: Макрокоманды чувствительны к регистру!
Имеются несколько специальных макрокоманд, которые являются доступными для использования, но если Вы устанавливаете значение для них, это не будет иметь эффекта для результата заключительной инструкции SQL, поскольку все эти макрокоманды автоматически модифицируются и устанавливаются во время выполнения. Все они начинаются со знака $:
$RELOAD
Вызовет перезагрузку набора данных MySQLServer, результат этой макрокоманды: пустая строка.
$DATABASENAME
Будет заменен свойством DatabaseName Вашего MySQLDataset.
$TABLENAME
Будет заменен свойством TableName Вашего MySQLDatasset.
$FIELDNAME
Будет заменен первым полем в свойстве FieldName Вашего MySQLDataset. Разделитель ";" или ",".
$FIELDS
Будет заменен постоянными полями набора данных (поля, которые Вы определили двойным нажатием на Ваш набор данных). Если таких полей нет, макрос будет заменен на * (звездочку).
$WHERE
Будет заменен комбинацией свойств MasterFields и Filter. Например, если MasterFields установлен в "AccountID=AccountID" и Filter равен "AccountName like "J%", то результатом будет WHERE (AccountID=1) and (AccountName like "J%").
$MODIFIED$FIELDS&VALUES
Будет заменен изменяемыми полями текущей записи, результат примерно таков:
FieldName1="Value1",FieldName2="Value2",...
Обратите внимание: значения экранируются, пустые поля будут равны NULL, типы BLOB будут равняться 0x874365837546.
$UNMODIFIED$FIELDS&VALUES
Будет заменен неизменяемыми полями текущей записи, результат примерно таков: FieldName1="Value1",FieldName2="Value2",....
$MODIFIED$FIELD$NAMES
Будет заменен именами изменяемых полей текущей записи, результат примерно таков: FieldName1,FieldName2,....
$UNMODIFIED$FIELD$NAMES
Будет заменен именами неизменяемых полей текущей записи, результат примерно таков: FieldName1,FieldName2,....
$MODIFIED$FIELD$VALUES
Будет заменен значениями изменяемых полей текущей записи, результат примерно таков: "FieldValue1","FieldValue2",....
$UNMODIFIED$FIELD$VALUES
Будет заменен значениями неизменяемых полей текущей записи, результат примерно таков: "FieldValue1","FieldValue2",....
$OLD$FIELDS&VALUES
Будет заменен всеми полями в текущем наборе результатов и значениями для предыдущих значений текущей записи, результат напомнит: (FieldName1="Value1") and (FieldName2="Value2") and ....
$FIELDNAMES&VALUES
Будет заменен всеми свойствами FieldName (разделенными ";" или ","), именами полей и значениями для текущей записи, результат напомнит: (FieldName1="Value1") and (FieldName2="Value2") and ....
$PRIMARYFIELDS&VALUES
Будет заменен всеми полями первичного ключа в текущем наборе результатов и значениями для текущей записи, результат примерно такой: (FieldName1="Value1") and (FieldName2="Value2") and ....
ОБРАТИТЕ ВНИМАНИЕ: Если не имеется никаких полей первичного ключа в текущем результате, эта макрокоманда возвратит поля и значения для макроса $OLD$FIELDS&VALUES.
$UNIQUEFIELDS&VALUES
Будет заменен всеми уникальными полями в текущем наборе результатов и значениями для текущей записи, результат примерно такой: (FieldName1="Value1") and (FieldName2="Value2") and ....
$MULTIFIELDS&VALUES
Будет заменен всеми полями, которые являются частями составного ключа в текущем наборе результатов и значениями для текущей записи, результат будет примерно таким: (FieldName1="Value1") and (FieldName2="Value2") and ... .
$FIELDNAMES&VALUES$COMMA
Будет заменен всеми именами полей из свойства FieldName (разделенными ; или ,) и значениями для текущей записи: FieldName1="Value1",FieldName2="Value2",....
$FIELDNAME$VALUE
Будет заменен первым полем в свойстве FieldName текущей записи MySQLDataset: "FieldValue1".
YourFieldNameHere
Будет заменен полем, имя которого определено значением текущей записи. Регистр не имеет значения: "FieldValue1".
$OLD$YourFieldNameHere
Будет заменен полем, имя которого определено предыдущим значением текущей записи. Регистр не имеет значения: "FieldOldValue1".
Например, если Вы должны модифицировать запись в наборе результатов: update mytable set AccountName="abc" where AccountName="cba", Вы изменяете свойство SQL на update mytable set AccountName=|AccountName where AccountName=|$OLD$AccountName.
$PROMPT$Caption$PromptName$DefaultValue$PasswordChar
Запросит Вашего конечного пользователя на предмет значения, которое будет вставлено в sql-запрос. Параметры:
Caption: факультативный заголовок для диалога
PromptName: факультативное имя запрашиваемого значения
DefaultValue: факультативное значение по умолчанию
PasswordChar: факультативный парольный символ, например, *
Если макрокоманды не соответствуют никакому из этих специальных имен, то Macro.AsString используется, чтобы заменить макрокоманду в SQL, например: MySQLDataset1.MacroByName('WHERE').AsString := 'WHERE AccountID=1'; MySQLDataset1.Open;
Следующее предстваляет собой пример инструкций SQL из фактических программ:
SQL Property: Select
select * from |$TABLENAME WHERE AccountType LIKE "%Employee%"
SQLInsert Property: Insert
use MYSQL; insert into USER set host="%",user=|ACCOUNTNAME, password=PASSWORD(|$PROMPT$Password$$*), select_priv="Y",insert_priv="Y",update_priv="Y", delete_priv="Y", reload_priv="Y"; use |$DATABASENAME; insert into |$TABLENAME set |$MODIFIED$FIELDS&VALUES; |$RELOAD;
SQLUpdate Property: Update
use MYSQL; update user set user=|ACCOUNTNAME where user=|$OLD$ACCOUNTNAME; use |$DATABASENAME; update |$TABLENAME set |$MODIFIED$FIELDS&VALUES where |$FIELDNAME=|$FIELDNAME$VALUE; |$RELOAD;
SQLDelete Property: Delete
use MYSQL; delete from user where user=|ACCOUNTNAME; use |$DATABASENAME; delete from |$TABLENAME where |$FIELDNAME=|$FIELDNAME$VALUE; |$RELOAD;
Cascading deletes made easy:
delete from |$TABLENAME where |$FIELDNAMES&VALUES; //Master table
delete from devices where |$FIELDNAMES&VALUES; // Detail table
Метод ParseSQL
Применим к TMySQLDataset
Определение
function ParseSQL(SQL : string) : string;
Описание
Анализирует строку SQL, извлекает и добавлет все найденные макрокоманды.
Метод QuoteStr
Применим к TMySQLDataset
Определение
function QuoteStr(const S : string) : string;
Описание
Создает цитированную строку, например, "string" превратится в "`string`".
Метод ClearMacros
Применим к TMySQLDataset
Определение
procedure ClearMacros;
Описание
Очищает все установленные значения для существующих макрокоманд.
Метод ConnectEvent
Применим к TMySQLDataset
Определение
procedure ConnectEvent(Sender : TObject; Connecting : Boolean);
Описание
Позволяет набору данных знать то, что делает TMySQLServer. Это обычно используется только внутреннее между набором данных и TMySQLServer.
Событие OnExecSQL
Применимо к TMySQLDataset
Определение
property OnExecSQL : TMySQLEvent;
Описание
Это событие происходит только прежде, чем инструкция SQL будет послана серверу MySQL. SQL содержит полный SQL-запрос, который, возможно, изменен или продолжен, в зависимости от того, была ли эта инструкция выполнена или нет. Удобно для отладки.
Тип TMySQLEvent
Модуль MySQLDataset
Определение
type TMySQLEvent = procedure(Server: TMySQLDataset; var SQL: string; var Continue: boolean); of object;
Описание
Это событие происходит только прежде, чем инструкция SQL будет послана серверу MySQL. SQL содержит полный SQL-запрос, который, возможно, изменен или продолжен, в зависимости от того, была ли эта инструкция выполнена или нет. Удобно для отладки.
Тип TMySQLLocateOptions
Модуль MySQLDataset
Определение
type TMySQLLocateOptions = set of (loFirst, loNext, loPrior, loLast, loTextSearch, loMatchAll);
Описание
loFirst: вызывает First на наборе данных перед стартом поиска.
loNext: использует Next на наборе данных, чтобы искать вперед.
loPrior: использует Prior на наборе данных, чтобы искать назад.
loLast: вызывает Last на наборе данных перед стартом поиска.
loTextSearch: выполняет текстовый поиск на полях, включенных в search, таким образом, KeyValues должен содержать строку.
loMatchAll: все поля записи должны содержать значение, определенное для поиска в KeyValues.
Пример: свойства сервера
ShowMessage('MySQL server''s properties are:'#13#10+ 'Server version:'+MySQLServer1.ServerVersion+#13#10+ 'Client version:'+MySQLServer1.ClientVersion+#13#10+ 'Protocol:'+MySQLServer1.Protocol+#13#10+ 'Information:'+MySQLServer1.Info+#13#10+ 'Major:'+IntToStr(MySQLServer1.Major)+#13#10+ 'Minor:'+IntToStr(MySQLServer1.Minor)+#13#10+ 'Build:'+IntToStr(MySQLServer1.Build)+#13#10+ 'Complete:'+IntToStr(MySQLServer1.IntVer)+#13#10);
Пример: создание сервера
with TMySQLServer.Create(nil) do try Host := 'localhost'; Username := 'root'; Password := ''; DatabaseName := 'mysql'; LoginPrompt := False; Connected := True; ExecSQL('GRANT SELECT, INSERT, UPDATE, DELETE, RELOAD ON *.* TO 'Admin'@'%''); Reload; CreateDatabase('Test'); DropDatabase('Test'); GetDatabaseNames(List); GetTableNames('mysql',List); GetFieldNames('mysql','user',List); finally Free; end;
Пример: использование MySQLDataset
with TMySQLDataset.Create(nil) do try Server := MySQLServer1; DatabaseName := 'mysql'; TableName := 'user'; Active := True; ExecSQL(' GRANT SELECT, INSERT, UPDATE, DELETE, RELOAD ON *.* TO ''Admin''@''%''', True, False); Server.Reload; MacroByName('WHERE').AsString := 'where user=''root'''; Close; Open; ShareConnection := False; Open; // Now the dataset has it's own threaded connection ShareConnection := True; Open; // Now we are back on the TMySQLServer connection ClearMacros; MacroByName('ORDER').AsString := 'order by user'; MacroByName('LIMIT').AsString := 'limit 0,10'; Close; Open; CahcedUpdates := True; // All edits, insert, deletes, updates are now cached Edit; FieldByName('user').AsString := 'test'; Post; Close; // Cached statements flushed CachedUpdates := False; // Statements not cached, sent real-time to server finally Free; end;
Модуль MySQLServer
Этот модуль включает объект TMySQLServer, полученный из стандартного класса Delphi 5 TCustomConnection.
Компонент: TMySQLServer
Типы: TMySQLServerLoginEvent
Подпрограммы: MYSQLError
Описание
TMySQLServer представляет собой основной компонент в наборе TMySQLComponent. TMySQLServer используется, чтобы обработать фактические подключения к серверу MySQL, используя стандартные функции из libmysql.dll. Большую часть времени Вы будете использовать только один компонент сервера, зато много компонентов TMySQLDatasets.
Важно обратить внимание на то, что есть только одно физическое подключение к серверу MySQL. Все наборы данных, приложенные к этому TMySQLServer, используют это подключение или породят собственные подключения, использующие те же самые параметры настройки TMySQLServer.
Помимо этих функций, этот компонент имеет много полезных свойств и функций, чтобы создавать, удалять, использовать базы данных, получать информацию о версии, собирать списки баз данных, таблиц, полей и т. д.
Свойства
AfterConnect!AL("AfterConnect_Property") AfterDisconnect!AL("AfterDisconnect_Property") BeforeConnect!AL("BeforeConnect_Property") BeforeDisconnect!AL("BeforeDisconnect_Property") Build ClientVersion Compression Connected!AL("Connected_Property") DatabaseName Host IdleTimer Info IntVer LoginPrompt Major Minor Params Password Port Protocol ServerVersion UserName
Методы
Create!AL("Create_Method") Destroy!AL("Destroy_Method") AllocConnection ExecSQL FormatIdentifier FormatIdentifiers SelectDatabase Server CreateDatabase DropDatabase FreeConnection GetDatabaseNames GetFieldNames GetTableNames RegisterClient!AL("RegisterClient_Method") Reload SendEvent UnRegisterClient!AL("UnRegisterClient_Method")
События
Key events OnIdleTimer OnLogin
Цель
Обеспечить все приложенные наборы данных физическими подключениями к серверу MySQL, используя стандартную библиотеку libmysql.dll. Это основной компонент в наборе TMySQLComponent.
Свойство Build
Применимо к TMySQLServer
Определение
property Build : word;
Описание
Сервер формирует версию как слово, например, 32
Read-only
Свойство ClientVersion
Применимо к TMySQLServer
Определение
property ClientVersion : string;
Описание
Используемая версия клиентской разделяемой библиотеки libmysql.dll.
Read-only
Свойство Compression
Применимо к TMySQLServer
Определение
property Compression : boolean;
Описание
Определяет протокол сжатия, используемый при связи с сервером MySQL.
Свойство DatabaseName
Применимо к TMySQLServer
Определение
property DatabaseName : string;
Описание
Получает или определяет текущую (актуальную) базу данных для этого подключения.
Свойство Host
Применимо к TMySQLServer
Определение
property Host : string;
Описание
Получает или определяет имя хоста, используемое при создании новых подключений.
Свойство IdleTimer
Применимо к TMySQLServer
Определение
property IdleTimer : longword;
Описание
Получает или определяет актуальное время неактивности (тайм-аут), позволенное для этого подключения. Подключение автоматически будет пересоздано после того, как это время закончится, а связь еще нужна.
Свойство Info
Применимо к TMySQLServer
Определение
property Info : string;
Описание
Более подробная информация о сервере.
Read-only
Свойство IntVer
Применимо к TMySQLServer
Определение
property IntVer : longword;
Описание
Версия сервера как слово, например, 32306.
Read-only
Свойство LoginPrompt
Применимо к TMySQLServer
Определение
property LoginPrompt;
Описание
Если установлено в True, это учитывает настроенный диалог подсказки MySQL входа в систему, который будет появляться каждый раз, когда устанавливается связь с этим сервером.
Свойство Major
Применимо к TMySQLServer
Определение
property Major : word;
Описание
Старшая часть версии сервера как слово, например, 3
Read-only
Свойство Minor
Применимо к TMySQLServer
Определение
property Minor : word;
Описание
Младшая часть версии сервера как слово, например, 22
Read-only
Свойство Params
Применимо к TMySQLServer
Определение
property Params : TStrings;
Описание
Стандартные параметры, используемые для сервера событием OnLogin. Могут быть изменены во время выполнения.
Свойство Password
Применимо к TMySQLServer
Определение
property Password : string;
Описание
Получает или определяет текущий пароль, используемый при создании нового подключения.
Свойство Port
Применимо к TMySQLServer
Определение
property Port : word;
Описание
Получает или определяет текущий порт, используемый при связи с сервером.
Свойство Protocol
Применимо к TMySQLServer
Определение
property Protocol : string;
Описание
Используемый протокол связи: TCP/IP, Pipes и т.д.
Read-only
Свойство ServerVersion
Применимо к TMySQLServer
Определение
property ServerVersion : string;
Описание
Версия сервера MySQL в виде строки.
Read-only
Свойство UserName
Применимо к TMySQLServer
Определение
property UserName : string;
Описание
Получает или определяет текущее имя пользователя, используемое при создании нового подключения.
Метод AllocConnection
Применим к TMySQLServer
Определение
function AllocConnection : PMYSQL;
Описание
Распределяет новое подключение для TMySQLServer и TMySQLDatasets, используя текущие параметры настройки Username, Password, Port и прочие.
Это внутренне используемый метод, обычно он используется только порожденными классами TMySQLServer.
Метод ExecSQL
Применим к TMySQLServer
Определение
function ExecSQL(SQL : string) : boolean;
Описание
Используя подключение, выполнит любую инструкцию SQL на сервере.
Метод FormatIdentifier
Применим к TMySQLServer
Определение
function FormatIdentifier(Value : string) : string;
Описание
Форматирует идентификатор Value, используя информацию о версии сервера. Например, "Table 1" превратится в "`Table 1`".
Метод FormatIdentifiers
Применим к TMySQLServer
Определение
function FormatIdentifiers(const Value : string) : string;
Описание
Форматирует идентификаторы, полученные в строке Value, используя информацию о версии сервера. Например, "Table 1#10#13Table2#10#13Table 3" превратится в "`Table 1`,Table 2,`Table 3`".
Метод SelectDatabase
Применим к TMySQLServer
Определение
function SelectDatabase(Conn : PMYSQL; DB : string) : boolean;
Описание
Для данного подключения выбирает текущую (актуальную) базу данных, то есть действует аналогично команде "USE Database;". Это внутренне используемый метод. Обычно он применяется только классами, порожденными от TMySQLServer.
Метод Server
Применим к TMySQLServer
Определение
function Server : PMYSQL;
Описание
Представляет собой указатель на текущее потоковое подключение к серверу. Это может использоваться со всеми стандартными функциями mysql_, найденными в библиотеке libmysql.dll. Это внутренне используемый метод. Обычно он применяется только классами, порожденными от TMySQLServer.
Метод CreateDatabase
Применим к TMySQLServer
Определение
procedure CreateDatabase(Value : string);
Описание
При использовании подключения к серверу создает новую базу данных, то есть работает аналогично инструкции "CREATE Database;".
Метод DropDatabase
Применим к TMySQLServer
Определение
procedure DropDatabase(Value : string);
Описание
При использовании текущего подключения к серверу удаляет указанную базу данных, то есть работает аналогично инструкции "DROP Database;".
Метод FreeConnection
Применим к TMySQLServer
Определение
procedure FreeConnection(var Value : PMYSQL);
Описание
Освобождает активное подключение.
Метод GetDatabaseNames
Применим к TMySQLServer
Определение
procedure GetDatabaseNames(List : TStrings);
Описание
Заполняет список со всеми именами баз данных, найденными на сервере. Замечание: в этом списке не будут перечислены те базы данных, на которых Вы не имеете никаких привилегий.
Метод GetFieldNames
Применим к TMySQLServer
Определение
procedure GetFieldNames(const DatabaseName, TableName : string; List : TStrings);
Описание
Заполняет cписок всеми именами полей для таблицы TableName из базы данных DatabaseName с сервера.
Метод GetTableNames
Применим к TMySQLServer
Определение
procedure GetTableNames(const DatabaseName : string; List : TStrings);
Описание
Заполняет cписок всеми именами таблиц из базы данных DatabaseName.
Метод Reload
Применим к TMySQLServer
Определение
procedure Reload;
Описание
Перезагружает права доступа на сервере, то есть работает как команда "RELOAD;"
Метод SendEvent
Применим к TMySQLServer
Определение
procedure SendEvent(Connecting : Boolean);
Описание
Используется, чтобы разъединить все наборы данных, если сервер завершается. Это внутренне используемый метод. Обычно он применяется только классами, порожденными от TMySQLServer.
Событие OnIdleTimer
Применимо к TMySQLServer
Определение
property OnIdleTimer : TNotifyEvent;
Описание
Это событие происходит, когда заканчивается время ожидания подключения.
Событие OnLogin
Применимо к TMySQLServer
Определение
property OnLogin : TMySQLServerLoginEvent;
Описание
Это событие происходит прежде, чем подключение будет сделано, чтобы позволить Вам изменять свойства Params.
Тип TMySQLServerLoginEvent
Модуль MySQLServer
Определение
type TMySQLServerLoginEvent = procedure(Server : TMySQLServer; LoginParams : TStrings); of object;
Описание
Это событие происходит до установки связи с сервером MySQL. Список строк LoginParams в настоящее время поддерживает только два ключевых слова в форме: USERNAME=root, PASSWORD=.
Процедура MYSQLError
Модуль MySQLServer
Определение
procedure MYSQLError(MySQLHandle : PMySQL=nil; ErrNo : integer=-1; Msg : string=''; IntVer : longword=32100);
Описание
Универсальная функция создания исключительной ситуации, предоставляет зависящую от версии информацию относительно последней ошибки MySQL.
MySQL- Руководство разработчика
Использование модуля MySQL
import MySQL DBH = MySQL.connect() # localhost print DBH.listdbs() DBH.selectdb('test') print DBH.serverinfo() print DBH.stat() DBH["create table pytest (x int, y int, s char(20))"] DBH["insert into pytest values (1,2,'abc')"] DBH.do("insert into pytest values (3,4,'def')") STH = DBH.query("insert into pytest values (5,6,'ghi')") print STH.affectedrows() print DBH['select * from pytest'] STH = DBH.query("select * from pytest") print STH.numrows() print STH.fields() print STH.fetchrows(-1) STH.seek(0) print STH.fetchrows(1) print STH.fetchrows(1) STH.seek(0) print STH.fetchrows(2) print STH.fetchrows(2) print STH.numfields() STH.seek(0) print STH.fetchdict(1) print STH.fetchdict() STH = DBH.query("select * from pytest",1) print STH.fetchdict(1) print STH.fetchdict() # compare to previous dicts STH = DBH.query("select * from pytest",1) print STH.fetchrows(1) print STH.eof() print STH.fetchrows() print STH.eof() DBH['drop table pytest']
Экспортируемые типы, функции и классы
Модуль MySQL экспортирует следующее:
Тип объекта базы данных.
Тип ошибки объекта курсора (исключительная ситуация, выдаваемая в некоторых обстоятельствах вместо TypeError).
Версия, доступная из Python
Функциональный возврат объекта базы данных. Факультативные параметры: имя компьютера (host), с которым надлежит соединиться, username для связи с MySQL и соответствуюющий пароль password. Если никакой компьютер не задан, функция примет localhost (и будет использовать Unix-сокет для подключения к нему).
Вернет правильно экранированную строку, чтобы позволить вставку в DB. Эта подпрограмма вызывает mysql_escape_string(), которая в 3.21.29-gamma не работает. Версия 3.21.30 и выше работают нормально.
Обратите внимание: в следующем "таблица" означает "список списков" (за исключением fetchdict). MySQL.connect() вернет дескриптор базы данных (DBH) со следующими методами:
Возвращает таблицу, дающую имена баз данных на компьютере MySQL, с которым соединился через вызов MySQL.connect(). Факультативный параметр: MySQL-строка с символами подстановки (синтаксис аналогичен LIKE).
Присоединяет этот объект к специфической базе данных. Выполненные запросы будут направлены к этой базе данных, пока не будет сделано другое обращение метода selectdb. Факультативный параметр storage типа integer может использоваться, чтобы хранить наборы результатов запросов на сервере. Обратите внимание, что это отрицательно воздействует на эффективность сервера, но позволяет клиентуре с маленькой памятью работать с записями по мере надобности. Значение по умолчанию: 0, то есть все записи перемещены пользователю сразу.
Возвращает таблицу с именами таблиц в выбранной базе данных. Имеет силу только после того, как было сделано обращение selectdb. Факультативный параметр может использоваться, чтобы ограничить возвращенный набор таблиц (тот же самый синтаксис, какой принят в LIKE).
Возвращает таблицу описаний полей в данной таблице. Факультативный параметр может использоваться, чтобы ограничить возвращенный набор полей (тот же самый синтаксис, какой принят в LIKE).
Возвращает информацию относительно работающих процессов MySQL. Требует соответствующих привилегий (иначе возвращает None).
Возвращает информацию состояния из MySQL.
Создает новую базу данных.
Удаляет базу данных.
Перезагружает таблицы привилегий MySQL.
Завершает сервер MySQL.
Закрывает DB-подключение.
Возвращает информацию о версии MySQLmodule.
Возвращает информацию о сервере MySQL.
Возвращает информацию относительно хоста соединения и типа подключения.
Возвращает информацию о версии протокола MySQL.
Возвращает результат запроса SQL или число обработанных строк. Оба метода используют тип памяти, установленный в DBH.selectdb().
Предоставляет доступ к последнему сгенерированному числу auto_increment. Это число может изменяться, если были запросы между обращениями.
Возвращает операторный дескриптор для методов курсора (см. ниже). Факультативный параметр storage может использоваться, чтобы отменить значение по умолчанию DBH, установленное DBH.selectdb().
Методы для операторных дескрипторов (STH):
Возвращает результаты запроса к DB. Если n<0, все строки будут выбраны. Иначе будут возвращены только следующие n строк. Значение по умолчанию должно возвратить все строки.
Аналогично STH.fetchrows(), за исключением того, что список словарей возвращен с парами tablename.fieldname:data.
Возвращает описания поля результата запроса STH. В настоящее время MySQLmodule понимает "pri", "notnull", "auto_inc", "ukey" и "mkey" .
Двигает курсор к строке n (0 определяет первую строку). Доступен только, если результат хранится на стороне пользователя (выбрано в DBH.selectdb). Иначе создает исключительную ситуацию.
Возвращает, сколько строк находятся в результате запроса STH. Предупреждение: в действительности это число отражает сколько записей получил клиент. Для методов хранения на стороне сервера, это начинается с 0 и увеличивается по мере того, как пользователь выбирает строки. Для методов хранения на стороне клиента это число немедленно дает общее количество строк для этого запроса.
Возвращает, сколько столбцов находятся в результате запроса STH.
Возвращает данные на сколько строк воздействовал последний запрос. Обратите внимание, что MySQL не всегда возвращает правильное значение.
Возвращает значение auto_increment из STH-запроса insert. Обратите внимание, что это число постоянно, пока STH существует.
Возвратит 1, если последняя строка читалась, иначе 0. Всегда 1, если выбрано хранение данных на стороне пользователя (значение по умолчанию).
Компиляция и установка модуля MySQL
Обратите внимание, что расположение библиотеки MySQL и include-каталога может быть иным на Вашей специфической системе. Вы можете формировать разделяемый модуль (вставкой ниже индикатора shared в файле Setup).
Чтобы формировать динамически загружаемый модуль без доступа к дереву исходников python, используйте: gcc -shared -I/usr/include/python1.5 -I/usr/local/include/mysql \ MySQLmodule.c -lmysqlclient -L/usr/lib/python1.5/config \ -lpython1.5 -o MySQLmodule.so
Переместите возникающий в результате файл MySQLmodule.so в PYTHONPATH. Замените соответствующие расположения Ваших библиотек и include-файлов.
Обратите внимание, что модуль чувствителен к регистру, и что имя было изменено на MySQL, чтобы не разорвать любой существующий код, который использует старый модуль mySQL.
Этот модуль был разработан под
Этот модуль был разработан под Linux (RH50), MySQL 3.21.30 и Python 1.5.1. MySQLmodule-1.x основан на mySQLmodule-0.1.4, разработанном:
mySQLmodule-0.1.4 в свою очередь основан на mSQLmodule, разработанном:
Почему другой интерфейс Python/MySQL?
Была обнаружена проблема при сохранении строк, содержащих ASCII-ноль (\0) в базе данных MySQL. После расследования в языке Python (который создал первоначальную ошибку), был проверен код mySQLmodule и там найден ряд проблем. Некоторые подпрограммы не освобождают распределенную память, некоторые функции MySQL API не были доступны, и многих разработчиков совершенно не устраивал тот факт, что mySQLmodule возвратит различные структуры данных в зависимости от метода. Так что я переделал код. Так как эти изменения включают изменение в методах Python и значениях возврата, был повышен код версии и изменено имя модуля на MySQL, чтобы оно не столкнулось с оригиналом (mySQL).
Рационально возвратить список списков вместо набора или списка наборов. Не стоит создавать ситуацию, когда подпрограммы доступа к DB занимаются обработкой типа возврата, и стоит предусмотреть возможность изменить данные в возвращенной таблице напрямую. Data = DBH['select * from MyTable'] if Data: rows = len(Data) cols = len(Data[0]) for i in range(rows): for j in range(cols): if not Data[i][j]: Data[i][j] = DefaultElement() Do_Something(Data)
Никакой потребности усложнять это при наличии наборов внутри внешнего списка нет. Для тех, кто предпочитает словари, метод STH fetchdict() возвратит список словарей. Ключи словаря квалифицированы с соответствующим именем (возможно, не одним) обрабатываемой таблицы.
Примечания относительно хранения на сервере
MySQL предлагает два немного различных пути доступа к данным из базы данных.
Заданный по умолчанию метод в MySQLmodule состоит в том, чтобы использовать хранение на стороне пользователя, то есть все запросы, включая методы курсора (STH), выбирают все данные с сервера. К строкам обращаются через STH.fetchrows(n) или STH.fetchdict(n) индивидуально (n=1), блочно (n>1), все строки забирают одной порцией (n<0) или не обращаются вообще (n=0). STH.numrows() может сообщать после запроса сколько строк находится в результате. STH.seek(k) может использоваться, чтобы обратиться к строкам в произвольном порядке. Недостаток хранения на стороне пользователя состоит в том, что это использует память пользователя, чтобы сохранить все строки. Этот способ учитывает конструкции типа: STH = DBH.query("select * from Foo") N = STH.numrows() if N > 1000: raise Hell,"You must be joking!" for i in xrange(N): [Data] = STH.fetchdict(1)
Так как пользователь действительно переместил к себе все строки, которые подготовил сервер, все транзакции на этом канале прекратились, и сервер готов принять новые команды. Это также означает, что STH.eof() всегда true (1) для хранения данных на стороне клиента.
Хранение на стороне сервера не требует, чтобы у пользователя было много памяти. Все записи будут перемещены на основании запроса. Однако, этот способ имеет несколько недостатков. Так как теперь возникает возможность того, что пользователь не забрал все строки, каждая новая команда должна проверить, является ли свободным, то есть готов ли он принять новую команду. Если нет, команда должна очистить канал команды, выдавая запросы на чтение в количестве, достаточном, чтобы получить оставшиеся строки. MySQL API 3.21 не предлагает команды abort(). STH.numrows() не знает ничего относительно того, сколько строк были выбраны запросом, так что вышеупомянутый код примера будет падать. STH.numrows() будет, однако, модифицироваться, поскольку строки все-таки читаются, например: STH = DBH.query("select * from Foo") Data = STH.fetchrows(-1) print "Got",STH.numrows(),"rows." # len(Data) is the same
STH.eof() имеет смысл только при хранении данных на сервере, но даже здесь такой код полезен не всегда: STH = DBH.query("select 1") print STH.eof() # will print 0 Data = STH.fetchrows(1) # retrieve the row print STH.eof() # still 0 :-( Data = STH.fetchrows(1) # must repeat. Data will be [] print STH.eof() # now we get 1, but we already # knew that we've hit the end
Можно было рассматривать это, как ошибку. STH.seek(k) больше не доступен и создает исключение ("cannot seek on server"), то есть строки должны теперь читаться последовательно.
Хранение на стороне сервера также создает дополнительную нагрузку на сервер. В частности, он должен остаться в контакте с пользователем, пока все строки не будут прочитаны. Так что лучше бы быстро получить все строки и не делать длинную обработку или, что еще хуже, позволять пользователю останавливать поиск (например, нажимая клавиши Ctrl-S в интерактивном интерфейсе).
Для тех, кто не может решить, который метод является более подходящим для прикладной программы, MySQLmodule позволяет смешивать оба метода свободно. Заданное по умолчанию поведение может быть установлено через DBH.selectdb() и может быть изменено для индивидуального курсора (STH). Обратите внимание, что незавершенные запросы будут отменены последующими командами: STH = DBH.query("select * from Foo",1) # use server side storage Tables = DBH.listtables() # stomp on previous results Data = STH.fetchrows() # nothing here anymore vs. STH = DBH.query("select * from Foo",0) # use client side storage Tables = DBH.listtables() # won't interfere Data = STH.fetchrows() # no problem...
Хранение на стороне сервера также создает более сложный код в MySQLmodule. Обычно при хранении на стороне клиента STH-курсоры независимы от дескриптора базы данных. Немедленно после запроса все данные будут перекачаны клиенту, и пользователь может делать все, что сочтет необходимым с дескриптором DBH. Но при хранении на стороне сервера это становится сложным. С курсорами стороны сервера указатель на дескриптор сохранен в дескрипторе STH. MySQLmodule удостоверится, что этот кусок памяти не освобожден прежде, чем закроются все ожидающие обработки курсоры. Это означает, что mysql_close() не обязательно вызван, если база данных, обрабатываемая DBH, разрушена: DBH = MySQL.connect() # get a DB handle STH = DBH.query("select 1",1) # server side cursor del DBH # mysql_close() *not* called STH.fetchrows() # will succeed! del STH # now mysql_close() will be called # in DBH_dealloc()
Если Вы должны закрыть дескриптор DB немедленно, используйте DBH.close(). Все дальнейшие попытки работать на этом дескрипторе (даже ожидающие обработки курсоры стороны сервера) получат исключительную ситуацию "... server has gone away". Начиная с того момента, как mySQL не может принимать команды из последовательности, все DBH-методы должны проверить незавершенные STH-курсоры. Чтобы обращаться к ним, дескриптор DBH хранит указатель на STH-курсор.
Установка MySQLmodule-1.4 под Windows NT
Следующие инструкции основаны на информации, предоставленной Nigel Head (nhead@houbits.com).
Если что-то пойдет не так, помощь лучше всего поискать в конференции comp.lang.python.
MySQL- Руководство разработчика
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License).
To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the ``copyright'' line and a pointer to where the full notice is found. one line to give the library's name and an idea of what it does.
Copyright (C) year name of author
This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your school, if any, to sign a ``copyright disclaimer'' for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker.
signature of Ty Coon, 1 April 1990 Ty Coon, President of Vice
That's all there is to it!
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the ``copyright'' line and a pointer to where the full notice is found.
one line to give the program's name and a brief idea of what it does.
Copyright (C) yyyy name of author
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details.
The hypothetical commands show w and show c should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than show w and show c; they could even be mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your school, if any, to sign a ``copyright disclaimer'' for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker.
signature of Ty Coon, 1 April 1989 Ty Coon, President of Vice
This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License.
Как сообщать об ошибках и сбоях
Написание хорошего отчета об ошибке требует немало терпения, но при выполнении этого экономится много времени Вам и всем окружающим. Хороший отчет об ошибке, содержащий полный случай теста для ошибки, делает весьма вероятным скорейшее исправление проблемы. Этот раздел поможет Вам написать Ваш отчет так, чтобы Вы не тратили впустую Ваше время, выполняя действия, которые не могут ничем помочь.
Пользуйтесь скриптом mysqlbug, чтобы генерировать отчет об ошибке (или отчет относительно любой проблемы), если возможно. Сам mysqlbug может быть найден в каталоге scripts в дистрибутиве исходного кода или (для двоичного дистрибутива) в каталоге bin под Вашим каталогом установки MySQL. Если Вы не можете использовать mysqlbug, Вы должны все же включать всю необходимую информацию, перечисленную в этом разделе.
Скрипт mysqlbug помогает Вам сгенерировать отчет, определяя многое из следующей информации автоматически, но если кое-что важное отсутствует, пожалуйста, включите это в Ваше сообщение! Пожалуйста, читайте этот раздел тщательно и удостоверьтесь, что вся информация, описанная здесь, включена в Ваш отчет.
Нормальное место, чтобы сообщить ошибки и проблемы: mysql@lists.mysql.com. Если Вы можете создать случай теста, который ясно показывает ошибку, Вы должны его послать на . Обратите внимание, что в этом списке Вы должны только регистрировать полный повторимый отчет ошибки, использующий скрипт mysqlbug. Если Вы работаете под Windows, Вы должны включить описание операционной системы и версии MySQL. Предпочтительно, Вы должны проверить проблему при использовании последнего устойчивого дистрибутива или версии для разработчика. Любой должен быть способен повторить ошибку, используя только mysql test