Skip to content
Snippets Groups Projects
Select Git revision
  • 513cb88d77ba697dece424130ce6d399a6f0d14f
  • main default protected
  • f-jdk-update
  • f-overview
  • f-linkahead-rename
  • dev protected
  • f-remote-path
  • f-full-ak-uploadFile
  • f-pipeline-test
  • f-cxx-include
  • cxxwrap-bugreport
  • v0.0.5
  • v0.0.4
  • v0.0.3
  • v0.0.2
15 results

Transaction.jl

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    Transaction.jl 14.82 KiB
    # ** header v3.0
    # This file is a part of the CaosDB Project.
    #
    # Copyright (C) 2021 Indiscale GmbH <info@indiscale.com>
    # Copyright (C) 2021 Florian Spreckelsen <f.spreckelsen@indiscale.com>
    #
    # This program is free software: you can redistribute it and/or modify
    # it under the terms of the GNU Affero General Public License as
    # published by the Free Software Foundation, either version 3 of the
    # License, or (at your option) any later version.
    #
    # This program is distributed in the hope that it will be useful, but
    # WITHOUT ANY WARRANTY; without even the implied warranty of
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    # Affero General Public License for more details.
    #
    # You should have received a copy of the GNU Affero General Public
    # License along with this program. If not, see
    # <https://www.gnu.org/licenses/>.
    #
    # ** end header
    #
    
    module Transaction
    
    export create_transaction,
        add_retrieve_by_id,
        add_query,
        add_insert_entity,
        add_update_entity,
        add_delete_by_id,
        add_retrieve_and_download_file_by_id,
        execute,
        get_result_set,
        get_count_result,
        get_result_at,
        get_results,
        execute_query,
        retrieve
    
    using CaosDB
    
    """
    Struct containing a pointer to the wrapped cpp transaction
    object. Meant for internal use; call
    `CaosDB.Transaction.create_transaction` to create a transaction
    object.
    """
    mutable struct _Transaction
        wrapped_transaction::Ptr{Cvoid}
        _deletable::Bool
        function _Transaction(managed_by_julia::Bool = false)
            trans = new()
            trans._deletable = false
            if managed_by_julia
                function f(t)
                    ccall(
                        (:caosdb_transaction_delete_transaction, CaosDB.library_name),
                        Cint,
                        (Ref{_Transaction},),
                        Ref{_Transaction}(t),
                    )
                end
                finalizer(f, trans)
            end
            return trans
        end
    end
    
    """
    Struct containing a pointer to the wrapped cpp result set of a
    transaction. The struct is meant for internal use only and shouldn't
    be created directly by the user but is returned by, e.g.,
    `get_result_set`.
    """
    mutable struct _ResultSet
        wrapped_result_set::Ptr{Cvoid}
        _deletable::Bool
    
        function _ResultSet()
            rs = new()
            rs._deletable = false
            return rs
        end
    end
    
    """
        create_transaction(name::AbstractString = "default")
    
    Return a transaction created with the connection of the given name. If
    none is given, the defult connection is used.
    """
    function create_transaction(name::AbstractString = "default")
        connection = CaosDB.Connection.get_connection(name)
    
        return create_transaction(connection)
    end
    
    """
        function create_transaction(connection::Ref{CaosDB.Connection._Connection})
    
    Return a transactioncreated with the given connection object.
    """
    function create_transaction(connection::Ref{CaosDB.Connection._Connection})
    
        transaction = Ref{_Transaction}(_Transaction(true))
    
        err_code = ccall(
            (:caosdb_connection_connection_create_transaction, CaosDB.library_name),
            Cint,
            (Ref{CaosDB.Connection._Connection}, Ref{_Transaction}),
            connection,
            transaction,
        )
    
        CaosDB.Exceptions.evaluate_return_code(err_code)
    
        return transaction
    end
    
    """
        function add_retrieve_by_id(transaction::Ref{_Transaction}, id::AbstractString)
    
    Add a sub-request to retrieve a single entity by its `id` to the given
    `transaction`.
    
    !!! info
    
        This does not execute the transaction.
    """
    function add_retrieve_by_id(transaction::Ref{_Transaction}, id::AbstractString)
    
        err_code = ccall(
            (:caosdb_transaction_transaction_retrieve_by_id, CaosDB.library_name),
            Cint,
            (Ref{_Transaction}, Cstring),
            transaction,
            id,
        )
    
        CaosDB.Exceptions.evaluate_return_code(err_code)
    end
    
    """
        function add_insert_entity(transaction::Ref{_Transaction}, entity::Ref{_CaosDB.Entity.Entity})
    
    Add a sub-request to insert a single entity to the given `transaction`.
    
    !!! info
    
        This does not execute the transaction.
    """
    function add_insert_entity(
        transaction::Ref{_Transaction},
        entity::Ref{CaosDB.Entity._Entity},
    )
    
        err_code = ccall(
            (:caosdb_transaction_transaction_insert_entity, CaosDB.library_name),
            Cint,
            (Ref{_Transaction}, Ref{CaosDB.Entity._Entity}),
            transaction,
            entity,
        )
    
        CaosDB.Exceptions.evaluate_return_code(err_code)
    end
    """
        function add_update_entity(transaction::Ref{_Transaction}, entity::Ref{_CaosDB.Entity.Entity})
    
    Add a sub-request to update a single entity to the given `transaction`.
    
    !!! info
    
        This does not execute the transaction.
    """
    function add_update_entity(
        transaction::Ref{_Transaction},
        entity::Ref{CaosDB.Entity._Entity},
    )
    
        err_code = ccall(
            (:caosdb_transaction_transaction_update_entity, CaosDB.library_name),
            Cint,
            (Ref{_Transaction}, Ref{CaosDB.Entity._Entity}),
            transaction,
            entity,
        )
    
        CaosDB.Exceptions.evaluate_return_code(err_code)
    end
    """
        function add_delete_by_id(transaction::Ref{_Transaction}, id::AbstractString)
    
    Add a sub-request to delete a single entity to the given `transaction`.
    
    !!! info
    
        This does not execute the transaction.
    """
    function add_delete_by_id(transaction::Ref{_Transaction}, id::AbstractString)
    
        err_code = ccall(
            (:caosdb_transaction_transaction_delete_by_id, CaosDB.library_name),
            Cint,
            (Ref{_Transaction}, Cstring),
            transaction,
            id,
        )
    
        CaosDB.Exceptions.evaluate_return_code(err_code)
    end
    
    """
        function add_retrieve_by_id(
            transaction::Ref{_Transaction},
            ids::Vector{T},
        ) where {T<:AbstractString}
    
    Add a sub-request to retrieve several entities by their `ids` to the
    given `transaction`.
    
    !!! info
    
        This does not execute the transaction.
    """
    function add_retrieve_by_id(
        transaction::Ref{_Transaction},
        ids::Vector{T},
    ) where {T<:AbstractString}
    
        len = Cint(length(ids))
        err_code = ccall(
            (:caosdb_transaction_transaction_retrieve_by_ids, CaosDB.library_name),
            Cint,
            (Ref{_Transaction}, Ptr{Ptr{Cchar}}, Cint),
            transaction,
            ids,
            len,
        )
    
        CaosDB.Exceptions.evaluate_return_code(err_code)
    end
    
    """
        function add_retrieve_and_download_file_by_id(
            transaction::Ref{_Transaction},
            id::AbstractString,
            path::AbstractString,
        )
    
    Add a sub-request to retrieve and download a single entity (File) to the given `transaction`.
    
    !!! info
    
        This does not execute the transaction.
    """
    function add_retrieve_and_download_file_by_id(
        transaction::Ref{_Transaction},
        id::AbstractString,
        path::AbstractString,
    )
    
        err_code = ccall(
            (
                :caosdb_transaction_transaction_retrieve_and_download_file_by_id,
                CaosDB.library_name,
            ),
            Cint,
            (Ref{_Transaction}, Cstring, Cstring),
            transaction,
            id,
            path,
        )
    
        CaosDB.Exceptions.evaluate_return_code(err_code)
    end
    
    
    """
        function add_query(transaction::Ref{_Transaction}, query::AbstractString)
    
    Add a query sub-request to the given `transaction`.
    
    !!! warning
    
        Only COUNT queris and FIND queries (and no SELECT queries) are
        currently supported.
    
    !!! info
    
        This does not execute the transaction
    """
    function add_query(transaction::Ref{_Transaction}, query::AbstractString)
    
        err_code = ccall(
            (:caosdb_transaction_transaction_query, CaosDB.library_name),
            Cint,
            (Ref{_Transaction}, Cstring),
            transaction,
            query,
        )
    
        CaosDB.Exceptions.evaluate_return_code(err_code)
    end
    
    """
        function execute(transaction::Ref{_Transaction})
    
    Send the given `transaction` to the CaosDB server for excecution and
    wait for it to finish.
    """
    function execute(transaction::Ref{_Transaction})
    
        err_code = ccall(
            (:caosdb_transaction_transaction_execute, CaosDB.library_name),
            Cint,
            (Ref{_Transaction},),
            transaction,
        )
    
        CaosDB.Exceptions.evaluate_return_code(err_code)
    end
    
    """
        function get_result_set(transaction::Ref{_Transaction})
    
    Return the result set of the given `transaction`.
    """
    function get_result_set(transaction::Ref{_Transaction})
    
        results = Ref{_ResultSet}(_ResultSet())
    
        err_code = ccall(
            (:caosdb_transaction_transaction_get_result_set, CaosDB.library_name),
            Cint,
            (Ref{_Transaction}, Ref{_ResultSet}),
            transaction,
            results,
        )
    
        CaosDB.Exceptions.evaluate_return_code(err_code)
    
        return results
    end
    
    """
        function get_count_result(transaction::Ref{_Transaction})
    
    Return the number of results of the COUNT query in the given `transaction`.
    
    !!! info
    
        This is only a meaningful quantity if there actually was a COUNT
        query in the `transaction`, and it already has been executed. In
        all other cases the return value will be -1.
    """
    function get_count_result(transaction::Ref{_Transaction})
    
        out = Ref{Clong}(0)
    
        err_code = ccall(
            (:caosdb_transaction_transaction_get_count_result, CaosDB.library_name),
            Cint,
            (Ref{_Transaction}, Ref{Clong}),
            transaction,
            out,
        )
    
        CaosDB.Exceptions.evaluate_return_code(err_code)
    
        return out[]
    end
    
    """
        function get_result_size(results::Ref{_ResultSet})
    
    Return the size of the given `results`, i.e., the number of entities
    or other responses returned in this result set.
    """
    function get_result_size(results::Ref{_ResultSet})
    
        size = Ref{Cint}(0)
    
        err_code = ccall(
            (:caosdb_transaction_result_set_size, CaosDB.library_name),
            Cint,
            (Ref{_ResultSet}, Ref{Cint}),
            results,
            size,
        )
    
        CaosDB.Exceptions.evaluate_return_code(err_code)
    
        return size[]
    end
    
    """
        function get_result_at(results::Ref{_ResultSet}, index::Cint)
    
    Return the entity at position `index` of the given `results`.
    """
    function get_result_at(results::Ref{_ResultSet}, index::Cint)
    
        size = get_result_size(results)
    
        if index > size
            throw(
                DomainError(
                    index,
                    "You tried to access the result at position $index but the result set only has $size results.",
                ),
            )
        end
    
        entity = Ref{CaosDB.Entity._Entity}(CaosDB.Entity._Entity())
    
        err_code = ccall(
            (:caosdb_transaction_result_set_at, CaosDB.library_name),
            Cint,
            (Ref{_ResultSet}, Ref{CaosDB.Entity._Entity}, Cint),
            results,
            entity,
            index - Cint(1),
        )
    
        CaosDB.Exceptions.evaluate_return_code(err_code)
    
        return entity
    end
    
    """
        function get_result_at(results::Ref{_ResultSet}, index::Integer)
    
    Convenience wrapper for `get_result_at(::Ref{_ResultSet},
    ::Cint)`. Convert the given `index` to Int32 and return the result at
    position `index` of `results`.
    """
    function get_result_at(results::Ref{_ResultSet}, index::Integer)
    
        return get_result_at(results, Cint(index))
    end
    
    """
        function get_results(result_set::Ref{_ResultSet})
    
    Return al  results of the given `result_set`.
    """
    function get_results(result_set::Ref{_ResultSet})
    
        size = get_result_size(result_set)
    
        return [get_result_at(result_set, Cint(ii)) for ii = 1:size]
    end
    
    """
        function get_results(transaction::Ref{_Transaction})
    
    Return all results of the given `transaction`.
    """
    function get_results(transaction::Ref{_Transaction})
    
        result_set = get_result_set(transaction)
    
        return get_results(result_set)
    end
    
    """
        function execute_query(
            query::AbstractString,
            name::AbstractString = "default"
        )
    
    Execute the given `query` and return its results. Use the connection
    with the given `name`. If none is given, the default connection is
    used.
    
    !!! info
    
        Since only the resulting entities are returned, this only makes
        sense for FIND (and, in the future, SELECT) queries. To get the
        result of a `COUNT` query, you have to execute the transaction
        yourself using `create_transaction`, `add_query`, and `execute`,
        and get the result with `get_count_result`.
    """
    function execute_query(query::AbstractString, name::AbstractString = "default")
    
        transaction = create_transaction(name)
    
        add_query(transaction, query)
    
        execute(transaction)
    
        return get_results(transaction)
    end
    
    """
        function execute_query(
            query::AbstractString,
            connection::Ref{CaosDB.Connection._Connection}
        )
    
    Execute the given `query` and return its results. Use the given
    `connection`.
    
    !!! info
    
        Since only the resulting entities are returned, this only makes
        sense for FIND (and, in the future, SELECT) queries. To get the
        result of a `COUNT` query, you have to execute the transaction
        yourself using `create_transaction`, `add_query`, and `execute`,
        and get the result with `get_count_result`.
    """
    function execute_query(
        query::AbstractString,
        connection::Ref{CaosDB.Connection._Connection},
    )
    
        transaction = create_transaction(connection)
    
        add_query(transaction, query)
    
        execute(transaction)
    
        return get_results(transaction)
    end
    
    """
        function retrieve(id::AbstractString, name::AbstractString = "default")
    
    Retrieve and return the entity with the given `id`. Use the connection
    with the given `name`. If none is provided, the default connection is
    used.
    """
    function retrieve(id::AbstractString, name::AbstractString = "default")
    
        transaction = create_transaction(name)
    
        add_retrieve_by_id(transaction, id)
    
        execute(transaction)
    
        return get_results(transaction)[1]
    end
    
    """
        function retrieve(id::AbstractString, connection::Ref{CaosDB.Connection._Connection})
    
    Retrieve and return the entity with the given `id`. Use the given
    `connection`.
    """
    function retrieve(id::AbstractString, connection::Ref{CaosDB.Connection._Connection})
    
        transaction = create_transaction(connection)
    
        add_retrieve_by_id(transaction, id)
    
        execute(transaction)
    
        return get_results(transaction)[1]
    end
    
    """
        function retrieve(
            ids::Vector{T},
            name::AbstractString = "default",
        ) where {T<:AbstractString}
    
    Retrieve and return the entities with the given `ids`. Use the
    connection of the given `name`. If none is provided, the default
    connection is used.
    """
    function retrieve(
        ids::Vector{T},
        name::AbstractString = "default",
    ) where {T<:AbstractString}
    
        transaction = create_transaction(name)
    
        add_retrieve_by_id(transaction, ids)
    
        execute(transaction)
    
        return get_results(transaction)
    end
    
    """
        function retrieve(
            ids::Vector{T},
            connection::Ref{CaosDB.Connection._Connection},
        ) where {T<:AbstractString}
    
    Retrieve and return the entities with the given `ids`. Use the given
    `connection`.
    """
    function retrieve(
        ids::Vector{T},
        connection::Ref{CaosDB.Connection._Connection},
    ) where {T<:AbstractString}
    
        transaction = create_transaction(connection)
    
        add_retrieve_by_id(transaction, ids)
    
        execute(transaction)
    
        return get_results(transaction)
    end
    
    end # Transaction