MscmpSystDb.Types (mscmp_syst_db v0.1.0)

Defines public types for use with the MscmpSystDb module.

Summary

Types

The value type for names which describe a specific instance of an Application's Datastore Context.

The allowable Datastore Context name registration options.

The database role name for the specific access context defined by the context_name().

The extended naming value of a Datastore Context for use when starting a Datastore Context.

Defines the available states in which a context may exist.

Values indicating the state of the database which backs a given Datastore.

A type describing the allowed values for use in datastore_naming.

The extended naming value of a Datastore for use when starting a Datastore.

Defines operators for use in comparison functions.

Error codes which may be raised by database procedural logic errors.

Defines the available states in which a Datastore might exist in relation to its schema migrations.

Options which are expected by the Timex library.

Types

context_name()

@type context_name() :: String.t() | atom()

The value type for names which describe a specific instance of an Application's Datastore Context.

A Context Name provides a reference to a specific Instance's database access in a way that decouples the application reference name from the database role which that name represents.

This name will commonly be used as the registered name for the Datastore Context when registering the associated database repository pid value.

context_registry()

@type context_registry() :: :global | :atom

The allowable Datastore Context name registration options.

Values of this type describe the available options for registering a Datastore Context name. The options are:

  • :global - the Datastore Context name is registered globally and can be using the Erlang :global registry.

  • {:via, module()} - the Datastore Context name is registered using the identified module which must implement the Registry behaviour.

  • nil - the Datastore Context name will be registered locally using the VM's built-in registration mechanisms. In this case the Datastore Context name must be represented as an atom.

context_role()

@type context_role() :: String.t()

The database role name for the specific access context defined by the context_name().

context_service_name()

@type context_service_name() :: GenServer.name() | nil

The extended naming value of a Datastore Context for use when starting a Datastore Context.

This name can include process registry information and takes the same for as that allowed for GenServer naming.

context_state_values()

@type context_state_values() ::
  :not_found | :not_ready | :ready | :not_started | :started

Defines the available states in which a context may exist.

  • :not_found - The database role backing the context was not found on the Datastore database server.

  • :not_ready - The database role backing the context exists, but is not completely set up yet. This is an interim stage that usually has to cross transaction boundaries.

  • :not_started - When starting contexts the system doesn't check for the existence of each context which in turn means that a start failure could be indicative of either non-existence or some other problem. In these start-up scenarios the state would be :not_started.

  • :ready - The context was found and may be connected to the database, but the database connections for the context have not been started yet.

  • :started - The context was found and database connections for the context have already been started.

database_state_values()

@type database_state_values() :: :not_found | :ready

Values indicating the state of the database which backs a given Datastore.

  • :not_found - The database for the Datastore does not exist on the database server.

  • :ready - The database is ready for further processing by the migrations subsystem.

datastore_name()

@type datastore_name() :: String.t() | atom()

A type describing the allowed values for use in datastore_naming.

datastore_service_name()

@type datastore_service_name() :: GenServer.name() | nil

The extended naming value of a Datastore for use when starting a Datastore.

This name can include process registry information and takes the same for as that allowed for GenServer naming.

db_type_comparison_operators()

@type db_type_comparison_operators() :: :gt | :lt | :eq | :lcr | :rcl | :gto | :lto

Defines operators for use in comparison functions.

These operators are used in conjunction with the MscmpSystDb.DbTypes and MscmpSystDb.DbTypes.Range protocols.

The range related operator values are generally the same as those defined by the PostgreSQL database range types, but there are some small differences.

  • :gt - left is greater than right.

  • :lt - left is less than right.

  • :eq - the values are equal.

  • :lcr - left contains right.

  • :rcl - right contains left.

  • :gto - greater than overlapping.

  • :lto - less than overlapping.

Examples

Greater Than (:gt)

iex> left_range =
...>   %MscmpSystDb.DbTypes.IntegerRange{
...>     lower: 200,
...>     upper: 210
...>   }
iex> right_range =
...>   %MscmpSystDb.DbTypes.IntegerRange{
...>     lower: 100,
...>     upper: 110
...>   }
iex> MscmpSystDb.DbTypes.compare(left_range, right_range)
:gt

Less Than (:lt)

iex> left_range =
...>   %MscmpSystDb.DbTypes.IntegerRange{
...>     lower: 100,
...>     upper: 110
...>   }
iex> right_range =
...>   %MscmpSystDb.DbTypes.IntegerRange{
...>     lower: 200,
...>     upper: 210
...>   }
iex> MscmpSystDb.DbTypes.compare(left_range, right_range)
:lt

Equal (:eq)

iex> left_range =
...>   %MscmpSystDb.DbTypes.IntegerRange{
...>     lower: 100,
...>     upper: 110
...>   }
iex> right_range =
...>   %MscmpSystDb.DbTypes.IntegerRange{
...>     lower: 100,
...>     upper: 110
...>   }
iex> MscmpSystDb.DbTypes.compare(left_range, right_range)
:eq

Left Contains Right (:lcr)

iex> left_range =
...>   %MscmpSystDb.DbTypes.IntegerRange{
...>     lower: 90,
...>     upper: 110
...>   }
iex> right_range =
...>   %MscmpSystDb.DbTypes.IntegerRange{
...>     lower: 100,
...>     upper: 110
...>   }
iex> MscmpSystDb.DbTypes.compare(left_range, right_range)
:lcr

Right Contains Left (:rcl)

iex> left_range =
...>   %MscmpSystDb.DbTypes.IntegerRange{
...>     lower: 100,
...>     upper: 110
...>   }
iex> right_range =
...>   %MscmpSystDb.DbTypes.IntegerRange{
...>     lower: 100,
...>     upper: 111
...>   }
iex> MscmpSystDb.DbTypes.compare(left_range, right_range)
:rcl

Greater Than Overlapping (:gto)

iex> left_range =
...>   %MscmpSystDb.DbTypes.IntegerRange{
...>     lower: 150,
...>     upper: 250
...>   }
iex> right_range =
...>   %MscmpSystDb.DbTypes.IntegerRange{
...>     lower: 100,
...>     upper: 175
...>   }
iex> MscmpSystDb.DbTypes.compare(left_range, right_range)
:gto

Less Than Overlapping (:lto)

iex> left_range =
...>   %MscmpSystDb.DbTypes.IntegerRange{
...>     lower: 100,
...>     upper: 150
...>   }
iex> right_range =
...>   %MscmpSystDb.DbTypes.IntegerRange{
...>     lower: 125,
...>     upper: 175
...>   }
iex> MscmpSystDb.DbTypes.compare(left_range, right_range)
:lto

error_code()

@type error_code() :: {code :: atom(), message :: String.t()}

Error codes which may be raised by database procedural logic errors.

When database functions and stored procedures raise exceptions, they do so with SQL Error Codes which may have specific meanings within our applications. This type defines the known error codes which may be raised by the database.

The error code is represented as an atom and the message is a string which provides additional information about the error. The error code is either a standard PostgreSQL error code or a custom error code defined by our applications.

Custom Error Codes

This is the list of known error codes which may be raised by the database that are unique to our applications. The parenthetical value is the SQLSTATE values reported by the database. Our database applications raise exceptions with these codes when they encounter an custom error condition.

  • :msdata_disallowed_field_change ("PM001") - A change was attempted on a field which does not allow changes.

  • :msdata_disallowed_operation ("PM002") - An INSERT, UPDATE, or DELETE operation was attempted on a record which does not allow that operation.

  • :msdata_syst_defined ("PM003") - Invalid change of a system defined record or field.

  • :msdata_logical_duplicate ("PM101") - A logical duplicate was detected. This can happen when the business rules dictate a condition of uniqueness which cannot be readily implemented by a UNIQUE constraint.

  • :msdata_resource_exhausted ("PM102") - A limited resource, such as a finite numbering sequence, has been exhausted.

  • :msdata_out_of_range ("PM103") - Out of range values were detected.

  • :msdata_parent_child_mismatch ("PM104") - A parent/child mismatch was detected.

  • :msdata_out_of_order_prereq ("PM105") - Out of order pre-requisite establishment. This error is raised when an optional pre-requisite is established after records which would have to satisfy the pre-requisite have already been created.

  • :msdata_ineligible_deletion ("PM106") - Ineligible for deletion. This error is raised when an attempt is made to delete a record or child of a record which is still either active or not purge eligible.

  • :msdata_invalid_data_change ("PM107") - Invalid change for type. This error occurs when an operation or other data change is attempted where such a change is not allowed by the application's rules.

  • :msdata_invalid_state_change ("PM108") - Invalid state change. This error occurs when an attempt is made to create a record or change the existing state of a record to an invalid state.

  • :msdata_out_of_order_deletion ("PM109") - Out of order deletion. This error occurs when an attempt is made to delete a record or child of a record which would leave some other record or child of a record orphaned in some fashion.

  • :msdata_missing_parameter ("PM110") - Missing parameter. This error occurs when a required parameter value is missing or was passed as a null value.

For PostgreSQL error codes, please refer to the PostgreSQL documentation.

migration_state_values()

@type migration_state_values() :: :not_initialized | :not_updated | :ready

Defines the available states in which a Datastore might exist in relation to its schema migrations.

  • :not_initialized - The Datastore does not have the table which manages the migrations installed. This is also the value reported when the database_state_values() value for the Datastore is :not_found.

  • :not_updated - The Datastore database exists and has been initialized, but does not have the most recent migrations available applied per the migrations management table.

  • :ready - The migrations are fully up-to-date and the Datastore is ready to serve the application as needed.

timex_shift_options()

@type timex_shift_options() :: [
  microseconds: integer(),
  seconds: integer(),
  days: integer(),
  months: integer()
]

Options which are expected by the Timex library.

The MscmpSystDb.DbTypes.Interval struct can be converted into a form which can be consumed by Timex.shift/2 and this type defines the possible return values.

Note that this type should closely match the t:Timex.shift_options types except that we limit it to the types present in the MscmpSystDb.DbTypes.Interval.t/0 data type.