MarcoPolo - command()

This function executes a query or command on the database.

Sending Commands

OrientDB SQL differentiates between idempotent queries (such as SELECT and non-idempotent commands, such as INSERT. The MarcoPolo Elixir API does not make this distinction, providing this function for use with both queries and commands..

Syntax

command(<conn>, <query>, <opts>)
  • <conn> Defines the database connection.
  • <query> Defines the query or command you want to execute.
  • <opts> Defines additional options to set on the command. For more information, see options below.

Options

When issuing queries or commands using this function, there are a series of additional options available to you to further define how MarcoPolo performs the operation.

  • :params Defines a map of parameters for OrientDB to use in building prepared statements. The map must use atoms or strings as keys, but can take any encodable term as values.

    It defaults to #{}

  • :timeout Defines the timeout value in milliseconds. In the event that the query takes longer than the allotted time, MarcoPolo sends an exit signal to the calling process.

  • :fetch_plan Defines a fetch plan, which is only available when using this function with idempotent queries. It is a mandatory argument with fetch queries.

Return Values

When the query or command is successful it returns the tuple {:ok, values}. The values variable is a map with the following keys:

  • :response Provides the return value given by OrientDB. This varies depending the query. For instance, SELECT returns a list of records, CREATE CLUSTER returns the new cluster's Cluster ID.

  • :linked_records Provides a set of additional records fetched by OrientDB. The :fetch_plan option controls the number of records retrieved to this value.

In the event that the query or command fails, it returns the tuple {:error, term}. The term variable provides the error message.

Examples

Non-idempotent Commands

For instance, in cases where you find yourself making frequent insertions of a particular class, you might want to set up a function to streamline this process and to make it easier to insert a series of records through a single function call.

@doc """Inserts records from array into the given class"""
def insert_records(conn, class, properties, records) do

	# Log Operation
	IO.puts("Adding Records to #{class}")
	
	# Build Initial INSERT Statement
	joined_prop = Enum.join(properties, ",")
	insert = "INSERT INTO #{class} (#{joined_prop}) "

	# Loop over Given Records
	for record <- records do

		# Complete INSERT Statement
		data = Enum.join(record, ", ")
		sql = "#{insert} VALUES(#{data})"

		# Issue INSERT Statement
		MarcoPolo.command(conn, sql)

	end
end

Idempotent Queries

You might find yourself in similar situations when working with idempotent queries. For instance, if you frequently query the same class on the database with close or identical options passed to the query, you can save yourself some time by standardizing the process in a function.

@doc """ Retrieve User Profile """
def fetch_profile(conn, user) do

	# Log Operation
	IO.puts("Retrieving Profile for User ID: #{uid}"

	# Build SELECT Statement
	select = "SELECT FROM :class WHERE userId=':uid'"

	# Query Database
	options = [params: %{uid: user, class: "Profile"}, fetch_plan: "*:-1"]
	MarcoPolo.command(conn, select, options)
end