|
1 | 1 | .. _getting_started-go: |
2 | 2 |
|
3 | | --------------------------------------------------------------------------------- |
4 | 3 | Connecting from Go |
5 | | --------------------------------------------------------------------------------- |
| 4 | +================== |
6 | 5 |
|
7 | | -.. _getting_started-go-pre-requisites: |
| 6 | +**Examples on GitHub**: `sample_db <https://github.com/tarantool/doc/tree/latest/doc/code_snippets/snippets/connectors/instances.enabled/sample_db>`_, `go <https://github.com/tarantool/doc/tree/latest/doc/code_snippets/snippets/connectors/go>`_ |
8 | 7 |
|
9 | | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
10 | | -Pre-requisites |
11 | | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 8 | +The tutorial shows how to use the `go-tarantool <https://github.com/tarantool/go-tarantool#installation>`__ library to connect to a remote Tarantool instance, perform CRUD operations, and execute stored procedures. |
12 | 9 |
|
13 | | -Before we proceed: |
| 10 | +.. _getting_started_go_sample_db: |
14 | 11 |
|
15 | | -#. `Install <https://github.com/tarantool/go-tarantool#installation>`__ |
16 | | - the ``go-tarantool`` library. |
| 12 | +Sample database configuration |
| 13 | +----------------------------- |
17 | 14 |
|
18 | | -#. :ref:`Start <getting_started_db>` Tarantool (locally or in Docker) |
19 | | - and make sure that you have created and populated a database as we suggested |
20 | | - :ref:`earlier <creating-db-locally>`: |
| 15 | +.. include:: getting_started_net_box.rst |
| 16 | + :start-after: connectors_sample_db_config_start |
| 17 | + :end-before: connectors_sample_db_config_end |
21 | 18 |
|
22 | | - .. code-block:: lua |
| 19 | +.. _getting_started_go_sample_db_start: |
23 | 20 |
|
24 | | - box.cfg{listen = 3301} |
25 | | - s = box.schema.space.create('tester') |
26 | | - s:format({ |
27 | | - {name = 'id', type = 'unsigned'}, |
28 | | - {name = 'band_name', type = 'string'}, |
29 | | - {name = 'year', type = 'unsigned'} |
30 | | - }) |
31 | | - s:create_index('primary', { |
32 | | - type = 'hash', |
33 | | - parts = {'id'} |
34 | | - }) |
35 | | - s:create_index('secondary', { |
36 | | - type = 'hash', |
37 | | - parts = {'band_name'} |
38 | | - }) |
39 | | - s:insert{1, 'Roxette', 1986} |
40 | | - s:insert{2, 'Scorpions', 2015} |
41 | | - s:insert{3, 'Ace of Base', 1993} |
| 21 | +Starting a sample database application |
| 22 | +-------------------------------------- |
42 | 23 |
|
43 | | - .. IMPORTANT:: |
| 24 | +To try out ``go-tarantool``, you need to start the :ref:`sample_db <getting_started_net_box_sample_db>` application using ``tt start``: |
44 | 25 |
|
45 | | - Please do not close the terminal window |
46 | | - where Tarantool is running -- you'll need it soon. |
| 26 | +.. code-block:: console |
47 | 27 |
|
48 | | -#. In order to connect to Tarantool as an administrator, reset the password |
49 | | - for the ``admin`` user: |
| 28 | + $ tt start sample_db |
50 | 29 |
|
51 | | - .. code-block:: lua |
| 30 | +Now you can create a client Go application that makes requests to this database. |
52 | 31 |
|
53 | | - box.schema.user.passwd('pass') |
54 | 32 |
|
55 | | -.. _getting_started-go-connecting: |
| 33 | +.. _getting_started_go_create_client_app: |
56 | 34 |
|
57 | | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
58 | 35 | Connecting to Tarantool |
59 | | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 36 | +----------------------- |
60 | 37 |
|
61 | | -To get connected to the Tarantool server, write a simple Go program: |
| 38 | +.. _getting_started_go_creating_connection: |
62 | 39 |
|
63 | | -.. code-block:: go |
| 40 | +Creating a connection |
| 41 | +~~~~~~~~~~~~~~~~~~~~~ |
64 | 42 |
|
65 | | - package main |
| 43 | +Import ``go-tarantool``: |
66 | 44 |
|
67 | | - import ( |
68 | | - "fmt" |
| 45 | +.. literalinclude:: /code_snippets/snippets/connectors/go/hello.go |
| 46 | + :language: go |
| 47 | + :start-at: package main |
| 48 | + :end-before: func main() |
| 49 | + :dedent: |
69 | 50 |
|
70 | | - "github.com/tarantool/go-tarantool" |
71 | | - ) |
| 51 | +To create a connection, pass a database URI as follows: |
72 | 52 |
|
73 | | - func main() { |
| 53 | +.. literalinclude:: /code_snippets/snippets/connectors/go/hello.go |
| 54 | + :language: go |
| 55 | + :start-at: func main() |
| 56 | + :end-at: // Interacting with the database |
| 57 | + :dedent: |
74 | 58 |
|
75 | | - conn, err := tarantool.Connect("127.0.0.1:3301", tarantool.Opts{ |
76 | | - User: "admin", |
77 | | - Pass: "pass", |
78 | | - }) |
79 | 59 |
|
80 | | - if err != nil { |
81 | | - log.Fatalf("Connection refused") |
82 | | - } |
83 | 60 |
|
84 | | - defer conn.Close() |
| 61 | +.. _getting_started_go_using_data_operations: |
85 | 62 |
|
86 | | - // Your logic for interacting with the database |
87 | | - } |
| 63 | +Using data operations |
| 64 | +~~~~~~~~~~~~~~~~~~~~~ |
88 | 65 |
|
89 | | -The default user is ``guest``. |
| 66 | +.. _getting_started_go_inserting_data: |
90 | 67 |
|
91 | | -.. _getting_started-go-manipulate: |
92 | | - |
93 | | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
94 | | -Manipulating the data |
95 | | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
96 | | - |
97 | | -.. _getting_started-go-insert: |
98 | | - |
99 | | -******************************************************************************** |
100 | 68 | Inserting data |
101 | | -******************************************************************************** |
102 | | - |
103 | | -To insert a :term:`tuple` into a :term:`space`, use ``Insert``: |
104 | | - |
105 | | -.. code-block:: go |
| 69 | +************** |
106 | 70 |
|
107 | | - resp, err = conn.Insert("tester", []interface{}{4, "ABBA", 1972}) |
| 71 | +In the example below, four tuples are inserted into the ``bands`` space: |
108 | 72 |
|
109 | | -This inserts the tuple ``(4, "ABBA", 1972)`` into a space named ``tester``. |
| 73 | +.. literalinclude:: /code_snippets/snippets/connectors/go/hello.go |
| 74 | + :language: go |
| 75 | + :start-after: // Insert data |
| 76 | + :end-before: Last inserted tuple: |
| 77 | + :dedent: |
110 | 78 |
|
111 | | -The response code and data are available in the |
112 | | -`tarantool.Response <https://github.com/tarantool/go-tarantool#usage>`_ |
113 | | -structure: |
114 | 79 |
|
115 | | -.. code-block:: go |
116 | 80 |
|
117 | | - code := resp.Code |
118 | | - data := resp.Data |
| 81 | +.. _getting_started_go_querying_data: |
119 | 82 |
|
120 | | -.. _getting_started-go-query: |
121 | | - |
122 | | -******************************************************************************** |
123 | 83 | Querying data |
124 | | -******************************************************************************** |
125 | | - |
126 | | -To select a tuple from a space, use |
127 | | -`Select <https://github.com/tarantool/go-tarantool#api-reference>`_: |
128 | | - |
129 | | -.. code-block:: go |
| 84 | +************* |
130 | 85 |
|
131 | | - resp, err = conn.Select("tester", "primary", 0, 1, tarantool.IterEq, []interface{}{4}) |
| 86 | +The example below shows how to get a tuple by the specified primary key value: |
132 | 87 |
|
133 | | -This selects a tuple by the primary key with ``offset = 0`` and ``limit = 1`` |
134 | | -from a space named ``tester`` (in our example, this is the index named ``primary``, |
135 | | -based on the ``id`` field of each tuple). |
| 88 | +.. literalinclude:: /code_snippets/snippets/connectors/go/hello.go |
| 89 | + :language: go |
| 90 | + :start-after: // Select by primary key |
| 91 | + :end-before: Select a tuple by the primary key value |
| 92 | + :dedent: |
136 | 93 |
|
137 | | -Next, select tuples by a secondary key. |
| 94 | +You can also get a tuple by the value of the specified index as follows: |
138 | 95 |
|
139 | | -.. code-block:: go |
| 96 | +.. literalinclude:: /code_snippets/snippets/connectors/go/hello.go |
| 97 | + :language: go |
| 98 | + :start-after: // Select by secondary key |
| 99 | + :end-before: Select a tuple by the secondary key value |
| 100 | + :dedent: |
140 | 101 |
|
141 | | - resp, err = conn.Select("tester", "secondary", 0, 1, tarantool.IterEq, []interface{}{"ABBA"}) |
142 | 102 |
|
143 | | -Finally, it would be nice to select all the tuples in a space. But there is no |
144 | | -one-liner for this in Go; you would need a script like |
145 | | -:ref:`this one <cookbook-select-all-go>`. |
146 | 103 |
|
147 | | -For more examples, see https://github.com/tarantool/go-tarantool#usage |
| 104 | +.. _getting_started_go_updating_data: |
148 | 105 |
|
149 | | -.. _getting_started-go-update: |
150 | | - |
151 | | -******************************************************************************** |
152 | 106 | Updating data |
153 | | -******************************************************************************** |
154 | | - |
155 | | -Update a :term:`field` value using ``Update``: |
| 107 | +************* |
156 | 108 |
|
157 | | -.. code-block:: go |
| 109 | +``NewUpdateRequest`` can be used to update a tuple identified by the primary key as follows: |
158 | 110 |
|
159 | | - resp, err = conn.Update("tester", "primary", []interface{}{4}, []interface{}{[]interface{}{"+", 2, 3}}) |
| 111 | +.. literalinclude:: /code_snippets/snippets/connectors/go/hello.go |
| 112 | + :language: go |
| 113 | + :start-after: // Update |
| 114 | + :end-before: Update a tuple by the primary key value |
| 115 | + :dedent: |
160 | 116 |
|
161 | | -This increases by 3 the value of field ``2`` in the tuple with ``id = 4``. |
162 | | -If a tuple with this ``id`` doesn't exist, Tarantool will return an error. |
| 117 | +``NewUpsertRequest`` can be used to update an existing tuple or inserts a new one. |
| 118 | +In the example below, a new tuple is inserted: |
163 | 119 |
|
164 | | -Now use ``Replace`` to totally replace the tuple that matches the |
165 | | -primary key. If a tuple with this primary key doesn't exist, Tarantool will |
166 | | -do nothing. |
| 120 | +.. literalinclude:: /code_snippets/snippets/connectors/go/hello.go |
| 121 | + :language: go |
| 122 | + :start-after: // Upsert |
| 123 | + :end-before: // Replace |
| 124 | + :dedent: |
167 | 125 |
|
168 | | -.. code-block:: go |
169 | 126 |
|
170 | | - resp, err = conn.Replace("tester", []interface{}{4, "New band", 2011}) |
| 127 | +In this example, ``NewReplaceRequest`` is used to delete the existing tuple and insert a new one: |
171 | 128 |
|
172 | | -You can also update the data using ``Upsert`` that works similarly |
173 | | -to ``Update``, but creates a new tuple if the old one was not found. |
| 129 | +.. literalinclude:: /code_snippets/snippets/connectors/go/hello.go |
| 130 | + :language: go |
| 131 | + :start-after: // Replace |
| 132 | + :end-before: Replace a tuple |
| 133 | + :dedent: |
174 | 134 |
|
175 | | -.. code-block:: go |
176 | 135 |
|
177 | | - resp, err = conn.Upsert("tester", []interface{}{4, "Another band", 2000}, []interface{}{[]interface{}{"+", 2, 5}}) |
178 | 136 |
|
179 | | -This increases by 5 the value of the third field in the tuple with ``id = 4``, or |
180 | | -inserts the tuple ``(4, "Another band", 2000)`` if a tuple with this ``id`` |
181 | | -doesn't exist. |
182 | 137 |
|
183 | | -.. _getting_started-go-delete: |
| 138 | +.. _getting_started_go_deleting_data: |
184 | 139 |
|
185 | | -******************************************************************************** |
186 | 140 | Deleting data |
187 | | -******************************************************************************** |
| 141 | +************* |
188 | 142 |
|
189 | | -To delete a tuple, use ``connection.Delete``: |
| 143 | +``NewDeleteRequest`` in the example below is used to delete a tuple whose primary key value is ``5``: |
190 | 144 |
|
191 | | -.. code-block:: go |
| 145 | +.. literalinclude:: /code_snippets/snippets/connectors/go/hello.go |
| 146 | + :language: go |
| 147 | + :start-after: // Delete |
| 148 | + :end-before: Delete a tuple |
| 149 | + :dedent: |
192 | 150 |
|
193 | | - resp, err = conn.Delete("tester", "primary", []interface{}{4}) |
194 | 151 |
|
195 | | -To delete all tuples in a space (or to delete an entire space), use ``Call``. |
196 | | -We'll focus on this function in more detail in the |
197 | | -:ref:`next <getting_started-go-stored-procs>` section. |
198 | 152 |
|
199 | | -To delete all tuples in a space, call ``space:truncate``: |
| 153 | +.. _getting_started_go_stored_procedures: |
200 | 154 |
|
201 | | -.. code-block:: go |
202 | | -
|
203 | | - resp, err = conn.Call("box.space.tester:truncate", []interface{}{}) |
204 | | -
|
205 | | -To delete an entire space, call ``space:drop``. |
206 | | -This requires connecting to Tarantool as the ``admin`` user: |
207 | | - |
208 | | -.. code-block:: go |
209 | | -
|
210 | | - resp, err = conn.Call("box.space.tester:drop", []interface{}{}) |
211 | | -
|
212 | | -.. _getting_started-go-stored-procs: |
213 | | - |
214 | | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
215 | 155 | Executing stored procedures |
216 | | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
217 | | - |
218 | | -Switch to the terminal window where Tarantool is running. |
219 | | - |
220 | | -.. NOTE:: |
| 156 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
221 | 157 |
|
222 | | - If you don't have a terminal window with remote connection to Tarantool, |
223 | | - check out these guides: |
| 158 | +To execute a stored procedure, use ``NewCallRequest``: |
224 | 159 |
|
225 | | - * :ref:`connecting to a local Tarantool instance <connecting-remotely>` |
226 | | - * :ref:`attaching to a Tarantool instance that runs in a Docker container <getting_started-docker-attaching>` |
| 160 | +.. literalinclude:: /code_snippets/snippets/connectors/go/hello.go |
| 161 | + :language: go |
| 162 | + :start-after: // Call |
| 163 | + :end-before: Execute a stored procedure |
| 164 | + :dedent: |
227 | 165 |
|
228 | | -Define a simple Lua function: |
229 | 166 |
|
230 | | -.. code-block:: lua |
| 167 | +.. _getting_started_go_closing_connection: |
231 | 168 |
|
232 | | - function sum(a, b) |
233 | | - return a + b |
234 | | - end |
| 169 | +Closing the connection |
| 170 | +~~~~~~~~~~~~~~~~~~~~~~ |
235 | 171 |
|
236 | | -Now we have a Lua function defined in Tarantool. To invoke this function from |
237 | | -``go``, use ``Call``: |
| 172 | +The ``CloseGraceful()`` method can be used to close the connection when it is no longer needed: |
238 | 173 |
|
239 | | -.. code-block:: go |
| 174 | +.. literalinclude:: /code_snippets/snippets/connectors/go/hello.go |
| 175 | + :language: go |
| 176 | + :start-after: // Close connection |
| 177 | + :end-before: Connection is closed |
| 178 | + :dedent: |
240 | 179 |
|
241 | | - resp, err = conn.Call("sum", []interface{}{2, 3}) |
| 180 | +.. NOTE:: |
242 | 181 |
|
243 | | -To send bare Lua code for execution, use ``Eval``: |
| 182 | + You can find the example with all the requests above on GitHub: `go <https://github.com/tarantool/doc/tree/latest/doc/code_snippets/snippets/connectors/go>`_. |
244 | 183 |
|
245 | | -.. code-block:: go |
246 | | -
|
247 | | - resp, err = connection.Eval("return 4 + 5", []interface{}{}) |
248 | 184 |
|
249 | 185 | .. _getting_started-go-comparison: |
250 | 186 |
|
251 | | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
252 | 187 | Feature comparison |
253 | | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 188 | +------------------ |
| 189 | + |
254 | 190 |
|
255 | | -There are two more connectors from the open-source community: |
| 191 | +There are two more connectors from the open source community: |
256 | 192 |
|
257 | 193 | * `viciious/go-tarantool <https://github.com/viciious/go-tarantool>`_ |
258 | 194 |
|
|
0 commit comments