diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bf7f5fd..3740556 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,13 +20,12 @@ jobs: runs-on: macos-latest steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Set up V version latest - uses: nocturlab/setup-vlang-action@v1 + uses: vlang/setup-v@v1.4 with: - id: v - v-version: master + check-latest: true - name: Verify fmt run: make fmt-verify @@ -52,13 +51,12 @@ jobs: runs-on: macos-latest steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Set up V version latest - uses: nocturlab/setup-vlang-action@v1 + uses: vlang/setup-v@v1.4 with: - id: v - v-version: master + check-latest: true - name: Build macOS binaries run: | @@ -78,13 +76,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Set up V version latest - uses: nocturlab/setup-vlang-action@v1 + uses: vlang/setup-v@v1.4 with: - id: v - v-version: master + check-latest: true - name: Build linux binaries run: | @@ -107,13 +104,12 @@ jobs: runs-on: macos-latest steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Set up V version latest - uses: nocturlab/setup-vlang-action@v1 + uses: vlang/setup-v@v1.4 with: - id: v - v-version: master + check-latest: true - name: Build Windows binaries run: | diff --git a/Makefile b/Makefile index 649b96e..a194e11 100644 --- a/Makefile +++ b/Makefile @@ -82,10 +82,10 @@ test: oldv $(V) -stats $(BUILD_OPTIONS) $(PROD) test vsql btree-test: oldv - $(V) -stats $(BUILD_OPTIONS) $(PROD) test vsql/btree_test.v + $(V) -stats $(BUILD_OPTIONS) $(PROD) vsql/btree_test.v sql-test: oldv - $(V) -stats $(BUILD_OPTIONS) test vsql/sql_test.v + $(V) -stats $(BUILD_OPTIONS) vsql/sql_test.v # CLI Tests diff --git a/cmd/vsql/in.v b/cmd/vsql/in.v index ce8a34e..2fce7e9 100644 --- a/cmd/vsql/in.v +++ b/cmd/vsql/in.v @@ -42,7 +42,7 @@ fn in_command(cmd cli.Command) ! { mut stmt := '' for !f.eof() { mut buf := []u8{len: 100} - f.read_bytes_into_newline(mut buf) or { return err } + f.read_bytes_with_newline(mut buf) or { return err } line := buf.bytestr() stmt += line.trim_right('\0 \n;') diff --git a/docs/requirements.txt b/docs/requirements.txt index 9d1272d..483eb39 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,3 +1,3 @@ -sphinx==4.2.0 +sphinx==5.0.0 sphinx_rtd_theme==1.0.0 readthedocs-sphinx-search==0.1.1 diff --git a/docs/v-client-library-docs.rst b/docs/v-client-library-docs.rst index d4265f4..1a95ebe 100644 --- a/docs/v-client-library-docs.rst +++ b/docs/v-client-library-docs.rst @@ -13,16 +13,6 @@ Constants -fn open -------- - - -.. code-block:: v - - pub fn open(path string) !&Connection - -open is the convenience function for open_database() with default options. - fn catalog_name_from_path ------------------------- @@ -33,48 +23,6 @@ fn catalog_name_from_path -fn sqlstate_to_int ------------------- - - -.. code-block:: v - - pub fn sqlstate_to_int(code string) int - -sqlstate_to_int converts the 5 character SQLSTATE code (such as "42P01") into an integer representation. The returned value can be converted back to its respective string by using sqlstate_from_int(). - -If code is invalid the result will be unexpected. - -fn start_timer --------------- - - -.. code-block:: v - - pub fn start_timer() Timer - - - -fn sqlstate_from_int --------------------- - - -.. code-block:: v - - pub fn sqlstate_from_int(code int) string - -sqlstate_from_int performs the inverse operation of sqlstate_to_int. - -fn pluralize ------------- - - -.. code-block:: v - - pub fn pluralize(n int, word string) string - -TODO(elliotchance): Make private when CLI is moved into vsql package. - fn default_connection_options ----------------------------- @@ -85,30 +33,6 @@ fn default_connection_options default_connection_options returns the sensible defaults used by open() and the correct base to provide your own option overrides. See ConnectionOptions. -fn open_database ----------------- - - -.. code-block:: v - - pub fn open_database(path string, options ConnectionOptions) !&Connection - -open_database will open an existing database file or create a new file if the path does not exist. - -If the file does exist, open_database will assume that the file is a valid database file (not corrupt). Otherwise unexpected behavior or even a crash may occur. - -The special file name ":memory:" can be used to create an entirely in-memory database. This will be faster but all data will be lost when the connection is closed. - -open_database can be used concurrently for reading and writing to the same file and provides the following default protections: - -- Fine: Multiple processes open_database() the same file. - -- Fine: Multiple goroutines sharing an open_database() on the same file. - -- Bad: Multiple goroutines open_database() the same file. - -See ConnectionOptions and default_connection_options(). - fn new_benchmark ---------------- @@ -287,6 +211,16 @@ fn new_timestamp_value new_timestamp_value creates a ``TIMESTAMP`` value. +fn new_unknown_value +-------------------- + + +.. code-block:: v + + pub fn new_unknown_value() Value + +new_unknown_value returns an ``UNKNOWN`` value. This is the ``NULL`` representation of ``BOOLEAN``. + fn new_varchar_value -------------------- @@ -297,19 +231,79 @@ fn new_varchar_value new_varchar_value creates a ``CHARACTER VARYING`` value. -fn new_unknown_value +fn open +------- + + +.. code-block:: v + + pub fn open(path string) !&Connection + +open is the convenience function for open_database() with default options. + +fn open_database +---------------- + + +.. code-block:: v + + pub fn open_database(path string, options ConnectionOptions) !&Connection + +open_database will open an existing database file or create a new file if the path does not exist. + +If the file does exist, open_database will assume that the file is a valid database file (not corrupt). Otherwise unexpected behavior or even a crash may occur. + +The special file name ":memory:" can be used to create an entirely in-memory database. This will be faster but all data will be lost when the connection is closed. + +open_database can be used concurrently for reading and writing to the same file and provides the following default protections: + +- Fine: Multiple processes open_database() the same file. + +- Fine: Multiple goroutines sharing an open_database() on the same file. + +- Bad: Multiple goroutines open_database() the same file. + +See ConnectionOptions and default_connection_options(). + +fn pluralize +------------ + + +.. code-block:: v + + pub fn pluralize(n int, word string) string + +TODO(elliotchance): Make private when CLI is moved into vsql package. + +fn sqlstate_from_int -------------------- .. code-block:: v - pub fn new_unknown_value() Value + pub fn sqlstate_from_int(code int) string -new_unknown_value returns an ``UNKNOWN`` value. This is the ``NULL`` representation of ``BOOLEAN``. +sqlstate_from_int performs the inverse operation of sqlstate_to_int. -type Row --------- +fn sqlstate_to_int +------------------ + + +.. code-block:: v + + pub fn sqlstate_to_int(code string) int +sqlstate_to_int converts the 5 character SQLSTATE code (such as "42P01") into an integer representation. The returned value can be converted back to its respective string by using sqlstate_from_int(). + +If code is invalid the result will be unexpected. + +fn start_timer +-------------- + + +.. code-block:: v + + pub fn start_timer() Timer @@ -319,6 +313,12 @@ type Column +type Row +-------- + + + + type Server ----------- @@ -341,6 +341,88 @@ enum Boolean Possible values for a BOOLEAN. +struct Benchmark +---------------- + + +.. code-block:: v + + pub struct Benchmark { + pub mut: + conn &Connection + account_rows int + teller_rows int + branch_rows int + run_for time.Duration + } + + + +struct CatalogConnection +------------------------ + + +.. code-block:: v + + @[heap] + pub struct CatalogConnection { + // path is the file name of the database. It can be the special name + // ':memory:'. + path string + catalog_name string + mut: + // storage will be replaced when the file is reopend for reading or writing. + storage Storage + // options are used when aquiring each file connection. + options ConnectionOptions + // virtual_tables can be created independent from the physical schema. + virtual_tables map[string]VirtualTable + } + +A Connection allows querying and other introspection for a database file. Use open() or open_database() to create a Connection. + +struct Connection +----------------- + + +.. code-block:: v + + @[heap] + pub struct Connection { + mut: + catalogs map[string]&CatalogConnection + // funcs only needs to be initialized once on open() + funcs []Func + // query_cache is maintained over file reopens. + query_cache &QueryCache + // cast_rules are use for CAST() (see cast.v) + cast_rules map[string]CastFunc + // unary_operators and binary_operators are for operators (see operators.v) + unary_operators map[string]UnaryOperatorFunc + binary_operators map[string]BinaryOperatorFunc + // current_schema is where to search for unquailified table names. It will + // have an initial value of 'PUBLIC'. + current_schema string + // current_catalog (also known as the database). It will have an inital value + // derived from the first database file loaded. + current_catalog string + pub mut: + // now allows you to override the wall clock that is used. The Time must be + // in UTC with a separate offset for the current local timezone (in positive + // or negative minutes). + now fn () (time.Time, i16) @[required] + // warnings are SQLSTATE errors that do not stop the execution. For example, + // if a value must be truncated during a runtime CAST. + // + // Warnings are not ever reset, although only 100 of the most recent warnings + // are retained. This is to be able to collect all warnings during some + // arbitrary process defined by the application. Instead, you should call + // clear_warnings() before starting a block of work. + warnings []IError + } + +A Connection allows querying and other introspection for a database file. Use open() or open_database() to create a Connection. + struct ConnectionOptions ------------------------ @@ -384,6 +466,65 @@ struct ConnectionOptions ConnectionOptions can modify the behavior of a connection when it is opened. You should not create the ConnectionOptions instance manually. Instead, use default_connection_options() as a starting point and modify the attributes. +struct Identifier +----------------- + + +.. code-block:: v + + pub struct Identifier { + pub: + // catalog_name is optional. If not provided, the CURRENT_CATALOG will be + // used. + catalog_name string + // schema_name is optional. If not provided, it will use CURRENT_SCHEMA. + schema_name string + // entity_name would be the table name, sequence name, etc. Something inside + // of a schema. It is case sensitive. + entity_name string + // sub_entity_name would represent a column name. It is case sensitive. + sub_entity_name string + // custom_id is a way to override the behavior of rendering and storage. This + // is only used for internal identifiers. + custom_id string + custom_typ Type + } + +Identifier is used to describe a object within a schema (such as a table name) or a property of an object (like a column name of a table). You should not instantiate this directly, instead use the appropriate new_*_identifier() function. + +If you need the fully qualified (canonical) form of an identified you can use Connection.resolve_schema_identifier(). + +struct PageObject +----------------- + + +.. code-block:: v + + pub struct PageObject { + // The key is not required to be unique in the page. It becomes unique when + // combined with tid. However, no more than two version of the same key can + // exist in a page. See the caveats at the top of btree.v. + key []u8 + // The value contains the serialized data for the object. The first byte of + // key is used to both identify what type of object this is and also keep + // objects within the same collection also within the same range. + value []u8 + // When is_blob_ref is true, the value will be always be 5 bytes. See + // blob_info(). + is_blob_ref bool + mut: + // The tid is the transaction that created the object. + // + // TODO(elliotchance): It makes more sense to construct a new PageObject + // when changing the tid and xid. + tid int + // The xid is the transaciton that deleted the object, or zero if it has + // never been deleted. + xid int + } + +TODO(elliotchance): This does not need to be public. It was required for a bug at the time with V not being able to pass this to the shuffle function. At some point in the future remove the pub and see if it works. + struct PreparedStmt ------------------- @@ -446,23 +587,6 @@ A Result contains zero or more rows returned from a query. See next() for an example on iterating rows in a Result. -struct Benchmark ----------------- - - -.. code-block:: v - - pub struct Benchmark { - pub mut: - conn &Connection - account_rows int - teller_rows int - branch_rows int - run_for time.Duration - } - - - struct Schema ------------- @@ -514,23 +638,6 @@ struct Sequence A SEQUENCE definition. -struct VirtualTable -------------------- - - -.. code-block:: v - - pub struct VirtualTable { - create_table_sql string - create_table_stmt TableDefinition - data VirtualTableProviderFn @[required] - mut: - is_done bool - rows []Row - } - - - struct ServerOptions -------------------- @@ -538,6 +645,7 @@ struct ServerOptions .. code-block:: v pub struct ServerOptions { + pub: db_file string port int verbose bool @@ -545,71 +653,6 @@ struct ServerOptions -struct Connection ------------------ - - -.. code-block:: v - - @[heap] - pub struct Connection { - mut: - catalogs map[string]&CatalogConnection - // funcs only needs to be initialized once on open() - funcs []Func - // query_cache is maintained over file reopens. - query_cache &QueryCache - // cast_rules are use for CAST() (see cast.v) - cast_rules map[string]CastFunc - // unary_operators and binary_operators are for operators (see operators.v) - unary_operators map[string]UnaryOperatorFunc - binary_operators map[string]BinaryOperatorFunc - // current_schema is where to search for unquailified table names. It will - // have an initial value of 'PUBLIC'. - current_schema string - // current_catalog (also known as the database). It will have an inital value - // derived from the first database file loaded. - current_catalog string - pub mut: - // now allows you to override the wall clock that is used. The Time must be - // in UTC with a separate offset for the current local timezone (in positive - // or negative minutes). - now fn () (time.Time, i16) @[required] - // warnings are SQLSTATE errors that do not stop the execution. For example, - // if a value must be truncated during a runtime CAST. - // - // Warnings are not ever reset, although only 100 of the most recent warnings - // are retained. This is to be able to collect all warnings during some - // arbitrary process defined by the application. Instead, you should call - // clear_warnings() before starting a block of work. - warnings []IError - } - -A Connection allows querying and other introspection for a database file. Use open() or open_database() to create a Connection. - -struct CatalogConnection ------------------------- - - -.. code-block:: v - - @[heap] - pub struct CatalogConnection { - // path is the file name of the database. It can be the special name - // ':memory:'. - path string - catalog_name string - mut: - // storage will be replaced when the file is reopend for reading or writing. - storage Storage - // options are used when aquiring each file connection. - options ConnectionOptions - // virtual_tables can be created independent from the physical schema. - virtual_tables map[string]VirtualTable - } - -A Connection allows querying and other introspection for a database file. Use open() or open_database() to create a Connection. - struct Table ------------ @@ -684,62 +727,20 @@ struct Value A single value. It contains it's type information in ``typ``. -struct PageObject ------------------ +struct VirtualTable +------------------- .. code-block:: v - pub struct PageObject { - // The key is not required to be unique in the page. It becomes unique when - // combined with tid. However, no more than two version of the same key can - // exist in a page. See the caveats at the top of btree.v. - key []u8 - // The value contains the serialized data for the object. The first byte of - // key is used to both identify what type of object this is and also keep - // objects within the same collection also within the same range. - value []u8 - // When is_blob_ref is true, the value will be always be 5 bytes. See - // blob_info(). - is_blob_ref bool + pub struct VirtualTable { + create_table_sql string + create_table_stmt TableDefinition + data VirtualTableProviderFn @[required] mut: - // The tid is the transaction that created the object. - // - // TODO(elliotchance): It makes more sense to construct a new PageObject - // when changing the tid and xid. - tid int - // The xid is the transaciton that deleted the object, or zero if it has - // never been deleted. - xid int - } - -TODO(elliotchance): This does not need to be public. It was required for a bug at the time with V not being able to pass this to the shuffle function. At some point in the future remove the pub and see if it works. - -struct Identifier ------------------ - - -.. code-block:: v - - pub struct Identifier { - pub: - // catalog_name is optional. If not provided, the CURRENT_CATALOG will be - // used. - catalog_name string - // schema_name is optional. If not provided, it will use CURRENT_SCHEMA. - schema_name string - // entity_name would be the table name, sequence name, etc. Something inside - // of a schema. It is case sensitive. - entity_name string - // sub_entity_name would represent a column name. It is case sensitive. - sub_entity_name string - // custom_id is a way to override the behavior of rendering and storage. This - // is only used for internal identifiers. - custom_id string - custom_typ Type + is_done bool + rows []Row } -Identifier is used to describe a object within a schema (such as a table name) or a property of an object (like a column name of a table). You should not instantiate this directly, instead use the appropriate new_*_identifier() function. -If you need the fully qualified (canonical) form of an identified you can use Connection.resolve_schema_identifier(). diff --git a/vsql/numeric.v b/vsql/numeric.v index 498d353..16ed1c3 100644 --- a/vsql/numeric.v +++ b/vsql/numeric.v @@ -3,7 +3,6 @@ module vsql -import math import math.big import strings diff --git a/vsql/row.v b/vsql/row.v index db37c30..448b1fa 100644 --- a/vsql/row.v +++ b/vsql/row.v @@ -364,7 +364,7 @@ fn (mut r Row) object_key(t Table) ![]u8 { if r.id.len == 0 { // TODO(elliotchance): This is a terrible hack to make sure we have // a globally unique but also ordered id for the row. - unique_id := u64(time.now().unix_time_milli()) + unique_id := u64(time.now().unix_milli()) time.sleep(time.millisecond) mut buf := new_empty_bytes() diff --git a/vsql/server.v b/vsql/server.v index 6327c36..c1b75a9 100644 --- a/vsql/server.v +++ b/vsql/server.v @@ -12,6 +12,7 @@ mut: } pub struct ServerOptions { +pub: db_file string port int verbose bool diff --git a/vsql/sql_test.v b/vsql/sql_test.v index 4f0cd4b..415ca1e 100644 --- a/vsql/sql_test.v +++ b/vsql/sql_test.v @@ -176,7 +176,7 @@ fn run_single_test(test SQLTest, query_cache &QueryCache, verbose bool, filter_l mut db := open_database(':memory:', options)! db.now = fn () (time.Time, i16) { - return time.new_time(time.Time{ + return time.new(time.Time{ year: 2022 month: 7 day: 4 diff --git a/vsql/time.v b/vsql/time.v index e249ecf..de9874d 100644 --- a/vsql/time.v +++ b/vsql/time.v @@ -141,7 +141,7 @@ fn new_date_from_string(s string) !Time { } fn new_time_from_components(typ Type, year int, month int, day int, hour int, minute int, second int, microsecond int, time_zone i16) Time { - return Time{typ, time_zone, time.new_time(time.Time{ + return Time{typ, time_zone, time.new(time.Time{ year: year month: month day: day