diff --git a/doc/sphinx/_static/sphinx_design.css b/doc/sphinx/_static/sphinx_design.css index 760feb48d4d87e9f3d201709a9abc0039231f607..09561bcb29f512808d3a8c4c0f30e2972d6b68a2 100644 --- a/doc/sphinx/_static/sphinx_design.css +++ b/doc/sphinx/_static/sphinx_design.css @@ -368,3 +368,66 @@ div.b-cols_content_left .b-search-text { float: left; position: relative; } + +.b-switcher-item-url { + -webkit-transition: all 0.2s ease-in-out; + -moz-transition: all 0.2s ease-in-out; + -o-transition: all 0.2s ease-in-out; + -ms-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; +} +.b-tab_switcher { + display:inline-block; + border:1px solid #168de2; + background:#FFF; + -webkit-border-radius: 6px 6px 0 0; + -moz-border-radius: 6px 6px 0 0; + border-radius: 6px 6px 0 0; + font-size: 0; + padding: 0px !important; +} + +.b-tab_switcher-item { + display:inline-block; + font-size:16px; + color:#262626; + border-right:1px solid #168de2; + padding: 0px !important; +} +.b-tab_switcher-item:last-child { + border: 0; +} +.b-tab_switcher-item-url { + display:inline-block; + color:inherit; + text-decoration:none; + padding:8px 19px; + text-transform:uppercase; +} +.b-tab_switcher-item-url:hover { + background:#e7f3fc; +} +.b-tab_switcher-item-url.p-active { + background:#168de2; + color:#FFF; +} +.b-tab_switcher-item:first-child .b-tab_switcher-item-url { + -webkit-border-radius: 4px 0 0 0px; + -moz-border-radius: 4px 0 0 0px; + border-radius: 4px 0 0 0px; +} +.b-tab_switcher-item:last-child .b-tab_switcher-item-url { + -webkit-border-radius: 0 4px 0px 0; + -moz-border-radius: 0 4px 0px 0; + border-radius: 0 4px 0px 0; +} + +.b-documentation-tab-content { + border: 1px solid #168de2; + margin-top: -1px; + padding: 5px; +} + +.b-documentation-tab div { + height: 100%; +} diff --git a/doc/sphinx/_templates/searchbox.html b/doc/sphinx/_templates/searchbox.html index 508b4b30257d4d207f3b38c565122adc9a9aec70..d2d38c46c82994c3186b50482ff6d58b1d145b46 100644 --- a/doc/sphinx/_templates/searchbox.html +++ b/doc/sphinx/_templates/searchbox.html @@ -1,6 +1,6 @@ {%- if builder != "singlehtml" %} <form id="searchbox" role="search" class="search b-search" action="{{ pathto('search') }}" method="get"> - <input class="b-search-text" name="q" type="text"/ placeholder="Search"> + <input class="b-search-text" name="q" type="text"/ placeholder="Search the manual"> <input class="b-search-but" type="submit" /> <input type="hidden" name="check_keywords" value="yes" /> <input type="hidden" name="area" value="default" /> diff --git a/doc/sphinx/book/app_c_lua_tutorial.rst b/doc/sphinx/book/app_c_lua_tutorial.rst index 80e91273d86e300d010b2396934148102996765a..b04ccdd21f28df39f084505fdfa2f939d95320e8 100644 --- a/doc/sphinx/book/app_c_lua_tutorial.rst +++ b/doc/sphinx/book/app_c_lua_tutorial.rst @@ -511,7 +511,7 @@ that are declared in line 1, because all of them are for use only within the fun LINE 3: WHY "PAIRS()". Our job is to go through all the rows and there are two ways to do it: with ``box.space.space-name:pairs()`` or with -:func:`index.iterator <box.space.space-name.index[.index-name]:pairs>`. +:func:`index.iterator <index_object.pairs>`. We preferred ``pairs()`` because it is simpler. LINE 4: WHY "PCALL". If we simply said "``lua_table = json.decode(t[2]))``", then diff --git a/doc/sphinx/book/box/box_index.rst b/doc/sphinx/book/box/box_index.rst index 899ee23d44f428c609f5a44c9aeadaf370df490f..481d5a8a36b9e250822df79926a7c57423c72ef7 100644 --- a/doc/sphinx/book/box/box_index.rst +++ b/doc/sphinx/book/box/box_index.rst @@ -10,478 +10,480 @@ API is a direct binding to corresponding methods of index objects of type .. module:: box.index -.. data:: box.space.space-name.index.index-name.unique - - true if the index is unique. - - :rtype: boolean - -.. data:: box.space.space-name.index.index-name.type - - Index type, 'TREE' or 'HASH' or 'BITSET' or 'RTREE'. - - :rtype: string - -.. data:: box.space.space-name.index.index-name.parts - - An array describing index key fields. - - :rtype: table - - .. code-block:: lua - - tarantool> box.space.tester.index.primary - --- - unique: true - parts: - 0: - type: NUM - fieldno: 1 - id: 0 - space_id: 513 - name: primary - type: TREE - ... - -.. function:: box.space.space-name.index[.index-name]:pairs(bitset-value | field-value..., iterator-type) - - This method provides iteration support within an index. Parameter type is - used to identify the semantics of iteration. Different index types support - different iterators. The remaining arguments of the function are varying - and depend on the iteration type. For example, a TREE index maintains a - strict order of keys and can return all tuples in ascending or descending - order, starting from the specified key. Other index types, however, do not - support ordering. - - To understand consistency of tuples returned by an iterator, it's essential - to know the principles of the Tarantool transaction processing subsystem. An - iterator in Tarantool does not own a consistent read view. Instead, each - procedure is granted exclusive access to all tuples and spaces until it - encounters a "context switch": by causing a write to disk, network, or by an - explicit call to :func:`fiber.yield`. When the execution flow returns - to the yielded procedure, the data set could have changed significantly. - Iteration, resumed after a yield point, does not preserve the read view, - but continues with the new content of the database. - - :param type: iteration strategy as defined in tables below - :return: this method returns an iterator closure, i.e. a function which can - be used to get the next value on each invocation - :rtype: function, tuple - - :except: Selected iteration type is not supported in the subject index type, - or supplied parameters do not match iteration type. - - Complexity Factors: Index size, Index type, Number of tuples accessed. - - .. container:: table - - **TREE iterator types** - - +---------------+-----------+---------------------------------------------+ - | Type | Arguments | Description | - +===============+===========+=============================================+ - | box.index.ALL | none | Iterate over all tuples in an index. Tuples | - | or 'ALL' | | are returned in ascending order of the key. | - +---------------+-----------+---------------------------------------------+ - | box.index.EQ | field | Equality iterator: iterate over all tuples | - | or 'EQ' | values | where field values = key values. Parts of a | - | | | multi-part key need to be separated by | - | | | commas. | - | | | | - | | | If the number of field values is less than | - | | | the number of parts of a multi-part key, | - | | | the missing field values are considered to | - | | | be matching. | - | | | | - | | | If there are multiple matches, then tuples | - | | | are returned in ascending order by key. | - +---------------+-----------+---------------------------------------------+ - | box.index.GT | field | Keys match if key values are greater than | - | or 'GT' | values | field values. If the number of field values | - | | | is less than the number of parts of a | - | | | multi-part key, the missing field values | - | | | are considered to be matching. If the field | - | | | value is ``nil``, iteration starts from the | - | | | smallest key in the index. Tuples are | - | | | returned in ascending order by key. | - +---------------+-----------+---------------------------------------------+ - | box.index.REQ | field | Reverse equality iterator. Matching is | - | or 'REQ' | values | determined in the same way as for | - | | | ``box.index.EQ``, but, if there are multiple| - | | | matches, then tuples are returned in | - | | | descending order by key, | - +---------------+-----------+---------------------------------------------+ - | box.index.GE | field | Keys match if key values are greater than | - | or 'GE' | values | or equal to field values. Tuples are | - | | | returned in ascending order by key. If the | - | | | field value is ``nil``, iteration starts | - | | | from the first key in the index. | - +---------------+-----------+---------------------------------------------+ - | box.index.LT | field | Keys match if key values are less than | - | or 'LT' | values | field values. Tuples are returned in | - | | | descending order by key. If the field value | - | | | is ``nil``, iteration starts from the last | - | | | key in the index. | - +---------------+-----------+---------------------------------------------+ - | box.index.LE | field | Keys match if key values are less than or | - | or 'LE' | values | equal to field values. Tuples are returned | - | | | in descending order by key. If the field | - | | | value is ``nil``, iteration starts from | - | | | the last key in the index. | - +---------------+-----------+---------------------------------------------+ - - **HASH iterator types** - - +---------------+-----------+---------------------------------------------+ - | Type | Arguments | Description | - +===============+===========+=============================================+ - | box.index.ALL | none | Iterate over all tuples in an index. Tuples | - | or 'ALL' | | are returned in ascending order of the key. | - +---------------+-----------+---------------------------------------------+ - | box.index.EQ | field | Equality iterator: iterate over all tuples | - | or 'EQ' | values | matching the key. Parts of a multi-part | - | | | key need to be separated by commas. | - | | | | - | | | A HASH index only supports exact match: | - | | | all parts of a key participating in the | - | | | index must be provided. | - | | | | - | | | HASH indexes are always unique. | - +---------------+-----------+---------------------------------------------+ - | box.index.GT | field | Keys match if hashed key values are greater | - | or 'GT' | values | than hashed field values. If the number of | - | | | field values is less than the number of | - | | | parts of a multi-part key, the result is an | - | | | error. Tuples are returned in ascending | - | | | order by hashed key, so the order will | - | | | appear to be random. Provided that the | - | | | space is not being updated, the 'GT' | - | | | iterator can be used to retrieve all | - | | | tuples piece by piece, by supplying the | - | | | last returned value from the previous | - | | | range as the start field value for an | - | | | iterator over the next range. | - +---------------+-----------+---------------------------------------------+ - - **BITSET iterator types** - - +----------------------------+-----------+---------------------------------------------+ - | Type | Arguments | Description | - +============================+===========+=============================================+ - | box.index.ALL | none | Iterate over all tuples in an index. Tuples | - | or 'ALL' | | are returned in ascending order of the | - | | | key's bitset, and so will appear to be | - | | | unordered. | - +----------------------------+-----------+---------------------------------------------+ - | box.index.EQ | field | Equality iterator: iterate over all tuples | - | or 'EQ' | values | matching the field values. If there are | - | | | multiple field values, they need to be | - | | | separated by commas. | - | | | | - | | | BITSET indexes are always unique. | - +----------------------------+-----------+---------------------------------------------+ - | box.index.BITS_ALL_SET | field | Keys match if all of the bits specified in | - | | values | 'bit mask' are set. | - +----------------------------+-----------+---------------------------------------------+ - | box.index.BITS_ANY_SET | field | Keys match if any of the bits specified in | - | | values | 'bit mask' is set. | - +----------------------------+-----------+---------------------------------------------+ - | box.index.BITS_ALL_NOT_SET | field | Keys match if none of the bits specified in | - | | values | 'bit mask' is set. | - +----------------------------+-----------+---------------------------------------------+ - - .. _rtree-iterator: - - **RTREE iterator types** - - +--------------------+-----------+---------------------------------------------+ - | Type | Arguments | Description | - +====================+===========+=============================================+ - | box.index.ALL | none | All keys match. Tuples are returned in | - | or 'ALL' | | ascending order of the primary key. | - +--------------------+-----------+---------------------------------------------+ - | box.index.EQ | field | Keys match if the rectangle defined by the | - | or 'EQ' | values | field values is the same as the rectangle | - | | | defined by the key -- where "key" means | - | | | "the key in the RTREE index" and | - | | | "rectangle" means "rectangle as explained | - | | | in section RTREE_. | - +--------------------+-----------+---------------------------------------------+ - | box.index.GT | field | Keys match if all points of the rectangle | - | or 'GT' | values | defined by the field values are within the | - | | | rectangle defined by the key. | - +--------------------+-----------+---------------------------------------------+ - | box.index.GE | field | Keys match if all points of the rectangle | - | or 'GE' | values | defined by the field values are within, or | - | | | at the side of, the rectangle defined by | - | | | the key. | - +--------------------+-----------+---------------------------------------------+ - | box.index.LT | field | Keys match if all points of the rectangle | - | or 'LT' | values | defined by the key are within the rectangle | - | | | defined by the field values. | - +--------------------+-----------+---------------------------------------------+ - | box.index.LE | field | Keys match if all points of the rectangle | - | or 'LE' | values | defined by the key are within, or at the | - | | | side of, the rectangle defined by the field | - | | | values. | - +--------------------+-----------+---------------------------------------------+ - | box.index.OVERLAPS | field | Keys match if all points of the rectangle | - | or 'OVERLAPS' | values | defined by the key are within, or at the | - | | | side of, the rectangle defined by the field | - | | | values. | - +--------------------+-----------+---------------------------------------------+ - | box.index.NEIGHBOR | field | Keys match if all points of the rectangle | - | or 'NEIGHBOR' | values | defined by the key are within, or at the | - | | | side of, the rectangle defined by the field | - | | | values. | - +--------------------+-----------+---------------------------------------------+ - - .. code-block:: lua - - tarantool> s = box.schema.space.create('space17') - --- - ... - tarantool> s:create_index('primary', {parts = {1, 'STR', 2, 'STR'}}) - --- - ... - tarantool> s:insert{'C', 'C'} - --- - - ['C', 'C'] - ... - tarantool> s:insert{'B', 'A'} - --- - - ['B', 'A'] - ... - tarantool> s:insert{'C', '!'} - --- - - ['C', '!'] - ... - tarantool> s:insert{'A', 'C'} - --- - - ['A', 'C'] - ... - tarantool> console = require('console'); console.delimiter('!') - --- - ... - tarantool> function example() - > for _, tuple in - > s.index.primary:pairs(nil, {iterator = box.index.ALL}) do - > print(tuple) - > end - > end! - --- - ... - tarantool> console.delimiter('')! - --- - ... - tarantool> example() - ['A', 'C'] - ['B', 'A'] - ['C', '!'] - ['C', 'C'] - --- - ... - tarantool> s:drop() - --- - ... - -.. function:: box.space.space-name[.index.index-name]:select({[field-value [, field-value ...]]}, {[option [, option ...]]}) - - This is is an alternative to box.space...select() which goes via a - particular index and can make use of additional parameters that specify the - iterator type, and the limit (that is, the maximum number of tuples to - return) and the offset (that is, which tuple to start with in the list). - - :param lua-value field-value(s): values to be matched against the index key. - :param lua-value option(s): any or all of iterator=iterator-type - limit=maximum-number-of-tuples, - offset=start-tuple-number. - - :return: the tuple or tuples that match the field values. - :rtype: tuple set as a Lua table - - .. code-block:: lua - - -- Create a space named tester. - -- Create a unique index 'primary', which won't be needed for this example. - -- Create a non-unique index 'secondary' with an index on the second field. - -- Insert three tuples, values in field[2] equal to 'X', 'Y', and 'Z'. - -- Select all tuples where the secondary index keys are greater than 'X'. - box.schema.space.create('tester') - box.space.tester:create_index('primary', {parts = {1, 'NUM' }}) - box.space.tester:create_index('secondary', {type = 'tree', unique = false, parts = {2, 'STR'}}) - box.space.tester:insert{1,'X','Row with field[2]=X'} - box.space.tester:insert{2,'Y','Row with field[2]=Y'} - box.space.tester:insert{3,'Z','Row with field[2]=Z'} - box.space.tester.index.secondary:select({'X'}, {iterator = 'GT', limit = 1000}) - - The result will be a table of tuple and will look like this: - - .. code-block:: yaml - - --- - - - [2, 'Y', 'Row with field[2]=Y'] - - [3, 'Z', 'Row with field[2]=Z'] - ... - - .. NOTE:: - - [.index.index-name] is optional. If it is omitted, then the assumed - index is the first (primary-key) index. Therefore, for the example - above, ``box.space.tester:select({1}, {iterator = 'GT'})`` would have - returned the same two rows, via the 'primary' index. - - .. NOTE:: - - ``iterator = iterator type`` is optional. If it is omitted, then - ``iterator = 'EQ'`` is assumed. - - .. NOTE:: - - ``field-value [, field-value ...]`` is optional. If it is omitted, - then every key in the index is considered to be a match, regardless of - iterator type. Therefore, for the example above, - ``box.space.tester:select{}`` will select every tuple in the tester - space via the first (primary-key) index. - - .. NOTE:: - - ``box.space.space-name.index.index-name:select(...)[1]``. can be - replaced by ``box.space.space-name.index.index-name:get(...)``. - That is, get can be used as a convenient shorthand to get the first - tuple in the tuple set that would be returned by select. However, - if there is more than one tuple in the tuple set, then get returns - an error. - -.. function:: box.space.space-name.index.index-name:min([key-value]) +.. class:: index_object + + .. data:: unique + + true if the index is unique. + + :rtype: boolean + + .. data:: type + + Index type, 'TREE' or 'HASH' or 'BITSET' or 'RTREE'. + + :rtype: string + + .. data:: parts + + An array describing index key fields. + + :rtype: table + + .. code-block:: lua + + tarantool> box.space.tester.index.primary + --- + unique: true + parts: + 0: + type: NUM + fieldno: 1 + id: 0 + space_id: 513 + name: primary + type: TREE + ... + + .. function:: pairs(bitset-value | field-value..., iterator-type) + + This method provides iteration support within an index. Parameter type is + used to identify the semantics of iteration. Different index types support + different iterators. The remaining arguments of the function are varying + and depend on the iteration type. For example, a TREE index maintains a + strict order of keys and can return all tuples in ascending or descending + order, starting from the specified key. Other index types, however, do not + support ordering. + + To understand consistency of tuples returned by an iterator, it's essential + to know the principles of the Tarantool transaction processing subsystem. An + iterator in Tarantool does not own a consistent read view. Instead, each + procedure is granted exclusive access to all tuples and spaces until it + encounters a "context switch": by causing a write to disk, network, or by an + explicit call to :func:`fiber.yield`. When the execution flow returns + to the yielded procedure, the data set could have changed significantly. + Iteration, resumed after a yield point, does not preserve the read view, + but continues with the new content of the database. + + :param type: iteration strategy as defined in tables below + :return: this method returns an iterator closure, i.e. a function which can + be used to get the next value on each invocation + :rtype: function, tuple + + :except: Selected iteration type is not supported in the subject index type, + or supplied parameters do not match iteration type. + + Complexity Factors: Index size, Index type, Number of tuples accessed. + + .. container:: table + + **TREE iterator types** + + +---------------+-----------+---------------------------------------------+ + | Type | Arguments | Description | + +===============+===========+=============================================+ + | box.index.ALL | none | Iterate over all tuples in an index. Tuples | + | or 'ALL' | | are returned in ascending order of the key. | + +---------------+-----------+---------------------------------------------+ + | box.index.EQ | field | Equality iterator: iterate over all tuples | + | or 'EQ' | values | where field values = key values. Parts of a | + | | | multi-part key need to be separated by | + | | | commas. | + | | | | + | | | If the number of field values is less than | + | | | the number of parts of a multi-part key, | + | | | the missing field values are considered to | + | | | be matching. | + | | | | + | | | If there are multiple matches, then tuples | + | | | are returned in ascending order by key. | + +---------------+-----------+---------------------------------------------+ + | box.index.GT | field | Keys match if key values are greater than | + | or 'GT' | values | field values. If the number of field values | + | | | is less than the number of parts of a | + | | | multi-part key, the missing field values | + | | | are considered to be matching. If the field | + | | | value is ``nil``, iteration starts from the | + | | | smallest key in the index. Tuples are | + | | | returned in ascending order by key. | + +---------------+-----------+---------------------------------------------+ + | box.index.REQ | field | Reverse equality iterator. Matching is | + | or 'REQ' | values | determined in the same way as for | + | | | ``box.index.EQ``, but, if there are multiple| + | | | matches, then tuples are returned in | + | | | descending order by key, | + +---------------+-----------+---------------------------------------------+ + | box.index.GE | field | Keys match if key values are greater than | + | or 'GE' | values | or equal to field values. Tuples are | + | | | returned in ascending order by key. If the | + | | | field value is ``nil``, iteration starts | + | | | from the first key in the index. | + +---------------+-----------+---------------------------------------------+ + | box.index.LT | field | Keys match if key values are less than | + | or 'LT' | values | field values. Tuples are returned in | + | | | descending order by key. If the field value | + | | | is ``nil``, iteration starts from the last | + | | | key in the index. | + +---------------+-----------+---------------------------------------------+ + | box.index.LE | field | Keys match if key values are less than or | + | or 'LE' | values | equal to field values. Tuples are returned | + | | | in descending order by key. If the field | + | | | value is ``nil``, iteration starts from | + | | | the last key in the index. | + +---------------+-----------+---------------------------------------------+ + + **HASH iterator types** + + +---------------+-----------+---------------------------------------------+ + | Type | Arguments | Description | + +===============+===========+=============================================+ + | box.index.ALL | none | Iterate over all tuples in an index. Tuples | + | or 'ALL' | | are returned in ascending order of the key. | + +---------------+-----------+---------------------------------------------+ + | box.index.EQ | field | Equality iterator: iterate over all tuples | + | or 'EQ' | values | matching the key. Parts of a multi-part | + | | | key need to be separated by commas. | + | | | | + | | | A HASH index only supports exact match: | + | | | all parts of a key participating in the | + | | | index must be provided. | + | | | | + | | | HASH indexes are always unique. | + +---------------+-----------+---------------------------------------------+ + | box.index.GT | field | Keys match if hashed key values are greater | + | or 'GT' | values | than hashed field values. If the number of | + | | | field values is less than the number of | + | | | parts of a multi-part key, the result is an | + | | | error. Tuples are returned in ascending | + | | | order by hashed key, so the order will | + | | | appear to be random. Provided that the | + | | | space is not being updated, the 'GT' | + | | | iterator can be used to retrieve all | + | | | tuples piece by piece, by supplying the | + | | | last returned value from the previous | + | | | range as the start field value for an | + | | | iterator over the next range. | + +---------------+-----------+---------------------------------------------+ + + **BITSET iterator types** + + +----------------------------+-----------+---------------------------------------------+ + | Type | Arguments | Description | + +============================+===========+=============================================+ + | box.index.ALL | none | Iterate over all tuples in an index. Tuples | + | or 'ALL' | | are returned in ascending order of the | + | | | key's bitset, and so will appear to be | + | | | unordered. | + +----------------------------+-----------+---------------------------------------------+ + | box.index.EQ | field | Equality iterator: iterate over all tuples | + | or 'EQ' | values | matching the field values. If there are | + | | | multiple field values, they need to be | + | | | separated by commas. | + | | | | + | | | BITSET indexes are always unique. | + +----------------------------+-----------+---------------------------------------------+ + | box.index.BITS_ALL_SET | field | Keys match if all of the bits specified in | + | | values | 'bit mask' are set. | + +----------------------------+-----------+---------------------------------------------+ + | box.index.BITS_ANY_SET | field | Keys match if any of the bits specified in | + | | values | 'bit mask' is set. | + +----------------------------+-----------+---------------------------------------------+ + | box.index.BITS_ALL_NOT_SET | field | Keys match if none of the bits specified in | + | | values | 'bit mask' is set. | + +----------------------------+-----------+---------------------------------------------+ + + .. _rtree-iterator: + + **RTREE iterator types** + + +--------------------+-----------+---------------------------------------------+ + | Type | Arguments | Description | + +====================+===========+=============================================+ + | box.index.ALL | none | All keys match. Tuples are returned in | + | or 'ALL' | | ascending order of the primary key. | + +--------------------+-----------+---------------------------------------------+ + | box.index.EQ | field | Keys match if the rectangle defined by the | + | or 'EQ' | values | field values is the same as the rectangle | + | | | defined by the key -- where "key" means | + | | | "the key in the RTREE index" and | + | | | "rectangle" means "rectangle as explained | + | | | in section RTREE_. | + +--------------------+-----------+---------------------------------------------+ + | box.index.GT | field | Keys match if all points of the rectangle | + | or 'GT' | values | defined by the field values are within the | + | | | rectangle defined by the key. | + +--------------------+-----------+---------------------------------------------+ + | box.index.GE | field | Keys match if all points of the rectangle | + | or 'GE' | values | defined by the field values are within, or | + | | | at the side of, the rectangle defined by | + | | | the key. | + +--------------------+-----------+---------------------------------------------+ + | box.index.LT | field | Keys match if all points of the rectangle | + | or 'LT' | values | defined by the key are within the rectangle | + | | | defined by the field values. | + +--------------------+-----------+---------------------------------------------+ + | box.index.LE | field | Keys match if all points of the rectangle | + | or 'LE' | values | defined by the key are within, or at the | + | | | side of, the rectangle defined by the field | + | | | values. | + +--------------------+-----------+---------------------------------------------+ + | box.index.OVERLAPS | field | Keys match if all points of the rectangle | + | or 'OVERLAPS' | values | defined by the key are within, or at the | + | | | side of, the rectangle defined by the field | + | | | values. | + +--------------------+-----------+---------------------------------------------+ + | box.index.NEIGHBOR | field | Keys match if all points of the rectangle | + | or 'NEIGHBOR' | values | defined by the key are within, or at the | + | | | side of, the rectangle defined by the field | + | | | values. | + +--------------------+-----------+---------------------------------------------+ + + .. code-block:: lua + + tarantool> s = box.schema.space.create('space17') + --- + ... + tarantool> s:create_index('primary', {parts = {1, 'STR', 2, 'STR'}}) + --- + ... + tarantool> s:insert{'C', 'C'} + --- + - ['C', 'C'] + ... + tarantool> s:insert{'B', 'A'} + --- + - ['B', 'A'] + ... + tarantool> s:insert{'C', '!'} + --- + - ['C', '!'] + ... + tarantool> s:insert{'A', 'C'} + --- + - ['A', 'C'] + ... + tarantool> console = require('console'); console.delimiter('!') + --- + ... + tarantool> function example() + > for _, tuple in + > s.index.primary:pairs(nil, {iterator = box.index.ALL}) do + > print(tuple) + > end + > end! + --- + ... + tarantool> console.delimiter('')! + --- + ... + tarantool> example() + ['A', 'C'] + ['B', 'A'] + ['C', '!'] + ['C', 'C'] + --- + ... + tarantool> s:drop() + --- + ... + + .. function:: select(key, options) + + This is is an alternative to box.space...select() which goes via a + particular index and can make use of additional parameters that specify the + iterator type, and the limit (that is, the maximum number of tuples to + return) and the offset (that is, which tuple to start with in the list). + + :param lua-table or scalar key: values to be matched against the index key. + :param lua-table options: table with any or all of iterator=iterator-type + limit=maximum-number-of-tuples, + offset=start-tuple-number. + + :return: the tuple or tuples that match the field values. + :rtype: tuple set as a Lua table + + .. code-block:: lua + + -- Create a space named tester. + -- Create a unique index 'primary', which won't be needed for this example. + -- Create a non-unique index 'secondary' with an index on the second field. + -- Insert three tuples, values in field[2] equal to 'X', 'Y', and 'Z'. + -- Select all tuples where the secondary index keys are greater than 'X'. + box.schema.space.create('tester') + box.space.tester:create_index('primary', {parts = {1, 'NUM' }}) + box.space.tester:create_index('secondary', {type = 'tree', unique = false, parts = {2, 'STR'}}) + box.space.tester:insert{1,'X','Row with field[2]=X'} + box.space.tester:insert{2,'Y','Row with field[2]=Y'} + box.space.tester:insert{3,'Z','Row with field[2]=Z'} + box.space.tester.index.secondary:select({'X'}, {iterator = 'GT', limit = 1000}) + + The result will be a table of tuple and will look like this: + + .. code-block:: yaml + + --- + - - [2, 'Y', 'Row with field[2]=Y'] + - [3, 'Z', 'Row with field[2]=Z'] + ... + + .. NOTE:: + + [.index.index-name] is optional. If it is omitted, then the assumed + index is the first (primary-key) index. Therefore, for the example + above, ``box.space.tester:select({1}, {iterator = 'GT'})`` would have + returned the same two rows, via the 'primary' index. + + .. NOTE:: + + ``iterator = iterator type`` is optional. If it is omitted, then + ``iterator = 'EQ'`` is assumed. + + .. NOTE:: + + ``field-value [, field-value ...]`` is optional. If it is omitted, + then every key in the index is considered to be a match, regardless of + iterator type. Therefore, for the example above, + ``box.space.tester:select{}`` will select every tuple in the tester + space via the first (primary-key) index. + + .. NOTE:: + + ``box.space.space-name.index.index-name:select(...)[1]``. can be + replaced by ``box.space.space-name.index.index-name:get(...)``. + That is, get can be used as a convenient shorthand to get the first + tuple in the tuple set that would be returned by select. However, + if there is more than one tuple in the tuple set, then get returns + an error. + + .. function:: min([key-value]) - Find the minimum value in the specified index. + Find the minimum value in the specified index. - :return: the tuple for the first key in the index. If optional - ``key-value`` is supplied, returns the first key which - is greater than or equal to ``key-value``. - :rtype: tuple - :except: index is not of type 'TREE'. + :return: the tuple for the first key in the index. If optional + ``key-value`` is supplied, returns the first key which + is greater than or equal to ``key-value``. + :rtype: tuple + :except: index is not of type 'TREE'. - Complexity Factors: Index size, Index type. + Complexity Factors: Index size, Index type. - .. code-block:: lua + .. code-block:: lua - tarantool> box.space.tester.index.primary:min() - --- - - ['Alpha!', 55, 'This is the first tuple!'] - ... + tarantool> box.space.tester.index.primary:min() + --- + - ['Alpha!', 55, 'This is the first tuple!'] + ... -.. function:: box.space.space-name.index.index-name:max([key-value]) + .. function:: max([key-value]) - Find the maximum value in the specified index. + Find the maximum value in the specified index. - :return: the tuple for the last key in the index. If optional ``key-value`` - is supplied, returns the last key which is less than or equal to - ``key-value``. - :rtype: tuple - :except: index is not of type 'TREE'. + :return: the tuple for the last key in the index. If optional ``key-value`` + is supplied, returns the last key which is less than or equal to + ``key-value``. + :rtype: tuple + :except: index is not of type 'TREE'. - Complexity Factors: Index size, Index type. + Complexity Factors: Index size, Index type. - .. code-block:: lua + .. code-block:: lua - tarantool> box.space.tester.index.primary:max() - --- - - ['Gamma!', 55, 'This is the third tuple!'] - ... + tarantool> box.space.tester.index.primary:max() + --- + - ['Gamma!', 55, 'This is the third tuple!'] + ... -.. function:: box.space.space-name.index.index-name:random(random-value) + .. function:: random(random-value) - Find a random value in the specified index. This method is useful when it's - important to get insight into data distribution in an index without having - to iterate over the entire data set. + Find a random value in the specified index. This method is useful when it's + important to get insight into data distribution in an index without having + to iterate over the entire data set. - :param integer random-value: an arbitrary non-negative integer. - :return: the tuple for the random key in the index. - :rtype: tuple + :param integer random-value: an arbitrary non-negative integer. + :return: the tuple for the random key in the index. + :rtype: tuple - Complexity Factors: Index size, Index type. + Complexity Factors: Index size, Index type. - .. code-block:: lua + .. code-block:: lua - tarantool> box.space.tester.index.secondary:random(1) - --- - - ['Beta!', 66, 'This is the second tuple!'] - ... + tarantool> box.space.tester.index.secondary:random(1) + --- + - ['Beta!', 66, 'This is the second tuple!'] + ... -.. function:: box.space.space-name.index.index-name:count(key-value, options) + .. function:: count(key-value, options) - Iterate over an index, counting the number of - tuples which equal the provided search criteria. + Iterate over an index, counting the number of + tuples which equal the provided search criteria. - :param lua-value key-value: the value which must match the key(s) in the - specified index. The type may be a list of - field-values, or a tuple containing only - the field-values. + :param lua-value key-value: the value which must match the key(s) in the + specified index. The type may be a list of + field-values, or a tuple containing only + the field-values. - :return: the number of matching index keys. The ``index`` function - is only applicable for the memtx storage engine. - :rtype: number + :return: the number of matching index keys. The ``index`` function + is only applicable for the memtx storage engine. + :rtype: number - .. code-block:: lua + .. code-block:: lua - tarantool> box.space.tester.index.primary:count(999) - --- - - 0 - ... - tarantool> box.space.tester.index.primary:count('Alpha!', { iterator = 'LE' }) - --- - - 1 - ... + tarantool> box.space.tester.index.primary:count(999) + --- + - 0 + ... + tarantool> box.space.tester.index.primary:count('Alpha!', { iterator = 'LE' }) + --- + - 1 + ... -.. function:: box.space.space-name.index.index-name:alter{options} + .. function:: alter({options}) - Alter an index. + Alter an index. - :param table options: options list for create_index(). - :return: nil + :param table options: options list for create_index(). + :return: nil - :except: If index-name doesn't exist. - :except: The first index cannot be changed to {unique = false}. - :except: The alter function is only applicable for the memtx storage engine. + :except: If index-name doesn't exist. + :except: The first index cannot be changed to {unique = false}. + :except: The alter function is only applicable for the memtx storage engine. - .. code-block:: lua + .. code-block:: lua - tarantool> box.space.space55.index.primary:alter({type = 'HASH'}) - --- - ... + tarantool> box.space.space55.index.primary:alter({type = 'HASH'}) + --- + ... -.. function:: space-name.index.index-name:drop() + .. function:: drop() - Drop an index. Dropping a primary-key index has - a side effect: all tuples are deleted. + Drop an index. Dropping a primary-key index has + a side effect: all tuples are deleted. - :return: nil. - :except: If index-name doesn't exist. + :return: nil. + :except: If index-name doesn't exist. - .. code-block:: lua + .. code-block:: lua - tarantool> box.space.space55.index.primary:drop() - --- - ... + tarantool> box.space.space55.index.primary:drop() + --- + ... -.. function:: space-name.index.index-name:rename(index-name) + .. function:: rename(index-name) - Rename an index. + Rename an index. - :param string index-name: new name for index. - :return: nil - :except: If index-name doesn't exist. + :param string index-name: new name for index. + :return: nil + :except: If index-name doesn't exist. - .. code-block:: lua + .. code-block:: lua - tarantool> box.space.space55.index.primary:rename('secondary') - --- - ... + tarantool> box.space.space55.index.primary:rename('secondary') + --- + ... - Complexity Factors: Index size, Index type, Number of tuples accessed. + Complexity Factors: Index size, Index type, Number of tuples accessed. =========================================================== diff --git a/doc/sphinx/book/box/box_schema.rst b/doc/sphinx/book/box/box_schema.rst index 8b6bdebc740c5702229e799299860279e43ad8b8..ce26ff70c6a2ca73df8e2b36a4db1d2f045608c4 100644 --- a/doc/sphinx/book/box/box_schema.rst +++ b/doc/sphinx/book/box/box_schema.rst @@ -55,6 +55,6 @@ The ``box.schema`` package has one data-definition function: ``space.create()``. ... After a space is created, usually the next step is to -:func:`create an index <box.space.space-name.create_index>` for it, +:func:`create an index <space_object.create_index>` for it, and then it is available for insert, select, and all the other :mod:`box.space` functions. diff --git a/doc/sphinx/book/box/box_space.rst b/doc/sphinx/book/box/box_space.rst index 0ba777a62beb3cd2a5f01164268287431925985a..8fa06ed36d5b7c32ad9e2b8ecdaf25da632e855a 100644 --- a/doc/sphinx/book/box/box_space.rst +++ b/doc/sphinx/book/box/box_space.rst @@ -13,566 +13,586 @@ is available in file A list of all ``box.space`` functions follows, then comes a list of all ``box.space`` members. -.. function:: box.space.space-name:create_index(index-name [, {options} ]) - - Create an index. It is **mandatory** to create an index for a tuple set - before trying to insert tuples into it, or select tuples from it. The - first created index, which will be used as the primary-key index, must be - **unique**. - - :param string index-name: name of index, which should not be a number and - should not contain special characters; - :param table options: - - :return: index object - :rtype: userdata - - .. container:: table - - **Options for box.space...create_index** - - +---------------+--------------------+-----------------------------+---------------------+ - | Name | Effect | Type | Default | - +===============+====================+=============================+=====================+ - | type | type of index | string | 'TREE' | - | | | ('HASH', 'TREE', | | - | | | 'BITSET', 'RTREE') | | - | | | | | - | | | | | - | | | | | - +---------------+--------------------+-----------------------------+---------------------+ - | id | unique identifier | number | last index's id, +1 | - +---------------+--------------------+-----------------------------+---------------------+ - | unique | index is unique | boolean | true | - +---------------+--------------------+-----------------------------+---------------------+ - | if_not_exists | no error if | boolean | false | - | | duplicate name | | | - +---------------+--------------------+-----------------------------+---------------------+ - | parts | field-numbers + | ``{field_no, 'NUM'|'STR'}`` | ``{1, 'NUM'}`` | - | | types | | | - +---------------+--------------------+-----------------------------+---------------------+ - - Possible errors: too many parts. A type options other than TREE, or a - unique option other than unique, or a parts option with more than one - field component, is only applicable for the memtx storage engine. +.. class:: space_object - .. code-block:: lua + .. function:: create_index(index-name [, {options} ]) - tarantool> s = box.space.space55 - --- - ... - tarantool> s:create_index('primary', {unique = true, parts = {1, 'NUM', 2, 'STR'}}) - --- - ... + Create an index. It is **mandatory** to create an index for a tuple set + before trying to insert tuples into it, or select tuples from it. The + first created index, which will be used as the primary-key index, must be + **unique**. -.. function:: box.space.space-name:insert{field-value [, field-value ...]} + :param string index-name: name of index, which should not be a number and + should not contain special characters; + :param table options: - Insert a tuple into a space. + :return: index object + :rtype: index_object - :param userdata space-name: - :param lua-value field-value(s): fields of the new tuple. - :return: the inserted tuple - :rtype: tuple + .. container:: table - :except: If a tuple with the same unique-key value already exists, - returns ``ER_TUPLE_FOUND``. + **Options table** - .. code-block:: lua - - box.space.tester:insert{5000,'tuple number five thousand'} + +---------------+--------------------+-----------------------------+---------------------+ + | Name | Effect | Type | Default | + +===============+====================+=============================+=====================+ + | type | type of index | string | 'TREE' | + | | | ('HASH', 'TREE', | | + | | | 'BITSET', 'RTREE') | | + | | | | | + | | | | | + | | | | | + +---------------+--------------------+-----------------------------+---------------------+ + | id | unique identifier | number | last index's id, +1 | + +---------------+--------------------+-----------------------------+---------------------+ + | unique | index is unique | boolean | true | + +---------------+--------------------+-----------------------------+---------------------+ + | if_not_exists | no error if | boolean | false | + | | duplicate name | | | + +---------------+--------------------+-----------------------------+---------------------+ + | parts | field-numbers + | ``{field_no, 'NUM'|'STR'}`` | ``{1, 'NUM'}`` | + | | types | | | + +---------------+--------------------+-----------------------------+---------------------+ -.. function:: box.space.space-name:select{field-value [, field-value ...]} + Possible errors: too many parts. A type options other than TREE, or a + unique option other than unique, or a parts option with more than one + field component, is only applicable for the memtx storage engine. - Search for a tuple or a set of tuples in the given space. + .. code-block:: lua - :param userdata space-name: - :param lua-value field-value(s): values to be matched against the index - key, which may be multi-part. + tarantool> s = box.space.space55 + --- + ... + tarantool> s:create_index('primary', {unique = true, parts = {1, 'NUM', 2, 'STR'}}) + --- + ... - :return: the tuples whose primary-key fields are equal to the passed - field-values. If the number of passed field-values is less - than the number of fields in the primary key, then only the - passed field-values are compared, so ``select{1,2}`` will match - a tuple whose primary key is ``{1,2,3}``. - :rtype: tuple + .. function:: insert(tuple) - :except: No such space; wrong type. + Insert a tuple into a space. - Complexity Factors: Index size, Index type. + :param space_object space-object: + :param lua-table,box.tuple tuple: tuple to be inserted. + :return: the inserted tuple + :rtype: tuple - .. code-block:: lua + Possible errors: If a tuple with the same unique-key value already exists, + returns :errcode:`ER_TUPLE_FOUND`. - tarantool> s = box.schema.space.create('tmp', {temporary=true}) - --- - ... - tarantool> s:create_index('primary',{parts = {1,'NUM', 2, 'STR'}}) - --- - ... - tarantool> s:insert{1,'A'} - --- - - [1, 'A'] - ... - tarantool> s:insert{1,'B'} - --- - - [1, 'B'] - ... - tarantool> s:insert{1,'C'} - --- - - [1, 'C'] - ... - tarantool> s:insert{2,'D'} - --- - - [2, 'D'] - ... - tarantool> -- must equal both primary-key fields - tarantool> s:select{1,'B'} - --- - - - [1, 'B'] - ... - tarantool> -- must equal only one primary-key field - tarantool> s:select{1} - --- - - - [1, 'A'] - - [1, 'B'] - - [1, 'C'] - ... - tarantool> -- must equal 0 fields, so returns all tuples - tarantool> s:select{} - --- - - - [1, 'A'] - - [1, 'B'] - - [1, 'C'] - - [2, 'D'] - ... + .. code-block:: lua - For examples of complex ``select`` requests, where one can specify which index to - search and what condition to use (for example "greater than" instead of - "equal to") and how many tuples to return, see the later section - ``box.space.space-name[.index.index-name]:select``. + box.space.tester:insert{5000,'tuple number five thousand'} -.. function:: box.space.space-name:get{field-value [, field-value ...]} + .. function:: select(key) - Search for a tuple in the given space. + Search for a tuple or a set of tuples in the given space. - :param userdata space-name: - :param lua-value field-value(s): values to be matched against the index + :param space_object space-object: + :param lua-table,scalar key: key to be matched against the index key, which may be multi-part. - :return: the selected tuple. - :rtype: tuple - - :except: If space-name does not exist. - - Complexity Factors: Index size, Index type, - Number of indexes accessed, WAL settings. - - .. code-block:: lua - - tarantool> box.space.tester:get{1} - -.. function:: box.space.space-name:drop() - - Drop a space. - - :return: nil - :except: If space-name does not exist. - - Complexity Factors: Index size, Index type, - Number of indexes accessed, WAL settings. - - .. code-block:: lua - - tarantool> box.space.space_that_does_not_exist:drop() - -.. function:: box.space.space-name:rename(space-name) - - Rename a space. - - :param string space-name: new name for space. - - :return: nil - :except: If space-name does not exist. - - .. code-block:: lua - - tarantool> box.space.space55:rename('space56') - --- - ... - tarantool> box.space.space56:rename('space55') - --- - ... - -.. function:: box.space.space-name:replace{field-value [, field-value ...]} - box.space.space-name:put{field-value [, field-value ...]} - - Insert a tuple into a space. If a tuple with the same primary key already - exists, ``box.space...:replace()`` replaces the existing tuple with a new - one. The syntax variants ``box.space...:replace()`` and - ``box.space...:put()`` have the same effect; the latter is sometimes used - to show that the effect is the converse of ``box.space...:get()``. - - :param userdata space-name: - :param lua-value field-value(s): fields of the new tuple. - - :return: the inserted tuple. - :rtype: tuple - - :except: If a different tuple with the same unique-key - value already exists, returns ``ER_TUPLE_FOUND``. - (This would only happen if there was a secondary - index. By default secondary indexes are unique.) - - Complexity Factors: Index size, Index type, - Number of indexes accessed, WAL settings. - - .. code-block:: lua - - tarantool> box.space.tester:replace{5000, 'New value'} - -.. function:: box.space.space-name:update(key, {{operator, field_no, value}, ...}) - - Update a tuple. - - The ``update`` function supports operations on fields — assignment, - arithmetic (if the field is unsigned numeric), cutting and pasting - fragments of a field, deleting or inserting a field. Multiple - operations can be combined in a single update request, and in this - case they are performed atomically and sequentially. Each operation - requires specification of a field number. When multiple operations - are present, the field number for each operation is assumed to be - relative to the most recent state of the tuple, that is, as if all - previous operations in a multi-operation update have already been - applied. In other words, it is always safe to merge multiple update - invocations into a single invocation, with no change in semantics. - - :param userdata space-name: - :param lua-value key: primary-key field values, must be passed as a Lua - table if key is multi-part - :param table {operator, field_no, value}: a group of arguments for each - operation, indicating what the operation is, what field the - operation will apply to, and what value will be applied. For - some operations the field number can be -1, meaning the last - field in the tuple. Possible operators are: “+†for addition, - “-†for subtraction, “&†for bitwise AND, “|†for bitwise OR, - “^†for bitwise exclusive OR (XOR), “:†for string splice, “!†- for insert, “#†for delete. Thus in the instruction - ``s:update(44, {{'+',1,55},{'=',3,'x'}})`` the primary-key - value is 44, the operators are '+' and '=' meaning "add a value - to a field and then assign a value to a field", the first - affected field is field 1 and the value which will be added to - it is 55, the second affected field is field 3 and the value - which will be assigned to it is 'x'. - - :return: the updated tuple. - :rtype: tuple - - :except: it is illegal to modify a primary-key field. - - Complexity Factors: Index size, Index type, number of indexes accessed, WAL - settings. - - .. code-block:: lua - - -- Assume that the initial state of the database is ... - -- tester has one tuple set and one primary key whose type is 'NUM'. - -- There is one tuple, with field[1] = 999 and field[2] = 'A'. - - -- In the following update ... - -- The first argument is tester, that is, the affected space is tester - -- The second argument is 999, that is, the affected tuple is identified by - -- primary key value = 999 - -- The third argument is '=', that is, there is one operation, assignment - -- to a field - -- The fourth argument is 2, that is, the affected field is field[2] - -- The fifth argument is 'B', that is, field[2] contents change to 'B' - -- Therefore, after the following update, field[1] = 999 and field[2] = 'B'. - box.space.tester:update(999, {{'=', 2, 'B'}}) - - -- In the following update, the arguments are the same, except that ... - -- the key is passed as a Lua table (inside braces). This is unnecessary - -- when the primary key has only one field, but would be necessary if the - -- primary key had more than one field. - -- Therefore, after the following update, field[1] = 999 and field[2] = 'B' - -- (no change). - box.space.tester:update({999}, {{'=', 2, 'B'}}) - - -- In the following update, the arguments are the same, except that ... - -- The fourth argument is 3, that is, the affected field is field[3]. - -- It is okay that, until now, field[3] has not existed. It gets added. - -- Therefore, after the following update, field[1] = 999, field[2] = 'B', - -- field[3] = 1. - box.space.tester:update({999}, {{'=', 3, 1}}) - - -- In the following update, the arguments are the same, except that ... - -- The third argument is '+', that is, the operation is addition rather - -- than assignment. - -- Since field[3] previously contained 1, this means we're adding 1 to 1. - -- Therefore, after the following update, field[1] = 999, field[2] = 'B', - -- field[3] = 2. - box.space.tester:update({999}, {{'+', 3, 1}}) - - -- In the following update ... - -- The idea is to modify two fields at once. - -- The formats are '|' and '=', that is, there are two operations, OR and - -- assignment. - -- The fourth and fifth arguments mean that field[3] gets ORed with 1. - -- The seventh and eighth arguments mean that field[2] gets assigned 'C'. - -- Therefore, after the following update, field[1] = 999, field[2] = 'C', - -- field[3] = 3. - box.space.tester:update({999}, {{'|', 3, 1}, {'=', 2, 'C'}}) - - -- In the following update ... - -- The idea is to delete field[2], then subtract 3 from field[3], but ... - -- after the delete, there is a renumbering -- so field[3] becomes field[2] - -- before we subtract 3 from it, and that's why the seventh argument is 2 not 3. - -- Therefore, after the following update, field[1] = 999, field[2] = 0. - box.space.tester:update({999}, {{'-- ', 2, 1}, {'-', 2, 3}}) - - -- In the following update ... - -- We're making a long string so that splice will work in the next example. - -- Therefore, after the following update, field[1] = 999, field[2] = 'XYZ'. - box.space.tester:update({999}, {{'=', 2, 'XYZ'}}) - - -- In the following update ... - -- The third argument is ':', that is, this is the example of splice. - -- The fourth argument is 2 because the change will occur in field[2]. - -- The fifth argument is 2 because deletion will begin with the second byte. - -- The sixth argument is 1 because the number of bytes to delete is 1. - -- The seventh argument is '!!' because '!!' is to be added at this position. - -- Therefore, after the following update, field[1] = 999, field[2] = 'X!!Z'. - box.space.tester:update({999}, {{':', 2, 2, 1, '!!'}}) - -.. function:: box.space.space-name:delete{field-value [, field-value ...]} - - Delete a tuple identified by a primary key. - - :param userdata space-name: - :param lua-value field-value(s): values to match against keys - in the primary index. - - :return: the deleted tuple - :rtype: tuple - - Complexity Factors: Index size, Index type - - .. code-block:: lua - - tarantool> box.space.tester:delete(0) - --- - - [0, 'My first tuple'] - ... - tarantool> box.space.tester:delete(0) - --- - ... - tarantool> box.space.tester:delete('a') - --- - - error: 'Supplied key type of part 0 does not match index part type: - expected NUM' - ... -.. data:: space-name.id + :return: the tuples whose primary-key fields are equal to the passed + field-values. If the number of passed field-values is less + than the number of fields in the primary key, then only the + passed field-values are compared, so ``select{1,2}`` will match + a tuple whose primary key is ``{1,2,3}``. + :rtype: tuple + + Possible errors: No such space; wrong type. - Ordinal space number. Spaces can be referenced by either name or - number. Thus, if space 'tester' has id = 800, then - ``box.space.tester:insert{0}`` and ``box.space[800]:insert{0}`` - are equivalent requests. + Complexity Factors: Index size, Index type. - :rtype: number + .. code-block:: lua -.. data:: space-name.enabled + tarantool> s = box.schema.space.create('tmp', {temporary=true}) + --- + ... + tarantool> s:create_index('primary',{parts = {1,'NUM', 2, 'STR'}}) + --- + ... + tarantool> s:insert{1,'A'} + --- + - [1, 'A'] + ... + tarantool> s:insert{1,'B'} + --- + - [1, 'B'] + ... + tarantool> s:insert{1,'C'} + --- + - [1, 'C'] + ... + tarantool> s:insert{2,'D'} + --- + - [2, 'D'] + ... + tarantool> -- must equal both primary-key fields + tarantool> s:select{1,'B'} + --- + - - [1, 'B'] + ... + tarantool> -- must equal only one primary-key field + tarantool> s:select{1} + --- + - - [1, 'A'] + - [1, 'B'] + - [1, 'C'] + ... + tarantool> -- must equal 0 fields, so returns all tuples + tarantool> s:select{} + --- + - - [1, 'A'] + - [1, 'B'] + - [1, 'C'] + - [2, 'D'] + ... - Whether or not this space is enabled. - The value is false if there is no index. + For examples of complex ``select`` requests, where one can specify which index to + search and what condition to use (for example "greater than" instead of + "equal to") and how many tuples to return, see the later section + ``box.space.space-name[.index.index-name]:select``. - :rtype: boolean + .. function:: get(key) -.. data:: space-name.field_count + Search for a tuple in the given space. - The required field count for all tuples in this space. The field_count - can be set initially with - ``box.schema.space.create... field_count = new-field-count-value ...``. - The default value is 0, which means there is no required field count. + :param space_object space-object: + :param lua-table,scalar key: key to be matched against the index + key, which may be multi-part. + :return: the selected tuple. + :rtype: tuple + + Possible errors: If space-name does not exist. + + Complexity Factors: Index size, Index type, + Number of indexes accessed, WAL settings. + + .. code-block:: lua + + tarantool> box.space.tester:get{1} + + .. function:: drop() + + Drop a space. + + :param space_object space-object: + + :return: nil + + Possible errors: If space-name does not exist. - :rtype: number + Complexity Factors: Index size, Index type, + Number of indexes accessed, WAL settings. -.. data:: space-name.index[] + .. code-block:: lua + + tarantool> box.space.space_that_does_not_exist:drop() + + .. function:: rename(space-name) + + Rename a space. + + :param space_object space-object: + :param string space-name: new name for space. - A container for all defined indexes. An index is a Lua object of type - :mod:`box.index` with methods to search tuples and iterate over them in - predefined order. + :return: nil - :rtype: table + Possible errors: ``space-name`` does not exist. + + .. code-block:: lua + + tarantool> box.space.space55:rename('space56') + --- + ... + tarantool> box.space.space56:rename('space55') + --- + ... + + .. function:: replace(tuple) + put(tuple) + + Insert a tuple into a space. If a tuple with the same primary key already + exists, ``box.space...:replace()`` replaces the existing tuple with a new + one. The syntax variants ``box.space...:replace()`` and + ``box.space...:put()`` have the same effect; the latter is sometimes used + to show that the effect is the converse of ``box.space...:get()``. + + :param space_object space-object: + :param lua-table,box.tuple tuple: tuple to be inserted. + + :return: the inserted tuple. + :rtype: tuple + + Possible errors: If a different tuple with the same unique-key + value already exists, returns :errcode:`ER_TUPLE_FOUND`. (This + would only happen if there was a secondary index. By default + secondary indexes are unique) + + Complexity Factors: Index size, Index type, + Number of indexes accessed, WAL settings. - .. code-block: lua + .. code-block:: lua - tarantool> box.space.tester.id - --- - - 512 - ... - tarantool> box.space.tester.field_count - --- - - 0 - ... - tarantool> box.space.tester.index.primary.type - --- - - TREE - ... + tarantool> box.space.tester:replace{5000, 'New value'} -.. function:: box.space.space-name:len() + .. function:: update(key, {{operator, field_no, value}, ...}) - .. NOTE:: + Update a tuple. - The ``len()`` function is only applicable for the memtx storage engine. + The ``update`` function supports operations on fields — assignment, + arithmetic (if the field is unsigned numeric), cutting and pasting + fragments of a field, deleting or inserting a field. Multiple + operations can be combined in a single update request, and in this + case they are performed atomically and sequentially. Each operation + requires specification of a field number. When multiple operations + are present, the field number for each operation is assumed to be + relative to the most recent state of the tuple, that is, as if all + previous operations in a multi-operation update have already been + applied. In other words, it is always safe to merge multiple update + invocations into a single invocation, with no change in semantics. - :return: Number of tuples in the space. + Possible operators are: - .. code-block:: lua + * '+' for addition + * '-' for substraction + * '&' for bitwise AND + * '|' for bitwise OR + * '^' for butwise :abbr:`XOR(exclusive OR)` + * ':' for string splice + * '!' for insert + * '#' for delete - tarantool> box.space.tester:len() - --- - - 2 - ... + :param space_object space-object: + :param lua-value key: primary-key field values, must be passed as a Lua + table if key is multi-part + :param table {operator, field_no, value}: a group of arguments for each + operation, indicating what the operation is, what field the + operation will apply to, and what value will be applied. For + some operations the field number can be -1, meaning the last + field in the tuple. Thus in the instruction -.. function:: box.space.space-name:truncate() + :return: the updated tuple. + :rtype: tuple + + Possible errors: it is illegal to modify a primary-key field. + + Complexity Factors: Index size, Index type, number of indexes accessed, WAL + settings. + + .. code-block:: lua + + s:update(44, {{'+',1,55},{'=',3,'x'}}) + + the primary-key value is 44, the operators are '+' and '=' meaning + "add a value to a field and then assign a value to a field", the first + affected field is field 1 and the value which will be added to it is + 55, the second affected field is field 3 and the value which will be + assigned to it is 'x'. + + .. code-block:: lua + + -- Assume that the initial state of the database is ... + -- tester has one tuple set and one primary key whose type is 'NUM'. + -- There is one tuple, with field[1] = 999 and field[2] = 'A'. + + -- In the following update ... + -- The first argument is tester, that is, the affected space is tester + -- The second argument is 999, that is, the affected tuple is identified by + -- primary key value = 999 + -- The third argument is '=', that is, there is one operation, assignment + -- to a field + -- The fourth argument is 2, that is, the affected field is field[2] + -- The fifth argument is 'B', that is, field[2] contents change to 'B' + -- Therefore, after the following update, field[1] = 999 and field[2] = 'B'. + box.space.tester:update(999, {{'=', 2, 'B'}}) + + -- In the following update, the arguments are the same, except that ... + -- the key is passed as a Lua table (inside braces). This is unnecessary + -- when the primary key has only one field, but would be necessary if the + -- primary key had more than one field. + -- Therefore, after the following update, field[1] = 999 and field[2] = 'B' + -- (no change). + box.space.tester:update({999}, {{'=', 2, 'B'}}) + + -- In the following update, the arguments are the same, except that ... + -- The fourth argument is 3, that is, the affected field is field[3]. + -- It is okay that, until now, field[3] has not existed. It gets added. + -- Therefore, after the following update, field[1] = 999, field[2] = 'B', + -- field[3] = 1. + box.space.tester:update({999}, {{'=', 3, 1}}) + + -- In the following update, the arguments are the same, except that ... + -- The third argument is '+', that is, the operation is addition rather + -- than assignment. + -- Since field[3] previously contained 1, this means we're adding 1 to 1. + -- Therefore, after the following update, field[1] = 999, field[2] = 'B', + -- field[3] = 2. + box.space.tester:update({999}, {{'+', 3, 1}}) + + -- In the following update ... + -- The idea is to modify two fields at once. + -- The formats are '|' and '=', that is, there are two operations, OR and + -- assignment. + -- The fourth and fifth arguments mean that field[3] gets ORed with 1. + -- The seventh and eighth arguments mean that field[2] gets assigned 'C'. + -- Therefore, after the following update, field[1] = 999, field[2] = 'C', + -- field[3] = 3. + box.space.tester:update({999}, {{'|', 3, 1}, {'=', 2, 'C'}}) + + -- In the following update ... + -- The idea is to delete field[2], then subtract 3 from field[3], but ... + -- after the delete, there is a renumbering -- so field[3] becomes field[2] + -- before we subtract 3 from it, and that's why the seventh argument is 2 not 3. + -- Therefore, after the following update, field[1] = 999, field[2] = 0. + box.space.tester:update({999}, {{'-- ', 2, 1}, {'-', 2, 3}}) + + -- In the following update ... + -- We're making a long string so that splice will work in the next example. + -- Therefore, after the following update, field[1] = 999, field[2] = 'XYZ'. + box.space.tester:update({999}, {{'=', 2, 'XYZ'}}) + + -- In the following update ... + -- The third argument is ':', that is, this is the example of splice. + -- The fourth argument is 2 because the change will occur in field[2]. + -- The fifth argument is 2 because deletion will begin with the second byte. + -- The sixth argument is 1 because the number of bytes to delete is 1. + -- The seventh argument is '!!' because '!!' is to be added at this position. + -- Therefore, after the following update, field[1] = 999, field[2] = 'X!!Z'. + box.space.tester:update({999}, {{':', 2, 2, 1, '!!'}}) + + .. function:: delete(key) - Deletes all tuples. + Delete a tuple identified by a primary key. + + :param space_object space-object: + :param lua-table,scalar key: key to be matched against the index + key, which may be multi-part. + + :return: the deleted tuple + :rtype: tuple - Complexity Factors: Index size, Index type, Number of tuples accessed. + Complexity Factors: Index size, Index type - :return: nil + .. code-block:: lua + + tarantool> box.space.tester:delete(0) + --- + - [0, 'My first tuple'] + ... + tarantool> box.space.tester:delete(0) + --- + ... + tarantool> box.space.tester:delete('a') + --- + - error: 'Supplied key type of part 0 does not match index part type: + expected NUM' + ... + + .. data:: id + + Ordinal space number. Spaces can be referenced by either name or + number. Thus, if space 'tester' has id = 800, then + ``box.space.tester:insert{0}`` and ``box.space[800]:insert{0}`` + are equivalent requests. + + :rtype: number + + .. data:: enabled + + Whether or not this space is enabled. + The value is false if there is no index. + + :rtype: boolean + + .. data:: field_count + + The required field count for all tuples in this space. The field_count + can be set initially with + ``box.schema.space.create... field_count = new-field-count-value ...``. + The default value is 0, which means there is no required field count. + + :rtype: number + + .. data:: index + + A container for all defined indexes. An index is a Lua object of type + :mod:`box.index` with methods to search tuples and iterate over them in + predefined order. + + :rtype: table - .. code-block:: lua + .. code-block: lua + + tarantool> box.space.tester.id + --- + - 512 + ... + tarantool> box.space.tester.field_count + --- + - 0 + ... + tarantool> box.space.tester.index.primary.type + --- + - TREE + ... + + .. function:: len() + + .. NOTE:: + + The ``len()`` function is only applicable for the memtx storage engine. + + :return: Number of tuples in the space. + + .. code-block:: lua - tarantool> box.space.tester:truncate() - --- - ... - tarantool> box.space.tester:len() - --- - - 0 - ... + tarantool> box.space.tester:len() + --- + - 2 + ... -.. function:: box.space.space-name:inc{field-value [, field-value ...]} + .. function:: truncate() - Increments a counter in a tuple whose primary key matches the - ``field-value(s)``. The field following the primary-key fields - will be the counter. If there is no tuple matching the - ``field-value(s)``, a new one is inserted with initial counter - value set to 1. + Deletes all tuples. - :param userdata space-name: - :param lua-value field-value(s): values which must match the primary key. - :return: the new counter value - :rtype: number + Complexity Factors: Index size, Index type, Number of tuples accessed. - Complexity Factors: Index size, Index type, WAL settings. + :return: nil - .. code-block:: lua + .. code-block:: lua - tarantool> s = box.schema.space.create('forty_second_space') - --- - ... - tarantool> s:create_index('primary', {unique = true, parts = {1, 'NUM', 2, 'STR'}}) - --- - ... - tarantool> box.space.forty_second_space:inc{1,'a'} - --- - - 1 - ... - tarantool> box.space.forty_second_space:inc{1,'a'} - --- - - 2 - ... + tarantool> box.space.tester:truncate() + --- + ... + tarantool> box.space.tester:len() + --- + - 0 + ... -.. function:: box.space.space-name:dec{field-value [, field-value ...]} + .. function:: inc(key) - Decrements a counter in a tuple whose primary key matches the - ``field-value(s)``. The field following the primary-key fields - will be the counter. If there is no tuple matching the - ``field-value(s)``, a new one is not inserted. If the counter value drops - to zero, the tuple is deleted. + Increments a counter in a tuple whose primary key matches the + ``key``. The field following the primary-key fields + will be the counter. If there is no tuple matching the + ``field-value(s)``, a new one is inserted with initial counter + value set to 1. - :param userdata space-name: - :param lua-value field-value(s): values which must match the primary key. - :return: the new counter value - :rtype: number + :param space_object space-object: + :param lua-table,scalar key: key to be matched against the index + key, which may be multi-part. + :return: the new counter value + :rtype: number - Complexity Factors: Index size, Index type, WAL settings. + Complexity Factors: Index size, Index type, WAL settings. - .. code-block:: lua + .. code-block:: lua - tarantool> s = box.schema.space.create('space19') - --- - ... - tarantool> s:create_index('primary', {unique = true, parts = {1, 'NUM', 2, 'STR'}}) - --- - ... - tarantool> box.space.space19:insert{1,'a',1000} - --- - - [1, 'a', 1000] - ... - tarantool> box.space.space19:dec{1,'a'} - --- - - 999 - ... - tarantool> box.space.space19:dec{1,'a'} - --- - - 998 - ... - -.. function:: box.space.space-name:auto_increment{field-value [, field-value ...]} - - Insert a new tuple using an auto-increment primary key. The space specified - by space-name must have a NUM primary key index of type TREE. The - primary-key field will be incremented before the insert. - - :param userdata space-name: - :param lua-value field-value(s): values for the tuple's fields, - other than the primary-key field. - - :return: the inserted tuple. - :rtype: tuple - - Complexity Factors: Index size, Index type, - Number of indexes accessed, WAL settings. - - :except: index has wrong type or primary-key indexed field is not a number. - - .. code-block:: lua - - tarantool> box.space.tester:auto_increment{'Fld#1', 'Fld#2'} - --- - - [1, 'Fld#1', 'Fld#2'] - ... - tarantool> box.space.tester:auto_increment{'Fld#3'} - --- - - [2, 'Fld#3'] - ... - -.. function:: box.space.space-name:pairs() - - A helper function to prepare for iterating over all tuples in a space. - - :return: function which can be used in a for/end loop. Within the loop, a value is returned for each iteration. - :rtype: function, tuple - - .. code-block:: lua - - tarantool> s = box.schema.space.create('space33') - --- - ... - tarantool> -- index 'X' has default parts {1,'NUM'} - tarantool> s:create_index('X', {}) - --- - ... - tarantool> s:insert{0,'Hello my '}; s:insert{1,'Lua world'} - --- - ... - tarantool> tmp = ''; for k, v in s:pairs() do tmp = tmp .. v[2] end - --- - ... - tarantool> tmp - --- - - Hello my Lua world - ... + tarantool> s = box.schema.space.create('forty_second_space') + --- + ... + tarantool> s:create_index('primary', {unique = true, parts = {1, 'NUM', 2, 'STR'}}) + --- + ... + tarantool> box.space.forty_second_space:inc{1,'a'} + --- + - 1 + ... + tarantool> box.space.forty_second_space:inc{1,'a'} + --- + - 2 + ... + + .. function:: dec(key) + + Decrements a counter in a tuple whose primary key matches the + ``field-value(s)``. The field following the primary-key fields + will be the counter. If there is no tuple matching the + ``field-value(s)``, a new one is not inserted. If the counter value drops + to zero, the tuple is deleted. + + :param space_object space-object: + :param lua-table,scalar key: key to be matched against the index + key, which may be multi-part. + :return: the new counter value + :rtype: number + + Complexity Factors: Index size, Index type, WAL settings. + + .. code-block:: lua + + tarantool> s = box.schema.space.create('space19') + --- + ... + tarantool> s:create_index('primary', {unique = true, parts = {1, 'NUM', 2, 'STR'}}) + --- + ... + tarantool> box.space.space19:insert{1,'a',1000} + --- + - [1, 'a', 1000] + ... + tarantool> box.space.space19:dec{1,'a'} + --- + - 999 + ... + tarantool> box.space.space19:dec{1,'a'} + --- + - 998 + ... + + .. function:: auto_increment(tuple) + + Insert a new tuple using an auto-increment primary key. The space specified + by space-name must have a NUM primary key index of type TREE. The + primary-key field will be incremented before the insert. + + :param space_object space-object: + :param lua-table,box.tuple tuple: tuple's fields, other than the primary-key field. + + :return: the inserted tuple. + :rtype: tuple + + Complexity Factors: Index size, Index type, + Number of indexes accessed, WAL settings. + + Possible errors: index has wrong type or primary-key indexed field is not a number. + + .. code-block:: lua + + tarantool> box.space.tester:auto_increment{'Fld#1', 'Fld#2'} + --- + - [1, 'Fld#1', 'Fld#2'] + ... + tarantool> box.space.tester:auto_increment{'Fld#3'} + --- + - [2, 'Fld#3'] + ... + + .. function:: pairs() + + A helper function to prepare for iterating over all tuples in a space. + + :return: function which can be used in a for/end loop. Within the loop, a value is returned for each iteration. + :rtype: function, tuple + + .. code-block:: lua + + tarantool> s = box.schema.space.create('space33') + --- + ... + tarantool> -- index 'X' has default parts {1,'NUM'} + tarantool> s:create_index('X', {}) + --- + ... + tarantool> s:insert{0,'Hello my '}; s:insert{1,'Lua world'} + --- + ... + tarantool> tmp = ''; for k, v in s:pairs() do tmp = tmp .. v[2] end + --- + ... + tarantool> tmp + --- + - Hello my Lua world + ... .. data:: _schema diff --git a/doc/sphinx/book/replication/index.rst b/doc/sphinx/book/replication/index.rst index 05ed77f15668937d408dceea4cda7cf2b079c8bd..9f4a9fdd58fcd4e6e037eadcdc76813a837186b3 100644 --- a/doc/sphinx/book/replication/index.rst +++ b/doc/sphinx/book/replication/index.rst @@ -212,17 +212,68 @@ a cluster and adding a replica. Start two shells. Put them side by side on the screen. -.. container:: table-wide - - +----------------------+---------------------+ - | Terminal #1 | Terminal #2 | - +======================+=====================+ - | | | - | .. code-block:: lua | .. code-block:: lua | - | | | - | $ | $ | - | | | - +----------------------+---------------------+ +.. container:: b-block-wrapper_doc + + .. container:: b-doc_catalog + :name: catalog-1 + + .. raw:: html + + <ul class="b-tab_switcher"> + <li class="b-tab_switcher-item"> + <a href="#terminal-1-1" class="b-tab_switcher-item-url p-active">Terminal #1</a> + </li> + <li class="b-tab_switcher-item"> + <a href="#terminal-1-2" class="b-tab_switcher-item-url">Terminal #2</a> + </li> + </ul> + + .. container:: b-documentation_tab_content + :name: catalog-1-content + + .. container:: b-documentation_tab + :name: terminal-1-1 + + .. code-block:: lua + + $ + + .. container:: b-documentation_tab + :name: terminal-1-2 + + .. code-block:: lua + + $ + + .. raw:: html + + <script> + (function(){ + var dOn = $(document); + dOn.on({ + click: function(event) { + event.preventDefault(); + link = $(this).children('a'); + target = link.attr('href'); + if (!(link.hasClass('p-active'))) { + active = $('#catalog-1 .b-tab_switcher-item-url.p-active'); + $(active.attr('href')).hide(); + active.removeClass('p-active'); + link.addClass('p-active'); + $(link.attr('href')).show(); + } + } + }, '#catalog-1 .b-tab_switcher-item'); + dOn.ready(function(event) { + maxHeight = Math.max($('#terminal-1-1').height(), $('#terminal-1-2').height()); + $('#catalog-1-content').height(maxHeight + 10); + $('#terminal-1-1').height(maxHeight); + $('#terminal-1-2').height(maxHeight); + $('#terminal-1-1').show(); + $('#terminal-1-2').hide(); + }); + })(); + </script> On the first shell, which we'll call Terminal #1, execute these commands: @@ -241,16 +292,64 @@ On the first shell, which we'll call Terminal #1, execute these commands: The result is that a new cluster is set up, and the UUID is displayed. Now the screen looks like this: (except that UUID values are always different): - -.. container:: table-wide - - +----------------------------------+----------------------------------+ - | Terminal #1 | Terminal #2 | - +==================================+==================================+ - | | | - | .. include:: 1-1.rst | .. include:: 1-2.rst | - | | | - +----------------------------------+----------------------------------+ +.. container:: b-block-wrapper_doc + + .. container:: b-doc_catalog + :name: catalog-2 + + .. raw:: html + + <ul class="b-tab_switcher"> + <li class="b-tab_switcher-item"> + <a href="#terminal-2-1" class="b-tab_switcher-item-url p-active">Terminal #1</a> + </li> + <li class="b-tab_switcher-item"> + <a href="#terminal-2-2" class="b-tab_switcher-item-url">Terminal #2</a> + </li> + </ul> + + .. container:: b-documentation_tab_content + :name: catalog-2-content + + .. container:: b-documentation_tab + :name: terminal-2-1 + + .. include:: 1-1.rst + + .. container:: b-documentation_tab + :name: terminal-2-2 + + .. include:: 1-2.rst + + .. raw:: html + + <script> + (function(){ + var dOn = $(document); + dOn.on({ + click: function(event) { + event.preventDefault(); + link = $(this).children('a'); + target = link.attr('href'); + if (!(link.hasClass('p-active'))) { + active = $('#catalog-2 .b-tab_switcher-item-url.p-active'); + $(active.attr('href')).hide(); + active.removeClass('p-active'); + link.addClass('p-active'); + $(link.attr('href')).show(); + } + } + }, '#catalog-2 .b-tab_switcher-item'); + dOn.ready(function(event) { + maxHeight = Math.max($('#terminal-2-1').height(), $('#terminal-2-2').height()); + $('#catalog-2-content').height(maxHeight); + $('#terminal-2-1').height(maxHeight); + $('#terminal-2-2').height(maxHeight); + $('#terminal-2-1').show(); + $('#terminal-2-2').hide(); + }); + })(); + </script> On the second shell, which we'll call Terminal #2, execute these commands: @@ -271,16 +370,64 @@ replication is starting. Also on Terminal#2 the _cluster UUID value is displayed, and it is the same as the _cluster UUID value that was displayed on Terminal #1, because both servers are in the same cluster. - -.. container:: table-wide - - +----------------------------------+----------------------------------+ - | Terminal #1 | Terminal #2 | - +==================================+==================================+ - | | | - | .. include:: 2-1.rst | .. include:: 2-2.rst | - | | | - +----------------------------------+----------------------------------+ +.. container:: b-block-wrapper_doc + + .. container:: b-doc_catalog + :name: catalog-3 + + .. raw:: html + + <ul class="b-tab_switcher"> + <li class="b-tab_switcher-item"> + <a href="#terminal-3-1" class="b-tab_switcher-item-url p-active">Terminal #1</a> + </li> + <li class="b-tab_switcher-item"> + <a href="#terminal-3-2" class="b-tab_switcher-item-url">Terminal #2</a> + </li> + </ul> + + .. container:: b-documentation_tab_content + :name: catalog-3-content + + .. container:: b-documentation_tab + :name: terminal-3-1 + + .. include:: 2-1.rst + + .. container:: b-documentation_tab + :name: terminal-3-2 + + .. include:: 2-2.rst + + .. raw:: html + + <script> + (function(){ + var dOn = $(document); + dOn.on({ + click: function(event) { + event.preventDefault(); + link = $(this).children('a'); + target = link.attr('href'); + if (!(link.hasClass('p-active'))) { + active = $('#catalog-3 .b-tab_switcher-item-url.p-active'); + $(active.attr('href')).hide(); + active.removeClass('p-active'); + link.addClass('p-active'); + $(link.attr('href')).show(); + } + } + }, '#catalog-3 .b-tab_switcher-item'); + dOn.ready(function(event) { + maxHeight = Math.max($('#terminal-3-1').height(), $('#terminal-3-2').height()); + $('#catalog-3-content').height(maxHeight + 10); + $('#terminal-3-1').height(maxHeight); + $('#terminal-3-2').height(maxHeight); + $('#terminal-3-1').show(); + $('#terminal-3-2').hide(); + }); + })(); + </script> On Terminal #1, execute these requests: @@ -292,15 +439,64 @@ On Terminal #1, execute these requests: Now the screen looks like this: -.. container:: table-wide - - +----------------------------------+----------------------------------+ - | Terminal #1 | Terminal #2 | - +==================================+==================================+ - | | | - | .. include:: 3-1.rst | .. include:: 3-2.rst | - | | | - +----------------------------------+----------------------------------+ +.. container:: b-block-wrapper_doc + + .. container:: b-doc_catalog + :name: catalog-4 + + .. raw:: html + + <ul class="b-tab_switcher"> + <li class="b-tab_switcher-item"> + <a href="#terminal-4-1" class="b-tab_switcher-item-url p-active">Terminal #1</a> + </li> + <li class="b-tab_switcher-item"> + <a href="#terminal-4-2" class="b-tab_switcher-item-url">Terminal #2</a> + </li> + </ul> + + .. container:: b-documentation_tab_content + :name: catalog-4-content + + .. container:: b-documentation_tab + :name: terminal-4-1 + + .. include:: 3-1.rst + + .. container:: b-documentation_tab + :name: terminal-4-2 + + .. include:: 3-2.rst + + .. raw:: html + + <script> + (function(){ + var dOn = $(document); + dOn.on({ + click: function(event) { + event.preventDefault(); + link = $(this).children('a'); + target = link.attr('href'); + if (!(link.hasClass('p-active'))) { + active = $('#catalog-4 .b-tab_switcher-item-url.p-active'); + $(active.attr('href')).hide(); + active.removeClass('p-active'); + link.addClass('p-active'); + $(link.attr('href')).show(); + } + } + }, '#catalog-4 .b-tab_switcher-item'); + dOn.ready(function(event) { + maxHeight = Math.max($('#terminal-4-1').height(), $('#terminal-4-2').height()); + $('#catalog-4-content').height(maxHeight + 10); + $('#terminal-4-1').height(maxHeight); + $('#terminal-4-2').height(maxHeight); + $('#terminal-4-1').show(); + $('#terminal-4-2').hide(); + }); + })(); + </script> The creation and insertion were successful on Terminal #1. Nothing has happened on Terminal #2. @@ -315,15 +511,64 @@ On Terminal #2, execute these requests: Now the screen looks like this: -.. container:: table-wide - - +----------------------------------+----------------------------------+ - | Terminal #1 | Terminal #2 | - +==================================+==================================+ - | | | - | .. include:: 4-1.rst | .. include:: 4-2.rst | - | | | - +----------------------------------+----------------------------------+ +.. container:: b-block-wrapper_doc + + .. container:: b-doc_catalog + :name: catalog-5 + + .. raw:: html + + <ul class="b-tab_switcher"> + <li class="b-tab_switcher-item"> + <a href="#terminal-5-1" class="b-tab_switcher-item-url p-active">Terminal #1</a> + </li> + <li class="b-tab_switcher-item"> + <a href="#terminal-5-2" class="b-tab_switcher-item-url">Terminal #2</a> + </li> + </ul> + + .. container:: b-documentation_tab_content + :name: catalog-5-content + + .. container:: b-documentation_tab + :name: terminal-5-1 + + .. include:: 4-1.rst + + .. container:: b-documentation_tab + :name: terminal-5-2 + + .. include:: 4-2.rst + + .. raw:: html + + <script> + (function(){ + var dOn = $(document); + dOn.on({ + click: function(event) { + event.preventDefault(); + link = $(this).children('a'); + target = link.attr('href'); + if (!(link.hasClass('p-active'))) { + active = $('#catalog-5 .b-tab_switcher-item-url.p-active'); + $(active.attr('href')).hide(); + active.removeClass('p-active'); + link.addClass('p-active'); + $(link.attr('href')).show(); + } + } + }, '#catalog-5 .b-tab_switcher-item'); + dOn.ready(function(event) { + maxHeight = Math.max($('#terminal-5-1').height(), $('#terminal-5-2').height()); + $('#catalog-5-content').height(maxHeight + 10); + $('#terminal-5-1').height(maxHeight); + $('#terminal-5-2').height(maxHeight); + $('#terminal-5-1').show(); + $('#terminal-5-2').hide(); + }); + })(); + </script> The selection and insertion were successful on Terminal #2. Nothing has happened on Terminal #1. @@ -340,15 +585,64 @@ Now Tarantool #1 is stopped. Messages appear on Terminal #2 announcing that fact The "ls -l" commands show that both servers have made snapshots, which have the same size because they both contain the same tuples. -.. container:: table-wide - - +----------------------------------+----------------------------------+ - | Terminal #1 | Terminal #2 | - +==================================+==================================+ - | | | - | .. include:: 5-1.rst | .. include:: 5-2.rst | - | | | - +----------------------------------+----------------------------------+ +.. container:: b-block-wrapper_doc + + .. container:: b-doc_catalog + :name: catalog-6 + + .. raw:: html + + <ul class="b-tab_switcher"> + <li class="b-tab_switcher-item"> + <a href="#terminal-6-1" class="b-tab_switcher-item-url p-active">Terminal #1</a> + </li> + <li class="b-tab_switcher-item"> + <a href="#terminal-6-2" class="b-tab_switcher-item-url">Terminal #2</a> + </li> + </ul> + + .. container:: b-documentation_tab_content + :name: catalog-6-content + + .. container:: b-documentation_tab + :name: terminal-6-1 + + .. include:: 5-1.rst + + .. container:: b-documentation_tab + :name: terminal-6-2 + + .. include:: 5-2.rst + + .. raw:: html + + <script> + (function(){ + var dOn = $(document); + dOn.on({ + click: function(event) { + event.preventDefault(); + link = $(this).children('a'); + target = link.attr('href'); + if (!(link.hasClass('p-active'))) { + active = $('#catalog-6 .b-tab_switcher-item-url.p-active'); + $(active.attr('href')).hide(); + active.removeClass('p-active'); + link.addClass('p-active'); + $(link.attr('href')).show(); + } + } + }, '#catalog-6 .b-tab_switcher-item'); + dOn.ready(function(event) { + maxHeight = Math.max($('#terminal-6-1').height(), $('#terminal-6-2').height()); + $('#catalog-6-content').height(maxHeight + 10); + $('#terminal-6-1').height(maxHeight); + $('#terminal-6-2').height(maxHeight); + $('#terminal-6-1').show(); + $('#terminal-6-2').hide(); + }); + })(); + </script> On Terminal #2, ignore the repeated messages saying "failed to connect", and execute these requests: @@ -361,15 +655,64 @@ and execute these requests: Now the screen looks like this (ignoring the repeated messages saying "failed to connect"): -.. container:: table-wide - - +----------------------------------+----------------------------------+ - | Terminal #1 | Terminal #2 | - +==================================+==================================+ - | | | - | .. include:: 6-1.rst | .. include:: 6-2.rst | - | | | - +----------------------------------+----------------------------------+ +.. container:: b-block-wrapper_doc + + .. container:: b-doc_catalog + :name: catalog-7 + + .. raw:: html + + <ul class="b-tab_switcher"> + <li class="b-tab_switcher-item"> + <a href="#terminal-7-1" class="b-tab_switcher-item-url p-active">Terminal #1</a> + </li> + <li class="b-tab_switcher-item"> + <a href="#terminal-7-2" class="b-tab_switcher-item-url">Terminal #2</a> + </li> + </ul> + + .. container:: b-documentation_tab_content + :name: catalog-7-content + + .. container:: b-documentation_tab + :name: terminal-7-1 + + .. include:: 6-1.rst + + .. container:: b-documentation_tab + :name: terminal-7-2 + + .. include:: 6-2.rst + + .. raw:: html + + <script> + (function(){ + var dOn = $(document); + dOn.on({ + click: function(event) { + event.preventDefault(); + link = $(this).children('a'); + target = link.attr('href'); + if (!(link.hasClass('p-active'))) { + active = $('#catalog-7 .b-tab_switcher-item-url.p-active'); + $(active.attr('href')).hide(); + active.removeClass('p-active'); + link.addClass('p-active'); + $(link.attr('href')).show(); + } + } + }, '#catalog-7 .b-tab_switcher-item'); + dOn.ready(function(event) { + maxHeight = Math.max($('#terminal-7-1').height(), $('#terminal-7-2').height()); + $('#catalog-7-content').height(maxHeight + 10); + $('#terminal-7-1').height(maxHeight); + $('#terminal-7-2').height(maxHeight); + $('#terminal-7-1').show(); + $('#terminal-7-2').hide(); + }); + })(); + </script> Terminal #2 has done a select and an insert, even though Terminal #1 is down. @@ -384,15 +727,64 @@ On Terminal #1 execute these commands: Now the screen looks like this (ignoring the repeated messages on terminal #2 saying "failed to connect"): -.. container:: table-wide - - +----------------------------------+----------------------------------+ - | Terminal #1 | Terminal #2 | - +==================================+==================================+ - | | | - | .. include:: 7-1.rst | .. include:: 7-2.rst | - | | | - +----------------------------------+----------------------------------+ +.. container:: b-block-wrapper_doc + + .. container:: b-doc_catalog + :name: catalog-8 + + .. raw:: html + + <ul class="b-tab_switcher"> + <li class="b-tab_switcher-item"> + <a href="#terminal-8-1" class="b-tab_switcher-item-url p-active">Terminal #1</a> + </li> + <li class="b-tab_switcher-item"> + <a href="#terminal-8-2" class="b-tab_switcher-item-url">Terminal #2</a> + </li> + </ul> + + .. container:: b-documentation_tab_content + :name: catalog-8-content + + .. container:: b-documentation_tab + :name: terminal-8-1 + + .. include:: 7-1.rst + + .. container:: b-documentation_tab + :name: terminal-8-2 + + .. include:: 7-2.rst + + .. raw:: html + + <script> + (function(){ + var dOn = $(document); + dOn.on({ + click: function(event) { + event.preventDefault(); + link = $(this).children('a'); + target = link.attr('href'); + if (!(link.hasClass('p-active'))) { + active = $('#catalog-8 .b-tab_switcher-item-url.p-active'); + $(active.attr('href')).hide(); + active.removeClass('p-active'); + link.addClass('p-active'); + $(link.attr('href')).show(); + } + } + }, '#catalog-8 .b-tab_switcher-item'); + dOn.ready(function(event) { + maxHeight = Math.max($('#terminal-8-1').height(), $('#terminal-8-2').height()); + $('#catalog-8-content').height(maxHeight + 10); + $('#terminal-8-1').height(maxHeight); + $('#terminal-8-2').height(maxHeight); + $('#terminal-8-1').show(); + $('#terminal-8-2').hide(); + }); + })(); + </script> The master has reconnected to the cluster, and has NOT found what the replica wrote while the master was away. That is not a surprise -- the replica has not @@ -407,15 +799,64 @@ On Terminal #1, say: The screen now looks like this: -.. container:: table-wide - - +----------------------------------+----------------------------------+ - | Terminal #1 | Terminal #2 | - +==================================+==================================+ - | | | - | .. include:: 8-1.rst | .. include:: 8-2.rst | - | | | - +----------------------------------+----------------------------------+ +.. container:: b-block-wrapper_doc + + .. container:: b-doc_catalog + :name: catalog-9 + + .. raw:: html + + <ul class="b-tab_switcher"> + <li class="b-tab_switcher-item"> + <a href="#terminal-9-1" class="b-tab_switcher-item-url p-active">Terminal #1</a> + </li> + <li class="b-tab_switcher-item"> + <a href="#terminal-9-2" class="b-tab_switcher-item-url">Terminal #2</a> + </li> + </ul> + + .. container:: b-documentation_tab_content + :name: catalog-9-content + + .. container:: b-documentation_tab + :name: terminal-9-1 + + .. include:: 8-1.rst + + .. container:: b-documentation_tab + :name: terminal-9-2 + + .. include:: 8-2.rst + + .. raw:: html + + <script> + (function(){ + var dOn = $(document); + dOn.on({ + click: function(event) { + event.preventDefault(); + link = $(this).children('a'); + target = link.attr('href'); + if (!(link.hasClass('p-active'))) { + active = $('#catalog-9 .b-tab_switcher-item-url.p-active'); + $(active.attr('href')).hide(); + active.removeClass('p-active'); + link.addClass('p-active'); + $(link.attr('href')).show(); + } + } + }, '#catalog-9 .b-tab_switcher-item'); + dOn.ready(function(event) { + maxHeight = Math.max($('#terminal-9-1').height(), $('#terminal-9-2').height()); + $('#catalog-9-content').height(maxHeight + 10); + $('#terminal-9-1').height(maxHeight); + $('#terminal-9-2').height(maxHeight); + $('#terminal-9-1').show(); + $('#terminal-9-2').hide(); + }); + })(); + </script> This shows that the two servers are once again in synch, and that each server sees what the other server wrote. diff --git a/doc/user/configuration-reference.xml b/doc/user/configuration-reference.xml deleted file mode 100644 index 11ae16e312d78a994cfd9252cb02c8c0318df15c..0000000000000000000000000000000000000000 --- a/doc/user/configuration-reference.xml +++ /dev/null @@ -1,766 +0,0 @@ -<!DOCTYPE book [ -<!ENTITY % tnt SYSTEM "../tnt.ent"> -%tnt; -]> -<chapter 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" - xml:id="configuration-reference"> - -<title>Configuration reference</title> -<blockquote><para> - This chapter provides a reference of options which - can be set on the command line or in an initialization file. -</para></blockquote> - -<para> -Tarantool is started by entering the command: - -<programlisting><prompt>$ </prompt><userinput>tarantool</userinput></programlisting> -or -<programlisting><prompt>$ </prompt><userinput>tarantool <replaceable>options</replaceable></userinput></programlisting> -or -<programlisting><prompt>$ </prompt><userinput>tarantool <replaceable>Lua-initialization-file</replaceable> [<replaceable>arguments</replaceable>]</userinput></programlisting> - -</para> - -<section xml:id="command-line-options"> -<title>Command options</title> - <para> - - </para> - <itemizedlist> - <listitem xml:id="help-option"> - <para><option>--help</option>, <option>-h</option></para> - <para>Print an annotated list of all available options and exit.</para> - </listitem> - - <listitem xml:id="version-option"> - <para><option>--version</option>, <option>-V</option></para> - <para>Print product name and version, for example: - <programlisting><prompt>$ </prompt> <userinput>./tarantool --version</userinput> -Tarantool 1.6.3-439-g7e1011b -Target: Linux-x86_64-Debug -... - </programlisting> - In this example: - <simplelist> - <member> - <quote>Tarantool</quote> is the name - of the reusable asynchronous networking programming framework. - </member> - <member> - The 3-number version follows the standard - <literal><major>-<minor>-<patch></literal> - scheme, in which <literal><major></literal> number - is changed only rarely, <literal><minor></literal> - is incremented for each new milestone and - indicates possible incompatible changes, - and <literal><patch></literal> stands for the number of - bug fix releases made after the start of the - milestone. For non-released versions only, there may be a - commit number and commit SHA1 - to indicate how much this particular build has diverged - from the last release. - </member> - <member> - <quote>Target</quote> is the platform tarantool was built on. - Some platform-specific details may follow this line. - </member> - </simplelist> - </para> - <note><para> - Tarantool uses <link - xlink:href="http://www.kernel.org/pub/software/scm/git/docs/git-describe.html">git describe</link> to produce its version id, and - this id can be used at any time to check out the - corresponding source from our <link - xlink:href="http://github.com/tarantool/tarantool.git">git repository</link>. - </para></note> - </listitem> - - </itemizedlist> - -</section> - - -<section xml:id="URI" xreflabel="URI"> - <title>URI</title> - <para> -Some configuration parameters and some functions -depend on a URI, or "Universal Resource Identifier". -The URI string format is similar to the -<link -xlink:href="http://en.wikipedia.org/wiki/URI_scheme#Generic_syntax">generic syntax for a URI schema</link>. -So it may contain (in order) a user name for login, a password, -a host name or host IP address, and a port number. -Only the port number is always mandatory. The password -is mandatory if the user name is specified, -unless the user name is 'guest'. -So, formally, the URI syntax is -<code>[host:]port</code> -or <code>[username:password@]host:port</code>. -If host is omitted, then 'localhost' is assumed. -If username:password is omitted, then 'guest' is assumed. -Some examples: - <informaltable> - <tgroup cols="2" align="left" colsep="1" rowsep="0"> - <thead> - <row><entry>URI fragment</entry><entry>Example</entry></row> - </thead> - <tbody> - <row><entry>port</entry><entry> 3301</entry></row> - <row><entry>host:port</entry><entry> 127.0.0.1:3301</entry></row> - <row><entry>username:password@host:port</entry><entry> guest:sesame@mail.ru:3301</entry></row> - </tbody> - </tgroup> - </informaltable> -In certain circumstances a Unix socket may be used where a URI is required. -</para> -</section> - - -<section xml:id="initialization-file" xreflabel="initialization file"> -<title>Initialization file</title> -<para> -If the command to start Tarantool includes <option><replaceable>lua-initialization-file</replaceable></option>, -then Tarantool begins by invoking the Lua program in the file, -which by convention may have the name <filename>"script.lua"</filename>. - -The Lua program may get further arguments from the command line -or may use operating-system functions, such as getenv(). -The Lua program almost always begins by invoking <code>box.cfg()</code>, -if the database server will be used or if ports need to be opened. -For example, suppose <filename>script.lua</filename> contains the lines<programlisting>#!/usr/bin/env tarantool -box.cfg{ - listen = os.getenv("LISTEN_URI"), - slab_alloc_arena = 0.1, - pid_file = "tarantool.pid", - rows_per_wal = 50 -} -print('Starting ',arg[1])</programlisting> -and suppose the environment variable LISTEN_URI contains 3301, -and suppose the command line is <code>~/tarantool/src/tarantool script.lua ARG</code>. -Then the screen might look like this:<programlisting> -<prompt>$</prompt> <userinput>export LISTEN_URI=3301</userinput> -<prompt>$</prompt> <userinput>~/tarantool/src/tarantool script.lua ARG</userinput> -... main/101/script.lua C> version 1.6.3-439-g7e1011b -... main/101/script.lua C> log level 5 -... main/101/script.lua I> mapping 107374184 bytes for a shared arena... -... main/101/script.lua I> recovery start -... main/101/script.lua I> recovering from `./00000000000000000000.snap' -... main/101/script.lua I> primary: bound to 0.0.0.0:3301 -... main/102/leave_local_hot_standby I> ready to accept requests -Starting ARG -... main C> entering the event loop</programlisting> -</para> -</section> - -<section xml:id="configuration-parameters" xreflabel="configuration parameters"> -<title>Configuration parameters</title> -<para> - Configuration parameters have the form - <code>box.cfg{<replaceable> key = value [, key = value ...]</replaceable>}</code>. - Since box.cfg may contain many configuration parameters - and since some of the parameters (such as directory addresses) - are semi-permanent, it's best to keep box.cfg in a Lua file. - Typically this Lua file is the initialization file - which is specified on the tarantool command line. - </para> - <para> - Most configuration parameters are for allocating resources, - opening ports, and specifying database behavior. - All parameters are optional. - A few parameters are dynamic, that is, they can be changed - at runtime by calling box.cfg{} a second time. - </para> - <para> - To see all the non-null parameters, say <code>box.cfg</code> (no parentheses). - To see a particular parameter, for example the listen address, say <code>box.cfg.listen</code>. - </para> - <para> - The following tables describe all parameters for basic operation, - for storage, for binary logging and snapshots, for replication, - for networking, and for logging. - </para> - - <table frame='all' pgwide='1'> - <title>Basic parameters</title> - <tgroup cols='5' colsep='1' rowsep='1'> - <colspec colnum="1" colname="col1" colwidth="2*"/> - <colspec colnum="5" colname="col4" colwidth="6*"/> - - <thead> - <row> - <entry>Name</entry> - <entry>Type</entry> - <entry>Default</entry> - <entry>Dynamic?</entry> - <entry>Description</entry> - </row> - </thead> - - <tbody> - - <row> - <entry>username</entry> - <entry>string</entry> - <entry>null</entry> - <entry>no</entry> - <entry>UNIX user name to switch to after start.</entry> - </row> - - <row> - <entry xml:id="work_dir" xreflabel="work_dir">work_dir</entry> - <entry>string</entry> - <entry>null</entry> - <entry>no</entry> - <entry>A directory where database working files will be stored. - The server switches to work_dir with chdir(2) after - start. Can be relative to the current directory. - If not specified, defaults to the current directory.</entry> - </row> - - <row> - <entry xml:id="wal_dir" xreflabel="wal_dir">wal_dir</entry> - <entry>string</entry> - <entry>"."</entry> - <entry>no</entry> - <entry>A directory where write-ahead log (.xlog) files are stored. - Can be relative to work_dir. Most commonly used so - that snapshot files and write-ahead log files - can be stored on separate disks. - If not specified, defaults to work_dir.</entry> - </row> - - <row> - <entry xml:id="snap_dir" xreflabel="snap_dir">snap_dir</entry> - <entry>string</entry> - <entry>"."</entry> - <entry>no</entry> - <entry>A directory where snapshot (.snap) files will be stored. Can be - relative to work_dir. If not specified, defaults to - work_dir. See also <olink targetptr="wal_dir"/>.</entry> - </row> - - <row> - <entry xml:id="sophia_dir" xreflabel="sophia_dir">sophia_dir</entry> - <entry>string</entry> - <entry>"sophia"</entry> - <entry>no</entry> - <entry>A directory where sophia files will be stored. Can be - relative to work_dir. If not specified, defaults to - work_dir/sophia.</entry> - </row> - - <row> - <entry xml:id="core-dump" xreflabel="core-dump">coredump</entry> - <entry>boolean</entry> - <entry>false</entry> - <entry>no</entry> - <entry>Deprecated. Do not use.</entry> - </row> - <row> - <entry xml:id="primary_port" xreflabel="primary_port">listen</entry> - <entry>integer or string</entry> - <entry>null</entry> - <entry>yes</entry> - <entry>The read/write data port number or <link linkend="URI">URI</link> (Universal Resource Identifier) string. - Has no default value, so <emphasis - role="strong">must be specified</emphasis> - if connections will occur from remote clients - that do not use "admin address" (the administrative host and port). - Note: a replica also binds to this port, and accepts - connections, but these connections can only serve - reads until the replica becomes a master. - A typical value is 3301. - The listen parameter may also be set for <olink targetptr="local_hot_standby">local hot standby</olink>.</entry> - </row> - - <row> - <entry>pid_file</entry> - <entry>string</entry> - <entry>null</entry> - <entry>no</entry> - <entry>Store the process id in this file. Can be - relative to work_dir. A typical value is "tarantool.pid".</entry> - </row> - - <row> - <entry xml:id="custom_proc_title" - xreflabel="custom_proc_title"> - custom_proc_title - </entry> - <entry>string</entry> - <entry>null</entry> - <entry>no</entry> - <entry> - <para>Inject the given string into <olink - targetptr="proctitle">server process title</olink> - (what's shown in the COMMAND column for <command>ps</command> - and <command>top</command> commands). For example, - ordinarily <command>ps</command> shows the Tarantool server process thus: - </para><programlisting><prompt>$</prompt> <userinput>ps -ef | grep tarantool</userinput> -1000 22364 2778 0 09:14 pts/0 00:00:00 tarantool: running -1000 22394 22364 0 09:14 pts/0 00:00:00 tarantool: spawner -tarantool: primary pri: 3301 adm: 3313</programlisting> - <para>But if the configuration parameters include custom_proc_title='sessions' then - the output looks like:</para> -<programlisting><prompt>$</prompt> <userinput>ps -ef | grep tarantool</userinput> -1000 22364 2778 0 09:14 pts/0 00:00:00 tarantool: running@sessions -1000 22394 22364 0 09:14 pts/0 00:00:00 tarantool: spawner@sessions -tarantool: primary pri: 3301 adm: 3313</programlisting> - </entry> - </row> - - <row> - <entry>background</entry> - <entry>boolean</entry> - <entry>false</entry> - <entry>no</entry> - <entry>Run the server as a background task. - The logger and pid_file parameters must be non-null for this to work.</entry> - </row> - - </tbody> - </tgroup> - </table> - - <table frame='all' pgwide='1'> - <title>Configuring the storage</title> - <tgroup cols='5' colsep='1' rowsep='1'> - <colspec colnum="1" colname="col1" colwidth="2*"/> - <colspec colnum="5" colname="col4" colwidth="6*"/> - - <thead> - <row> - <entry>Name</entry> - <entry>Type</entry> - <entry>Default</entry> - <entry>Dynamic?</entry> - <entry>Description</entry> - </row> - </thead> - - <tbody> - - <row> - <entry>slab_alloc_arena</entry> - <entry>float</entry> - <entry>1.0</entry> - <entry>no</entry> - <entry> - <anchor xml:id="slab_alloc_arena" xreflabel="slab_alloc_arena"/> - How much memory Tarantool - allocates to actually - store tuples, <emphasis role="strong">in - gigabytes</emphasis>. When the limit is reached, INSERT - or UPDATE requests begin failing with error - <olink targetptr="ER_MEMORY_ISSUE"/>. - While the server does not go - beyond the defined limit to allocate tuples, there is - additional memory used to store indexes and connection - information. Depending on actual configuration and - workload, Tarantool can consume up to 20% more than the - limit set here.</entry> - </row> - - <row> - <entry>slab_alloc_minimal</entry> - <entry>integer</entry> - <entry>64</entry> - <entry>no</entry> - <entry>Size of the smallest allocation unit. It can be - tuned down if most of the tuples are very small.</entry> - </row> - - <row> - <entry>slab_alloc_factor</entry> - <entry>float</entry> - <entry>2.0</entry> - <entry>no</entry> - <entry>Use slab_alloc_factor as the multiplier for - computing the sizes of memory chunks that tuples are - stored in. A lower value may result in less wasted - memory depending on the total amount of memory available - and the distribution of item sizes.</entry> - </row> - - <row> - <entry>sophia</entry> - <entry>table</entry> - <entry>(see the note)</entry> - <entry>no</entry> - <entry>The default sophia configuration can be changed with - sophia={page_size=<replaceable>number</replaceable>, threads=<replaceable>number</replaceable>, - node_size=<replaceable>number</replaceable>, memory_limit=<replaceable>number</replaceable> }. - This method may change in the future.</entry> - </row> - - </tbody> - </tgroup> - </table> - - - <table xml:id="snapshot-daemon" frame='all' pgwide='1'> - <title>Snapshot daemon</title> - <tgroup cols='5' colsep='1' rowsep='1'> - <colspec colnum="1" colname="col1" colwidth="2*"/> - <colspec colnum="5" colname="col4" colwidth="6*"/> - - <thead> - <row> - <entry>Name</entry> - <entry>Type</entry> - <entry>Default</entry> - <entry>Dynamic?</entry> - <entry>Description</entry> - </row> - </thead> - - <tbody> - - <row> - <entry>snapshot_period</entry> - <entry>float</entry> - <entry>0</entry> - <entry>yes</entry> - <entry> - The interval between actions by the snapshot daemon, in seconds. - The snapshot daemon is a fiber which is constantly running. - If snapshot_period is set to a value greater than zero, - then the snapshot daemon - will call <olink targetptr="box.snapshot"/> every snapshot_period seconds, creating - a new snapshot file each time. - For example, <code>box.cfg{snapshot_period=3600}</code> - will cause the snapshot daemon to create a new database - snapshot once per hour. - </entry> - </row> - - <row> - <entry>snapshot_count</entry> - <entry>integer</entry> - <entry>6</entry> - <entry>yes</entry> - <entry> - <para> - The maximum number of snapshots that the snapshot daemon maintains. - For example, <code>box.cfg{snapshot_period=3600, snapshot_count=10}</code> - will cause the snapshot daemon - to create a new snapshot each hour until it has created - ten snapshots. After that, it will remove the oldest - snapshot (and any associated write-ahead-log files) after creating - a new one. If snapshot_count equals zero, then the snapshot - daemon does not remove old snapshots. - </para> - </entry> - </row> - </tbody> - </tgroup> - </table> - - <table frame='all' pgwide='1'> - <title>Binary logging and snapshots</title> - <tgroup cols='5' colsep='1' rowsep='1'> - <colspec colnum="1" colname="col1" colwidth="2*"/> - <colspec colnum="5" colname="col4" colwidth="6*"/> - - <thead> - <row> - <entry>Name</entry> - <entry>Type</entry> - <entry>Default</entry> - <entry>Dynamic?</entry> - <entry>Description</entry> - </row> - </thead> - - <tbody> - - <row> - <entry>panic_on_snap_error</entry> - <entry>boolean</entry> - <entry>true</entry> - <entry>no</entry> - <entry>If there is an error while reading the snapshot file (at - server start), abort.</entry> - </row> - - <row> - <entry>panic_on_wal_error</entry> - <entry>boolean</entry> - <entry>false</entry> - <entry>no</entry> - <entry>If there is an error while reading a write-ahead - log file (at server start), abort.</entry> - </row> - - <row> - <entry xml:id="rows_per_wal" xreflabel="rows_per_wal">rows_per_wal</entry> - <entry>integer</entry> - <entry>500000</entry> - <entry>no</entry> - <entry>How many log records to store in a single - write-ahead log file. When this limit is reached, Tarantool - creates another WAL file named - <filename><first-lsn-in-wal>.xlog</filename> - This can be useful for simple rsync-based backups. - </entry> - </row> - - <row> - <entry>snap_io_rate_limit</entry> - <entry>float</entry> - <entry>null</entry> - <entry><emphasis role="strong">yes</emphasis></entry> - <entry>Reduce the throttling effect of <olink - targetptr="box.snapshot"/> on INSERT/UPDATE/DELETE - performance by setting a limit on - how many megabytes per second it can write to disk. - The same can be achieved by splitting <olink - targetptr="wal_dir"/> and <olink targetptr="snap_dir"/> - locations and moving snapshots to a separate disk.</entry> - </row> - - <row> - <entry xml:id="wal_mode" xreflabel="wal_mode">wal_mode</entry> - <entry>string</entry> - <entry>"write"</entry> - <entry><emphasis role="strong">yes</emphasis></entry> - <entry>Specify fiber-WAL-disk synchronization mode as: - <emphasis>none:</emphasis> write-ahead log is not maintained; <emphasis>write:</emphasis> fibers wait for their data to - be written to the write-ahead log (no fsync(2)); <emphasis>fsync</emphasis>: - fibers wait for their data, fsync(2) follows each write(2); - </entry> - </row> - - <row> - <entry xml:id="wal_dir_rescan_delay" xreflabel="wal_dir_rescan_delay">wal_dir_rescan_delay</entry> - <entry>float</entry> - <entry>0.1</entry> - <entry>no</entry> - <entry>Number of seconds between periodic scans of the - write-ahead-log file directory, when checking for - changes to write-ahead-log files for the sake of - replication or local hot standby.</entry> - </row> - - </tbody> - </tgroup> - </table> - - <table frame='all' pgwide='1'> - <title>Replication</title> - <tgroup cols='5' colsep='1' rowsep='1'> - <colspec colnum="1" colname="col1" colwidth="2*"/> - <colspec colnum="5" colname="col4" colwidth="6*"/> - - <thead> - <row> - <entry>Name</entry> - <entry>Type</entry> - <entry>Default</entry> - <entry>Dynamic?</entry> - <entry>Description</entry> - </row> - </thead> - - <tbody> - - <row> - <entry xml:id="replication_source" - xreflabel="replication_source">replication_source</entry> - <entry>string</entry> - <entry>null</entry> - <entry><emphasis role="strong">yes</emphasis></entry> - <entry>If replication_source is not an empty string, the - server is considered to be a Tarantool replica. - The replica server will try to connect to the master - which replication_source specifies with a <link linkend="URI">URI</link> (Universal Resource Identifier), - for example 'konstantin:secret_password@tarantool.org:3301'. - The default user name is 'guest'. - A replica server does not accept data-change requests - on the <olink targetptr="primary_port">listen</olink> port. - The replication_source parameter is - dynamic, that is, to enter master mode, simply set - replication_source to an empty string and issue - "box.cfg{replication_source=new-value}".</entry> - </row> - - </tbody> - </tgroup> - </table> - - <table frame='all' pgwide='1'> - <title>Networking</title> - <tgroup cols='5' colsep='1' rowsep='1'> - <colspec colnum="1" colname="col1" colwidth="2*"/> - <colspec colnum="5" colname="col4" colwidth="6*"/> - - <thead> - <row> - <entry>Name</entry> - <entry>Type</entry> - <entry>Default</entry> - <entry>Dynamic?</entry> - <entry>Description</entry> - </row> - </thead> - - <tbody> - - <row> - <entry>io_collect_interval</entry> - <entry>float</entry> - <entry>null</entry> - <entry><emphasis role="strong">yes</emphasis></entry> - <entry>The server will sleep for io_collect_interval seconds - between iterations of the event loop. Can be - used to reduce CPU load in deployments in which the - number of client connections is large, but requests are - not so frequent (for example, each connection issues - just a handful of requests per second). </entry> - </row> - - <row> - <entry>readahead</entry> - <entry>integer</entry> - <entry>16320</entry> - <entry>yes</entry> - <entry>The size of the read-ahead buffer associated with a - client connection. The larger the buffer, the more - memory an active connection consumes and the more requests - can be read from the operating system buffer in a single - system call. The rule of thumb is to make sure the buffer - can contain at least a few dozen requests. Therefore, if - a typical tuple in a request is large, e.g. a few - kilobytes or even megabytes, the read-ahead buffer size should - be increased. If batched request processing is not - used, it's prudent to leave this setting at its - default.</entry> - </row> - - </tbody> - </tgroup> - </table> - - <table frame='all' pgwide='1'> - <title>Logging</title> - <tgroup cols='5' colsep='1' rowsep='1'> - <colspec colnum="1" colname="col1" colwidth="2*"/> - <colspec colnum="5" colname="col4" colwidth="6*"/> - - <thead> - <row> - <entry>Name</entry> - <entry>Type</entry> - <entry>Default</entry> - <entry>Dynamic?</entry> - <entry>Description</entry> - </row> - </thead> - - <tbody> - - <row> - <entry xml:id="log_level" xreflabel="log_level">log_level</entry> - <entry>integer</entry> - <entry>5</entry> - <entry><emphasis role="strong">yes</emphasis></entry> - <entry>How verbose the logging is. There are six log - verbosity classes: 1 -- SYSERROR, 2 -- ERROR, 3 -- CRITICAL, 4 -- - WARNING, 5 -- INFO, 6 -- DEBUG. By setting log_level, - one can enable logging of all classes below or equal - to the given level. Tarantool prints its logs to the - standard error stream by default, but this can be - changed with the "logger" configuration parameter. - </entry> - </row> - - <row> - <entry xml:id="logger" xreflabel="logger">logger</entry> - <entry>string</entry> - <entry>null</entry> - <entry>no</entry> - <entry>By default, the log is sent to the standard - error stream (<filename>stderr</filename>). If logger - is specified, the log is sent to the file named in the string. - Example setting: logger = 'tarantool.log' - (this will open tarantool.log for output on the - server's default directory). - </entry> - </row> - - <row> - <entry>logger_nonblock</entry> - <entry>boolean</entry> - <entry>true</entry> - <entry>no</entry> - <entry>If logger_nonblock equals true, Tarantool does not - block on the log file descriptor when it's not - ready for write, and drops the message instead. If - log_level is high, and a lot of messages go to the log - file, setting logger_nonblock to true may improve logging - performance at the cost of some log messages getting - lost.</entry> - </row> - - <row> - <entry>too_long_threshold</entry> - <entry>float</entry> - <entry>0.5</entry> - <entry><emphasis role="strong">yes</emphasis></entry> - <entry>If processing a request takes longer than the - given value (in seconds), warn about it in the log. - Has effect only if log_level is less than or equal to 4 - (WARNING).</entry> - </row> - - </tbody> - </tgroup> - </table> - -</section> - -<section xml:id="local_hot_standby" xreflabel="local_hot_standby"> -<title>Local hot standby</title> - - <para> - Local hot standby is a feature which provides a simple form of failover without replication. - To initiate it, start a second instance of the Tarantool server on the same computer with - the same <code>box.cfg</code> configuration settings -- including the same directories and - same non-null URIs. - A warning should appear with a message like - "W> primary: [URI] is already in use, will retry binding after [n] seconds". - This is fine. - It means that the second instance is ready to take over if the first instance goes down. - </para> - <para> - The expectation is that there will be two - instances of the server using the same configuration. - The first one to start will be the "primary" instance. - The second one to start will be the "standby" instance. - The standby instance will initialize and will try to connect on listen - address and admin address, but will fail because the - primary instance has already taken them. - So the standby instance goes into a loop, reading the write - ahead log which the primary instance is writing (so the - two instances are always in synch), and trying to connect on the - ports. If the primary instance goes down for any reason, - the ports will become free so the standby instance will - succeed in connecting, and will become the primary instance. - Thus there is no noticeable downtime if the primary instance goes down. - </para> - <para> - If this local_hot_standby feature is being used, then replication_source should be an - empty string and wal_mode should not be equal to "none". - </para> - -</section> - -</chapter> - -<!-- -vim: tw=66 syntax=docbk -vim: spell spelllang=en_us ---> diff --git a/doc/user/connectors.xml b/doc/user/connectors.xml deleted file mode 100644 index 578ed4a6cbf86467dd208e38f673a99fdd64be40..0000000000000000000000000000000000000000 --- a/doc/user/connectors.xml +++ /dev/null @@ -1,324 +0,0 @@ -<!DOCTYPE book [ -<!ENTITY % tnt SYSTEM "../tnt.ent"> -%tnt; -]> -<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" - xmlns:xlink="http://www.w3.org/1999/xlink" - xml:id="connectors"> - -<title>Connectors</title> -<blockquote><para> - This chapter documents APIs for various programming languages. -</para></blockquote> - -<section xml:id="protocol"> - <title>Protocol</title> - <para>Tarantool protocol was designed with a focus on asynchronous - I/O and easy integration with proxies. Each client - request starts with a variable-length binary header, containing - request id, request type, server id, log sequence number, and - so on. - </para> - - <para> - The mandatory length, present in request header simplifies - client or proxy I/O. A response to a request is sent to the - client as soon as it is ready. It always carries in its header - the same type and id as in the request. The id makes it - possible to match a request to a response, even if the latter - arrived out of order. - </para> - - <para>Unless implementing a client driver, one needn't - concern oneself with the complications of the binary - protocol. <olink targetptr="connectors">Language-specific - drivers</olink> provide a friendly way to store domain - language data structures in Tarantool. - A complete description of the binary protocol - is maintained in annotated Backus-Naur - form in the source tree: please see - <link xlink:href="http://tarantool.org/doc/box-protocol.html"><filename>doc/box-protocol.html</filename></link>. - </para> -</section> - -<section xml:id="connector-packet-example"> -<title>Packet example</title> -<para> -The Tarantool API exists so that a client program can send a request packet -to the server, and receive a response. Here is an example of a what the client - would send for <command>box.space[513]:insert{'A', 'BB'}</command>. The BNF description of the components -is in file <link xlink:href="http://tarantool.org/doc/box-protocol.html" xlink:title="A complete BNF of Tarantool client/server protocol">doc/box-protocol.html</link>. - -</para> - <informaltable frame='topbot'> - <tgroup cols='5' align='left' colsep='1' rowsep='1'> - <colspec colname='c1'/> - <colspec colname='c2'/> - <colspec colname='c3'/> - <colspec colname='c4'/> - <colspec colname='c5'/> - <thead> - <row> - <entry>Component</entry> - <entry>Byte#0</entry> - <entry>Byte#1</entry> - <entry>Byte#2</entry> - <entry>Byte#3</entry> - </row> - </thead> - <tbody> - <row> - <entry>code for insert</entry> - <entry>2</entry> - </row> - <row> - <entry>rest of header</entry> - <entry>...</entry> - <entry>...</entry> - <entry>...</entry> - <entry>...</entry> - </row> - <row> - <entry>2-digit number: space id</entry> - <entry>cd</entry> - <entry>02</entry> - <entry>01</entry> - </row> - <row> - <entry>code for tuple</entry> - <entry>21</entry> - </row> - <row> - <entry>1-digit number: field count = 2</entry> - <entry>92</entry> - </row> - <row> - <entry>1-character string: field[1]</entry> - <entry>a1</entry> - <entry>41</entry> - </row> - <row> - <entry>2-character string: field[2]</entry> - <entry>a2</entry> - <entry>42</entry> - <entry>42</entry> - </row> - </tbody> - </tgroup> - </informaltable> -<para> -Now, one could send that packet to the tarantool server, -and interpret the response (doc/box-protocol.html has a description -of the packet format for responses as well as requests). -But it would be easier, and less error-prone, if one could -invoke a routine that formats the packet according to typed -parameters. Something like <code>response=tarantool_routine("insert",513,"A","B");</code>. -And that is why APIs exist for drivers for Perl, Python, PHP, and so on. -</para> - </section> - - <section xml:id="connector-server"> - <title>Setting up the server for connector examples</title> - <para> - This chapter has examples that show how to connect to the Tarantool - server via the Perl, PHP, and Python connectors. - The examples contain hard code that will work if and only if - the server (tarantool) is running on localhost (127.0.0.1) and is listening on port 3301 - (<code>box.cfg.listen='3301'</code>) and space 'examples' has id = 999 - (<code>box.space.tester.id = 999</code>), and - space 'examples' has a primary-key index for a numeric field - (<code>box.space[999].index[0].parts[1].type = "NUM"</code>) - and user 'guest' has privileges for reading and writing. - </para> - <para> - It is easy to meet all the conditions by starting the - server and executing this script:<programlisting> -box.cfg{listen=3301} -box.schema.space.create('examples',{id=999}) -box.space.examples:create_index('primary', {type = 'hash', parts = {1, 'NUM'}}) -box.schema.user.grant('guest','read,write','space','examples') -box.schema.user.grant('guest','read','space','_space') -</programlisting> - </para> - </section> - - <section xml:id="connector-java"> - <title>Java</title> - <para> - Please see <link xlink:href="http://dgreenru.github.io/tarantool-java/"><filename>http://dgreenru.github.io/tarantool-java/</filename></link>. - </para> - </section> - - <section xml:id="connector-go"> - <title>Go</title> - <para> - Please see <link xlink:href="https://github.com/mialinx/go-tarantool-1.6"><filename>https://github.com/mialinx/go-tarantool-1.6</filename></link>. - </para> - </section> - - <section xml:id="connector-perl"> - <title>Perl</title> - <para> - The most commonly used Perl driver is <link xlink:href='http://search.cpan.org/~unera/DR-Tarantool/'>DR::Tarantool</link>. - It is not supplied as part of the Tarantool repository; it must be installed separately. - The most common way to install it is with <link xlink:href='https://en.wikipedia.org/wiki/Cpan'>CPAN, the Comprehensive Perl Archive Network</link>. - DR::Tarantool requires other modules which should be installed first. - For example, on Ubuntu, the installation could look like this:<programlisting> -sudo cpan install AnyEvent -sudo cpan install Devel::GlobalDestruction -sudo cpan install Coro -sudo cpan install Test::Pod -sudo cpan install Test::Spelling -sudo cpan install PAR::Dist -sudo cpan install List::MoreUtils -sudo cpan install DR::Tarantool</programlisting> - </para> - <para> - Here is a complete Perl program that inserts [99999,'BB'] into space[999] via the Perl API. - Before trying to run, check that the server is listening and that <code>examples</code> exists, - as described <link linkend="connector-server">earlier</link>. - To run, paste the code into a file named example.pl and say <code>perl example.pl</code>. - The program will connect using an application-specific definition of the space. - The program will open a socket connection - with the tarantool server at localhost:3301, then send an INSERT request, - then — if all is well — end without displaying any messages. - If tarantool is not running on localhost with listen address = 3301, the program will print - <quote>Connection refused</quote>. - </para> - <para> - <programlisting language="perl"> -#!/usr/bin/perl -use DR::Tarantool ':constant', 'tarantool'; -use DR::Tarantool ':all'; -use DR::Tarantool::MsgPack::SyncClient; - -my $tnt = DR::Tarantool::MsgPack::SyncClient->connect( - host => '127.0.0.1', # look for tarantool on localhost - port => 3301, # assume tarantool listen address = default - user => 'guest', # username. one could also say 'password=>...' - - spaces => { - 999 => { # definition of space[999] ... - name => 'examples', # space[999] name = 'examples' - default_type => 'STR', # space[999] field type is 'STR' if undefined - fields => [ { # definition of space[512].fields ... - name => 'field1', type => 'NUM' } ], # space[999].field[1] name='field1',type='NUM' - indexes => { # definition of space[999] indexes ... - 0 => { - name => 'primary', fields => [ 'field1' ] } } } } ); - -$tnt->insert('examples' => [ 99999, 'BB' ]);</programlisting> - </para> - <para> - The example program only shows one command and does not show all that's necessary for - good practice. For that, please see - <link xlink:href='http://search.cpan.org/~unera/DR-Tarantool/'>DR::Tarantool CPAN repository</link>. - </para> - </section> - - <section xml:id="connector-php"> - <title>PHP</title> - - <para> - The PHP driver is <link xlink:href='https://github.com/tarantool/tarantool-php'>tarantool-php</link>. - It is not supplied as part of the Tarantool repository; it must be installed separately. - It can be installed with git. - It requires other modules which should be installed first. - For example, on Ubuntu, the installation could look like this: - <programlisting> -sudo apt-get install php5-cli -sudo apt-get install php5-dev -sudo apt-get install php-pear -cd ~ -git clone https://github.com/tarantool/tarantool-php.git -cd tarantool-php -phpize -./configure -make -#make install is optional</programlisting> - </para> - <para> - At this point there is a file named <filename>~/tarantool-php/modules/tarantool.so</filename>. - PHP will only find it if the PHP initialization file <filename>php.ini</filename> contains a line like - <code>extension=./tarantool.so</code>. - So copy <filename>tarantool.so</filename> to the working directory and tell PHP where - to find the <filename>php.ini</filename> file that contains that line ... - <programlisting> -cd ~ -cp ./tarantool-php/modules/tarantool.so . -export PHP_INI_SCAN_DIR=~/tarantool-php/test/shared</programlisting> - </para> - <para> - Here is a complete PHP program that inserts [99999,'BB'] into a space named 'examples' via the PHP API. - Before trying to run, check that the server is listening and that <code>examples</code> exists, - as described <link linkend="connector-server">earlier</link>. - To run, paste the code into a file named example.php and say <code>php example.php</code>. - The program will open a socket connection - with the tarantool server at localhost:3301, then send an INSERT request, - then — if all is well — print "Insert succeeded". - If the tuple already exists, the program will print <quote>Duplicate key exists in unique index 0</quote>. - </para> - <para> - <programlisting> -<?php -$tarantool = new Tarantool("localhost", 3301); -try { - $tarantool->insert("examples", array(99999, "BB")); - print "Insert succeeded\n"; - } -catch (Exception $e) { - echo "Exception: ", $e->getMessage(), "\n"; - } -?></programlisting> - </para> - <para> - After running the example, it is good practice to delete the file ./tarantool.so, - since it is only compatible with PHP and its existence could confuse non-PHP applications. - </para> - <para> - The example program only shows one command and does not show all that's necessary for - good practice. For that, please see - <link - xlink:href="https://github.com/tarantool/tarantool-php/"><filename>tarantool-php</filename></link> project at GitHub. - </para> - </section> - - <section xml:id="connector-python"> - <title>Python</title> - <para> - Here is a complete Python program that inserts [99999,'Value','Value'] into space <code>examples</code> via the high-level Python API. - </para> -<programlisting language="python"> -#!/usr/bin/python -from tarantool import Connection - -c = Connection("127.0.0.1", 3301) -result = c.insert("examples",(99999,'Value', 'Value')) -print result -</programlisting> - <para> - To prepare, paste the code into a file named example.py and install tarantool-python with either - <userinput><code>pip install tarantool\>0.4</code></userinput> to install in <filename>/usr</filename> (requires root privilege) - or - <userinput><code>pip install tarantool\>0.4 --user</code></userinput> to install in <filename>~</filename> i.e. user's default directory. - Before trying to run, check that the server is listening and that <code>examples</code> exists, - as described <link linkend="connector-server">earlier</link>. - To run the program, say <code>python example.py</code>. - The program will connect to the server, will send the request, and will not throw an exception if all went well. - If the tuple already exists, the program will throw DatabaseException(“Duplicate key exists in unique indexâ€). - </para> - <para> - The example program only shows one request and does not show all that's necessary for - good practice. For that, see - <link xlink:href="http://github.com/tarantool/tarantool-python"><filename>http://github.com/tarantool/tarantool-python</filename></link>. - For an example of a Python API for <link xlink:href="https://github.com/tarantool/queue">Queue managers on Tarantool</link>, see - <link xlink:href="https://github.com/tarantool/tarantool-queue-python"><filename>https://github.com/tarantool/tarantool-queue-python</filename></link>. - </para> - </section> - -</chapter> - -<!-- -vim: tw=66 syntax=docbk -vim: spell spelllang=en_us ---> diff --git a/doc/www/content/js/old_tabs.js b/doc/www/content/js/old_tabs.js deleted file mode 100644 index 7f8891a8fb11ebf57c44f40cc141c724af1952d1..0000000000000000000000000000000000000000 --- a/doc/www/content/js/old_tabs.js +++ /dev/null @@ -1,187 +0,0 @@ -(function(){ -var dOn = $(document); - -dOn.on({ - click: function(){ - if (!($(this).hasClass('b-button_on'))){ - $('.b-button_on').removeClass('b-button_on'); - $(this).addClass('b-button_on'); - - switch ($(this).html()) { - case 'A_Read' : { - $('#picture2').renderChart('/ycsb/A_READ_latency.json'); - break; - } - case 'A_Update' : { - $('#picture2').renderChart('/ycsb/A_UPDATE_latency.json'); - break; - } - case 'B_Read' : { - $('#picture2').renderChart('/ycsb/B_READ_latency.json'); - break; - } - case 'B_Update' : { - $('#picture2').renderChart('/ycsb/B_UPDATE_latency.json'); - break; - } - case 'C_Read' : { - $('#picture2').renderChart('/ycsb/C_READ_latency.json'); - break; - } - case 'D_Insert' : { - $('#picture2').renderChart('/ycsb/D_INSERT_latency.json'); - break; - } - case 'D_Read' : { - $('#picture2').renderChart('/ycsb/D_READ_latency.json'); - break; - } - case 'E_Insert' : { - $('#picture2').renderChart('/ycsb/E_INSERT_latency.json'); - break; - } - case 'E_Scan' : { - $('#picture2').renderChart('/ycsb/E_SCAN_latency.json'); - break; - } - case 'F_Read' : { - $('#picture2').renderChart('/ycsb/F_READ_latency.json'); - break; - } - case 'F_Read-Modify-Write' : { - $('#picture2').renderChart('/ycsb/F_READ-MODIFY-WRITE_latency.json'); - break; - } - case 'F_Update' : { - $('#picture2').renderChart('/ycsb/F_UPDATE_latency.json'); - break; - } - case 'LOAD_Insert' : { - $('#picture2').renderChart('/ycsb/LOAD_INSERT_latency.json'); - break; - } - } - - } - } -}, '.b-button'); - -dOn.on({ - click: function(){ - if (!($(this).hasClass('b-tabs__li_on'))){ - $('.b-tabs__li_on').removeClass('b-tabs__li_on'); - $(this).addClass('b-tabs__li_on'); - - $('.b-button').remove(); - var head = $('.b-tabs__header'), ul = $('.b-tabs__buttons'), li, desc = $('.b-tabs__description'); - - switch ($(this).html()) { - case 'A' : { - head.html('Workload A') - $('#picture1').renderChart('/ycsb/A_throughput.json'); - $('#picture2').renderChart('/ycsb/A_READ_latency.json'); - - li = $('<li class="b-button b-button_on">A_Read</li>'); - ul.append(li); - li = $('<li class="b-button">A_Update</li>'); - ul.append(li); - - desc.html('50/50 update/read ratio'); - - break; - } - case 'B' : { - head.html('Workload B') - $('#picture1').renderChart('/ycsb/B_throughput.json'); - $('#picture2').renderChart('/ycsb/B_READ_latency.json'); - - li = $('<li class="b-button b-button_on">B_Read</li>'); - ul.append(li); - li = $('<li class="b-button">B_Update</li>'); - ul.append(li); - - desc.html('5/95 update/read ratio'); - - break; - } - case 'C' : { - head.html('Workload C') - $('#picture1').renderChart('/ycsb/C_throughput.json'); - $('#picture2').renderChart('/ycsb/C_READ_latency.json'); - - li = $('<li class="b-button b-button_on">C_Read</li>'); - ul.append(li); - - desc.html('100% read-only'); - - break; - } - case 'D' : { - head.html('Workload D') - $('#picture1').renderChart('/ycsb/D_throughput.json'); - $('#picture2').renderChart('/ycsb/D_READ_latency.json'); - - li = $('<li class="b-button b-button_on">D_Read</li>'); - ul.append(li); - li = $('<li class="b-button">D_Insert</li>'); - ul.append(li); - - desc.html('5/95 insert/read ratio, the read load is skewed towards the end of the key range'); - - break; - } - case 'E' : { - head.html('Workload E') - $('#picture1').renderChart('/ycsb/E_throughput.json'); - $('#picture2').renderChart('/ycsb/E_INSERT_latency.json'); - - li = $('<li class="b-button b-button_on">E_Insert</li>'); - ul.append(li); - li = $('<li class="b-button">E_Scan</li>'); - ul.append(li); - - desc.html('5/95 ratio of insert/reads over a range of 10 records'); - - break; - } - case 'F' : { - head.html('Workload F') - $('#picture1').renderChart('/ycsb/F_throughput.json'); - $('#picture2').renderChart('/ycsb/F_READ_latency.json'); - - li = $('<li class="b-button b-button_on">F_Read</li>'); - ul.append(li); - li = $('<li class="b-button">F_Read-Modify-Write</li>'); - ul.append(li); - li = $('<li class="b-button">F_Update</li>'); - ul.append(li); - - desc.html('95% read/modify/write, 5% read'); - - break; - } - case 'LOAD' : { - head.html('Insert only') - $('#picture1').renderChart('/ycsb/LOAD_throughput.json'); - $('#picture2').renderChart('/ycsb/LOAD_INSERT_latency.json'); - - li = $('<li class="b-button b-button_on">L_Insert</li>'); - ul.append(li); - - desc.html(''); - - break; - } - } - } - } -}, '.b-tabs__li'); -})(); - -(function(){ -var dOn = $(document); -dOn.ready(function() { - $('#picture1').renderChart('/ycsb/A_throughput.json'); - $('#picture2').renderChart('/ycsb/A_READ_latency.json'); -}); -})(); diff --git a/doc/www/content/newsite/documentation.yml b/doc/www/content/newsite/documentation.yml deleted file mode 100644 index 739f503d27d4751ac0b1c6eae7f5d181a0b9b425..0000000000000000000000000000000000000000 --- a/doc/www/content/newsite/documentation.yml +++ /dev/null @@ -1,33 +0,0 @@ ---- -title : "Tarantool - Documentation" -slug : "documentation" -save_as : "documentation.html" -template: "documentation" -blocks : - sections: - - name: "Introduction" - list: - - name: "What is Tarantool?" - link: "doc/introduction.html#what-is-tarantool" - - name: "An overview of the architecture" - link: "doc/introduction.html#an-overview-of-the-architecture" - - name: "Key features" - link: "doc/introduction.html#key-features" - - name: "How stable is the software?" - link: "doc/introduction.html#how-stable-is-the-software" - - name: "User Guide" - list: - - name: "Multi page HTML" - link: "doc/user_guide/" - - name: "Single page HTML" - link: "doc/user_guide.html" - - name: "FAQ" - link: "doc/faq.html" - - name: "Developer section" - list: - - name: "Developer Guide" - link: "doc/dev_guide.html" - - name: "IProto Protocol" - link: "doc/box-protocol.html" - -... diff --git a/doc/www/theme/static/docbook.css b/doc/www/theme/static/docbook.css deleted file mode 100644 index d2fe22e9eb230662f7f3b2c73d3ffb6d10e7577c..0000000000000000000000000000000000000000 --- a/doc/www/theme/static/docbook.css +++ /dev/null @@ -1,89 +0,0 @@ -.tntadmin { - font-family: monospace; - font-weight: bold; - text-transform: uppercase; - color: green; -} - -.lua { - font-family: monospace; - font-weight: bold; -} - -strong.hl-keyword { - color: green !important; - font-weight: bold; -} - -em.hl-comment { - color: #3366FF !important; - font-weight: normal; -} - -strong.hl-string em { - color: red !important; - font-weight: bold; -} - -body { - min-width: 768px; - max-width: 1024px; - margin: auto; -} - -.book { - margin: 2pt auto; - font-size: 100% -} - -.book h1 { - font-size: 150% -} - -pre { - white-space: pre; - white-space: pre-wrap; - word-wrap: break-word; - text-decoration: none; - outline: 0; - padding: 5px; - background-color: rgba(0,0,0,0.1); - -moz-box-shadow: 0 1px 3px rgba(0,0,0,0.3); - -webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.3); - box-shadow: 0 1px 3px rgba(0,0,0,0.3); -} - -div.toc dl{ - margin-top: 0px; -} - -div.itemizedlist ul li p{ - margin: 4px; -} - -div#header { - display: block; -} - -div#content { - border-top: 1px dotted black; -} - -div#headwrap { - width: 100%; -} - -div.column { - display: inline-block; -} - -div#headl { - float: left; - width: 30%; -} - -div#headr { - float: right; - width: 69%; - text-align: right -} diff --git a/doc/www/theme/static/old_global.css b/doc/www/theme/static/old_global.css deleted file mode 100644 index 781768112a00a318575533a63ef08f9e531d0b1a..0000000000000000000000000000000000000000 --- a/doc/www/theme/static/old_global.css +++ /dev/null @@ -1,355 +0,0 @@ -/* This stylesheet heavily borrows from http://necolas.github.com/normalize.css */ - -/* ============================================================================= - Base - ========================================================================== */ - -/* - * 1. Corrects text resizing oddly in IE6/7 when body font-size is set using em units - * http://clagnut.com/blog/348/#c790 - * 2. Keeps page centred in all browsers regardless of content height - * 3. Prevents iOS text size adjust after orientation change, without disabling user zoom - * www.456bereastreet.com/archive/201012/controlling_text_size_in_safari_for_ios_without_disabling_user_zoom/ - */ - -html { - font-size: 100%; /* 1 */ - overflow-y: scroll; /* 2 */ - -webkit-text-size-adjust: 100%; /* 3 */ - -ms-text-size-adjust: 100%; /* 3 */ -} - -/* - * Addresses margins handled incorrectly in IE6/7 - */ - -body { - margin: 0; -} - -/* ============================================================================= - Typography - ========================================================================== */ - -/* - * Neutralise smaller font-size in 'section' and 'article' in FF4+, Chrome, S5 - */ - -h1 { - font-size: 1.5em; -} - -/* - * Addresses style set to 'bolder' in FF3+, S4/5, Chrome - */ - -b, strong { - font-weight: bold; -} - -blockquote { - margin: 1em 40px; -} - -/* - * Corrects font family set oddly in IE6, S4/5, Chrome - * en.wikipedia.org/wiki/User:Davidgothberg/Test59 - */ - -pre, code, kbd, samp { - font-family: monospace, serif; - _font-family: 'courier new', monospace; - font-size: 100%; -} - - -/* - * Improves readability of pre-formatted text in all browsers - */ - -pre { - white-space: pre; - white-space: pre-wrap; - word-wrap: break-word; - text-decoration: none; - outline: 0; - background-color: rgba(0,0,0,0.1); - -moz-box-shadow: 0 1px 3px rgba(0,0,0,0.3); - -webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.3); - box-shadow: 0 1px 3px rgba(0,0,0,0.3); -} - -/* - * 1. Addresses CSS quotes not supported in IE6/7 - * 2. Addresses quote property not supported in S4 - */ - -/* 1 */ - -q { - quotes: none; -} - -/* 2 */ - -q:before, -q:after { - content: ''; - content: none; -} - -/* - * XXX - */ - -small { - font-size: 75%; -} - -/* - * Prevents sub and sup affecting line-height in all browsers - * gist.github.com/413930 - */ - -sub, sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; -} - -sup { - top: -0.5em; -} - -sub { - bottom: -0.25em; -} - - -/* ============================================================================= - Lists - ========================================================================== */ - -ul, ol { - margin-left: 0; - padding: 0 0 0 40px; -} - -dd { - margin: 0 0 0 40px; -} - - -/* ============================================================================= - Embedded content - ========================================================================== */ - -/* - * 1. Removes border when inside 'a' element in IE6/7/8/9, FF3 - * 2. Improves image quality when scaled in IE7 - * code.flickr.com/blog/2008/11/12/on-ui-quality-the-little-things-client-side-image-resizing/ - */ - -img { - border: 0; /* 1 */ - -ms-interpolation-mode: bicubic; /* 2 */ -} - -.ycsb { - width: 768px; -} - -/* ============================================================================= - Tables - ========================================================================== */ - -/* - * Remove most spacing between table cells - */ - -table { - border-collapse: collapse; - border-spacing: 0; -} - -/* ========================================================================== - Grid - ======================================================================== */ - -.grid { - width: 768px; - overflow: hidden; - margin-left: auto; - margin-right: auto; - padding: 0 10px 0 0; - -moz-border-radius: 3px; - -webkit-border-radius: 3px; - border-radius: 3px; - clear: both; -} - -.span_1, .span_2, .span_3, .span_4, .span_5, .span_6, -.span_7, .span_8, .span_9, .span_10, .span_11, .span_12 { - float: left; - dsiplay: inline; /* IE workaround */ - margin-left: 10px; -} - -.span_1 { width: 70px; } -.span_2 { width: 150px; } -.span_3 { width: 230px; } -.span_4 { width: 303px; } -.span_5 { width: 390px; } -.span_6 { width: 470px; } -.span_7 { width: 550px; } -.span_8 { width: 630px; } -.span_9 { width: 710px; } -.span_10 { width: 790px; } -.span_11 { width: 870px; } -.span_12 { width: 950px; } - -.lpad_1 { padding-left: 80px; } -.lpad_2 { padding-left: 160px; } -.lpad_3 { padding-left: 240px; } -.lpad_4 { padding-left: 320px; } -.lpad_5 { padding-left: 400px; } -.lpad_6 { padding-left: 480px; } -.lpad_7 { padding-left: 560px; } -.lpad_8 { padding-left: 640px; } -.lpad_9 { padding-left: 720px; } -.lpad_10 { padding-left: 800px; } -.lpad_11 { padding-left: 880px; } - -.rpad_1 { padding-right: 80px; } -.rpad_2 { padding-right: 160px; } -.rpad_3 { padding-right: 240px; } -.rpad_4 { padding-right: 320px; } -.rpad_5 { padding-right: 400px; } -.rpad_6 { padding-right: 480px; } -.rpad_7 { padding-right: 560px; } -.rpad_8 { padding-right: 640px; } -.rpad_9 { padding-right: 720px; } -.rpad_10 { padding-right: 800px; } -.rpad_11 { padding-right: 880px; } - - -/* ============================================================================= - Custom styles - ========================================================================== */ - -html, body{ - width: 768px; - margin: auto; -} - -/* ============================================================================= - Styles for tabs and buttons used in benchmark*.html - ========================================================================== */ - -.b-schedule{ - height: 100%; - width: 768px; - margin:0 auto; - padding: 0; -} - -.header{ - font-size: 2em; - line-height: 1; - text-align: center; - margin: 40 auto; -} - -.b-tabs{ - height: 100%; -} -.b-tabs__list{ - padding: 0px; - list-style: none; - border: 1px solid #b2b2b2; - border-bottom: 0; - -webkit-border-radius: 5px 5px 0 0; - -moz-border-radius: 5px 5px 0 0; - border-radius: 5px 5px 0 0; - -webkit-user-select: none; - box-shadow: 0 2px 4px -3px #000; - -webkit-padding-start: 0; - background-color: #f5f5f5; - -webkit-padding-start: 0; - overflow: hidden; - margin: 0; -} -.b-tabs__li{ - float: left; - padding: 10px; - cursor: pointer; - border-right: 1px solid #b2b2b2; -} -.b-tabs__li:last-child{ - border-right: none; -} -.b-tabs__li_on, .b-tabs__li:active{ - background-color: #fafafa; - padding: 11px 9px 9px 11px; - color: #3f3f3f; -} -.b-tabs__body{ - position: relative; - padding: 20px; - height: 980px; - border: 2px solid black; -} -#picture1, #picture2{ - min-width: 400px; - margin: 0 auto; -} -.b-tabs__buttons{ - padding: 0; - right: 20px; - border: 2px solid #b2b2b2; - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; - -webkit-user-select: none; - box-shadow: 0 2px 4px -3px #000; - -webkit-padding-start: 0; - background-color: #eaeaea; - outline: none; - cursor: pointer; - list-style: none; - float: right; -} -.b-button{ - float: left; - margin: 0; - padding: 3px; - border-right: 1px solid #b2b2b2; - font-size: medium; -} -.b-button:last-child{ - border: none; -} -.b-button_on, .b-button:active{ - background-color: #fafafa; - padding: 4px 2px 3px 4px; - color: #3f3f3f; -} - -h3 { - text-align:center; -} - -/* - * Disable current link in header, when we are on current page - */ - -body#tarantool.index #header #blurb h1 a.index, -body#tarantool.intro #header #blurb h3 a.intro, -body#tarantool.documentation #header #blurb h3 a.documentation, -body#tarantool.download #header #blurb h3 a.download, -body#tarantool.support #header #blurb h3 a.support { - pointer-events: none; - cursor: default; - text-decoration: none; -} diff --git a/doc/www/theme/static/old_header.css b/doc/www/theme/static/old_header.css deleted file mode 100644 index 22ad82701c83ce70185c6e4f121f5c4eedf46855..0000000000000000000000000000000000000000 --- a/doc/www/theme/static/old_header.css +++ /dev/null @@ -1,142 +0,0 @@ -#header, #content{ - background-color: #fff; -} - -#content { - padding-bottom: 5px; -} - -#blurb { - margin: 20px auto; -} - -#blurb h1 { - font-size: 2em; - line-height: 1; - text-align: center; - margin: 15px; -} - -#blurb h2 { - font-size: 1.2em; - font-weight: normal; - line-height: 1; - text-align: center; - margin: 5px; -} - -#blurb h3 { - text-align: center; - margin: 5px; -} - -/* =========================================================================== - Layout - ======================================================================== */ - -/* - * Top-level page sections: - * body > #header #content - */ - -#header, #content { - width: 100%; - margin: 0px auto; - padding: 0px; - overflow: hidden; -} - -#header { - margin-bottom: 5px; -} -/* - * http://sonspring.com/journal/clearing-floats - */ - -.clear { - clear: both; - display: block; - visibility: hidden; - width: 0; - height: 0; -} - -/* -- relbar ---------------------------------------------------------------- */ - -div.related { - width: 100%; - font-size: 90%; -} - -div.related h3 { - display: none; -} - -div.related ul { - margin: 0; - padding: 0 0 0 10px; - list-style: none; -} - -div.related li { - display: inline; -} - -div.related li.right { - float: right; - margin-right: 5px; -} - -div.related li.center { - float: center; - margin-right: 5px; -} - - -/* ============================================================================= - Links - ========================================================================== */ -a { - color: #201e9e; -} - -/* - * Addresses outline displayed oddly in Chrome - */ - -a:focus { - outline: thin dotted; -} - -/* - * Improves readability when focused and also mouse hovered in all browsers - * people.opera.com/patrickl/experiments/keyboard/test - */ - -a:active { - outline: 0; -} - -a:hover { - outline: 0; - background-color: rgba(0,0,0,0.1); - -moz-box-shadow: 0 1px 3px rgba(0,0,0,0.3); - -webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.3); - box-shadow: 0 1px 3px rgba(0,0,0,0.3); -} - -a.imglink:hover { - border : 0; - background-color: inherit; - -moz-box-shadow: none; - -webkit-box-shadow: none; - box-shadow: none; -} - -a:visited { - color: #3f3f3f; -} - -body { - margin-bottom: 100px; -} diff --git a/doc/www/theme/templates/documentation.html b/doc/www/theme/templates/documentation.html deleted file mode 100644 index 195d1dfc065532f34092d2d83761c204bf30a7ae..0000000000000000000000000000000000000000 --- a/doc/www/theme/templates/documentation.html +++ /dev/null @@ -1,37 +0,0 @@ -{% extends "base" %} - -{% block header_scripts %} -{% endblock header_scripts %} - -{% block content %} -<section class="b-lightgray_block b-documentation_top b-clearbox"> - <div class="b-block-wrapper"> - <h2 class="b-section-title">Documentation</h2> - <!--div class="b-search"> - <input class="b-search-text" data-placeholder="Search in documentation" /> - <input class="b-search-but" type="submit" /> - </div--> - </div> -</section> - -<section class="b-block b-tcontents"> - <div class="b-block-wrapper"> - <ul class="b-tcontents-list"> - {% for item in page.blocks.sections %} - <li class="b-tcontents-list-item"> - <h2 class="b-tcontents-list-item-title">{{ item.name }}</h2> - <ul class="b-tcontents-sublist"> - {% for itemli in item.list %} - <li class="b-tcontents-sublist-item"> - <a href="{{ itemli.link }}">{{ itemli.name }}</a> - </li> - {% endfor %} - </ul> - </li> - {% endfor %} - </ul> - </div> -</section> -{% endblock content %} - -{# vim: syntax=htmldjango ts=2 sts=2 sw=2 expandtab #} diff --git a/doc/www/theme/templates/documentation_rst.html b/doc/www/theme/templates/documentation_rst.html deleted file mode 100644 index f7d4bab57b0ddac7d5922835dd10d0ce7dfcbde0..0000000000000000000000000000000000000000 --- a/doc/www/theme/templates/documentation_rst.html +++ /dev/null @@ -1,46 +0,0 @@ -{% extends "base" %} - -{% block header_scripts %} -<script src="js/main.js"></script> -{% endblock header_scripts %} - -{% block content %} -<section class="b-lightgray_block b-documentation_top b-clearbox p-documentation_in"> - <div class="b-block-wrapper"> - <h2 class="b-section-title">Documentation</h2> - <!--div class="b-search"> - <input class="b-search-text" data-placeholder="Search in documentation" /> - <input class="b-search-but" type="submit" /> - </div--> - </div> -</section> - -<div class="b-cols_content b-clearbox"> - <!--div class="b-cols_content_left"> - <ul class="b-tcontents_full-list"> - <li class="b-tcontents_full-list-item p-active"> - <h2 class="b-tcontents_full-list-item-title"> - {# number #}<a href="{# link #}">{# name #}</a> - </h2> - <p class="b-tcontents_full-list-item-disc">{# text #}</p> - <ul class="b-tcontents_full-sublist"> - <li class="b-tcontents_full-sublist-item"> - {# number #}<a href="{# link #}">{# name #}</a> - </li> - </ul> - </li> - </ul> - </div--> - <div class="b-cols_content_left"> - </div> - <div class="b-cols_content_right"> - <div class="b-cols_content_right-slot"> - <article class="b-article"> - {{ page.content }} - </article> - </div> - </div> -</div> -{% endblock %} - -{# vim: syntax=htmldjango ts=2 sts=2 sw=2 expandtab #} diff --git a/doc/www/theme/templates/old_base b/doc/www/theme/templates/old_base deleted file mode 100644 index 1b814a03124e8927d5fb175328026fd0d9c9e571..0000000000000000000000000000000000000000 --- a/doc/www/theme/templates/old_base +++ /dev/null @@ -1,22 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml"> - <head> - <title>{{ title }}</title> - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> - <link rel="shortcut icon" href="/theme/favicon.ico" /> - {% if not documentation %} - <link rel="stylesheet" type="text/css" href="/theme/old_global.css" /> - <link rel="stylesheet" type="text/css" href="/theme/pygmentize.css" /> - {% endif %} - <link rel="stylesheet" type="text/css" href="/theme/old_header.css"> - {% include "script" ignore missing %} - </head> - <body id="tarantool" {% if page %} class ="{{ page.slug }}" {% endif %}> - <div id="content"> - {% block content %} - {% endblock content %} - </div> - </body> -</html> - -{# vim: syntax=htmldjango ts=2 sts=2 sw=2 expandtab #} diff --git a/doc/www/theme/templates/old_documentation.html b/doc/www/theme/templates/old_documentation.html deleted file mode 100644 index 7ee4830249d895f2356116bc2658080f10d00306..0000000000000000000000000000000000000000 --- a/doc/www/theme/templates/old_documentation.html +++ /dev/null @@ -1,7 +0,0 @@ -{% extends "old_base" %} -{% set title = page.title %} -{% block content %} - {{ page.content }} -{% endblock content %} - -{# vim: syntax=htmldjango ts=2 sts=2 sw=2 expandtab #} diff --git a/doc/www/theme/templates/old_page.html b/doc/www/theme/templates/old_page.html deleted file mode 100644 index 2db3be222790859035b829517805b1b5fec96721..0000000000000000000000000000000000000000 --- a/doc/www/theme/templates/old_page.html +++ /dev/null @@ -1,9 +0,0 @@ -{% extends "old_base" %} -{% set title = page.title %} -{% block content %} -<section id="content" class="body"> - {{ page.content }} -</section> -{% endblock %} - -{# vim: syntax=htmldjango ts=2 sts=2 sw=2 expandtab #}