Skip to main content

src/gdo@connection.erl

-module(gdo@connection).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/gdo/connection.gleam").
-export([driver/1, sqlite/1, sqlite_config/1, server/6, no_authentication/0, username_and_password/2, disable_tls/0, prefer_tls/0, require_tls/0, with_option/3, config_driver/1, config_target/1, config_options/1, open/1, database/1, capabilities/1, target/1, options/1, in_transaction/1, 'begin'/1, commit/1, rollback/1, prepare/2, close/1, exec/3, query_one/3, query_all/3, query_one_as/4, query_all_as/4, last_insert_id/1]).
-export_type([connection_config/0, connection/0]).

-type connection_config() :: {connection_config,
        gdo@driver:driver(),
        gdo@driver:connection_target(),
        list({binary(), binary()})}.

-opaque connection() :: {connection,
        connection_config(),
        gdo@transaction:transaction_state(),
        gdo@driver:driver_contract(),
        gdo@driver:driver_connection_state()}.

-file("src/gdo/connection.gleam", 132).
-spec driver(connection()) -> gdo@driver:driver().
driver(Connection) ->
    {connection, Config, _, _, _} = Connection,
    {connection_config, Driver, _, _} = Config,
    Driver.

-file("src/gdo/connection.gleam", 30).
-spec sqlite(binary()) -> connection_config().
sqlite(Database) ->
    {connection_config, sqlite, {embedded_database, Database}, []}.

-file("src/gdo/connection.gleam", 38).
-spec sqlite_config(binary()) -> connection_config().
sqlite_config(Database) ->
    sqlite(Database).

-file("src/gdo/connection.gleam", 42).
-spec server(
    gdo@driver:driver(),
    binary(),
    integer(),
    binary(),
    gdo@driver:authentication(),
    gdo@driver:transport_security()
) -> connection_config().
server(Current_driver, Host, Port, Database, Authentication, Tls) ->
    {connection_config,
        Current_driver,
        {server_database,
            {network_endpoint, Host, Port, Database, Authentication, Tls}},
        []}.

-file("src/gdo/connection.gleam", 63).
-spec no_authentication() -> gdo@driver:authentication().
no_authentication() ->
    no_authentication.

-file("src/gdo/connection.gleam", 67).
-spec username_and_password(binary(), binary()) -> gdo@driver:authentication().
username_and_password(Username, Password) ->
    {username_and_password, Username, Password}.

-file("src/gdo/connection.gleam", 74).
-spec disable_tls() -> gdo@driver:transport_security().
disable_tls() ->
    disable_tls.

-file("src/gdo/connection.gleam", 78).
-spec prefer_tls() -> gdo@driver:transport_security().
prefer_tls() ->
    prefer_tls.

-file("src/gdo/connection.gleam", 82).
-spec require_tls() -> gdo@driver:transport_security().
require_tls() ->
    require_tls.

-file("src/gdo/connection.gleam", 86).
-spec with_option(connection_config(), binary(), binary()) -> connection_config().
with_option(Config, Key, Value) ->
    {connection_config, Driver, Target, Options} = Config,
    {connection_config, Driver, Target, [{Key, Value} | Options]}.

-file("src/gdo/connection.gleam", 95).
-spec config_driver(connection_config()) -> gdo@driver:driver().
config_driver(Config) ->
    {connection_config, Driver, _, _} = Config,
    Driver.

-file("src/gdo/connection.gleam", 100).
-spec config_target(connection_config()) -> gdo@driver:connection_target().
config_target(Config) ->
    {connection_config, _, Target, _} = Config,
    Target.

-file("src/gdo/connection.gleam", 105).
-spec config_options(connection_config()) -> list({binary(), binary()}).
config_options(Config) ->
    {connection_config, _, _, Options} = Config,
    Options.

-file("src/gdo/connection.gleam", 352).
-spec validate_authentication(gdo@driver:authentication()) -> {ok, nil} |
    {error, gdo@error:error()}.
validate_authentication(Authentication) ->
    case Authentication of
        no_authentication ->
            {ok, nil};

        {username_and_password, Username, _} ->
            case gleam@string:is_empty(gleam@string:trim(Username)) of
                true ->
                    {error,
                        {invalid_configuration,
                            <<"Username cannot be empty."/utf8>>}};

                false ->
                    {ok, nil}
            end
    end.

-file("src/gdo/connection.gleam", 327).
-spec validate_network_endpoint(gdo@driver:network_endpoint()) -> {ok, nil} |
    {error, gdo@error:error()}.
validate_network_endpoint(Network) ->
    {network_endpoint, Host, Port, Database, Authentication, _} = Network,
    case gleam@string:is_empty(gleam@string:trim(Host)) of
        true ->
            {error, {invalid_configuration, <<"Host cannot be empty."/utf8>>}};

        false ->
            case Port =< 0 of
                true ->
                    {error,
                        {invalid_configuration,
                            <<"Port must be greater than zero."/utf8>>}};

                false ->
                    case gleam@string:is_empty(gleam@string:trim(Database)) of
                        true ->
                            {error,
                                {invalid_configuration,
                                    <<"Database cannot be empty."/utf8>>}};

                        false ->
                            validate_authentication(Authentication)
                    end
            end
    end.

-file("src/gdo/connection.gleam", 315).
-spec validate_target(gdo@driver:connection_target()) -> {ok, nil} |
    {error, gdo@error:error()}.
validate_target(Target) ->
    case Target of
        {embedded_database, Path} ->
            case gleam@string:is_empty(gleam@string:trim(Path)) of
                true ->
                    {error,
                        {invalid_configuration,
                            <<"Database cannot be empty."/utf8>>}};

                false ->
                    {ok, nil}
            end;

        {server_database, Network} ->
            validate_network_endpoint(Network)
    end.

-file("src/gdo/connection.gleam", 110).
-spec open(connection_config()) -> {ok, connection()} |
    {error, gdo@error:error()}.
open(Config) ->
    {connection_config, Current_driver, Target, _} = Config,
    case validate_target(Target) of
        {ok, _} ->
            Contract = gdo@driver@registry:contract(Current_driver),
            case gdo@driver:connect(Contract, Target) of
                {ok, Connection_state} ->
                    {ok, {connection, Config, idle, Contract, Connection_state}};

                {error, Error} ->
                    {error, Error}
            end;

        {error, Error@1} ->
            {error, Error@1}
    end.

-file("src/gdo/connection.gleam", 138).
-spec database(connection()) -> binary().
database(Connection) ->
    {connection, Config, _, _, _} = Connection,
    {connection_config, _, Target, _} = Config,
    gdo@driver:identifier(Target).

-file("src/gdo/connection.gleam", 144).
-spec capabilities(connection()) -> list(gdo@driver:capability()).
capabilities(Connection) ->
    gdo@driver:capabilities(driver(Connection)).

-file("src/gdo/connection.gleam", 148).
-spec target(connection()) -> gdo@driver:connection_target().
target(Connection) ->
    {connection, Config, _, _, _} = Connection,
    {connection_config, _, Target, _} = Config,
    Target.

-file("src/gdo/connection.gleam", 154).
-spec options(connection()) -> list({binary(), binary()}).
options(Connection) ->
    {connection, Config, _, _, _} = Connection,
    {connection_config, _, _, Options} = Config,
    Options.

-file("src/gdo/connection.gleam", 160).
-spec in_transaction(connection()) -> boolean().
in_transaction(Connection) ->
    {connection, _, Transaction_state, _, _} = Connection,
    gdo@transaction:is_active(Transaction_state).

-file("src/gdo/connection.gleam", 165).
-spec 'begin'(connection()) -> {ok, connection()} | {error, gdo@error:error()}.
'begin'(Connection) ->
    {connection, Config, Transaction_state, Contract, Connection_state} = Connection,
    case gdo@transaction:'begin'(Transaction_state) of
        {ok, Next_state} ->
            case gdo@driver:'begin'(Contract, Connection_state) of
                {ok, Next_connection_state} ->
                    {ok,
                        {connection,
                            Config,
                            Next_state,
                            Contract,
                            Next_connection_state}};

                {error, Error} ->
                    {error, Error}
            end;

        {error, Error@1} ->
            {error, Error@1}
    end.

-file("src/gdo/connection.gleam", 185).
-spec commit(connection()) -> {ok, connection()} | {error, gdo@error:error()}.
commit(Connection) ->
    {connection, Config, Transaction_state, Contract, Connection_state} = Connection,
    case gdo@transaction:commit(Transaction_state) of
        {ok, Next_state} ->
            case gdo@driver:commit(Contract, Connection_state) of
                {ok, Next_connection_state} ->
                    {ok,
                        {connection,
                            Config,
                            Next_state,
                            Contract,
                            Next_connection_state}};

                {error, Error} ->
                    {error, Error}
            end;

        {error, Error@1} ->
            {error, Error@1}
    end.

-file("src/gdo/connection.gleam", 205).
-spec rollback(connection()) -> {ok, connection()} | {error, gdo@error:error()}.
rollback(Connection) ->
    {connection, Config, Transaction_state, Contract, Connection_state} = Connection,
    case gdo@transaction:rollback(Transaction_state) of
        {ok, Next_state} ->
            case gdo@driver:rollback(Contract, Connection_state) of
                {ok, Next_connection_state} ->
                    {ok,
                        {connection,
                            Config,
                            Next_state,
                            Contract,
                            Next_connection_state}};

                {error, Error} ->
                    {error, Error}
            end;

        {error, Error@1} ->
            {error, Error@1}
    end.

-file("src/gdo/connection.gleam", 225).
-spec prepare(connection(), binary()) -> {ok, gdo@statement:statement()} |
    {error, gdo@error:error()}.
prepare(Connection, Sql) ->
    {connection, _, _, Contract, Connection_state} = Connection,
    case gdo@statement:prepare(Sql) of
        {ok, Prepared_statement} ->
            case gdo@driver:prepare(
                Contract,
                Connection_state,
                gdo@statement:sql(Prepared_statement)
            ) of
                {ok, Statement_state} ->
                    {ok,
                        gdo@statement:bind(
                            Prepared_statement,
                            Contract,
                            Statement_state
                        )};

                {error, Error} ->
                    {error, Error}
            end;

        {error, Error@1} ->
            {error, Error@1}
    end.

-file("src/gdo/connection.gleam", 248).
-spec close(connection()) -> {ok, nil} | {error, gdo@error:error()}.
close(Connection) ->
    {connection, _, _, Contract, Connection_state} = Connection,
    gdo@driver:close(Contract, Connection_state).

-file("src/gdo/connection.gleam", 253).
-spec exec(connection(), binary(), list(gdo@value:param())) -> {ok,
        gdo@result:execution_result()} |
    {error, gdo@error:error()}.
exec(Connection, Sql, Params) ->
    case prepare(Connection, Sql) of
        {ok, Prepared} ->
            gdo@statement:exec(Prepared, Params);

        {error, Error} ->
            {error, Error}
    end.

-file("src/gdo/connection.gleam", 264).
-spec query_one(connection(), binary(), list(gdo@value:param())) -> {ok,
        gleam@option:option(gdo@row:row())} |
    {error, gdo@error:error()}.
query_one(Connection, Sql, Params) ->
    case prepare(Connection, Sql) of
        {ok, Prepared} ->
            gdo@statement:query_one(Prepared, Params);

        {error, Error} ->
            {error, Error}
    end.

-file("src/gdo/connection.gleam", 275).
-spec query_all(connection(), binary(), list(gdo@value:param())) -> {ok,
        gdo@result:query_result()} |
    {error, gdo@error:error()}.
query_all(Connection, Sql, Params) ->
    case prepare(Connection, Sql) of
        {ok, Prepared} ->
            gdo@statement:query_all(Prepared, Params);

        {error, Error} ->
            {error, Error}
    end.

-file("src/gdo/connection.gleam", 286).
-spec query_one_as(
    connection(),
    binary(),
    list(gdo@value:param()),
    fun((gdo@row:row()) -> {ok, LVE} | {error, gdo@error:error()})
) -> {ok, gleam@option:option(LVE)} | {error, gdo@error:error()}.
query_one_as(Connection, Sql, Params, Decoder) ->
    case prepare(Connection, Sql) of
        {ok, Prepared} ->
            gdo@statement:query_one_as(Prepared, Params, Decoder);

        {error, Error} ->
            {error, Error}
    end.

-file("src/gdo/connection.gleam", 298).
-spec query_all_as(
    connection(),
    binary(),
    list(gdo@value:param()),
    fun((gdo@row:row()) -> {ok, LVK} | {error, gdo@error:error()})
) -> {ok, list(LVK)} | {error, gdo@error:error()}.
query_all_as(Connection, Sql, Params, Decoder) ->
    case prepare(Connection, Sql) of
        {ok, Prepared} ->
            gdo@statement:query_all_as(Prepared, Params, Decoder);

        {error, Error} ->
            {error, Error}
    end.

-file("src/gdo/connection.gleam", 310).
-spec last_insert_id(connection()) -> gleam@option:option(integer()).
last_insert_id(Connection) ->
    {connection, _, _, Contract, Connection_state} = Connection,
    gdo@driver:last_insert_id(Contract, Connection_state).