Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
T
tarantool
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
core
tarantool
Commits
76f3942f
Commit
76f3942f
authored
11 years ago
by
ocelot-inc
Browse files
Options
Downloads
Patches
Plain Diff
stored-procedures.xml revised box.net.box
parent
33b80295
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
doc/user/stored-procedures.xml
+147
-116
147 additions, 116 deletions
doc/user/stored-procedures.xml
with
147 additions
and
116 deletions
doc/user/stored-procedures.xml
+
147
−
116
View file @
76f3942f
...
...
@@ -1315,7 +1315,7 @@ localhost> <userinput>lua t:transform(1,2,'x')</userinput>
then the result is returned.
</para>
<bridgehead
renderas=
"sect4"
>
Example
</bridgehead>
<programlisting>
localhost
>
lua t=box.tuple.new({'Field#1','Field#2','Field#3','Field#4','Field#5'})
<programlisting>
localhost
>
<userinput>
lua t=box.tuple.new({'Field#1','Field#2','Field#3','Field#4','Field#5'})
</userinput>
---
...
localhost
>
<userinput>
lua t:slice(1,3)
</userinput>
...
...
@@ -2619,75 +2619,41 @@ end
<section
xml:id=
"sp-box-net-box"
>
<title>
Package
<code>
box.net.box
</code>
—
working with networked Tarantool peers
</title>
<simpara>
Library
<code>
box.net
</code>
contains connectors
to remote database systems, such as MariaDB or PostgreSQL.
The first supported system is Tarantool itself.
The
<code>
box.net
</code>
library contains connectors to remote database systems.
One variant,
<code>
box.net.sql
</code>
, is for connecting to MySQL or MariaDB or PostgreSQL
—
that variant is the subject of the
<quote>
SQL DBMS plugins
</quote>
appendix.
In this section the subject is the built-in variant,
<code>
box.net.box
</code>
.
This is for connecting to tarantool_box servers via a network.
</simpara>
<variablelist
xml:id=
"box.net.box"
>
<simpara>
The basic object provided by
<code>
box.net.box
</code>
library is a connection. A connection is created by
calling
<code>
box.net.box.new()
</code>
. To
execute remote requests, simply invoke methods of the
connection object, a physical connection is established
upon request and is re-established if necessary.
When done, issue
<code>
conn:close()
</code>
. Connection
objects are garbage collected just like any other objects
in Lua, so an explicit destruction is not mandatory.
However, since
<code>
close()
</code>
is a system call, it
is a good programming practice to close a connection
explicitly when it is no longer needed, to avoid lengthy
stalls of the garbage collector.
</simpara>
<simpara>
The library also provides a pre-created connection object
to the local server,
<code>
box.net.self
</code>
. This
connection is always
<quote>
established
</quote>
. The
purpose of this object is to make polymorphic use of the
<code>
box.net.box
</code>
API easier. There is an
important difference, however, between the embedded
connection and a remote one. With the embedded connection,
requests which do not modify data do not yield. When using
a remote connection, it is important to keep in mind that
any request can yield, and local database state may
have changed by the time it returns.
Call
<code>
box.net.box.new()
</code>
to connect and get a connection object,
which will be called
<code>
conn
</code>
for examples in this section.
Call the other
<code>
box.net.box()
</code>
routines, passing
<code>
conn
</code>
,
to execute requests on the remote box.
Call
<code>
box.net.box.close(conn)
</code>
to disconnect.
Object-oriented and functional APIs are equivalent, so
<code>
conn:close()
</code>
is the same as
<code>
box.net.box.close(conn)
</code>
.
</simpara>
<simpara>
All
<code>
box.net.box
</code>
methods are fiber-safe
. It'
s
All
<code>
box.net.box
</code>
methods are fiber-safe
, that is, it i
s
safe to share and use the same connection object across
multiple concurrent fibers.
In fact, it's perhaps the
best programming practice with Tarantool
: w
hen multiple
multiple concurrent fibers. In fact, it's perhaps the
best programming practice with Tarantool
. W
hen multiple
fibers use the same connection, all requests are pipelined
through the same network socket, but each fiber gets a
correct response
back
. Reducing the number of active sockets
through the same network socket, but each fiber gets
back
a
correct response. Reducing the number of active sockets
lowers the overhead of system calls and increases the
overall server performance. There are, however cases, when
a single connection is not enough: when it's necessary to
prioritize requests, use different authentication ids,
etc.
</simpara>
<simpara>
All remote calls support execution timeouts. A specialized
wrapper,
<code>
box.net.box.timeout()
</code>
allows setting
a timeout. Using a wrapper object makes the remote
connection API compatible with the local one, removing
the need for a separate
<code>
timeout
</code>
argument, ignored
by the local version. Once sent, a
request can not be revoked from the remote server even if
a timeout expires: the expired timeout only aborts the
wait for the remote server response.
<code>
box.net.box.timeout()
</code>
,
</simpara>
<simpara>
Object-oriented and functional APIs are equivalent:
<code>
conn:close()
</code>
is identical to
<code>
box.net.box.close(conn)
</code>
.
overall server performance. There are, however, cases when
a single connection is not enough
—
for example when it's necessary to
prioritize requests or to use different authentication ids.
</simpara>
<varlistentry>
<term>
<emphasis
role=
"lua"
xml:id=
"box.net.box.new"
>
conn = box.net.box.new(
host, port [,
reconnect_interval])
</emphasis>
conn = box.net.box.new(
<replaceable>
host
</replaceable>
,
<replaceable>
port
</replaceable>
[,
<replaceable>
reconnect_interval
</replaceable>
])
</emphasis>
</term>
<listitem>
<para>
...
...
@@ -2697,155 +2663,220 @@ end
a disconnect. The argument
<code>
reconnect_interval
</code>
(in seconds) is
responsible for the amount of time the server
sleeps between failing attempts to reconnect. The
returned object supports methods for making remote
calls, such as select, update or delete.
sleeps between failing attempts to reconnect.
The returned
<code>
conn
</code>
object supports methods for making remote
requests, such as select, update or delete.
Example:
<code>
conn = box.net.box.new('localhost', 33013)
</code>
.
</para>
<para>
For the local tarantool_box server there is a pre-created always-established
connection object named
<code>
box.net.self
</code>
.
Its purpose is to make polymorphic use of the
<code>
box.net.box
</code>
API easier. Therefore
<code>
conn = box.net.box.new('localhost', 33013)
</code>
can
be replaced by
<code>
conn = box.net.box.self
</code>
.
However, there is an important difference between the embedded
connection and a remote one. With the embedded connection,
requests which do not modify data do not yield. When using
a remote connection, any request can yield, and local database state may
have changed by the time it returns.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis
role=
"lua"
xml:id=
"box.net.box.ping"
>
conn:ping()
</emphasis></term>
conn:ping()
</emphasis></term>
<listitem>
<para>
Execute a PING command.
Returns
<code>
true
</code>
on success,
<code>
false
</code>
on error.
<code>
false
</code>
on error.
Example:
<code>
self:ping()
</code>
.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis
role=
"lua"
xml:id=
"box.net.box.close"
>
conn:close()
</emphasis></term>
conn:close()
</emphasis></term>
<listitem>
<para>
Close a connection. The connection is also
closed when it's garbage collected. It's still
recommended to close connections explicitly,
to spare the garbage collector from heavy work
such as closing the socket.
Close a connection. Example:
<code>
conn:close()
</code>
.
</para>
<para>
Connection objects are garbage collected just like any other objects
in Lua, so an explicit destruction is not mandatory.
However, since
<code>
close()
</code>
is a system call, it
is good programming practice to close a connection
explicitly when it is no longer needed, to avoid lengthy
stalls of the garbage collector.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis
role=
"lua"
xml:id=
"box.net.box.select"
>
conn:select(
space_no, index_no
, ...)
</emphasis></term>
conn:select(
<replaceable>
space_no
</replaceable>
,
<replaceable>
index_no
</replaceable>
, ...)
</emphasis></term>
<listitem>
<para>
See
<code
xlink:href=
"#box.select"
>
box.select(...)
</code>
.
Please note, that unlike a local
<code>
box.select()
</code>
any call to a remote
server yields, thus local data may change while
remote
<code>
select()
</code>
is running.
<code>
conn:select(...)
</code>
is the remote-call equivalent of the local call
<code
xlink:href=
"#box.select"
>
box.select(...)
</code>
.
Please note this difference: a local
<code>
box.select()
</code>
does not yield,
but a remote
<code>
conn:select()
</code>
call does yield,
so local data may change while a remote
<code>
conn:select()
</code>
is running.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis
role=
"lua"
xml:id=
"box.net.box.select_limit"
>
conn:select_limit(
space_no, index_no, offset, limit
, ...)
</emphasis></term>
conn:select_limit(
<replaceable>
space_no
</replaceable>
,
<replaceable>
index_no
</replaceable>
,
<replaceable>
offset
</replaceable>
,
<replaceable>
limit
</replaceable>
, ...)
</emphasis></term>
<listitem>
<para>
See
<code
xlink:href=
"#box.select_limit"
>
box.select_limit(...)
</code>
<code>
conn:select_limit(...)
</code>
is the remote-call equivalent of the local call
<code
xlink:href=
"#box.select_limit"
>
box.select_limit(...)
</code>
.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis
role=
"lua"
xml:id=
"box.net.box.select_range"
>
conn:select_range(
space_no, index_no, limit, key
, ...)
</emphasis></term>
conn:select_range(
<replaceable>
space_no
</replaceable>
,
<replaceable>
index_no
</replaceable>
,
<replaceable>
limit
</replaceable>
,
<replaceable>
key
</replaceable>
, ...)
</emphasis></term>
<listitem>
<para>
See
<code
xlink:href=
"#box.select_range"
>
box.select_range(...)
</code>
.
<code>
conn:select_range(...)
</code>
is the remote-call equivalent of the local call
<code
xlink:href=
"#box.select_range"
>
box.select_range(...)
</code>
.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis
role=
"lua"
xml:id=
"box.net.box.insert"
>
conn:insert(space_no, ...)
</emphasis></term>
<term><emphasis
role=
"lua"
xml:id=
"box.net.box.insert"
>
conn:insert(
<replaceable>
space_no
</replaceable>
, ...)
</emphasis></term>
<listitem>
<para>
See
<code
xlink:href=
"#box.insert"
>
box.insert(...)
</code>
.
<code>
conn:insert(...)
</code>
is the remote-call equivalent of the local call
<code
xlink:href=
"#box.insert"
>
box.insert(...)
</code>
.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis
role=
"lua"
xml:id=
"box.net.box.replace"
>
conn:replace(space_no, ...)
</emphasis></term>
<term><emphasis
role=
"lua"
xml:id=
"box.net.box.replace"
>
conn:replace(
<replaceable>
space_no
</replaceable>
, ...)
</emphasis></term>
<listitem>
<para>
See
<code
xlink:href=
"#box.replace"
>
box.replace(...)
</code>
.
<code>
conn:replace(...)
</code>
is the remote-call equivalent of the local call
<code
xlink:href=
"#box.replace"
>
box.replace(...)
</code>
.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis
role=
"lua"
xml:id=
"box.net.box.update"
>
conn:update(...)
</emphasis></term>
<term><emphasis
role=
"lua"
xml:id=
"box.net.box.update"
>
conn:update(
<replaceable>
space_no
</replaceable>
,
<replaceable>
key
</replaceable>
,
<replaceable>
format
</replaceable>
, ...)
</emphasis></term>
<listitem>
<para>
See
<code
xlink:href=
"#box.update"
>
box.update(...)
</code>
.
<code>
conn:update(...)
</code>
is the remote-call equivalent of the local call
<code
xlink:href=
"#box.update"
>
box.update(...)
</code>
.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis
role=
"lua"
xml:id=
"box.net.box.delete"
>
conn:delete(space_no, key)
</emphasis></term>
<term><emphasis
role=
"lua"
xml:id=
"box.net.box.delete"
>
conn:delete(
<replaceable>
space_no
</replaceable>
,
<replaceable>
key
</replaceable>
)
</emphasis></term>
<listitem>
<para>
See
<code
xlink:href=
"#box.delete"
>
box.delete(...)
</code>
.
<code>
conn:delete(...)
</code>
is the remote-call equivalent of the local call
<code
xlink:href=
"#box.delete"
>
box.delete(...)
</code>
.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis
role=
"lua"
xml:id=
"box.net.box.call"
>
conn:call(proc_name, ...)
</emphasis></term>
<term><emphasis
role=
"lua"
xml:id=
"box.net.box.call"
>
conn:call(
<replaceable>
proc_name
</replaceable>
[,
<replaceable>
arguments
</replaceable>
])
</emphasis></term>
<listitem>
<para>
Call a remote stored procedure, such as
<code>
box.select_reverse_range()
</code>
.
<para>
<code>
conn:call('proc','1','2','3')
</code>
is the remote-call equivalent of
<code>
CALL proc('1','2','3')
</code>
.
That is, box.net.box.call is a remote stored-procedure call.
Please keep in mind that the call is using
the binary protocol to pack procedure arguments,
and since the latter is type-agnostic it's recommended
to pass all arguments of remote stored procedure as
strings, for example:
<programlisting>
conn:call("box.select_reverse_range", "1", "4", "10", "Smith")
</programlisting>
and the binary protocol is type agnostic, so it's recommended
to pass all arguments of remote stored procedure calls as
strings. Example:
<code>
conn:call("box.select_reverse_range", "1", "4", "10", "Smith")
</code>
.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis
role=
"lua"
xml:id=
"box.net.box.timeout"
>
conn:timeout(timeout)
</emphasis></term>
<term><emphasis
role=
"lua"
xml:id=
"box.net.box.timeout"
>
conn:timeout(
<replaceable>
timeout
</replaceable>
)
</emphasis></term>
<listitem>
<para>
Returns a closure which is identical to the
invoked function, except for the added timeout
functionality.
<programlisting>
-- wait for 'update' until it is finished
local tuple = conn:update('1', 'key', ...)
-- send update but don't bother to wait for results
local other = conn:timeout(0):update('1', 'arg1', ...)
</programlisting>
</para>
<code>
timeout(...)
</code>
is a wrapper which sets a timeout for the request that follows it.
Example:
<code>
conn:timeout(0):update('1', 'arg1', 15)
</code>
.
</para>
<para>
All remote calls support execution timeouts.
Using a wrapper object makes the remote
connection API compatible with the local one, removing
the need for a separate
<code>
timeout
</code>
argument, which
the local version would ignore. Once a request is sent,
it cannot be revoked from the remote server even if
a timeout expires: the timeout expiration only aborts the
wait for the remote server response, not the request itself.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead
renderas=
"sect4"
>
Example
</bridgehead>
<programlisting>
-- connect to the local server
local self = box.net.box.new('127.0.0.1', box.info.primary_port)
self:insert("1", "Hello", "World")
<bridgehead
renderas=
"sect4"
>
Example showing use of most of the box.net.box methods
</bridgehead>
<para>
This example will work with the sandbox configuration described in the preface.
That is, there is a space[0] with a numeric primary key.
Assume that the database is nearly empty.
Assume that the tarantool_box server is running on localhost 127.0.0.1:33013.
<programlisting><prompt>
localhost
>
</prompt>
<userinput>
setopt delimiter = '!'
</userinput>
<prompt>
localhost
>
</prompt>
<userinput>
lua function example()
</userinput>
<prompt>
-
>
</prompt>
<userinput>
if self:ping() then
</userinput>
<prompt>
-
>
</prompt>
<userinput>
print("self:ping() succeeded (not surprising since self is a pre-established connection).")
</userinput>
<prompt>
-
>
</prompt>
<userinput>
end
</userinput>
<prompt>
-
>
</prompt>
<userinput>
if box.cfg.primary_port == 33013 then
</userinput>
<prompt>
-
>
</prompt>
<userinput>
print('The local server primary port number is 33013 (the default)')
</userinput>
<prompt>
-
>
</prompt>
<userinput>
else
</userinput>
<prompt>
-
>
</prompt>
<userinput>
print('The local server primary port number is not 33013, so connect will fail')
</userinput>
<prompt>
-
>
</prompt>
<userinput>
end
</userinput>
<prompt>
-
>
</prompt>
<userinput>
conn = box.net.box.new('127.0.0.1', 33013)
</userinput>
<prompt>
-
>
</prompt>
<userinput>
conn:delete(0,800)
</userinput>
<prompt>
-
>
</prompt>
<userinput>
print('conn:delete done on space[0].')
</userinput>
<prompt>
-
>
</prompt>
<userinput>
conn:insert(0,800,'data')
</userinput>
<prompt>
-
>
</prompt>
<userinput>
print('conn:insert done on space[0], index 0. primary key value = 800.')
</userinput>
<prompt>
-
>
</prompt>
<userinput>
wtuple = conn:select(0,0,800)
</userinput>
<prompt>
-
>
</prompt>
<userinput>
print('conn:select done on space[0], index 0. number of fields = ', #wtuple)
</userinput>
<prompt>
-
>
</prompt>
<userinput>
conn:delete(0,800)
</userinput>
<prompt>
-
>
</prompt>
<userinput>
print('conn:delete done on space[0].')
</userinput>
<prompt>
-
>
</prompt>
<userinput>
conn:replace(0,800,'New data','Extra data')
</userinput>
<prompt>
-
>
</prompt>
<userinput>
print('conn:replace done on space[0].')
</userinput>
<prompt>
-
>
</prompt>
<userinput>
conn:timeout(0):update(0,800,'=p=p=p',1, 'Field#1', 2,'Field#2', 3,'Field#3')
</userinput>
<prompt>
-
>
</prompt>
<userinput>
print('conn:update done on space[0], timed out after waiting 0 seconds for a return')
</userinput>
<prompt>
-
>
</prompt>
<userinput>
conn:close()
</userinput>
<prompt>
-
>
</prompt>
<userinput>
print('conn:close done')
</userinput>
<prompt>
-
>
</prompt>
<userinput>
end!
</userinput>
---
...
<prompt>
localhost
>
</prompt>
<userinput>
setopt delimiter = ''!
</userinput>
<prompt>
localhost
>
</prompt>
<userinput>
lua example()
</userinput>
---
self:ping() succeeded (not surprising since self is a pre-established connection).
The local server primary port number is 33013 (the default)
conn:delete done on space[0].
conn:insert done on space[0], index 0. primary key value = 800.
conn:select done on space[0], index 0. number of fields = 2
conn:delete done on space[0].
conn:replace done on space[0].
conn:update done on space[0], timed out after waiting 0 seconds for a return
conn:close done
...
<prompt>
localhost
>
</prompt>
<userinput>
select * from t0 where k0 = 800 # Prove that the update succeeded.
</userinput>
Select OK, 1 rows affected
[800, 'Field#1', 'Field#2', 'Field#3']
</programlisting>
</para>
</section>
<section
xml:id=
"sp-box-cfg"
>
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment