From bfd79ec5211004e9a43ebe82751b8898d788e3f2 Mon Sep 17 00:00:00 2001 From: Konstantin Osipov <kostja.osipov@gmail.com> Date: Tue, 15 Nov 2011 01:10:50 +0400 Subject: [PATCH] Lua: continue extending the user guide. --- README | 17 +++- doc/user/connectors.xml | 2 +- doc/user/errcode.xml | 6 ++ doc/user/replication.xml | 8 +- doc/user/stored-programs.xml | 152 ++++++++++++++++++++++++++++------- doc/user/target.db | 2 +- doc/user/tnt.css | 6 ++ mod/box/box.lua | 53 ++++++------ mod/box/box_lua.m | 13 ++- test/box/lua.result | 4 - 10 files changed, 192 insertions(+), 71 deletions(-) diff --git a/README b/README index bb01f41d7c..95a384cdab 100644 --- a/README +++ b/README @@ -18,8 +18,8 @@ Caveats: COMPILATION AND INSTALL Tarantool is written in C and Objective C. -To build, you will need GCC Objective C frontend or -Apple CLang compiler. +To build, you will need GCC Objective C frontend +(gcc-objc package on most systems) or Apple CLang compiler. CMake is used for configuration management. 3 standard CMake build types are supported: @@ -28,6 +28,9 @@ CMake is used for configuration management. also provides debugging capabilities * Release -- use only if the highest performance is required +The only external library dependency is readline: libreadline-dev +is required to build the command line client. + Please follow these steps to compile Tarantool: tarantool $ cmake . @@ -37,8 +40,14 @@ To use a different release type, say, RelWithDebugInfo, use: tarantool $ cmake . -DCMAKE_BUILD_TYPE=RelWithDebugInfo -'make' will create tarantool_box executable in directory -mod/box. +Additional build options can be set similarly: + +tarantool $ cmake . -DCMAKE_BUILD_TYPE=RelWithDebugInfo -DENABLE_CLIENT=true + +-- builds the command line client. + +'make' creates tarantool_box executable in directory +mod/box and tarantool executable in client/tarantool. There is no 'make install' goal, but no installation is required either. diff --git a/doc/user/connectors.xml b/doc/user/connectors.xml index 65153e39ed..b97c6eaec6 100644 --- a/doc/user/connectors.xml +++ b/doc/user/connectors.xml @@ -18,7 +18,7 @@ <title>C</title> <para> Please see <link - xlink:href="https://github.com/mailru/tarantool/blob/master/connector/c/tnt.h"><filename>connector/c/tnt.h</filename></link> in the source tree. + xlink:href="https://github.com/mailru/tarantool/blob/master/connector/c"><filename>connector/c</filename></link> in the source tree. </para> </section> diff --git a/doc/user/errcode.xml b/doc/user/errcode.xml index 2246021fb3..c882838da5 100644 --- a/doc/user/errcode.xml +++ b/doc/user/errcode.xml @@ -68,6 +68,12 @@ of existing codes.</para> </para></listitem> </varlistentry> + <varlistentry> + <term xml:id="ER_PROC_LUA" xreflabel="ER_PROC_LUA">ER_PROC_LUA</term> + <listitem><para>An error inside Lua procedure. + </para></listitem> + </varlistentry> + </variablelist> </appendix> diff --git a/doc/user/replication.xml b/doc/user/replication.xml index dff80ab994..bd6db13944 100644 --- a/doc/user/replication.xml +++ b/doc/user/replication.xml @@ -20,10 +20,10 @@ fetching and applying its write ahead log (WAL). Each record in the WAL represents a single Tarantool/Box command, such as INSERT, UPDATE, DELETE and is assigned - a monotonically growing log sequence number (LSN) and a - timestamp. As long as all data change commands - are fully deterministic and operate on a single record, - Tarantool replication can be classified as row-based + a monotonically growing log sequence number (LSN). + In essence, Tarantool replication is row-based: + all data change commands are fully deterministic and operate + on a single record. </para> <para> A stored program invocation, unless requested explicitly, diff --git a/doc/user/stored-programs.xml b/doc/user/stored-programs.xml index 891b90dd59..70efccc7af 100644 --- a/doc/user/stored-programs.xml +++ b/doc/user/stored-programs.xml @@ -1,3 +1,7 @@ +<!DOCTYPE section [ +<!ENTITY % tnt SYSTEM "../tnt.ent"> +%tnt; +]> <section xmlns="http://docbook.org/ns/docbook" version="5.0" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" @@ -6,8 +10,8 @@ <blockquote> <para> Lua is a light-weight, multi-paradigm embeddable language. - Stored procedures in Lua can be used to implement complex - data manipulation patterns and data structures. A + Stored procedures in Lua can be used to implement + data manipulation patterns or data structures. A server-side procedure written in Lua can select and modify data, access configuration and perform administrative tasks. It is possible to dynamically define, invoke, @@ -30,15 +34,16 @@ Found 1 tuple: </programlisting> In the language of the administrative console <olink targetptr="lua-command" /> evaluates an arbitrary - Lua chunk. "CALL" is the SQL standard statement the command - line client uses to represent the CALL command of the binary + Lua chunk. "CALL" is the SQL standard statement used + to represent the CALL command of the binary protocol. - In the example above, we first define a Lua procedure + In the example above, a Lua procedure is first defined using the text protocol of the administrative port, - and then invoke it using the Tarantool client-side SQL - parser, and then the binary protocol on the <olink targetptr="primary_port" />. + and then invoked using the Tarantool client-side SQL + parser plus the binary protocol on the <olink targetptr="primary_port" />. Since it's possible to execute any Lua chunk in the - administrative console, the newly created <code language="Pascal">function f1()</code> + administrative console, the newly created <code + language="Pascal">function f1()</code> can be called there too: <programlisting> <computeroutput> @@ -60,9 +65,9 @@ localhost> lua "hello".." world" <para> There is a single global Lua interpreter state, which is shared across all connections. Each connection, however, is - running in its own Lua <quote>thread</quote> -- a mechanism, akin to - Tarantool <quote>fibers</quote>. - Anything, prefixed with "lua " on the administrative console + running in its own Lua <emphasis>thread</emphasis> -- a mechanism, akin to + Tarantool <emphasis>fibers</emphasis>. + Anything prefixed with <code>lua </code> on the administrative console is sent directly to the interpreter. In the binary protocol, however, it is only possible to invoke Lua functions, but not define or modify them. @@ -71,39 +76,132 @@ localhost> lua "hello".." world" of the command, is passed into the stored procedure, each field of the tuple converted to a string parameter of the procedure. As long as currently Tarantool tuples are - type-agnostic, Lua strings are chosen as the transport means + type-agnostic, Lua strings are chosen as the transport media between the server and the interpreter. </para> <para> Every value, returned from a stored function by means of - <quote>return</quote> clause, is converted to Tarantool/Box tuple + <code>return</code> clause, is converted to Tarantool/Box tuple and sent back to the client in binary form. </para> + <para> + When a function in Lua terminates with an error, it is + returned to the client as <olink targetptr="ER_PROC_LUA" /> + return code, with the original error message preserved. + Similarly, an error occurred inside Tarantool (observed on the + client as an error code), when happens during execution of a + Lua procedure, produces a genuine Lua exception. + </para> <para> It's possible not only to invoke trivial Lua code, but call - into Tarantool/Box storage functionality, using <quote>box</quote> - Lua library. - The main means of communication between Lua and Tarantool - is <quote>box.process()</quote> function, which allows - to send any kind of request to the server in the binary form. - Function <quote>box.process()</quote> is a server-side outlet - for Tarantool binary protocol. Any tuple returned by the - server is converted to a Lua object of type <quote>box.tuple</quote> - and appended to the return list of <quote>box.process()</quote>. + into Tarantool/Box storage functionality, using + <code>box</code> + Lua library. The actual contents of the library can be + inspected at runtime: +<programlisting> +<computeroutput> +localhost> lua for k, v in pairs(box) do print(k, ": ", type(v)) end +--- +fiber: table +space: table +cfg: table +on_reload_configuration: function +update: function +process: function +delete: function +insert: function +select: function +index: table +unpack: function +replace: function +select_range: function +pack: function +... +</computeroutput> +</programlisting> + As is shown in the listing, <code>box</code> package ships: + <itemizedlist> + <listitem><para> + high-level functions, such as + <code>process(), update(), select(), select_range(), insert(), + replace(), delete()</code>, to manipulate + tuples and access spaces from Lua. + </para></listitem> + <listitem><para> + libraries, such as <code>cfg, space, fiber, index, tuple</code>, + to access server configuration, create, resume and + interrupt fibers, inspect content of spaces, indexes + and tuples. + </para></listitem> + </itemizedlist> + </para> + +<para> +<variablelist> + <title>Package <code>box</code> function index</title> + + <varlistentry> + <term> + <emphasis role="lua">box.process(op, request)</emphasis> + </term> + <listitem> + <para> + The main extension provided to Lua by + Tarantool/Box -- ability to call + INSERT/UPDATE/SELECT/DELETE from within a Lua + procedure. + </para> + <para> + This is a low-level API, and it expects + all arguments to be packed in accordance + with the binary protocol format (iproto + header excluded). + <bridgehead renderas="sect4">Parameters</bridgehead> + <simplelist> + <member><code>op</code> — number, Tarantool/Box command code, see + <link xlink:href="https://github.com/mailru/tarantool/blob/master/doc/box-protocol.txt"> + <filename>doc/box-protocol.txt</filename></link>, + </member> + <member><code>request</code> — request packed in binary + format</member> + </simplelist> + <bridgehead renderas="sect4">Returns</bridgehead> + This function returns zero or more tuples. + <bridgehead renderas="sect4">Errors</bridgehead> + Any server error produced by the executed command. + </para> + </listitem> + </varlistentry> +</variablelist> +</para> + + <para> + Some of the functionality is implemented The Lua source code of these wrappers, as well as a more + extensive documentation can be found in + <filename>mod/box/box.lua</filename> file in the source tree. + </para> + <para> + The main communication portal between Lua and Tarantool + is <code>box.process()</code> function, which directly + invokes the Tarantool command handler and allows + to send any kind of request to the server. + Any tuple returned by the + server is converted to a Lua object of type + <code>box.tuple</code> + and is appended to the return list of + <code>box.process()</code>. </para> <para> A few wrappers are defined to simplify the most common tasks: <itemizedlist> - <listitem><para><quote>box.select(space, key, ...)</quote> + <listitem><para><code>box.select(space, key, ...)</code> to retrieve tuples. </para></listitem> - <listitem><para><quote>box.replace(space, ...)</quote> + <listitem><para><code>box.replace(space, ...)</code> to insert and replace tuples. The tuple is constructed from all the remaining arguments passed into the function.</para></listitem> - <listitem><para><quote>box.update(space, key, tuple)</quote> and <quote>box.delete(space, key)</quote>for updates and deletes respectively.</para></listitem> + <listitem><para><code>box.update(space, key, tuple)</code> and <code>box.delete(space, key)</code>for updates and deletes respectively.</para></listitem> </itemizedlist> - The Lua source code of these wrappers, as well as a more - extensive documentation can be found in <filename>mod/box/box.lua</filename> file in the source tree. </para> </section> <!-- diff --git a/doc/user/target.db b/doc/user/target.db index ee0f957b3d..b7be49cea9 100644 --- a/doc/user/target.db +++ b/doc/user/target.db @@ -1 +1 @@ -<div element="book" href="#tarantool-user-guide" number="" targetptr="tarantool-user-guide"><ttl>Tarantool/Box User Guide, version 1.4.3-9-g472a615</ttl><xreftext>Tarantool/Box User Guide, version 1.4.3-9-g472a615</xreftext><div element="chapter" href="#idm34816" number="1"><ttl>Preface</ttl><xreftext>Chapter 1, <i>Preface</i></xreftext><div element="section" href="#preface" number="" targetptr="preface"><ttl>Tarantool/Box: an overview</ttl><xreftext>the section called “Tarantool/Box: an overviewâ€</xreftext></div><div element="section" href="#idp17776" number=""><ttl>Conventions</ttl><xreftext>the section called “Conventionsâ€</xreftext></div><div element="section" href="#idp26672" number=""><ttl>Reporting bugs</ttl><xreftext>the section called “Reporting bugsâ€</xreftext></div></div><div element="chapter" href="#idp220784" number="2"><ttl>Getting started</ttl><xreftext>Chapter 2, <i>Getting started</i></xreftext></div><div element="chapter" href="#idp221040" number="3"><ttl>Dynamic data model</ttl><xreftext>Chapter 3, <i>Dynamic data model</i></xreftext></div><div element="chapter" href="#language-reference" number="4" targetptr="language-reference"><ttl>Language reference</ttl><xreftext>Chapter 4, <i>Language reference</i></xreftext><div element="section" href="#idm28384" number=""><ttl>Data manipulation</ttl><xreftext>the section called “Data manipulationâ€</xreftext><div element="section" href="#idp360848" number=""><ttl>Memcached protocol</ttl><xreftext>the section called “Memcached protocolâ€</xreftext></div></div><div element="section" href="#idp364528" number=""><ttl>Administrative console</ttl><xreftext>the section called “Administrative consoleâ€</xreftext><obj element="term" href="#save-snapshot" number="" targetptr="save-snapshot"><ttl>???TITLE???</ttl><xreftext>SAVE SNAPSHOT</xreftext></obj><obj element="term" href="#reload-configuration" number="" targetptr="reload-configuration"><ttl>???TITLE???</ttl><xreftext>RELOAD CONFIGURATION</xreftext></obj><obj element="term" href="#show-configuration" number="" targetptr="show-configuration"><ttl>???TITLE???</ttl><xreftext>SHOW CONFIGURATION</xreftext></obj><obj element="term" href="#show-info" number="" targetptr="show-info"><ttl>???TITLE???</ttl><xreftext>SHOW INFO</xreftext></obj><obj element="term" href="#show-stat" number="" targetptr="show-stat"><ttl>???TITLE???</ttl><xreftext>SHOW STAT</xreftext></obj><obj element="term" href="#show-slab" number="" targetptr="show-slab"><ttl>???TITLE???</ttl><xreftext>SHOW SLAB</xreftext></obj><obj element="term" href="#show-palloc" number="" targetptr="show-palloc"><ttl>???TITLE???</ttl><xreftext>SHOW PALLOC</xreftext></obj><obj element="term" href="#save-coredump" number="" targetptr="save-coredump"><ttl>???TITLE???</ttl><xreftext>SAVE COREDUMP</xreftext></obj><obj element="term" href="#show-fiber" number="" targetptr="show-fiber"><ttl>???TITLE???</ttl><xreftext>SHOW FIBER</xreftext></obj><obj element="term" href="#lua-command" number="" targetptr="lua-command"><ttl>???TITLE???</ttl><xreftext>LUA ...</xreftext></obj></div><div element="section" href="#stored-programs" number="" targetptr="stored-programs"><ttl>Writing stored procedures in Lua</ttl><xreftext>the section called “Writing stored procedures in Luaâ€</xreftext></div></div><div element="chapter" href="#replication" number="5" targetptr="replication"><ttl>Replication</ttl><xreftext>Chapter 5, <i>Replication</i></xreftext><div element="section" href="#idp348160" number=""><ttl>Replication architecture</ttl><xreftext>the section called “Replication architectureâ€</xreftext></div><div element="section" href="#idp352928" number=""><ttl>Setting up the master</ttl><xreftext>the section called “Setting up the masterâ€</xreftext></div><div element="section" href="#idp263504" number=""><ttl>Setting up a replica</ttl><xreftext>the section called “Setting up a replicaâ€</xreftext></div><div element="section" href="#idp269840" number=""><ttl>Recovering from a degraded state</ttl><xreftext>the section called “Recovering from a degraded stateâ€</xreftext></div></div><div element="chapter" href="#configuration-reference" number="6" targetptr="configuration-reference"><ttl>Configuration reference</ttl><xreftext>Chapter 6, <i>Configuration reference</i></xreftext><div element="section" href="#idp661264" number=""><ttl>Command line options</ttl><xreftext>the section called “Command line optionsâ€</xreftext><obj element="listitem" href="#help-option" number="" targetptr="help-option"><ttl>???TITLE???</ttl><xreftext/></obj><obj element="listitem" href="#version-option" number="" targetptr="version-option"><ttl>???TITLE???</ttl><xreftext/></obj><obj element="listitem" href="#config-option" number="" targetptr="config-option"><ttl>???TITLE???</ttl><xreftext/></obj><obj element="option" href="#init-storage-option" number="" targetptr="init-storage-option"><ttl>???TITLE???</ttl><xreftext>--init-storage</xreftext></obj><obj element="option" href="#cat-option" number="" targetptr="cat-option"><ttl>???TITLE???</ttl><xreftext>--cat</xreftext></obj></div><div element="section" href="#option-file" number="" targetptr="option-file"><ttl>The option file</ttl><xreftext>option file</xreftext><obj element="table" href="#idp673888" number="6.1"><ttl>Basic parameters</ttl><xreftext>Table 6.1, “Basic parametersâ€</xreftext></obj><obj element="entry" href="#wal_dir" number="" targetptr="wal_dir"><ttl>???TITLE???</ttl><xreftext>wal_dir</xreftext></obj><obj element="entry" href="#snap_dir" number="" targetptr="snap_dir"><ttl>???TITLE???</ttl><xreftext>snap_dir</xreftext></obj><obj element="entry" href="#primary_port" number="" targetptr="primary_port"><ttl>???TITLE???</ttl><xreftext>primary_port</xreftext></obj><obj element="entry" href="#secondary_port" number="" targetptr="secondary_port"><ttl>???TITLE???</ttl><xreftext>secondary_port</xreftext></obj><obj element="entry" href="#admin_port" number="" targetptr="admin_port"><ttl>???TITLE???</ttl><xreftext>admin_port</xreftext></obj><obj element="entry" href="#custom_proc_title" number="" targetptr="custom_proc_title"><ttl>???TITLE???</ttl><xreftext>custom_proc_title</xreftext></obj><obj element="table" href="#idp722528" number="6.2"><ttl>Configuring the storage</ttl><xreftext>Table 6.2, “Configuring the storageâ€</xreftext></obj><obj element="anchor" href="#slab_alloc_arena" number="" targetptr="slab_alloc_arena"><ttl>???TITLE???</ttl><xreftext>slab_alloc_arena</xreftext></obj><obj element="para" href="#space" number="" targetptr="space"><ttl>???TITLE???</ttl><xreftext>the section called “The option fileâ€</xreftext></obj><obj element="table" href="#idp758544" number="6.3"><ttl>Binary logging and snapshots</ttl><xreftext>Table 6.3, “Binary logging and snapshotsâ€</xreftext></obj><obj element="table" href="#idp789952" number="6.4"><ttl>Replication</ttl><xreftext>Table 6.4, “Replicationâ€</xreftext></obj><obj element="entry" href="#replication_port" number="" targetptr="replication_port"><ttl>???TITLE???</ttl><xreftext>replication_port</xreftext></obj><obj element="entry" href="#replication_source" number="" targetptr="replication_source"><ttl>???TITLE???</ttl><xreftext>replication_source</xreftext></obj><obj element="table" href="#idp808928" number="6.5"><ttl>Networking</ttl><xreftext>Table 6.5, “Networkingâ€</xreftext></obj><obj element="table" href="#idp827696" number="6.6"><ttl>Logging</ttl><xreftext>Table 6.6, “Loggingâ€</xreftext></obj><obj element="table" href="#idp852592" number="6.7"><ttl>Memcached protocol support</ttl><xreftext>Table 6.7, “Memcached protocol supportâ€</xreftext></obj><obj element="anchor" href="#memcached_port" number="" targetptr="memcached_port"><ttl>???TITLE???</ttl><xreftext>memcached_port</xreftext></obj><obj element="anchor" href="#memcached_space" number="" targetptr="memcached_space"><ttl>???TITLE???</ttl><xreftext>memcached_space</xreftext></obj><obj element="anchor" href="#memcached_expire" number="" targetptr="memcached_expire"><ttl>???TITLE???</ttl><xreftext>memcached_expire</xreftext></obj></div></div><div element="chapter" href="#connectors" number="7" targetptr="connectors"><ttl>Connectors</ttl><xreftext>Chapter 7, <i>Connectors</i></xreftext><div element="section" href="#idp491568" number=""><ttl>C</ttl><xreftext>the section called “Câ€</xreftext></div><div element="section" href="#idp493696" number=""><ttl>Perl</ttl><xreftext>the section called “Perlâ€</xreftext></div><div element="section" href="#idp537824" number=""><ttl>PHP</ttl><xreftext>the section called “PHPâ€</xreftext></div><div element="section" href="#idp539168" number=""><ttl>Python</ttl><xreftext>the section called “Pythonâ€</xreftext></div><div element="section" href="#idp632096" number=""><ttl>Ruby</ttl><xreftext>the section called “Rubyâ€</xreftext><obj element="example" href="#idp636896" number="7.1"><ttl>userbox.rb</ttl><xreftext>Example 7.1, “userbox.rbâ€</xreftext></obj></div></div><div element="appendix" href="#proctitle" number="A" targetptr="proctitle"><ttl>Server process titles</ttl><xreftext>Appendix A, <i>Server process titles</i></xreftext></div><div element="appendix" href="#errcode" number="B" targetptr="errcode"><ttl>List of error codes</ttl><xreftext>Appendix B, <i>List of error codes</i></xreftext><obj element="term" href="#ER_NONMASTER" number="" targetptr="ER_NONMASTER"><ttl>???TITLE???</ttl><xreftext>ER_NONMASTER</xreftext></obj><obj element="term" href="#ER_ILLEGAL_PARAMS" number="" targetptr="ER_ILLEGAL_PARAMS"><ttl>???TITLE???</ttl><xreftext>ER_ILLEGAL_PARAMS</xreftext></obj><obj element="term" href="#ER_TUPLE_IS_RO" number="" targetptr="ER_TUPLE_IS_RO"><ttl>???TITLE???</ttl><xreftext>ER_TUPLE_IS_RO</xreftext></obj><obj element="term" href="#ER_MEMORY_ISSUE" number="" targetptr="ER_MEMORY_ISSUE"><ttl>???TITLE???</ttl><xreftext>ER_MEMORY_ISSUE</xreftext></obj><obj element="term" href="#ER_WAL_IO" number="" targetptr="ER_WAL_IO"><ttl>???TITLE???</ttl><xreftext>ER_WAL_IO</xreftext></obj><obj element="term" href="#ER_INDEX_VIOLATION" number="" targetptr="ER_INDEX_VIOLATION"><ttl>???TITLE???</ttl><xreftext>ER_INDEX_VIOLATION</xreftext></obj><obj element="term" href="#ER_NO_SUCH_SPACE" number="" targetptr="ER_NO_SUCH_SPACE"><ttl>???TITLE???</ttl><xreftext>ER_NO_SUCH_SPACE</xreftext></obj><obj element="term" href="#ER_NO_SUCH_INDEX" number="" targetptr="ER_NO_SUCH_INDEX"><ttl>???TITLE???</ttl><xreftext>ER_NO_SUCH_INDEX</xreftext></obj></div></div> +<div element="book" href="#tarantool-user-guide" number="" targetptr="tarantool-user-guide"><ttl>Tarantool/Box User Guide, version 1.4.3-9-g472a615</ttl><xreftext>Tarantool/Box User Guide, version 1.4.3-9-g472a615</xreftext><div element="chapter" href="#idm34816" number="1"><ttl>Preface</ttl><xreftext>Chapter 1, <i>Preface</i></xreftext><div element="section" href="#preface" number="" targetptr="preface"><ttl>Tarantool/Box: an overview</ttl><xreftext>the section called “Tarantool/Box: an overviewâ€</xreftext></div><div element="section" href="#idp17776" number=""><ttl>Conventions</ttl><xreftext>the section called “Conventionsâ€</xreftext></div><div element="section" href="#idp26672" number=""><ttl>Reporting bugs</ttl><xreftext>the section called “Reporting bugsâ€</xreftext></div></div><div element="chapter" href="#idp220784" number="2"><ttl>Getting started</ttl><xreftext>Chapter 2, <i>Getting started</i></xreftext></div><div element="chapter" href="#idp221040" number="3"><ttl>Dynamic data model</ttl><xreftext>Chapter 3, <i>Dynamic data model</i></xreftext></div><div element="chapter" href="#language-reference" number="4" targetptr="language-reference"><ttl>Language reference</ttl><xreftext>Chapter 4, <i>Language reference</i></xreftext><div element="section" href="#idp384848" number=""><ttl>Data manipulation</ttl><xreftext>the section called “Data manipulationâ€</xreftext><div element="section" href="#idp378896" number=""><ttl>Memcached protocol</ttl><xreftext>the section called “Memcached protocolâ€</xreftext></div></div><div element="section" href="#idp376016" number=""><ttl>Administrative console</ttl><xreftext>the section called “Administrative consoleâ€</xreftext><obj element="term" href="#save-snapshot" number="" targetptr="save-snapshot"><ttl>???TITLE???</ttl><xreftext>SAVE SNAPSHOT</xreftext></obj><obj element="term" href="#reload-configuration" number="" targetptr="reload-configuration"><ttl>???TITLE???</ttl><xreftext>RELOAD CONFIGURATION</xreftext></obj><obj element="term" href="#show-configuration" number="" targetptr="show-configuration"><ttl>???TITLE???</ttl><xreftext>SHOW CONFIGURATION</xreftext></obj><obj element="term" href="#show-info" number="" targetptr="show-info"><ttl>???TITLE???</ttl><xreftext>SHOW INFO</xreftext></obj><obj element="term" href="#show-stat" number="" targetptr="show-stat"><ttl>???TITLE???</ttl><xreftext>SHOW STAT</xreftext></obj><obj element="term" href="#show-slab" number="" targetptr="show-slab"><ttl>???TITLE???</ttl><xreftext>SHOW SLAB</xreftext></obj><obj element="term" href="#show-palloc" number="" targetptr="show-palloc"><ttl>???TITLE???</ttl><xreftext>SHOW PALLOC</xreftext></obj><obj element="term" href="#save-coredump" number="" targetptr="save-coredump"><ttl>???TITLE???</ttl><xreftext>SAVE COREDUMP</xreftext></obj><obj element="term" href="#show-fiber" number="" targetptr="show-fiber"><ttl>???TITLE???</ttl><xreftext>SHOW FIBER</xreftext></obj><obj element="term" href="#lua-command" number="" targetptr="lua-command"><ttl>???TITLE???</ttl><xreftext>LUA ...</xreftext></obj></div><div element="section" href="#stored-programs" number="" targetptr="stored-programs"><ttl>Writing stored procedures in Lua</ttl><xreftext>the section called “Writing stored procedures in Luaâ€</xreftext></div></div><div element="chapter" href="#replication" number="5" targetptr="replication"><ttl>Replication</ttl><xreftext>Chapter 5, <i>Replication</i></xreftext><div element="section" href="#idp348448" number=""><ttl>Replication architecture</ttl><xreftext>the section called “Replication architectureâ€</xreftext></div><div element="section" href="#idp353184" number=""><ttl>Setting up the master</ttl><xreftext>the section called “Setting up the masterâ€</xreftext></div><div element="section" href="#idp262720" number=""><ttl>Setting up a replica</ttl><xreftext>the section called “Setting up a replicaâ€</xreftext></div><div element="section" href="#idp269168" number=""><ttl>Recovering from a degraded state</ttl><xreftext>the section called “Recovering from a degraded stateâ€</xreftext></div></div><div element="chapter" href="#configuration-reference" number="6" targetptr="configuration-reference"><ttl>Configuration reference</ttl><xreftext>Chapter 6, <i>Configuration reference</i></xreftext><div element="section" href="#idp679424" number=""><ttl>Command line options</ttl><xreftext>the section called “Command line optionsâ€</xreftext><obj element="listitem" href="#help-option" number="" targetptr="help-option"><ttl>???TITLE???</ttl><xreftext/></obj><obj element="listitem" href="#version-option" number="" targetptr="version-option"><ttl>???TITLE???</ttl><xreftext/></obj><obj element="listitem" href="#config-option" number="" targetptr="config-option"><ttl>???TITLE???</ttl><xreftext/></obj><obj element="option" href="#init-storage-option" number="" targetptr="init-storage-option"><ttl>???TITLE???</ttl><xreftext>--init-storage</xreftext></obj><obj element="option" href="#cat-option" number="" targetptr="cat-option"><ttl>???TITLE???</ttl><xreftext>--cat</xreftext></obj></div><div element="section" href="#option-file" number="" targetptr="option-file"><ttl>The option file</ttl><xreftext>option file</xreftext><obj element="table" href="#idp692032" number="6.1"><ttl>Basic parameters</ttl><xreftext>Table 6.1, “Basic parametersâ€</xreftext></obj><obj element="entry" href="#wal_dir" number="" targetptr="wal_dir"><ttl>???TITLE???</ttl><xreftext>wal_dir</xreftext></obj><obj element="entry" href="#snap_dir" number="" targetptr="snap_dir"><ttl>???TITLE???</ttl><xreftext>snap_dir</xreftext></obj><obj element="entry" href="#primary_port" number="" targetptr="primary_port"><ttl>???TITLE???</ttl><xreftext>primary_port</xreftext></obj><obj element="entry" href="#secondary_port" number="" targetptr="secondary_port"><ttl>???TITLE???</ttl><xreftext>secondary_port</xreftext></obj><obj element="entry" href="#admin_port" number="" targetptr="admin_port"><ttl>???TITLE???</ttl><xreftext>admin_port</xreftext></obj><obj element="entry" href="#custom_proc_title" number="" targetptr="custom_proc_title"><ttl>???TITLE???</ttl><xreftext>custom_proc_title</xreftext></obj><obj element="table" href="#idp740672" number="6.2"><ttl>Configuring the storage</ttl><xreftext>Table 6.2, “Configuring the storageâ€</xreftext></obj><obj element="anchor" href="#slab_alloc_arena" number="" targetptr="slab_alloc_arena"><ttl>???TITLE???</ttl><xreftext>slab_alloc_arena</xreftext></obj><obj element="para" href="#space" number="" targetptr="space"><ttl>???TITLE???</ttl><xreftext>the section called “The option fileâ€</xreftext></obj><obj element="table" href="#idp776688" number="6.3"><ttl>Binary logging and snapshots</ttl><xreftext>Table 6.3, “Binary logging and snapshotsâ€</xreftext></obj><obj element="table" href="#idp808096" number="6.4"><ttl>Replication</ttl><xreftext>Table 6.4, “Replicationâ€</xreftext></obj><obj element="entry" href="#replication_port" number="" targetptr="replication_port"><ttl>???TITLE???</ttl><xreftext>replication_port</xreftext></obj><obj element="entry" href="#replication_source" number="" targetptr="replication_source"><ttl>???TITLE???</ttl><xreftext>replication_source</xreftext></obj><obj element="table" href="#idp827072" number="6.5"><ttl>Networking</ttl><xreftext>Table 6.5, “Networkingâ€</xreftext></obj><obj element="table" href="#idp845840" number="6.6"><ttl>Logging</ttl><xreftext>Table 6.6, “Loggingâ€</xreftext></obj><obj element="table" href="#idp870736" number="6.7"><ttl>Memcached protocol support</ttl><xreftext>Table 6.7, “Memcached protocol supportâ€</xreftext></obj><obj element="anchor" href="#memcached_port" number="" targetptr="memcached_port"><ttl>???TITLE???</ttl><xreftext>memcached_port</xreftext></obj><obj element="anchor" href="#memcached_space" number="" targetptr="memcached_space"><ttl>???TITLE???</ttl><xreftext>memcached_space</xreftext></obj><obj element="anchor" href="#memcached_expire" number="" targetptr="memcached_expire"><ttl>???TITLE???</ttl><xreftext>memcached_expire</xreftext></obj></div></div><div element="chapter" href="#connectors" number="7" targetptr="connectors"><ttl>Connectors</ttl><xreftext>Chapter 7, <i>Connectors</i></xreftext><div element="section" href="#idp247104" number=""><ttl>C</ttl><xreftext>the section called “Câ€</xreftext></div><div element="section" href="#idp253312" number=""><ttl>Perl</ttl><xreftext>the section called “Perlâ€</xreftext></div><div element="section" href="#idp645056" number=""><ttl>PHP</ttl><xreftext>the section called “PHPâ€</xreftext></div><div element="section" href="#idp646400" number=""><ttl>Python</ttl><xreftext>the section called “Pythonâ€</xreftext></div><div element="section" href="#idp647744" number=""><ttl>Ruby</ttl><xreftext>the section called “Rubyâ€</xreftext><obj element="example" href="#idp652656" number="7.1"><ttl>userbox.rb</ttl><xreftext>Example 7.1, “userbox.rbâ€</xreftext></obj></div></div><div element="appendix" href="#proctitle" number="A" targetptr="proctitle"><ttl>Server process titles</ttl><xreftext>Appendix A, <i>Server process titles</i></xreftext></div><div element="appendix" href="#errcode" number="B" targetptr="errcode"><ttl>List of error codes</ttl><xreftext>Appendix B, <i>List of error codes</i></xreftext><obj element="term" href="#ER_NONMASTER" number="" targetptr="ER_NONMASTER"><ttl>???TITLE???</ttl><xreftext>ER_NONMASTER</xreftext></obj><obj element="term" href="#ER_ILLEGAL_PARAMS" number="" targetptr="ER_ILLEGAL_PARAMS"><ttl>???TITLE???</ttl><xreftext>ER_ILLEGAL_PARAMS</xreftext></obj><obj element="term" href="#ER_TUPLE_IS_RO" number="" targetptr="ER_TUPLE_IS_RO"><ttl>???TITLE???</ttl><xreftext>ER_TUPLE_IS_RO</xreftext></obj><obj element="term" href="#ER_MEMORY_ISSUE" number="" targetptr="ER_MEMORY_ISSUE"><ttl>???TITLE???</ttl><xreftext>ER_MEMORY_ISSUE</xreftext></obj><obj element="term" href="#ER_WAL_IO" number="" targetptr="ER_WAL_IO"><ttl>???TITLE???</ttl><xreftext>ER_WAL_IO</xreftext></obj><obj element="term" href="#ER_INDEX_VIOLATION" number="" targetptr="ER_INDEX_VIOLATION"><ttl>???TITLE???</ttl><xreftext>ER_INDEX_VIOLATION</xreftext></obj><obj element="term" href="#ER_NO_SUCH_SPACE" number="" targetptr="ER_NO_SUCH_SPACE"><ttl>???TITLE???</ttl><xreftext>ER_NO_SUCH_SPACE</xreftext></obj><obj element="term" href="#ER_NO_SUCH_INDEX" number="" targetptr="ER_NO_SUCH_INDEX"><ttl>???TITLE???</ttl><xreftext>ER_NO_SUCH_INDEX</xreftext></obj><obj element="term" href="#ER_PROC_LUA" number="" targetptr="ER_PROC_LUA"><ttl>???TITLE???</ttl><xreftext>ER_PROC_LUA</xreftext></obj></div></div> diff --git a/doc/user/tnt.css b/doc/user/tnt.css index 28bf7088da..8088f9f639 100644 --- a/doc/user/tnt.css +++ b/doc/user/tnt.css @@ -5,6 +5,12 @@ color: green; } +.lua { + font-family: monospace; + font-weight: bold; +} + + .hl-keyword { color: green; font-weight: bold; diff --git a/mod/box/box.lua b/mod/box/box.lua index ecca4cd86f..9a1a0cd8f6 100644 --- a/mod/box/box.lua +++ b/mod/box/box.lua @@ -2,16 +2,16 @@ -- -- function box.select(space, index, ...) - key = {...} - return select(2, -- skip the first return from select, number of tuples - box.process(17, box.pack('iiiiii'..string.rep('p', #key), + local key = {...} + return box.process(17, + box.pack('iiiiii'..string.rep('p', #key), space, index, 0, -- offset 4294967295, -- limit 1, -- key count #key, -- key cardinality - unpack(key)))) + unpack(key))) end -- @@ -28,49 +28,50 @@ end -- index is always 0. It doesn't accept compound keys -- function box.delete(space, key) - return select(2, -- skip the first return, tuple count - box.process(21, box.pack('iiip', space, + return box.process(21, + box.pack('iiip', space, 1, -- flags, BOX_RETURN_TUPLE 1, -- cardinality - key))) + key)) end -- insert or replace a tuple function box.replace(space, ...) - tuple = {...} - return select(2, - box.process(13, box.pack('iii'..string.rep('p', #tuple), + local tuple = {...} + return box.process(13, + box.pack('iii'..string.rep('p', #tuple), space, 1, -- flags, BOX_RETURN_TUPLE #tuple, -- cardinality - unpack(tuple)))) + unpack(tuple))) end -- insert a tuple (produces an error if the tuple already exists) function box.insert(space, ...) - tuple = {...} - return select(2, - box.process(13, box.pack('iii'..string.rep('p', #tuple), - space, - 3, -- flags, BOX_RETURN_TUPLE | BOX_ADD - #tuple, -- cardinality - unpack(tuple)))) + local tuple = {...} + return box.process(13, + box.pack('iii'..string.rep('p', #tuple), + space, + 3, -- flags, BOX_RETURN_TUPLE | BOX_ADD + #tuple, -- cardinality + unpack(tuple))) end +-- function box.update(space, key, format, ...) - ops = {...} - return select(2, - box.process(19, box.pack('iiipi'..format, + local ops = {...} + return box.process(19, + box.pack('iiipi'..format, space, 1, -- flags, BOX_RETURN_TUPLE 1, -- cardinality key, -- primary key #ops/2, -- op count - ...))) + unpack(ops))) end function box.on_reload_configuration() - index_mt = {} + local index_mt = {} -- __len and __index index_mt.len = function(index) return #index.idx end index_mt.__newindex = function(table, index) @@ -84,7 +85,7 @@ function box.on_reload_configuration() return index.idx.next, index.idx, nil end -- index_mt.range = function(index, limit, ...) - range = {} + local range = {} for k, v in index.idx.next, index.idx, ... do if #range >= limit then break @@ -94,7 +95,7 @@ function box.on_reload_configuration() return unpack(range) end -- - space_mt = {} + local space_mt = {} space_mt.len = function(space) return space.index[0]:len() end space_mt.__newindex = index_mt.__newindex space_mt.select = function(space, ...) return box.select(space.n, ...) end @@ -104,7 +105,7 @@ function box.on_reload_configuration() space_mt.delete = function(space, ...) return box.delete(space.n, ...) end space_mt.truncate = function(space) while true do - k, v = space.index[0].idx:next() + local k, v = space.index[0].idx:next() if v == nil then break end diff --git a/mod/box/box_lua.m b/mod/box/box_lua.m index 5988d13766..4d21f8c319 100644 --- a/mod/box/box_lua.m +++ b/mod/box/box_lua.m @@ -540,15 +540,20 @@ iov_add_multret(struct lua_State *L) } static void -box_lua_dup_u32(u32 u32) +box_lua_dup_u32(u32 u32 __attribute__((unused))) { - lua_pushinteger(in_txn()->L, u32); + /* + * Do nothing -- the only u32 Box can give us is + * tuple count, and we don't need it, since we intercept + * everything into Lua stack first. + * @sa iov_add_multret + */ } static void -box_lua_add_u32(u32 *p_u32) +box_lua_add_u32(u32 *p_u32 __attribute__((unused))) { - box_lua_dup_u32(*p_u32); /* xxx: this can't be done properly in Lua */ + /* See the comment in box_lua_dup_u32. */ } static void diff --git a/test/box/lua.result b/test/box/lua.result index eb600ed9a9..a9cb24b407 100644 --- a/test/box/lua.result +++ b/test/box/lua.result @@ -73,22 +73,18 @@ lua print(box.pack('p', 'this string is 45 characters long 1234567890 ')) ... lua box.process(13, box.pack('iiippp', 0, 1, 3, 1, 'testing', 'lua rocks')) --- - - 1 - 1: {'testing', 'lua rocks'} ... lua box.process(17, box.pack('iiiiiip', 0, 0, 0, 2^31, 1, 1, 1)) --- - - 0 - 1: {'testing', 'lua rocks'} ... lua box.process(21, box.pack('iiip', 0, 1, 1, 1)) --- - - 1 - 1: {'testing', 'lua rocks'} ... lua box.process(17, box.pack('iiiiiip', 0, 0, 0, 2^31, 1, 1, 1)) --- - - 0 ... lua box.process(22, box.pack('iii', 0, 0, 0)) --- -- GitLab