NAME
    Perinci::Sub::Gen::AccessTable - Generate function (and its Rinci
    metadata) to access table data

VERSION
    version 0.29

SYNOPSIS
    In list_countries.pl:

     #!perl
     use strict;
     use warnings;
     use Perinci::CmdLine;
     use Perinci::Sub::Gen::AccessTable qw(gen_read_table_func);

     our %SPEC;

     my $countries = [
         ['cn', 'China', 'Cina', [qw/panda/]],
         ['id', 'Indonesia', 'Indonesia', [qw/bali tropical/]],
         ['sg', 'Singapore', 'Singapura', [qw/tropical/]],
         ['us', 'United States of America', 'Amerika Serikat', [qw//]],
     ];

     my $res = gen_read_table_func(
         name        => 'list_countries',
         summary     => 'func summary',     # opt
         description => 'func description', # opt
         table_data  => $countries,
         table_spec  => {
             summary => 'List of countries',
             fields => {
                 id => {
                     schema => 'str*',
                     summary => 'ISO 2-letter code for the country',
                     index => 0,
                     sortable => 1,
                 },
                 eng_name => {
                     schema => 'str*',
                     summary => 'English name',
                     index => 1,
                     sortable => 1,
                 },
                 ind_name => {
                     schema => 'str*',
                     summary => 'Indonesian name',
                     index => 2,
                     sortable => 1,
                 },
                 tags => {
                     schema => 'array*',
                     summary => 'Keywords/tags',
                     index => 3,
                     sortable => 0,
                 },
             },
             pk => 'id',
         },
     );
     die "Can't generate function: $res->[0] - $res->[1]" unless $res->[0] == 200;

     Perinci::CmdLine->new(url=>'/main/list_countries')->run;

    Now you can do:

     # list all countries, by default only PK field is shown
     $ list_countries.pl --format=text-simple
     cn
     id
     sg
     us

     # show as json, randomize order
     $ list_countries.pl --format=json --random
     ["id","us","sg","cn"]

     # only list countries which are tagged as 'tropical', sort by ind_name field in
     # descending order, show all fields (--detail)
     $ list_countries.pl --detail --sort -ind_name --tags-has '[tropical]'
     .---------------------------------------------.
     | eng_name  | id | ind_name  | tags           |
     +-----------+----+-----------+----------------+
     | Singapore | sg | Singapura | tropical       |
     | Indonesia | id | Indonesia | bali, tropical |
     '-----------+----+-----------+----------------'

     # show only certain fields, limit number of records, return in YAML format
     $ list_countries.pl --fields '[id, eng_name]' --result-limit 2 --format=yaml
     - 200
     - OK
     -
       - id: cn
         eng_name: China
       - id: id
         eng_name: Indonesia

DESCRIPTION
    This module is useful when you want to expose a table data (an array of
    hashrefs, an array of arrays, or external data like a SQL table) as an
    API function. This module will generate a function (along with its Rinci
    metadata) that accepts arguments for specifying fields, filtering,
    sorting, and paging. The resulting function can then be run via
    command-line using Perinci::CmdLine (as demonstrated in Synopsis), or
    served via HTTP using Perinci::Access::HTTP::Server, or consumed
    normally by Perl programs.

    This module uses Log::Any for logging.

FUNCTIONS
  gen_read_table_func(%args) -> [status, msg, result, meta]
    {en_US Generate function (and its metadata) to read table data}.

    {en_US The generated function acts like a simple single table SQL SELECT
    query, featuring filtering, ordering, and paging, but using arguments as
    the 'query language'. The generated function is suitable for exposing a
    table data from an API function.

    The resulting function returns an array of results/records and accepts
    these arguments.

    *   *with_field_names* => BOOL (default 1)

          If set to 1, function will return records of field values along with field
          names (hashref), e.g. {id=>'ID', country=>'Indonesia', capital=>'Jakarta'}. If
          set to 0, then function will return record containing field values without
          field names (arrayref) instead, e.g.: ['ID', 'Indonesia', 'Jakarta'].

    *   *detail* => BOOL (default 0)

          This is a field selection option. If set to 0, function will return PK field
          only. If this argument is set to 1, then all fields will be returned (see also
          I<fields> to instruct function to return some fields only).

    *   *fields* => ARRAY

          This is a field selection option. If you only want certain fields, specify
          them here (see also I<detail>).

    *   *result_limit* => INT (default undef)

    *   *result_start* => INT (default 1)

          The I<result_limit> and I<result_start> arguments are paging options, they work
          like LIMIT clause in SQL, except that index starts at 1 and not 0. For
          example, to return the first 20 records in the result, set I<result_limit> to
          20 . To return the next 20 records, set I<result_limit> to 20 and
          I<result_start> to 21.

    *   *random* => BOOL (default 0)

          The random argument is an ordering option. If set to true, order of records
          returned will be shuffled first. This happened before paging.

    *   *sort* => STR

          The sort argument is an ordering option, containing name of field. A - prefix
          signifies descending instead of ascending order. Multiple fields are allowed,
          separated by comma.

    *   *q* => STR

          A filtering option. By default, all fields except those specified with
          searchable=0 will be searched using simple case-insensitive string search.
          There are a few options to customize this, using these gen arguments:
          I<word_search>, I<case_insensitive_search>, and I<custom_search>.

    *   Filter arguments

          They will be generated for each field, except when field has 'filterable'
          clause set to false.

          Undef values will not match any filter, just like NULL in SQL.

    *   *FIELD.is* and *FIELD.isnt* arguments for each field. Only records
        with field equalling (or not equalling) value exactly ('==' or 'eq')
        will be included. If doesn't clash with other function arguments,
        *FIELD* will also be added as an alias for *FIELD.is*.

    *   *FIELD.has* and *FIELD.lacks* array arguments for each set field.
        Only records with field having or lacking certain value will be
        included.

    *   *FIELD.min* and *FIELD.max* for each int/float/str field. Only
        records with field greater/equal than, or less/equal than a certain
        value will be included.

    *   *FIELD.contains* and *FIELD.not_contains* for each str field. Only
        records with field containing (or not containing) certain value
        (substring) will be included.

    *   *FIELD.matches* and *FIELD.not_matches* for each str field. Only
        records with field matching (or not matching) certain value (regex)
        (or will be included. Function will return 400 if regex is invalid.
        These arguments will not be generated if 'filterable_regex' clause
        in field specification is set to 0. }

    Arguments ('*' denotes required arguments):

    *   case_insensitive_search => *bool* (default: 1)

        {en_US Generate function (and its metadata) to read table data}.

        {en_US The generated function acts like a simple single table SQL
        SELECT query, featuring filtering, ordering, and paging, but using
        arguments as the 'query language'. The generated function is
        suitable for exposing a table data from an API function.

        The resulting function returns an array of results/records and
        accepts these arguments.

        *   *with_field_names* => BOOL (default 1)

              If set to 1, function will return records of field values along with field
              names (hashref), e.g. {id=>'ID', country=>'Indonesia', capital=>'Jakarta'}. If
              set to 0, then function will return record containing field values without
              field names (arrayref) instead, e.g.: ['ID', 'Indonesia', 'Jakarta'].

        *   *detail* => BOOL (default 0)

              This is a field selection option. If set to 0, function will return PK field
              only. If this argument is set to 1, then all fields will be returned (see also
              I<fields> to instruct function to return some fields only).

        *   *fields* => ARRAY

              This is a field selection option. If you only want certain fields, specify
              them here (see also I<detail>).

        *   *result_limit* => INT (default undef)

        *   *result_start* => INT (default 1)

              The I<result_limit> and I<result_start> arguments are paging options, they work
              like LIMIT clause in SQL, except that index starts at 1 and not 0. For
              example, to return the first 20 records in the result, set I<result_limit> to
              20 . To return the next 20 records, set I<result_limit> to 20 and
              I<result_start> to 21.

        *   *random* => BOOL (default 0)

              The random argument is an ordering option. If set to true, order of records
              returned will be shuffled first. This happened before paging.

        *   *sort* => STR

              The sort argument is an ordering option, containing name of field. A - prefix
              signifies descending instead of ascending order. Multiple fields are allowed,
              separated by comma.

        *   *q* => STR

              A filtering option. By default, all fields except those specified with
              searchable=0 will be searched using simple case-insensitive string search.
              There are a few options to customize this, using these gen arguments:
              I<word_search>, I<case_insensitive_search>, and I<custom_search>.

        *   Filter arguments

              They will be generated for each field, except when field has 'filterable'
              clause set to false.

              Undef values will not match any filter, just like NULL in SQL.

        *   *FIELD.is* and *FIELD.isnt* arguments for each field. Only
            records with field equalling (or not equalling) value exactly
            ('==' or 'eq') will be included. If doesn't clash with other
            function arguments, *FIELD* will also be added as an alias for
            *FIELD.is*.

        *   *FIELD.has* and *FIELD.lacks* array arguments for each set
            field. Only records with field having or lacking certain value
            will be included.

        *   *FIELD.min* and *FIELD.max* for each int/float/str field. Only
            records with field greater/equal than, or less/equal than a
            certain value will be included.

        *   *FIELD.contains* and *FIELD.not_contains* for each str field.
            Only records with field containing (or not containing) certain
            value (substring) will be included.

        *   *FIELD.matches* and *FIELD.not_matches* for each str field. Only
            records with field matching (or not matching) certain value
            (regex) (or will be included. Function will return 400 if regex
            is invalid. These arguments will not be generated if
            'filterable_regex' clause in field specification is set to 0. }

    *   custom_filters => *hash*

        {en_US Generate function (and its metadata) to read table data}.

        {en_US The generated function acts like a simple single table SQL
        SELECT query, featuring filtering, ordering, and paging, but using
        arguments as the 'query language'. The generated function is
        suitable for exposing a table data from an API function.

        The resulting function returns an array of results/records and
        accepts these arguments.

        *   *with_field_names* => BOOL (default 1)

              If set to 1, function will return records of field values along with field
              names (hashref), e.g. {id=>'ID', country=>'Indonesia', capital=>'Jakarta'}. If
              set to 0, then function will return record containing field values without
              field names (arrayref) instead, e.g.: ['ID', 'Indonesia', 'Jakarta'].

        *   *detail* => BOOL (default 0)

              This is a field selection option. If set to 0, function will return PK field
              only. If this argument is set to 1, then all fields will be returned (see also
              I<fields> to instruct function to return some fields only).

        *   *fields* => ARRAY

              This is a field selection option. If you only want certain fields, specify
              them here (see also I<detail>).

        *   *result_limit* => INT (default undef)

        *   *result_start* => INT (default 1)

              The I<result_limit> and I<result_start> arguments are paging options, they work
              like LIMIT clause in SQL, except that index starts at 1 and not 0. For
              example, to return the first 20 records in the result, set I<result_limit> to
              20 . To return the next 20 records, set I<result_limit> to 20 and
              I<result_start> to 21.

        *   *random* => BOOL (default 0)

              The random argument is an ordering option. If set to true, order of records
              returned will be shuffled first. This happened before paging.

        *   *sort* => STR

              The sort argument is an ordering option, containing name of field. A - prefix
              signifies descending instead of ascending order. Multiple fields are allowed,
              separated by comma.

        *   *q* => STR

              A filtering option. By default, all fields except those specified with
              searchable=0 will be searched using simple case-insensitive string search.
              There are a few options to customize this, using these gen arguments:
              I<word_search>, I<case_insensitive_search>, and I<custom_search>.

        *   Filter arguments

              They will be generated for each field, except when field has 'filterable'
              clause set to false.

              Undef values will not match any filter, just like NULL in SQL.

        *   *FIELD.is* and *FIELD.isnt* arguments for each field. Only
            records with field equalling (or not equalling) value exactly
            ('==' or 'eq') will be included. If doesn't clash with other
            function arguments, *FIELD* will also be added as an alias for
            *FIELD.is*.

        *   *FIELD.has* and *FIELD.lacks* array arguments for each set
            field. Only records with field having or lacking certain value
            will be included.

        *   *FIELD.min* and *FIELD.max* for each int/float/str field. Only
            records with field greater/equal than, or less/equal than a
            certain value will be included.

        *   *FIELD.contains* and *FIELD.not_contains* for each str field.
            Only records with field containing (or not containing) certain
            value (substring) will be included.

        *   *FIELD.matches* and *FIELD.not_matches* for each str field. Only
            records with field matching (or not matching) certain value
            (regex) (or will be included. Function will return 400 if regex
            is invalid. These arguments will not be generated if
            'filterable_regex' clause in field specification is set to 0. }

    *   custom_search => *code*

        {en_US Generate function (and its metadata) to read table data}.

        {en_US The generated function acts like a simple single table SQL
        SELECT query, featuring filtering, ordering, and paging, but using
        arguments as the 'query language'. The generated function is
        suitable for exposing a table data from an API function.

        The resulting function returns an array of results/records and
        accepts these arguments.

        *   *with_field_names* => BOOL (default 1)

              If set to 1, function will return records of field values along with field
              names (hashref), e.g. {id=>'ID', country=>'Indonesia', capital=>'Jakarta'}. If
              set to 0, then function will return record containing field values without
              field names (arrayref) instead, e.g.: ['ID', 'Indonesia', 'Jakarta'].

        *   *detail* => BOOL (default 0)

              This is a field selection option. If set to 0, function will return PK field
              only. If this argument is set to 1, then all fields will be returned (see also
              I<fields> to instruct function to return some fields only).

        *   *fields* => ARRAY

              This is a field selection option. If you only want certain fields, specify
              them here (see also I<detail>).

        *   *result_limit* => INT (default undef)

        *   *result_start* => INT (default 1)

              The I<result_limit> and I<result_start> arguments are paging options, they work
              like LIMIT clause in SQL, except that index starts at 1 and not 0. For
              example, to return the first 20 records in the result, set I<result_limit> to
              20 . To return the next 20 records, set I<result_limit> to 20 and
              I<result_start> to 21.

        *   *random* => BOOL (default 0)

              The random argument is an ordering option. If set to true, order of records
              returned will be shuffled first. This happened before paging.

        *   *sort* => STR

              The sort argument is an ordering option, containing name of field. A - prefix
              signifies descending instead of ascending order. Multiple fields are allowed,
              separated by comma.

        *   *q* => STR

              A filtering option. By default, all fields except those specified with
              searchable=0 will be searched using simple case-insensitive string search.
              There are a few options to customize this, using these gen arguments:
              I<word_search>, I<case_insensitive_search>, and I<custom_search>.

        *   Filter arguments

              They will be generated for each field, except when field has 'filterable'
              clause set to false.

              Undef values will not match any filter, just like NULL in SQL.

        *   *FIELD.is* and *FIELD.isnt* arguments for each field. Only
            records with field equalling (or not equalling) value exactly
            ('==' or 'eq') will be included. If doesn't clash with other
            function arguments, *FIELD* will also be added as an alias for
            *FIELD.is*.

        *   *FIELD.has* and *FIELD.lacks* array arguments for each set
            field. Only records with field having or lacking certain value
            will be included.

        *   *FIELD.min* and *FIELD.max* for each int/float/str field. Only
            records with field greater/equal than, or less/equal than a
            certain value will be included.

        *   *FIELD.contains* and *FIELD.not_contains* for each str field.
            Only records with field containing (or not containing) certain
            value (substring) will be included.

        *   *FIELD.matches* and *FIELD.not_matches* for each str field. Only
            records with field matching (or not matching) certain value
            (regex) (or will be included. Function will return 400 if regex
            is invalid. These arguments will not be generated if
            'filterable_regex' clause in field specification is set to 0. }

    *   default_arg_values => *hash*

        {en_US Generate function (and its metadata) to read table data}.

        {en_US The generated function acts like a simple single table SQL
        SELECT query, featuring filtering, ordering, and paging, but using
        arguments as the 'query language'. The generated function is
        suitable for exposing a table data from an API function.

        The resulting function returns an array of results/records and
        accepts these arguments.

        *   *with_field_names* => BOOL (default 1)

              If set to 1, function will return records of field values along with field
              names (hashref), e.g. {id=>'ID', country=>'Indonesia', capital=>'Jakarta'}. If
              set to 0, then function will return record containing field values without
              field names (arrayref) instead, e.g.: ['ID', 'Indonesia', 'Jakarta'].

        *   *detail* => BOOL (default 0)

              This is a field selection option. If set to 0, function will return PK field
              only. If this argument is set to 1, then all fields will be returned (see also
              I<fields> to instruct function to return some fields only).

        *   *fields* => ARRAY

              This is a field selection option. If you only want certain fields, specify
              them here (see also I<detail>).

        *   *result_limit* => INT (default undef)

        *   *result_start* => INT (default 1)

              The I<result_limit> and I<result_start> arguments are paging options, they work
              like LIMIT clause in SQL, except that index starts at 1 and not 0. For
              example, to return the first 20 records in the result, set I<result_limit> to
              20 . To return the next 20 records, set I<result_limit> to 20 and
              I<result_start> to 21.

        *   *random* => BOOL (default 0)

              The random argument is an ordering option. If set to true, order of records
              returned will be shuffled first. This happened before paging.

        *   *sort* => STR

              The sort argument is an ordering option, containing name of field. A - prefix
              signifies descending instead of ascending order. Multiple fields are allowed,
              separated by comma.

        *   *q* => STR

              A filtering option. By default, all fields except those specified with
              searchable=0 will be searched using simple case-insensitive string search.
              There are a few options to customize this, using these gen arguments:
              I<word_search>, I<case_insensitive_search>, and I<custom_search>.

        *   Filter arguments

              They will be generated for each field, except when field has 'filterable'
              clause set to false.

              Undef values will not match any filter, just like NULL in SQL.

        *   *FIELD.is* and *FIELD.isnt* arguments for each field. Only
            records with field equalling (or not equalling) value exactly
            ('==' or 'eq') will be included. If doesn't clash with other
            function arguments, *FIELD* will also be added as an alias for
            *FIELD.is*.

        *   *FIELD.has* and *FIELD.lacks* array arguments for each set
            field. Only records with field having or lacking certain value
            will be included.

        *   *FIELD.min* and *FIELD.max* for each int/float/str field. Only
            records with field greater/equal than, or less/equal than a
            certain value will be included.

        *   *FIELD.contains* and *FIELD.not_contains* for each str field.
            Only records with field containing (or not containing) certain
            value (substring) will be included.

        *   *FIELD.matches* and *FIELD.not_matches* for each str field. Only
            records with field matching (or not matching) certain value
            (regex) (or will be included. Function will return 400 if regex
            is invalid. These arguments will not be generated if
            'filterable_regex' clause in field specification is set to 0. }

    *   default_detail => *bool*

        {en_US Generate function (and its metadata) to read table data}.

        {en_US The generated function acts like a simple single table SQL
        SELECT query, featuring filtering, ordering, and paging, but using
        arguments as the 'query language'. The generated function is
        suitable for exposing a table data from an API function.

        The resulting function returns an array of results/records and
        accepts these arguments.

        *   *with_field_names* => BOOL (default 1)

              If set to 1, function will return records of field values along with field
              names (hashref), e.g. {id=>'ID', country=>'Indonesia', capital=>'Jakarta'}. If
              set to 0, then function will return record containing field values without
              field names (arrayref) instead, e.g.: ['ID', 'Indonesia', 'Jakarta'].

        *   *detail* => BOOL (default 0)

              This is a field selection option. If set to 0, function will return PK field
              only. If this argument is set to 1, then all fields will be returned (see also
              I<fields> to instruct function to return some fields only).

        *   *fields* => ARRAY

              This is a field selection option. If you only want certain fields, specify
              them here (see also I<detail>).

        *   *result_limit* => INT (default undef)

        *   *result_start* => INT (default 1)

              The I<result_limit> and I<result_start> arguments are paging options, they work
              like LIMIT clause in SQL, except that index starts at 1 and not 0. For
              example, to return the first 20 records in the result, set I<result_limit> to
              20 . To return the next 20 records, set I<result_limit> to 20 and
              I<result_start> to 21.

        *   *random* => BOOL (default 0)

              The random argument is an ordering option. If set to true, order of records
              returned will be shuffled first. This happened before paging.

        *   *sort* => STR

              The sort argument is an ordering option, containing name of field. A - prefix
              signifies descending instead of ascending order. Multiple fields are allowed,
              separated by comma.

        *   *q* => STR

              A filtering option. By default, all fields except those specified with
              searchable=0 will be searched using simple case-insensitive string search.
              There are a few options to customize this, using these gen arguments:
              I<word_search>, I<case_insensitive_search>, and I<custom_search>.

        *   Filter arguments

              They will be generated for each field, except when field has 'filterable'
              clause set to false.

              Undef values will not match any filter, just like NULL in SQL.

        *   *FIELD.is* and *FIELD.isnt* arguments for each field. Only
            records with field equalling (or not equalling) value exactly
            ('==' or 'eq') will be included. If doesn't clash with other
            function arguments, *FIELD* will also be added as an alias for
            *FIELD.is*.

        *   *FIELD.has* and *FIELD.lacks* array arguments for each set
            field. Only records with field having or lacking certain value
            will be included.

        *   *FIELD.min* and *FIELD.max* for each int/float/str field. Only
            records with field greater/equal than, or less/equal than a
            certain value will be included.

        *   *FIELD.contains* and *FIELD.not_contains* for each str field.
            Only records with field containing (or not containing) certain
            value (substring) will be included.

        *   *FIELD.matches* and *FIELD.not_matches* for each str field. Only
            records with field matching (or not matching) certain value
            (regex) (or will be included. Function will return 400 if regex
            is invalid. These arguments will not be generated if
            'filterable_regex' clause in field specification is set to 0. }

    *   default_fields => *str*

        {en_US Generate function (and its metadata) to read table data}.

        {en_US The generated function acts like a simple single table SQL
        SELECT query, featuring filtering, ordering, and paging, but using
        arguments as the 'query language'. The generated function is
        suitable for exposing a table data from an API function.

        The resulting function returns an array of results/records and
        accepts these arguments.

        *   *with_field_names* => BOOL (default 1)

              If set to 1, function will return records of field values along with field
              names (hashref), e.g. {id=>'ID', country=>'Indonesia', capital=>'Jakarta'}. If
              set to 0, then function will return record containing field values without
              field names (arrayref) instead, e.g.: ['ID', 'Indonesia', 'Jakarta'].

        *   *detail* => BOOL (default 0)

              This is a field selection option. If set to 0, function will return PK field
              only. If this argument is set to 1, then all fields will be returned (see also
              I<fields> to instruct function to return some fields only).

        *   *fields* => ARRAY

              This is a field selection option. If you only want certain fields, specify
              them here (see also I<detail>).

        *   *result_limit* => INT (default undef)

        *   *result_start* => INT (default 1)

              The I<result_limit> and I<result_start> arguments are paging options, they work
              like LIMIT clause in SQL, except that index starts at 1 and not 0. For
              example, to return the first 20 records in the result, set I<result_limit> to
              20 . To return the next 20 records, set I<result_limit> to 20 and
              I<result_start> to 21.

        *   *random* => BOOL (default 0)

              The random argument is an ordering option. If set to true, order of records
              returned will be shuffled first. This happened before paging.

        *   *sort* => STR

              The sort argument is an ordering option, containing name of field. A - prefix
              signifies descending instead of ascending order. Multiple fields are allowed,
              separated by comma.

        *   *q* => STR

              A filtering option. By default, all fields except those specified with
              searchable=0 will be searched using simple case-insensitive string search.
              There are a few options to customize this, using these gen arguments:
              I<word_search>, I<case_insensitive_search>, and I<custom_search>.

        *   Filter arguments

              They will be generated for each field, except when field has 'filterable'
              clause set to false.

              Undef values will not match any filter, just like NULL in SQL.

        *   *FIELD.is* and *FIELD.isnt* arguments for each field. Only
            records with field equalling (or not equalling) value exactly
            ('==' or 'eq') will be included. If doesn't clash with other
            function arguments, *FIELD* will also be added as an alias for
            *FIELD.is*.

        *   *FIELD.has* and *FIELD.lacks* array arguments for each set
            field. Only records with field having or lacking certain value
            will be included.

        *   *FIELD.min* and *FIELD.max* for each int/float/str field. Only
            records with field greater/equal than, or less/equal than a
            certain value will be included.

        *   *FIELD.contains* and *FIELD.not_contains* for each str field.
            Only records with field containing (or not containing) certain
            value (substring) will be included.

        *   *FIELD.matches* and *FIELD.not_matches* for each str field. Only
            records with field matching (or not matching) certain value
            (regex) (or will be included. Function will return 400 if regex
            is invalid. These arguments will not be generated if
            'filterable_regex' clause in field specification is set to 0. }

    *   default_random => *bool*

        {en_US Generate function (and its metadata) to read table data}.

        {en_US The generated function acts like a simple single table SQL
        SELECT query, featuring filtering, ordering, and paging, but using
        arguments as the 'query language'. The generated function is
        suitable for exposing a table data from an API function.

        The resulting function returns an array of results/records and
        accepts these arguments.

        *   *with_field_names* => BOOL (default 1)

              If set to 1, function will return records of field values along with field
              names (hashref), e.g. {id=>'ID', country=>'Indonesia', capital=>'Jakarta'}. If
              set to 0, then function will return record containing field values without
              field names (arrayref) instead, e.g.: ['ID', 'Indonesia', 'Jakarta'].

        *   *detail* => BOOL (default 0)

              This is a field selection option. If set to 0, function will return PK field
              only. If this argument is set to 1, then all fields will be returned (see also
              I<fields> to instruct function to return some fields only).

        *   *fields* => ARRAY

              This is a field selection option. If you only want certain fields, specify
              them here (see also I<detail>).

        *   *result_limit* => INT (default undef)

        *   *result_start* => INT (default 1)

              The I<result_limit> and I<result_start> arguments are paging options, they work
              like LIMIT clause in SQL, except that index starts at 1 and not 0. For
              example, to return the first 20 records in the result, set I<result_limit> to
              20 . To return the next 20 records, set I<result_limit> to 20 and
              I<result_start> to 21.

        *   *random* => BOOL (default 0)

              The random argument is an ordering option. If set to true, order of records
              returned will be shuffled first. This happened before paging.

        *   *sort* => STR

              The sort argument is an ordering option, containing name of field. A - prefix
              signifies descending instead of ascending order. Multiple fields are allowed,
              separated by comma.

        *   *q* => STR

              A filtering option. By default, all fields except those specified with
              searchable=0 will be searched using simple case-insensitive string search.
              There are a few options to customize this, using these gen arguments:
              I<word_search>, I<case_insensitive_search>, and I<custom_search>.

        *   Filter arguments

              They will be generated for each field, except when field has 'filterable'
              clause set to false.

              Undef values will not match any filter, just like NULL in SQL.

        *   *FIELD.is* and *FIELD.isnt* arguments for each field. Only
            records with field equalling (or not equalling) value exactly
            ('==' or 'eq') will be included. If doesn't clash with other
            function arguments, *FIELD* will also be added as an alias for
            *FIELD.is*.

        *   *FIELD.has* and *FIELD.lacks* array arguments for each set
            field. Only records with field having or lacking certain value
            will be included.

        *   *FIELD.min* and *FIELD.max* for each int/float/str field. Only
            records with field greater/equal than, or less/equal than a
            certain value will be included.

        *   *FIELD.contains* and *FIELD.not_contains* for each str field.
            Only records with field containing (or not containing) certain
            value (substring) will be included.

        *   *FIELD.matches* and *FIELD.not_matches* for each str field. Only
            records with field matching (or not matching) certain value
            (regex) (or will be included. Function will return 400 if regex
            is invalid. These arguments will not be generated if
            'filterable_regex' clause in field specification is set to 0. }

    *   default_result_limit => *int*

        {en_US Generate function (and its metadata) to read table data}.

        {en_US The generated function acts like a simple single table SQL
        SELECT query, featuring filtering, ordering, and paging, but using
        arguments as the 'query language'. The generated function is
        suitable for exposing a table data from an API function.

        The resulting function returns an array of results/records and
        accepts these arguments.

        *   *with_field_names* => BOOL (default 1)

              If set to 1, function will return records of field values along with field
              names (hashref), e.g. {id=>'ID', country=>'Indonesia', capital=>'Jakarta'}. If
              set to 0, then function will return record containing field values without
              field names (arrayref) instead, e.g.: ['ID', 'Indonesia', 'Jakarta'].

        *   *detail* => BOOL (default 0)

              This is a field selection option. If set to 0, function will return PK field
              only. If this argument is set to 1, then all fields will be returned (see also
              I<fields> to instruct function to return some fields only).

        *   *fields* => ARRAY

              This is a field selection option. If you only want certain fields, specify
              them here (see also I<detail>).

        *   *result_limit* => INT (default undef)

        *   *result_start* => INT (default 1)

              The I<result_limit> and I<result_start> arguments are paging options, they work
              like LIMIT clause in SQL, except that index starts at 1 and not 0. For
              example, to return the first 20 records in the result, set I<result_limit> to
              20 . To return the next 20 records, set I<result_limit> to 20 and
              I<result_start> to 21.

        *   *random* => BOOL (default 0)

              The random argument is an ordering option. If set to true, order of records
              returned will be shuffled first. This happened before paging.

        *   *sort* => STR

              The sort argument is an ordering option, containing name of field. A - prefix
              signifies descending instead of ascending order. Multiple fields are allowed,
              separated by comma.

        *   *q* => STR

              A filtering option. By default, all fields except those specified with
              searchable=0 will be searched using simple case-insensitive string search.
              There are a few options to customize this, using these gen arguments:
              I<word_search>, I<case_insensitive_search>, and I<custom_search>.

        *   Filter arguments

              They will be generated for each field, except when field has 'filterable'
              clause set to false.

              Undef values will not match any filter, just like NULL in SQL.

        *   *FIELD.is* and *FIELD.isnt* arguments for each field. Only
            records with field equalling (or not equalling) value exactly
            ('==' or 'eq') will be included. If doesn't clash with other
            function arguments, *FIELD* will also be added as an alias for
            *FIELD.is*.

        *   *FIELD.has* and *FIELD.lacks* array arguments for each set
            field. Only records with field having or lacking certain value
            will be included.

        *   *FIELD.min* and *FIELD.max* for each int/float/str field. Only
            records with field greater/equal than, or less/equal than a
            certain value will be included.

        *   *FIELD.contains* and *FIELD.not_contains* for each str field.
            Only records with field containing (or not containing) certain
            value (substring) will be included.

        *   *FIELD.matches* and *FIELD.not_matches* for each str field. Only
            records with field matching (or not matching) certain value
            (regex) (or will be included. Function will return 400 if regex
            is invalid. These arguments will not be generated if
            'filterable_regex' clause in field specification is set to 0. }

    *   default_sort => *str*

        {en_US Generate function (and its metadata) to read table data}.

        {en_US The generated function acts like a simple single table SQL
        SELECT query, featuring filtering, ordering, and paging, but using
        arguments as the 'query language'. The generated function is
        suitable for exposing a table data from an API function.

        The resulting function returns an array of results/records and
        accepts these arguments.

        *   *with_field_names* => BOOL (default 1)

              If set to 1, function will return records of field values along with field
              names (hashref), e.g. {id=>'ID', country=>'Indonesia', capital=>'Jakarta'}. If
              set to 0, then function will return record containing field values without
              field names (arrayref) instead, e.g.: ['ID', 'Indonesia', 'Jakarta'].

        *   *detail* => BOOL (default 0)

              This is a field selection option. If set to 0, function will return PK field
              only. If this argument is set to 1, then all fields will be returned (see also
              I<fields> to instruct function to return some fields only).

        *   *fields* => ARRAY

              This is a field selection option. If you only want certain fields, specify
              them here (see also I<detail>).

        *   *result_limit* => INT (default undef)

        *   *result_start* => INT (default 1)

              The I<result_limit> and I<result_start> arguments are paging options, they work
              like LIMIT clause in SQL, except that index starts at 1 and not 0. For
              example, to return the first 20 records in the result, set I<result_limit> to
              20 . To return the next 20 records, set I<result_limit> to 20 and
              I<result_start> to 21.

        *   *random* => BOOL (default 0)

              The random argument is an ordering option. If set to true, order of records
              returned will be shuffled first. This happened before paging.

        *   *sort* => STR

              The sort argument is an ordering option, containing name of field. A - prefix
              signifies descending instead of ascending order. Multiple fields are allowed,
              separated by comma.

        *   *q* => STR

              A filtering option. By default, all fields except those specified with
              searchable=0 will be searched using simple case-insensitive string search.
              There are a few options to customize this, using these gen arguments:
              I<word_search>, I<case_insensitive_search>, and I<custom_search>.

        *   Filter arguments

              They will be generated for each field, except when field has 'filterable'
              clause set to false.

              Undef values will not match any filter, just like NULL in SQL.

        *   *FIELD.is* and *FIELD.isnt* arguments for each field. Only
            records with field equalling (or not equalling) value exactly
            ('==' or 'eq') will be included. If doesn't clash with other
            function arguments, *FIELD* will also be added as an alias for
            *FIELD.is*.

        *   *FIELD.has* and *FIELD.lacks* array arguments for each set
            field. Only records with field having or lacking certain value
            will be included.

        *   *FIELD.min* and *FIELD.max* for each int/float/str field. Only
            records with field greater/equal than, or less/equal than a
            certain value will be included.

        *   *FIELD.contains* and *FIELD.not_contains* for each str field.
            Only records with field containing (or not containing) certain
            value (substring) will be included.

        *   *FIELD.matches* and *FIELD.not_matches* for each str field. Only
            records with field matching (or not matching) certain value
            (regex) (or will be included. Function will return 400 if regex
            is invalid. These arguments will not be generated if
            'filterable_regex' clause in field specification is set to 0. }

    *   default_with_field_names => *bool*

        {en_US Generate function (and its metadata) to read table data}.

        {en_US The generated function acts like a simple single table SQL
        SELECT query, featuring filtering, ordering, and paging, but using
        arguments as the 'query language'. The generated function is
        suitable for exposing a table data from an API function.

        The resulting function returns an array of results/records and
        accepts these arguments.

        *   *with_field_names* => BOOL (default 1)

              If set to 1, function will return records of field values along with field
              names (hashref), e.g. {id=>'ID', country=>'Indonesia', capital=>'Jakarta'}. If
              set to 0, then function will return record containing field values without
              field names (arrayref) instead, e.g.: ['ID', 'Indonesia', 'Jakarta'].

        *   *detail* => BOOL (default 0)

              This is a field selection option. If set to 0, function will return PK field
              only. If this argument is set to 1, then all fields will be returned (see also
              I<fields> to instruct function to return some fields only).

        *   *fields* => ARRAY

              This is a field selection option. If you only want certain fields, specify
              them here (see also I<detail>).

        *   *result_limit* => INT (default undef)

        *   *result_start* => INT (default 1)

              The I<result_limit> and I<result_start> arguments are paging options, they work
              like LIMIT clause in SQL, except that index starts at 1 and not 0. For
              example, to return the first 20 records in the result, set I<result_limit> to
              20 . To return the next 20 records, set I<result_limit> to 20 and
              I<result_start> to 21.

        *   *random* => BOOL (default 0)

              The random argument is an ordering option. If set to true, order of records
              returned will be shuffled first. This happened before paging.

        *   *sort* => STR

              The sort argument is an ordering option, containing name of field. A - prefix
              signifies descending instead of ascending order. Multiple fields are allowed,
              separated by comma.

        *   *q* => STR

              A filtering option. By default, all fields except those specified with
              searchable=0 will be searched using simple case-insensitive string search.
              There are a few options to customize this, using these gen arguments:
              I<word_search>, I<case_insensitive_search>, and I<custom_search>.

        *   Filter arguments

              They will be generated for each field, except when field has 'filterable'
              clause set to false.

              Undef values will not match any filter, just like NULL in SQL.

        *   *FIELD.is* and *FIELD.isnt* arguments for each field. Only
            records with field equalling (or not equalling) value exactly
            ('==' or 'eq') will be included. If doesn't clash with other
            function arguments, *FIELD* will also be added as an alias for
            *FIELD.is*.

        *   *FIELD.has* and *FIELD.lacks* array arguments for each set
            field. Only records with field having or lacking certain value
            will be included.

        *   *FIELD.min* and *FIELD.max* for each int/float/str field. Only
            records with field greater/equal than, or less/equal than a
            certain value will be included.

        *   *FIELD.contains* and *FIELD.not_contains* for each str field.
            Only records with field containing (or not containing) certain
            value (substring) will be included.

        *   *FIELD.matches* and *FIELD.not_matches* for each str field. Only
            records with field matching (or not matching) certain value
            (regex) (or will be included. Function will return 400 if regex
            is invalid. These arguments will not be generated if
            'filterable_regex' clause in field specification is set to 0. }

    *   description => *str*

        {en_US Generate function (and its metadata) to read table data}.

        {en_US The generated function acts like a simple single table SQL
        SELECT query, featuring filtering, ordering, and paging, but using
        arguments as the 'query language'. The generated function is
        suitable for exposing a table data from an API function.

        The resulting function returns an array of results/records and
        accepts these arguments.

        *   *with_field_names* => BOOL (default 1)

              If set to 1, function will return records of field values along with field
              names (hashref), e.g. {id=>'ID', country=>'Indonesia', capital=>'Jakarta'}. If
              set to 0, then function will return record containing field values without
              field names (arrayref) instead, e.g.: ['ID', 'Indonesia', 'Jakarta'].

        *   *detail* => BOOL (default 0)

              This is a field selection option. If set to 0, function will return PK field
              only. If this argument is set to 1, then all fields will be returned (see also
              I<fields> to instruct function to return some fields only).

        *   *fields* => ARRAY

              This is a field selection option. If you only want certain fields, specify
              them here (see also I<detail>).

        *   *result_limit* => INT (default undef)

        *   *result_start* => INT (default 1)

              The I<result_limit> and I<result_start> arguments are paging options, they work
              like LIMIT clause in SQL, except that index starts at 1 and not 0. For
              example, to return the first 20 records in the result, set I<result_limit> to
              20 . To return the next 20 records, set I<result_limit> to 20 and
              I<result_start> to 21.

        *   *random* => BOOL (default 0)

              The random argument is an ordering option. If set to true, order of records
              returned will be shuffled first. This happened before paging.

        *   *sort* => STR

              The sort argument is an ordering option, containing name of field. A - prefix
              signifies descending instead of ascending order. Multiple fields are allowed,
              separated by comma.

        *   *q* => STR

              A filtering option. By default, all fields except those specified with
              searchable=0 will be searched using simple case-insensitive string search.
              There are a few options to customize this, using these gen arguments:
              I<word_search>, I<case_insensitive_search>, and I<custom_search>.

        *   Filter arguments

              They will be generated for each field, except when field has 'filterable'
              clause set to false.

              Undef values will not match any filter, just like NULL in SQL.

        *   *FIELD.is* and *FIELD.isnt* arguments for each field. Only
            records with field equalling (or not equalling) value exactly
            ('==' or 'eq') will be included. If doesn't clash with other
            function arguments, *FIELD* will also be added as an alias for
            *FIELD.is*.

        *   *FIELD.has* and *FIELD.lacks* array arguments for each set
            field. Only records with field having or lacking certain value
            will be included.

        *   *FIELD.min* and *FIELD.max* for each int/float/str field. Only
            records with field greater/equal than, or less/equal than a
            certain value will be included.

        *   *FIELD.contains* and *FIELD.not_contains* for each str field.
            Only records with field containing (or not containing) certain
            value (substring) will be included.

        *   *FIELD.matches* and *FIELD.not_matches* for each str field. Only
            records with field matching (or not matching) certain value
            (regex) (or will be included. Function will return 400 if regex
            is invalid. These arguments will not be generated if
            'filterable_regex' clause in field specification is set to 0. }

    *   enable_search => *bool* (default: 1)

        {en_US Generate function (and its metadata) to read table data}.

        {en_US The generated function acts like a simple single table SQL
        SELECT query, featuring filtering, ordering, and paging, but using
        arguments as the 'query language'. The generated function is
        suitable for exposing a table data from an API function.

        The resulting function returns an array of results/records and
        accepts these arguments.

        *   *with_field_names* => BOOL (default 1)

              If set to 1, function will return records of field values along with field
              names (hashref), e.g. {id=>'ID', country=>'Indonesia', capital=>'Jakarta'}. If
              set to 0, then function will return record containing field values without
              field names (arrayref) instead, e.g.: ['ID', 'Indonesia', 'Jakarta'].

        *   *detail* => BOOL (default 0)

              This is a field selection option. If set to 0, function will return PK field
              only. If this argument is set to 1, then all fields will be returned (see also
              I<fields> to instruct function to return some fields only).

        *   *fields* => ARRAY

              This is a field selection option. If you only want certain fields, specify
              them here (see also I<detail>).

        *   *result_limit* => INT (default undef)

        *   *result_start* => INT (default 1)

              The I<result_limit> and I<result_start> arguments are paging options, they work
              like LIMIT clause in SQL, except that index starts at 1 and not 0. For
              example, to return the first 20 records in the result, set I<result_limit> to
              20 . To return the next 20 records, set I<result_limit> to 20 and
              I<result_start> to 21.

        *   *random* => BOOL (default 0)

              The random argument is an ordering option. If set to true, order of records
              returned will be shuffled first. This happened before paging.

        *   *sort* => STR

              The sort argument is an ordering option, containing name of field. A - prefix
              signifies descending instead of ascending order. Multiple fields are allowed,
              separated by comma.

        *   *q* => STR

              A filtering option. By default, all fields except those specified with
              searchable=0 will be searched using simple case-insensitive string search.
              There are a few options to customize this, using these gen arguments:
              I<word_search>, I<case_insensitive_search>, and I<custom_search>.

        *   Filter arguments

              They will be generated for each field, except when field has 'filterable'
              clause set to false.

              Undef values will not match any filter, just like NULL in SQL.

        *   *FIELD.is* and *FIELD.isnt* arguments for each field. Only
            records with field equalling (or not equalling) value exactly
            ('==' or 'eq') will be included. If doesn't clash with other
            function arguments, *FIELD* will also be added as an alias for
            *FIELD.is*.

        *   *FIELD.has* and *FIELD.lacks* array arguments for each set
            field. Only records with field having or lacking certain value
            will be included.

        *   *FIELD.min* and *FIELD.max* for each int/float/str field. Only
            records with field greater/equal than, or less/equal than a
            certain value will be included.

        *   *FIELD.contains* and *FIELD.not_contains* for each str field.
            Only records with field containing (or not containing) certain
            value (substring) will be included.

        *   *FIELD.matches* and *FIELD.not_matches* for each str field. Only
            records with field matching (or not matching) certain value
            (regex) (or will be included. Function will return 400 if regex
            is invalid. These arguments will not be generated if
            'filterable_regex' clause in field specification is set to 0. }

    *   hooks => *hash*

        {en_US Generate function (and its metadata) to read table data}.

        {en_US The generated function acts like a simple single table SQL
        SELECT query, featuring filtering, ordering, and paging, but using
        arguments as the 'query language'. The generated function is
        suitable for exposing a table data from an API function.

        The resulting function returns an array of results/records and
        accepts these arguments.

        *   *with_field_names* => BOOL (default 1)

              If set to 1, function will return records of field values along with field
              names (hashref), e.g. {id=>'ID', country=>'Indonesia', capital=>'Jakarta'}. If
              set to 0, then function will return record containing field values without
              field names (arrayref) instead, e.g.: ['ID', 'Indonesia', 'Jakarta'].

        *   *detail* => BOOL (default 0)

              This is a field selection option. If set to 0, function will return PK field
              only. If this argument is set to 1, then all fields will be returned (see also
              I<fields> to instruct function to return some fields only).

        *   *fields* => ARRAY

              This is a field selection option. If you only want certain fields, specify
              them here (see also I<detail>).

        *   *result_limit* => INT (default undef)

        *   *result_start* => INT (default 1)

              The I<result_limit> and I<result_start> arguments are paging options, they work
              like LIMIT clause in SQL, except that index starts at 1 and not 0. For
              example, to return the first 20 records in the result, set I<result_limit> to
              20 . To return the next 20 records, set I<result_limit> to 20 and
              I<result_start> to 21.

        *   *random* => BOOL (default 0)

              The random argument is an ordering option. If set to true, order of records
              returned will be shuffled first. This happened before paging.

        *   *sort* => STR

              The sort argument is an ordering option, containing name of field. A - prefix
              signifies descending instead of ascending order. Multiple fields are allowed,
              separated by comma.

        *   *q* => STR

              A filtering option. By default, all fields except those specified with
              searchable=0 will be searched using simple case-insensitive string search.
              There are a few options to customize this, using these gen arguments:
              I<word_search>, I<case_insensitive_search>, and I<custom_search>.

        *   Filter arguments

              They will be generated for each field, except when field has 'filterable'
              clause set to false.

              Undef values will not match any filter, just like NULL in SQL.

        *   *FIELD.is* and *FIELD.isnt* arguments for each field. Only
            records with field equalling (or not equalling) value exactly
            ('==' or 'eq') will be included. If doesn't clash with other
            function arguments, *FIELD* will also be added as an alias for
            *FIELD.is*.

        *   *FIELD.has* and *FIELD.lacks* array arguments for each set
            field. Only records with field having or lacking certain value
            will be included.

        *   *FIELD.min* and *FIELD.max* for each int/float/str field. Only
            records with field greater/equal than, or less/equal than a
            certain value will be included.

        *   *FIELD.contains* and *FIELD.not_contains* for each str field.
            Only records with field containing (or not containing) certain
            value (substring) will be included.

        *   *FIELD.matches* and *FIELD.not_matches* for each str field. Only
            records with field matching (or not matching) certain value
            (regex) (or will be included. Function will return 400 if regex
            is invalid. These arguments will not be generated if
            'filterable_regex' clause in field specification is set to 0. }

    *   install => *bool* (default: 1)

        {en_US Generate function (and its metadata) to read table data}.

        {en_US The generated function acts like a simple single table SQL
        SELECT query, featuring filtering, ordering, and paging, but using
        arguments as the 'query language'. The generated function is
        suitable for exposing a table data from an API function.

        The resulting function returns an array of results/records and
        accepts these arguments.

        *   *with_field_names* => BOOL (default 1)

              If set to 1, function will return records of field values along with field
              names (hashref), e.g. {id=>'ID', country=>'Indonesia', capital=>'Jakarta'}. If
              set to 0, then function will return record containing field values without
              field names (arrayref) instead, e.g.: ['ID', 'Indonesia', 'Jakarta'].

        *   *detail* => BOOL (default 0)

              This is a field selection option. If set to 0, function will return PK field
              only. If this argument is set to 1, then all fields will be returned (see also
              I<fields> to instruct function to return some fields only).

        *   *fields* => ARRAY

              This is a field selection option. If you only want certain fields, specify
              them here (see also I<detail>).

        *   *result_limit* => INT (default undef)

        *   *result_start* => INT (default 1)

              The I<result_limit> and I<result_start> arguments are paging options, they work
              like LIMIT clause in SQL, except that index starts at 1 and not 0. For
              example, to return the first 20 records in the result, set I<result_limit> to
              20 . To return the next 20 records, set I<result_limit> to 20 and
              I<result_start> to 21.

        *   *random* => BOOL (default 0)

              The random argument is an ordering option. If set to true, order of records
              returned will be shuffled first. This happened before paging.

        *   *sort* => STR

              The sort argument is an ordering option, containing name of field. A - prefix
              signifies descending instead of ascending order. Multiple fields are allowed,
              separated by comma.

        *   *q* => STR

              A filtering option. By default, all fields except those specified with
              searchable=0 will be searched using simple case-insensitive string search.
              There are a few options to customize this, using these gen arguments:
              I<word_search>, I<case_insensitive_search>, and I<custom_search>.

        *   Filter arguments

              They will be generated for each field, except when field has 'filterable'
              clause set to false.

              Undef values will not match any filter, just like NULL in SQL.

        *   *FIELD.is* and *FIELD.isnt* arguments for each field. Only
            records with field equalling (or not equalling) value exactly
            ('==' or 'eq') will be included. If doesn't clash with other
            function arguments, *FIELD* will also be added as an alias for
            *FIELD.is*.

        *   *FIELD.has* and *FIELD.lacks* array arguments for each set
            field. Only records with field having or lacking certain value
            will be included.

        *   *FIELD.min* and *FIELD.max* for each int/float/str field. Only
            records with field greater/equal than, or less/equal than a
            certain value will be included.

        *   *FIELD.contains* and *FIELD.not_contains* for each str field.
            Only records with field containing (or not containing) certain
            value (substring) will be included.

        *   *FIELD.matches* and *FIELD.not_matches* for each str field. Only
            records with field matching (or not matching) certain value
            (regex) (or will be included. Function will return 400 if regex
            is invalid. These arguments will not be generated if
            'filterable_regex' clause in field specification is set to 0. }

    *   langs => *array* (default: ["en_US"])

        {en_US Generate function (and its metadata) to read table data}.

        {en_US The generated function acts like a simple single table SQL
        SELECT query, featuring filtering, ordering, and paging, but using
        arguments as the 'query language'. The generated function is
        suitable for exposing a table data from an API function.

        The resulting function returns an array of results/records and
        accepts these arguments.

        *   *with_field_names* => BOOL (default 1)

              If set to 1, function will return records of field values along with field
              names (hashref), e.g. {id=>'ID', country=>'Indonesia', capital=>'Jakarta'}. If
              set to 0, then function will return record containing field values without
              field names (arrayref) instead, e.g.: ['ID', 'Indonesia', 'Jakarta'].

        *   *detail* => BOOL (default 0)

              This is a field selection option. If set to 0, function will return PK field
              only. If this argument is set to 1, then all fields will be returned (see also
              I<fields> to instruct function to return some fields only).

        *   *fields* => ARRAY

              This is a field selection option. If you only want certain fields, specify
              them here (see also I<detail>).

        *   *result_limit* => INT (default undef)

        *   *result_start* => INT (default 1)

              The I<result_limit> and I<result_start> arguments are paging options, they work
              like LIMIT clause in SQL, except that index starts at 1 and not 0. For
              example, to return the first 20 records in the result, set I<result_limit> to
              20 . To return the next 20 records, set I<result_limit> to 20 and
              I<result_start> to 21.

        *   *random* => BOOL (default 0)

              The random argument is an ordering option. If set to true, order of records
              returned will be shuffled first. This happened before paging.

        *   *sort* => STR

              The sort argument is an ordering option, containing name of field. A - prefix
              signifies descending instead of ascending order. Multiple fields are allowed,
              separated by comma.

        *   *q* => STR

              A filtering option. By default, all fields except those specified with
              searchable=0 will be searched using simple case-insensitive string search.
              There are a few options to customize this, using these gen arguments:
              I<word_search>, I<case_insensitive_search>, and I<custom_search>.

        *   Filter arguments

              They will be generated for each field, except when field has 'filterable'
              clause set to false.

              Undef values will not match any filter, just like NULL in SQL.

        *   *FIELD.is* and *FIELD.isnt* arguments for each field. Only
            records with field equalling (or not equalling) value exactly
            ('==' or 'eq') will be included. If doesn't clash with other
            function arguments, *FIELD* will also be added as an alias for
            *FIELD.is*.

        *   *FIELD.has* and *FIELD.lacks* array arguments for each set
            field. Only records with field having or lacking certain value
            will be included.

        *   *FIELD.min* and *FIELD.max* for each int/float/str field. Only
            records with field greater/equal than, or less/equal than a
            certain value will be included.

        *   *FIELD.contains* and *FIELD.not_contains* for each str field.
            Only records with field containing (or not containing) certain
            value (substring) will be included.

        *   *FIELD.matches* and *FIELD.not_matches* for each str field. Only
            records with field matching (or not matching) certain value
            (regex) (or will be included. Function will return 400 if regex
            is invalid. These arguments will not be generated if
            'filterable_regex' clause in field specification is set to 0. }

    *   name* => *str*

        {en_US Generate function (and its metadata) to read table data}.

        {en_US The generated function acts like a simple single table SQL
        SELECT query, featuring filtering, ordering, and paging, but using
        arguments as the 'query language'. The generated function is
        suitable for exposing a table data from an API function.

        The resulting function returns an array of results/records and
        accepts these arguments.

        *   *with_field_names* => BOOL (default 1)

              If set to 1, function will return records of field values along with field
              names (hashref), e.g. {id=>'ID', country=>'Indonesia', capital=>'Jakarta'}. If
              set to 0, then function will return record containing field values without
              field names (arrayref) instead, e.g.: ['ID', 'Indonesia', 'Jakarta'].

        *   *detail* => BOOL (default 0)

              This is a field selection option. If set to 0, function will return PK field
              only. If this argument is set to 1, then all fields will be returned (see also
              I<fields> to instruct function to return some fields only).

        *   *fields* => ARRAY

              This is a field selection option. If you only want certain fields, specify
              them here (see also I<detail>).

        *   *result_limit* => INT (default undef)

        *   *result_start* => INT (default 1)

              The I<result_limit> and I<result_start> arguments are paging options, they work
              like LIMIT clause in SQL, except that index starts at 1 and not 0. For
              example, to return the first 20 records in the result, set I<result_limit> to
              20 . To return the next 20 records, set I<result_limit> to 20 and
              I<result_start> to 21.

        *   *random* => BOOL (default 0)

              The random argument is an ordering option. If set to true, order of records
              returned will be shuffled first. This happened before paging.

        *   *sort* => STR

              The sort argument is an ordering option, containing name of field. A - prefix
              signifies descending instead of ascending order. Multiple fields are allowed,
              separated by comma.

        *   *q* => STR

              A filtering option. By default, all fields except those specified with
              searchable=0 will be searched using simple case-insensitive string search.
              There are a few options to customize this, using these gen arguments:
              I<word_search>, I<case_insensitive_search>, and I<custom_search>.

        *   Filter arguments

              They will be generated for each field, except when field has 'filterable'
              clause set to false.

              Undef values will not match any filter, just like NULL in SQL.

        *   *FIELD.is* and *FIELD.isnt* arguments for each field. Only
            records with field equalling (or not equalling) value exactly
            ('==' or 'eq') will be included. If doesn't clash with other
            function arguments, *FIELD* will also be added as an alias for
            *FIELD.is*.

        *   *FIELD.has* and *FIELD.lacks* array arguments for each set
            field. Only records with field having or lacking certain value
            will be included.

        *   *FIELD.min* and *FIELD.max* for each int/float/str field. Only
            records with field greater/equal than, or less/equal than a
            certain value will be included.

        *   *FIELD.contains* and *FIELD.not_contains* for each str field.
            Only records with field containing (or not containing) certain
            value (substring) will be included.

        *   *FIELD.matches* and *FIELD.not_matches* for each str field. Only
            records with field matching (or not matching) certain value
            (regex) (or will be included. Function will return 400 if regex
            is invalid. These arguments will not be generated if
            'filterable_regex' clause in field specification is set to 0. }

    *   package => *str*

        {en_US Generate function (and its metadata) to read table data}.

        {en_US The generated function acts like a simple single table SQL
        SELECT query, featuring filtering, ordering, and paging, but using
        arguments as the 'query language'. The generated function is
        suitable for exposing a table data from an API function.

        The resulting function returns an array of results/records and
        accepts these arguments.

        *   *with_field_names* => BOOL (default 1)

              If set to 1, function will return records of field values along with field
              names (hashref), e.g. {id=>'ID', country=>'Indonesia', capital=>'Jakarta'}. If
              set to 0, then function will return record containing field values without
              field names (arrayref) instead, e.g.: ['ID', 'Indonesia', 'Jakarta'].

        *   *detail* => BOOL (default 0)

              This is a field selection option. If set to 0, function will return PK field
              only. If this argument is set to 1, then all fields will be returned (see also
              I<fields> to instruct function to return some fields only).

        *   *fields* => ARRAY

              This is a field selection option. If you only want certain fields, specify
              them here (see also I<detail>).

        *   *result_limit* => INT (default undef)

        *   *result_start* => INT (default 1)

              The I<result_limit> and I<result_start> arguments are paging options, they work
              like LIMIT clause in SQL, except that index starts at 1 and not 0. For
              example, to return the first 20 records in the result, set I<result_limit> to
              20 . To return the next 20 records, set I<result_limit> to 20 and
              I<result_start> to 21.

        *   *random* => BOOL (default 0)

              The random argument is an ordering option. If set to true, order of records
              returned will be shuffled first. This happened before paging.

        *   *sort* => STR

              The sort argument is an ordering option, containing name of field. A - prefix
              signifies descending instead of ascending order. Multiple fields are allowed,
              separated by comma.

        *   *q* => STR

              A filtering option. By default, all fields except those specified with
              searchable=0 will be searched using simple case-insensitive string search.
              There are a few options to customize this, using these gen arguments:
              I<word_search>, I<case_insensitive_search>, and I<custom_search>.

        *   Filter arguments

              They will be generated for each field, except when field has 'filterable'
              clause set to false.

              Undef values will not match any filter, just like NULL in SQL.

        *   *FIELD.is* and *FIELD.isnt* arguments for each field. Only
            records with field equalling (or not equalling) value exactly
            ('==' or 'eq') will be included. If doesn't clash with other
            function arguments, *FIELD* will also be added as an alias for
            *FIELD.is*.

        *   *FIELD.has* and *FIELD.lacks* array arguments for each set
            field. Only records with field having or lacking certain value
            will be included.

        *   *FIELD.min* and *FIELD.max* for each int/float/str field. Only
            records with field greater/equal than, or less/equal than a
            certain value will be included.

        *   *FIELD.contains* and *FIELD.not_contains* for each str field.
            Only records with field containing (or not containing) certain
            value (substring) will be included.

        *   *FIELD.matches* and *FIELD.not_matches* for each str field. Only
            records with field matching (or not matching) certain value
            (regex) (or will be included. Function will return 400 if regex
            is invalid. These arguments will not be generated if
            'filterable_regex' clause in field specification is set to 0. }

    *   summary => *str*

        {en_US Generate function (and its metadata) to read table data}.

        {en_US The generated function acts like a simple single table SQL
        SELECT query, featuring filtering, ordering, and paging, but using
        arguments as the 'query language'. The generated function is
        suitable for exposing a table data from an API function.

        The resulting function returns an array of results/records and
        accepts these arguments.

        *   *with_field_names* => BOOL (default 1)

              If set to 1, function will return records of field values along with field
              names (hashref), e.g. {id=>'ID', country=>'Indonesia', capital=>'Jakarta'}. If
              set to 0, then function will return record containing field values without
              field names (arrayref) instead, e.g.: ['ID', 'Indonesia', 'Jakarta'].

        *   *detail* => BOOL (default 0)

              This is a field selection option. If set to 0, function will return PK field
              only. If this argument is set to 1, then all fields will be returned (see also
              I<fields> to instruct function to return some fields only).

        *   *fields* => ARRAY

              This is a field selection option. If you only want certain fields, specify
              them here (see also I<detail>).

        *   *result_limit* => INT (default undef)

        *   *result_start* => INT (default 1)

              The I<result_limit> and I<result_start> arguments are paging options, they work
              like LIMIT clause in SQL, except that index starts at 1 and not 0. For
              example, to return the first 20 records in the result, set I<result_limit> to
              20 . To return the next 20 records, set I<result_limit> to 20 and
              I<result_start> to 21.

        *   *random* => BOOL (default 0)

              The random argument is an ordering option. If set to true, order of records
              returned will be shuffled first. This happened before paging.

        *   *sort* => STR

              The sort argument is an ordering option, containing name of field. A - prefix
              signifies descending instead of ascending order. Multiple fields are allowed,
              separated by comma.

        *   *q* => STR

              A filtering option. By default, all fields except those specified with
              searchable=0 will be searched using simple case-insensitive string search.
              There are a few options to customize this, using these gen arguments:
              I<word_search>, I<case_insensitive_search>, and I<custom_search>.

        *   Filter arguments

              They will be generated for each field, except when field has 'filterable'
              clause set to false.

              Undef values will not match any filter, just like NULL in SQL.

        *   *FIELD.is* and *FIELD.isnt* arguments for each field. Only
            records with field equalling (or not equalling) value exactly
            ('==' or 'eq') will be included. If doesn't clash with other
            function arguments, *FIELD* will also be added as an alias for
            *FIELD.is*.

        *   *FIELD.has* and *FIELD.lacks* array arguments for each set
            field. Only records with field having or lacking certain value
            will be included.

        *   *FIELD.min* and *FIELD.max* for each int/float/str field. Only
            records with field greater/equal than, or less/equal than a
            certain value will be included.

        *   *FIELD.contains* and *FIELD.not_contains* for each str field.
            Only records with field containing (or not containing) certain
            value (substring) will be included.

        *   *FIELD.matches* and *FIELD.not_matches* for each str field. Only
            records with field matching (or not matching) certain value
            (regex) (or will be included. Function will return 400 if regex
            is invalid. These arguments will not be generated if
            'filterable_regex' clause in field specification is set to 0. }

    *   table_data* => *any*

        {en_US Generate function (and its metadata) to read table data}.

        {en_US The generated function acts like a simple single table SQL
        SELECT query, featuring filtering, ordering, and paging, but using
        arguments as the 'query language'. The generated function is
        suitable for exposing a table data from an API function.

        The resulting function returns an array of results/records and
        accepts these arguments.

        *   *with_field_names* => BOOL (default 1)

              If set to 1, function will return records of field values along with field
              names (hashref), e.g. {id=>'ID', country=>'Indonesia', capital=>'Jakarta'}. If
              set to 0, then function will return record containing field values without
              field names (arrayref) instead, e.g.: ['ID', 'Indonesia', 'Jakarta'].

        *   *detail* => BOOL (default 0)

              This is a field selection option. If set to 0, function will return PK field
              only. If this argument is set to 1, then all fields will be returned (see also
              I<fields> to instruct function to return some fields only).

        *   *fields* => ARRAY

              This is a field selection option. If you only want certain fields, specify
              them here (see also I<detail>).

        *   *result_limit* => INT (default undef)

        *   *result_start* => INT (default 1)

              The I<result_limit> and I<result_start> arguments are paging options, they work
              like LIMIT clause in SQL, except that index starts at 1 and not 0. For
              example, to return the first 20 records in the result, set I<result_limit> to
              20 . To return the next 20 records, set I<result_limit> to 20 and
              I<result_start> to 21.

        *   *random* => BOOL (default 0)

              The random argument is an ordering option. If set to true, order of records
              returned will be shuffled first. This happened before paging.

        *   *sort* => STR

              The sort argument is an ordering option, containing name of field. A - prefix
              signifies descending instead of ascending order. Multiple fields are allowed,
              separated by comma.

        *   *q* => STR

              A filtering option. By default, all fields except those specified with
              searchable=0 will be searched using simple case-insensitive string search.
              There are a few options to customize this, using these gen arguments:
              I<word_search>, I<case_insensitive_search>, and I<custom_search>.

        *   Filter arguments

              They will be generated for each field, except when field has 'filterable'
              clause set to false.

              Undef values will not match any filter, just like NULL in SQL.

        *   *FIELD.is* and *FIELD.isnt* arguments for each field. Only
            records with field equalling (or not equalling) value exactly
            ('==' or 'eq') will be included. If doesn't clash with other
            function arguments, *FIELD* will also be added as an alias for
            *FIELD.is*.

        *   *FIELD.has* and *FIELD.lacks* array arguments for each set
            field. Only records with field having or lacking certain value
            will be included.

        *   *FIELD.min* and *FIELD.max* for each int/float/str field. Only
            records with field greater/equal than, or less/equal than a
            certain value will be included.

        *   *FIELD.contains* and *FIELD.not_contains* for each str field.
            Only records with field containing (or not containing) certain
            value (substring) will be included.

        *   *FIELD.matches* and *FIELD.not_matches* for each str field. Only
            records with field matching (or not matching) certain value
            (regex) (or will be included. Function will return 400 if regex
            is invalid. These arguments will not be generated if
            'filterable_regex' clause in field specification is set to 0. }

    *   table_spec* => *hash*

        {en_US Generate function (and its metadata) to read table data}.

        {en_US The generated function acts like a simple single table SQL
        SELECT query, featuring filtering, ordering, and paging, but using
        arguments as the 'query language'. The generated function is
        suitable for exposing a table data from an API function.

        The resulting function returns an array of results/records and
        accepts these arguments.

        *   *with_field_names* => BOOL (default 1)

              If set to 1, function will return records of field values along with field
              names (hashref), e.g. {id=>'ID', country=>'Indonesia', capital=>'Jakarta'}. If
              set to 0, then function will return record containing field values without
              field names (arrayref) instead, e.g.: ['ID', 'Indonesia', 'Jakarta'].

        *   *detail* => BOOL (default 0)

              This is a field selection option. If set to 0, function will return PK field
              only. If this argument is set to 1, then all fields will be returned (see also
              I<fields> to instruct function to return some fields only).

        *   *fields* => ARRAY

              This is a field selection option. If you only want certain fields, specify
              them here (see also I<detail>).

        *   *result_limit* => INT (default undef)

        *   *result_start* => INT (default 1)

              The I<result_limit> and I<result_start> arguments are paging options, they work
              like LIMIT clause in SQL, except that index starts at 1 and not 0. For
              example, to return the first 20 records in the result, set I<result_limit> to
              20 . To return the next 20 records, set I<result_limit> to 20 and
              I<result_start> to 21.

        *   *random* => BOOL (default 0)

              The random argument is an ordering option. If set to true, order of records
              returned will be shuffled first. This happened before paging.

        *   *sort* => STR

              The sort argument is an ordering option, containing name of field. A - prefix
              signifies descending instead of ascending order. Multiple fields are allowed,
              separated by comma.

        *   *q* => STR

              A filtering option. By default, all fields except those specified with
              searchable=0 will be searched using simple case-insensitive string search.
              There are a few options to customize this, using these gen arguments:
              I<word_search>, I<case_insensitive_search>, and I<custom_search>.

        *   Filter arguments

              They will be generated for each field, except when field has 'filterable'
              clause set to false.

              Undef values will not match any filter, just like NULL in SQL.

        *   *FIELD.is* and *FIELD.isnt* arguments for each field. Only
            records with field equalling (or not equalling) value exactly
            ('==' or 'eq') will be included. If doesn't clash with other
            function arguments, *FIELD* will also be added as an alias for
            *FIELD.is*.

        *   *FIELD.has* and *FIELD.lacks* array arguments for each set
            field. Only records with field having or lacking certain value
            will be included.

        *   *FIELD.min* and *FIELD.max* for each int/float/str field. Only
            records with field greater/equal than, or less/equal than a
            certain value will be included.

        *   *FIELD.contains* and *FIELD.not_contains* for each str field.
            Only records with field containing (or not containing) certain
            value (substring) will be included.

        *   *FIELD.matches* and *FIELD.not_matches* for each str field. Only
            records with field matching (or not matching) certain value
            (regex) (or will be included. Function will return 400 if regex
            is invalid. These arguments will not be generated if
            'filterable_regex' clause in field specification is set to 0. }

    *   word_search => *bool* (default: 0)

        {en_US Generate function (and its metadata) to read table data}.

        {en_US The generated function acts like a simple single table SQL
        SELECT query, featuring filtering, ordering, and paging, but using
        arguments as the 'query language'. The generated function is
        suitable for exposing a table data from an API function.

        The resulting function returns an array of results/records and
        accepts these arguments.

        *   *with_field_names* => BOOL (default 1)

              If set to 1, function will return records of field values along with field
              names (hashref), e.g. {id=>'ID', country=>'Indonesia', capital=>'Jakarta'}. If
              set to 0, then function will return record containing field values without
              field names (arrayref) instead, e.g.: ['ID', 'Indonesia', 'Jakarta'].

        *   *detail* => BOOL (default 0)

              This is a field selection option. If set to 0, function will return PK field
              only. If this argument is set to 1, then all fields will be returned (see also
              I<fields> to instruct function to return some fields only).

        *   *fields* => ARRAY

              This is a field selection option. If you only want certain fields, specify
              them here (see also I<detail>).

        *   *result_limit* => INT (default undef)

        *   *result_start* => INT (default 1)

              The I<result_limit> and I<result_start> arguments are paging options, they work
              like LIMIT clause in SQL, except that index starts at 1 and not 0. For
              example, to return the first 20 records in the result, set I<result_limit> to
              20 . To return the next 20 records, set I<result_limit> to 20 and
              I<result_start> to 21.

        *   *random* => BOOL (default 0)

              The random argument is an ordering option. If set to true, order of records
              returned will be shuffled first. This happened before paging.

        *   *sort* => STR

              The sort argument is an ordering option, containing name of field. A - prefix
              signifies descending instead of ascending order. Multiple fields are allowed,
              separated by comma.

        *   *q* => STR

              A filtering option. By default, all fields except those specified with
              searchable=0 will be searched using simple case-insensitive string search.
              There are a few options to customize this, using these gen arguments:
              I<word_search>, I<case_insensitive_search>, and I<custom_search>.

        *   Filter arguments

              They will be generated for each field, except when field has 'filterable'
              clause set to false.

              Undef values will not match any filter, just like NULL in SQL.

        *   *FIELD.is* and *FIELD.isnt* arguments for each field. Only
            records with field equalling (or not equalling) value exactly
            ('==' or 'eq') will be included. If doesn't clash with other
            function arguments, *FIELD* will also be added as an alias for
            *FIELD.is*.

        *   *FIELD.has* and *FIELD.lacks* array arguments for each set
            field. Only records with field having or lacking certain value
            will be included.

        *   *FIELD.min* and *FIELD.max* for each int/float/str field. Only
            records with field greater/equal than, or less/equal than a
            certain value will be included.

        *   *FIELD.contains* and *FIELD.not_contains* for each str field.
            Only records with field containing (or not containing) certain
            value (substring) will be included.

        *   *FIELD.matches* and *FIELD.not_matches* for each str field. Only
            records with field matching (or not matching) certain value
            (regex) (or will be included. Function will return 400 if regex
            is invalid. These arguments will not be generated if
            'filterable_regex' clause in field specification is set to 0. }

    Return value:

    Returns an enveloped result (an array). First element (status) is an
    integer containing HTTP status code (200 means OK, 4xx caller error, 5xx
    function error). Second element (msg) is a string containing error
    message, or 'OK' if status is 200. Third element (result) is optional,
    the actual result. Fourth element (meta) is called result metadata and
    is optional, a hash that contains extra information.

CAVEATS
    It is often not a good idea to expose your database schema directly as
    API.

FAQ
  I want my function to accept additional arguments.
    You can add arguments to the metadata by yourself, e.g.:

     our %SPEC;
     gen_read_table_func(name => 'myfunc', ...);
     $SPEC{myfunc}{args}{add1} = {...};

    As for the implementation, you can specify hooks to do things with the
    extra arguments.

SEE ALSO
    Rinci

    Perinci::CmdLine

HOMEPAGE
    Please visit the project's homepage at
    <https://metacpan.org/release/Perinci-Sub-Gen-AccessTable>.

SOURCE
    Source repository is at
    <https://github.com/sharyanto/perl-Perinci-Sub-Gen-AccessTable>.

BUGS
    Please report any bugs or feature requests on the bugtracker website
    <https://rt.cpan.org/Public/Dist/Display.html?Name=Perinci-Sub-Gen-Acces
    sTable>

    When submitting a bug or request, please include a test-file or a patch
    to an existing test-file that illustrates the bug or desired feature.

AUTHOR
    Steven Haryanto <stevenharyanto@gmail.com>

COPYRIGHT AND LICENSE
    This software is copyright (c) 2013 by Steven Haryanto.

    This is free software; you can redistribute it and/or modify it under
    the same terms as the Perl 5 programming language system itself.

