V Client Library

Install/Update

Install or update to the latest with:

v install elliotchance.vsql

Example

import elliotchance.vsql.vsql

fn example() ! {
  mut db := vsql.open('test.vsql') !

  // All SQL commands use query():
  db.query('CREATE TABLE foo (x DOUBLE PRECISION)') !
  db.query('INSERT INTO foo (x) VALUES (1.23)') !
  db.query('INSERT INTO foo (x) VALUES (4.56)') !

  // Iterate through a result:
  result := db.query('SELECT * FROM foo') !
  println(result.columns)

  for row in result {
      println(row.get_f64('X') !)
  }

  // See SQLSTATE (Errors) below for more examples.
}

Outputs:

['A']
1.23
4.56

V Module: vsql

Constants

pub const default_schema_name = 'PUBLIC'

fn catalog_name_from_path

pub fn catalog_name_from_path(path string) string

fn default_connection_options

pub fn default_connection_options() ConnectionOptions

default_connection_options returns the sensible defaults used by open() and the correct base to provide your own option overrides. See ConnectionOptions.

fn new_benchmark

pub fn new_benchmark(conn &Connection) Benchmark

fn new_bigint_value

pub fn new_bigint_value(x i64) Value

new_bigint_value creates a BIGINT value.

fn new_boolean_value

pub fn new_boolean_value(b bool) Value

new_boolean_value creates a TRUE or FALSE value. For UNKNOWN (the BOOLEAN equivilent of NULL) you will need to use new_unknown_value.

fn new_character_value

pub fn new_character_value(x string) Value

new_character_value creates a CHARACTER value. The size is determined from the length of the string itself.

fn new_date_value

pub fn new_date_value(ts string) !Value

new_date_value creates a DATE value.

fn new_decimal_value

pub fn new_decimal_value(x string) Value

new_decimal_value expects a value to be valid and the size and scale are determined from the value as:

123 -> DECIMAL(3, 0) 123. -> DECIMAL(3, 0) 1.23 -> DECIMAL(3, 2) -1.23 -> DECIMAL(3, 2) 12.00 -> DECIMAL(4, 2)

fn new_double_precision_value

pub fn new_double_precision_value(x f64) Value

new_double_precision_value creates a DOUBLE PRECISION value.

fn new_integer_value

pub fn new_integer_value(x int) Value

new_integer_value creates an INTEGER value.

fn new_null_value

pub fn new_null_value(typ SQLType) Value

new_null_value creates a NULL value of a specific type. In SQL, all NULL values need to have a type.

fn new_numeric_value

pub fn new_numeric_value(x string) Value

new_numeric_value expects a value to be valid and the size and scale are determined from the value as:

123 -> NUMERIC(3, 0) 123. -> NUMERIC(3, 0) 1.23 -> NUMERIC(3, 2) -1.23 -> NUMERIC(3, 2) 12.00 -> NUMERIC(4, 2)

fn new_query_cache

pub fn new_query_cache() &QueryCache

Create a new query cache.

fn new_real_value

pub fn new_real_value(x f32) Value

new_real_value creates a REAL value.

fn new_result

pub fn new_result(columns Columns, rows []Row, elapsed_parse time.Duration, elapsed_exec time.Duration) Result

fn new_server

pub fn new_server(options ServerOptions) Server

fn new_smallint_value

pub fn new_smallint_value(x i16) Value

new_smallint_value creates a SMALLINT value.

fn new_time_value

pub fn new_time_value(ts string) !Value

new_time_value creates a TIME value.

fn new_timestamp_value

pub fn new_timestamp_value(ts string) !Value

new_timestamp_value creates a TIMESTAMP value.

fn new_unknown_value

pub fn new_unknown_value() Value

new_unknown_value returns an UNKNOWN value. This is the NULL representation of BOOLEAN.

fn new_varchar_value

pub fn new_varchar_value(x string) Value

new_varchar_value creates a CHARACTER VARYING value.

fn open

pub fn open(path string) !&Connection

open is the convenience function for open_database() with default options.

fn open_database

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

pub fn pluralize(n int, word string) string

TODO(elliotchance): Make private when CLI is moved into vsql package.

fn sqlstate_from_int

pub fn sqlstate_from_int(code int) string

sqlstate_from_int performs the inverse operation of sqlstate_to_int.

fn sqlstate_to_int

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

pub fn start_timer() Timer

type Column

type Row

type Server

enum Boolean

pub enum Boolean {
     // These must not be negative values because they are encoded as u8 on disk.
     // 0 is resevered for encoding NULL on disk, but is not a valid value in
     // memory.
     is_false = 1
     is_true  = 2
}

Possible values for a BOOLEAN.

struct Benchmark

pub struct Benchmark {
pub mut:
     conn         &Connection
     account_rows int
     teller_rows  int
     branch_rows  int
     run_for      time.Duration
}

struct CatalogConnection

@[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

@[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

pub struct ConnectionOptions {
pub mut:
     // query_cache contains the precompiled prepared statements that can be
     // reused. This makes execution much faster as parsing the SQL is extremely
     // expensive.
     //
     // By default each connection will be given its own query cache. However,
     // you can safely share a single cache over multiple connections and you are
     // encouraged to do so.
     query_cache &QueryCache = unsafe { nil }
     // Warning: This only works for :memory: databases. Configuring it for
     // file-based databases will either be ignored or causes crashes.
     page_size int
     // In short, vsql (with default options) when dealing with concurrent
     // read/write access to single file provides the following protections:
     //
     // - Fine: Multiple processes open() the same file.
     //
     // - Fine: Multiple goroutines sharing an open() on the same file.
     //
     // - Bad: Multiple goroutines open() the same file.
     //
     // The mutex option will protect against the third Bad case if you
     // provide the same mutex instance to all open() calls:
     //
     //   mutex := sync.new_rwmutex() // only create one of these
     //
     //   mut options := default_connection_options()
     //   options.mutex = mutex
     //
     // Since locking all database isn't ideal. You could provide a consistent
     // RwMutex that belongs to each file - such as from a map.
     mutex &sync.RwMutex = unsafe { nil }
}

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

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

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

pub struct PreparedStmt {
     stmt Stmt
     // params can be set on the statement and will be merged with the extra
     // params at execution time. If name collisions occur, the params provided
     // at execution time will take precedence.
     params map[string]Value
     // explain is true if the query was prefixed with EXPLAIN. The EXPLAIN is
     // removed from the query before parsing since this keyword is not part of
     // the SQL standard.
     explain bool
mut:
     c             &Connection
     elapsed_parse time.Duration
}

A prepared statement is compiled and validated, but not executed. It can then be executed with a set of host parameters to be substituted into the statement. Each invocation requires all host parameters to be passed in.

struct QueryCache

@[heap]
pub struct QueryCache {
mut:
     stmts map[string]Stmt
}

A QueryCache improves the performance of parsing by caching previously cached statements. By default, a new QueryCache is created for each Connection. However, you can share a single QueryCache safely amung multiple connections for even better performance. See ConnectionOptions.

struct Result

pub struct Result {
     // rows is not public because in the future this may end up being a cursor.
     // You should use V iteration to read the rows.
     rows []Row
pub:
     // The columns provided for each row (even if there are zero rows.)
     columns []Column
     // The time it took to parse/compile the query before running it.
     elapsed_parse time.Duration
     // The time is took to execute the query.
     elapsed_exec time.Duration
mut:
     idx int
}

A Result contains zero or more rows returned from a query.

See next() for an example on iterating rows in a Result.

struct Schema

pub struct Schema {
     // The tid is the transaction ID that created this table.
     tid int
pub:
     // The name of the schema is case-sensitive.
     name string
}

Represents a schema.

struct Sequence

pub struct Sequence {
mut:
     // The tid is the transaction ID that created this table.
     tid int
pub mut:
     // name contains the other parts such as the schema.
     name Identifier
     // current_value is the current value before it is incremented by
     // "NEXT VALUE FOR".
     current_value i64
     // increment_by is added for each next value and defaults to 1.
     increment_by i64
     // cycle allows the sequence to repeat once MAXVALUE is reached. By default it
     // is not enabled.
     cycle bool
     // has_min_value is true when a MINVALUE is set.
     has_min_value bool
     // min_value is the smallest inclusive value allowed for the sequence. The
     // MINVALUE is optional.
     min_value i64
     // has_max_value is true when a MAXVALUE is set.
     has_max_value bool
     // max_value is the largest inclusive value allowed for the sequence. The
     // MAXVALUE is optional.
     max_value i64
}

A SEQUENCE definition.

struct ServerOptions

pub struct ServerOptions {
pub:
     db_file string
     port    int
     verbose bool
}

struct Table

pub struct Table {
mut:
     // The tid is the transaction ID that created this table.
     tid int
pub mut:
     // The name of the table including the schema.
     name Identifier
     // The column definitions for the table.
     columns Columns
     // If the table has a PRIMARY KEY defined the column (or columns) will be
     // defined here in order.
     primary_key []string
     // When the table is virtual it is not persisted to disk.
     is_virtual bool
}

Represents the structure of a table.

struct Time

pub struct Time {
pub mut:
     // typ.size is the precision (0 to 6)
     typ Type
     // Number of minutes from 00:00 (positive or negative)
     time_zone i16
     // Internal V time represenation.
     t time.Time
}

Time is the internal way that time is represented and provides other conversions such as to/from storage and to/from V’s native time.Time.

struct Timer

pub struct Timer {
     started_at time.Time
}

struct Value

pub struct Value {
pub mut:
     // TODO(elliotchance): Make these non-mutable.
     // The type of this Value.
     typ Type
     // Used by all types (including those that have NULL built in like BOOLEAN).
     is_null bool
     // v packs the actual value. You need to use one of the methods to get the
     // actual value safely.
     v InternalValue
}

A single value. It contains it’s type information in typ.

struct VirtualTable

pub struct VirtualTable {
     create_table_sql  string
     create_table_stmt TableDefinition
     data              VirtualTableProviderFn @[required]
mut:
     is_done bool
     rows    []Row
}