View Source MnesiaAssistant.Table (Mishka developer tools v0.1.8)
Within this module, you will find all of the functions that you require in order to operate with a table in Mnesia.
Summary
Functions
Makes another copy of a table on the Node you want. Argument Type must be either of the
atoms ram_copies
, disc_copies
, or disc_only_copies
. For example, the following call ensures
that a disc replica of the person table also exists at node Node
Table indexes can be used whenever the user wants to use frequently some other field than the key
field to look up records. If this other field has an associated index,
these lookups can occur in constant time and space. For example, if your application wishes to use field age
to find efficiently all persons with a specific age, it can be a good idea to have an index on field age.
This can be done with the following call
Returns a list of all keys in a table.
he semantics of this function is context-sensitive. For more information, see MnesiaAssistant.Transaction.activity/4
.
In transaction-context
, it acquires a read lock on the entire table.
AcccessMode is by default the atom read_write
but it can also be set to the atom read_only
.
If AccessMode
is set to read_only
, updates to the table cannot be performed.
At startup, Mnesia
always loads read_only
tables locally regardless of when and if Mnesia
is terminated on
other nodes.
After the table has been created, it is possible that you will need to modify the way of copying data in a Mnesia
table in accordance with the logic of your program.
Consider the following scenario: the existence of other tables is somewhat reliant on the existence of other tables, and the tables should be brought up in order based on a prioritization of the tables; therefore, this function may be useful in this part.
This function is part of Mnesia's advanced features for handling distributed data consistency. The majority property, when set to true, requires that a majority of replicas (nodes) for a given table must acknowledge a write operation for it to be considered successful. This can enhance data consistency in distributed environments at the cost of availability,
Deletes all entries in a table.
It returns size of a table by using table_info(module, :size)
.
You are possible to generate a table in Mnesia by utilizing this function. During the process of creating the table, it is important to know that the first input, which is the name of the table, and the second input, which is in the form of a list, are respectively options that you are required to apply to the table.
### Erlang document
Deletes the index on attribute with name AttrName
(for example :age) in a table.
Permanently deletes all replicas of table Tab.
Dirty equivalent of the function all_keys/1
.
Experimental:
The assumption here is that you do not wish to have a warranty for your data and that you also desire a copy
of the ram_copies
document. When it comes to this section, speed is of the utmost importance,
and you should concentrate on local ets
.
When you take into account all of these factors, this feature is really helpful.
Read ets/1
document.
Checking if the desired table exists?
The Mnesia algorithm for table load can lead to a situation where a table cannot be loaded. This situation occurs when a node is started and Mnesia concludes, or suspects, that another copy of the table was active after this local copy became inactive because of a system crash.
Checking whether the desired table is of bag
type or not?
Checking whether the desired table is of ordered_set
type or not?
Checking whether the desired table is of set
type or not?
Erlang document:
lock(LockItem, LockKind)
LockItem = {record, table(), Key :: term()} | {table, table()} | {global, Key :: term(), MnesiaNodes :: [node()]}
Moves the copy of table Tab from node From
to node To
.
Calls the function lock({:table, Person}, :read)
Erlang document:
For each table Mnesia determines its replica nodes (TabNodes
) and starts mnesia:set_master_nodes(Tab, TabMasterNodes)
.
where TabMasterNodes
is the intersection of MasterNodes
and TabNodes. For semantics, see mnesia:set_master_nodes/2
.
Erlang document:
If the application detects a communication failure (in a potentially partitioned network) that can
have caused an inconsistent database, it can use the function mnesia:set_master_nodes(Tab, MasterNodes)
to define from which nodes each table is to be loaded. At startup, the Mnesia
normal table load
algorithm is bypassed and the table is loaded from one of the master nodes defined for the table,
regardless of when and if Mnesia terminated on other nodes. MasterNodes
can only contain
nodes where the table has a replica. If the MasterNodes
list is empty,
the master node recovery mechanism for the particular table is reset, and the normal load
mechanism is used at the next restart.
Erlang document:
Returns a Query List Comprehension (QLC
) query handle, see the qlc(3)
manual page in STDLIB.
The module qlc implements a query language that can use Mnesia tables as sources of data.
Calling mnesia:table/1,2
is the means to make the mnesia table Tab usable to QLC
.
Read table/1
document.
You can use this function to see the information of a table.
The table_info/2
function takes two arguments. The first is the name of a Mnesia table.
The second is one of the following keys
When continuing or beginning to call a table from Mnesia
, it is possible that you will be required to
use an anonymous function in order to convert the previous data into the new data.
Some applications need to wait for certain tables to be accessible to do useful work.
mnesia:wait_for_tables/2
either hangs until all tables in TabList are accessible, or until timeout
is reached.
Calls the function mnesia:lock({table, Tab}, write)
. Read lock/2
document.
Types
@type table_type() :: :set | :ordered_set | :bag
Functions
Makes another copy of a table on the Node you want. Argument Type must be either of the
atoms ram_copies
, disc_copies
, or disc_only_copies
. For example, the following call ensures
that a disc replica of the person table also exists at node Node:
Example:
MnesiaAssistant.Table.add_table_copy(Person, A_NODE, :disc_copies)
Table indexes can be used whenever the user wants to use frequently some other field than the key
field to look up records. If this other field has an associated index,
these lookups can occur in constant time and space. For example, if your application wishes to use field age
to find efficiently all persons with a specific age, it can be a good idea to have an index on field age.
This can be done with the following call:
Example:
MnesiaAssistant.Table.add_table_index(Person, :age)
Returns a list of all keys in a table.
he semantics of this function is context-sensitive. For more information, see MnesiaAssistant.Transaction.activity/4
.
In transaction-context
, it acquires a read lock on the entire table.
Example:
MnesiaAssistant.Table.all_keys(Person)
AcccessMode is by default the atom read_write
but it can also be set to the atom read_only
.
If AccessMode
is set to read_only
, updates to the table cannot be performed.
At startup, Mnesia
always loads read_only
tables locally regardless of when and if Mnesia
is terminated on
other nodes.
Example:
MnesiaAssistant.Table.change_table_access_mode(Person, :read_write) # [:read_only, :read_write]
After the table has been created, it is possible that you will need to modify the way of copying data in a Mnesia
table in accordance with the logic of your program.
Table copy types: [:disc_only_copies, :disc_copies, :ram_copies]
Example:
MnesiaAssistant.Table.change_table_copy_type(Person, :disc_only_copies)
Consider the following scenario: the existence of other tables is somewhat reliant on the existence of other tables, and the tables should be brought up in order based on a prioritization of the tables; therefore, this function may be useful in this part.
Erlang document:
The LoadOrder priority is by default 0
(zero) but can be set to any integer.
The tables with the highest LoadOrder priority are loaded first at startup.
Example:
MnesiaAssistant.Table.change_table_load_order(Person, 10)
This function is part of Mnesia's advanced features for handling distributed data consistency. The majority property, when set to true, requires that a majority of replicas (nodes) for a given table must acknowledge a write operation for it to be considered successful. This can enhance data consistency in distributed environments at the cost of availability,
Erlang document:
Majority must be a boolean. Default is false. When true, a majority of the table replicas must be available for an update to succeed. When used on fragmented tables, Tab must be the base table name. Directly changing the majority setting on individual fragments is not allowed.
Example:
MnesiaAssistant.Table.change_table_majority(Person, true)
# OR
MnesiaAssistant.Table.change_table_majority(Person, false)
Deletes all entries in a table.
Example:
MnesiaAssistant.Table.clear_table(Person)
It returns size of a table by using table_info(module, :size)
.
Example:
MnesiaAssistant.Table.count(Person)
You are possible to generate a table in Mnesia by utilizing this function. During the process of creating the table, it is important to know that the first input, which is the name of the table, and the second input, which is in the form of a list, are respectively options that you are required to apply to the table.
It is important to note that you should make an effort to have a proper implementation at the beginning by thoroughly researching the possibilities that are dependent on your strategy. This will ensure that you do not have to repeat the procedures with as many different functions as possible.
Erlang Documents
{access_mode, Atom}
The access mode is by default the atom read_write but it can also be set to the atom read_only. If AccessMode is set to read_only, updates to the table cannot be performed. At startup, Mnesia always loads read_only table locally regardless of when and if Mnesia is terminated on other nodes. This argument returns the access mode of the table. The access mode can be read_only or read_write.{attributes, AtomList}
is a list of the attribute names for the records that are supposed to populate the table. Default is [key, val]. The table must at least have one extra attribute in addition to the key. When accessing single attributes in a record, it is not necessary, or even recommended, to hard code any attribute names as atoms. Use constructrecord_info(fields, RecordName)
instead. It can be used for records of type RecordName.{disc_copies, Nodelist}
, where Nodelist is a list of the nodes where this table is supposed to have disc copies. If a table replica is of type disc_copies, all write operations on this particular replica of the table are written to disc and to the RAM copy of the table. It is possible to have a replicated table of type disc_copies on one node and another type on another node. Default is [].{disc_only_copies, Nodelist}
, where Nodelist is a list of the nodes where this table is supposed to havedisc_only_copies
. A disc only table replica is kept on disc only and unlike the other replica types, the contents of the replica do not reside in RAM. These replicas are considerably slower than replicas held in RAM.{index, Intlist}
, where Intlist is a list of attribute names (atoms) or record fields for which Mnesia is to build and maintain an extra index table. The qlc query compiler may be able to optimize queries if there are indexes available.{load_order, Integer}
. The load order priority is by default 0(zero)
but can be set to any integer. The tables with the highest load order priority are loaded first at startup.{majority, Flag}
, where Flag must be a boolean. If true, any(non-dirty)
update to the table is aborted, unless a majority of the table replicas are available for the commit. When used on a fragmented table, allfragments
are given the same majority setting.{ram_copies, Nodelist}
, where Nodelist is a list of the nodes where this table is supposed to have RAM copies. A table replica of type ram_copies is not written to disc on a per transaction basis. ram_copies replicas can be dumped to disc with the function mnesia:dump_tables(Tabs). Default value for this attribute is[node()]
.{record_name, Name}
, where Name must be an atom. All records stored in the table must have this name as the first element. It defaults to the same name as the table name.{snmp, SnmpStruct}
. For a description of SnmpStruct, seemnesia:snmp_open_table/2
. If this attribute is present in ArgList tomnesia:create_table/2
, the table is immediately accessible by SNMP. Therefore applications that use SNMP to manipulate and control the system can be designed easily, since Mnesia provides a direct mapping between the logical tables that make up an SNMP control application and the physical data that makes up aMnesia
table.{storage_properties, [{Backend, Properties}]
forwards more properties to the back end storage. Backend can currently be ets or dets. Properties is a list of options sent to the back end storage during table creation. Properties cannot contain properties already used by Mnesia, such as type ornamed_table
.
For example:
mnesia:create_table(table, [{ram_copies, [node()]}, {disc_only_copies, nodes()},
{storage_properties,
[{ets, [compressed]}, {dets, [{auto_save, 5000}]} ]}])
{type, Type}
, where Type must be either of the atoms set,ordered_set
, orbag
. Default is set. In aset
, all records have unique keys. In a bag, several records can have the same key, but the record content is unique. If a non-unique record is stored, the old conflicting records are overwritten.
Notice that currently ordered_set
is not supported for disc_only_copies
.
{local_content, Bool}
, where Bool is true
or false
. Default is false
.
For example, the following call creates the person table (defined earlier) and replicates it on two nodes:
mnesia:create_table(person,
[{ram_copies, [N1, N2]},
{attributes, record_info(fields, person)}]).
If it is required that Mnesia must build and maintain an extra index table on attribute address of all the person records that are inserted in the table, the following code would be issued:
mnesia:create_table(person,
[{ram_copies, [N1, N2]},
{index, [address]},
{attributes, record_info(fields, person)}]).
The specification of index and attributes can be hard-coded as {index, [2]}
and
{attributes, [name, age, address, salary, children]}
, respectively.
mnesia:create_table/2
writes records into the table schema. This function, and all other schema
manipulation functions, are implemented with the normal transaction management system.
This guarantees that schema updates are performed on all nodes in an atomic manner.
### Example:
MnesiaAssistant.Table.create_table(Person, attributes: [:id, :name, :family, :age])
### Erlang document:
Deletes the replica of table Tab
at node Node
. When the last replica is deleted with this function,
the table disappears entirely.
This function can also be used to delete a replica of the table named schema. The Mnesia node is then removed. Notice that Mnesia must be stopped on the node first.
### Example:
MnesiaAssistant.Table.del_table_copy(Person, A_NODE)
Deletes the index on attribute with name AttrName
(for example :age) in a table.
Example:
MnesiaAssistant.Table.del_table_index(Person, :age)
Permanently deletes all replicas of table Tab.
Example:
MnesiaAssistant.Table.delete_table(Person)
Dirty equivalent of the function all_keys/1
.
Example:
MnesiaAssistant.Table.dirty_all_keys(Person)
Experimental:
The assumption here is that you do not wish to have a warranty for your data and that you also desire a copy
of the ram_copies
document. When it comes to this section, speed is of the utmost importance,
and you should concentrate on local ets
.
When you take into account all of these factors, this feature is really helpful.
Erlang document:
Calls the Fun in a raw context that is not protected by a transaction. The Mnesia
function call is
performed in the Fun and performed directly on the local ETS
tables on the assumption that
the local storage type is ram_copies and the tables are not replicated to other nodes.
Subscriptions are not triggered and checkpoints are not updated, but it is extremely fast.
This function can also be applied to disc_copies tables if all operations are read only.
For details, see mnesia:activity/4
and the User's Guide.
Notice that calling (nesting) a
mnesia:ets
inside a transaction-context inherits the transaction semantics.
Example:
fun = fn ->
# Use ETS to get all records from the :people table and count them
ets_table = :ets.tab2list(:people)
length(ets_table)
end
MnesiaAssistant.Table.ets(fun)
# OR
MnesiaAssistant.Table.ets(fn ->
MnesiaAssistant.Table.all_keys(module)
end)
# OR
MnesiaAssistant.Table.ets(fn -> Enum.each(list, &save_dirty/1) end)
Read ets/1
document.
Checking if the desired table exists?
Example:
MnesiaAssistant.Table.exists?(Person)
The Mnesia algorithm for table load can lead to a situation where a table cannot be loaded. This situation occurs when a node is started and Mnesia concludes, or suspects, that another copy of the table was active after this local copy became inactive because of a system crash.
If this situation is not acceptable, this function can be used to override the strategy of the Mnesia table load algorithm. This can lead to a situation where some transaction effects are lost with an inconsistent database as result, but for some applications high availability is more important than consistent data.
Example:
MnesiaAssistant.Table.force_load_table(Person)
Checking whether the desired table is of bag
type or not?
Example:
MnesiaAssistant.Table.is_bag?(Person)
Checking whether the desired table is of ordered_set
type or not?
Example:
MnesiaAssistant.Table.is_ordered_set?(Person)
Checking whether the desired table is of set
type or not?
Example:
MnesiaAssistant.Table.is_set?(Person)
Erlang document:
lock(LockItem, LockKind)
LockItem = {record, table(), Key :: term()} | {table, table()} | {global, Key :: term(), MnesiaNodes :: [node()]}
LockKind = [:read, :write, :sticky_write, :load]
Write locks are normally acquired on all nodes where a replica of the table resides (and is active). Read locks are acquired on one node (the local node if a local replica exists). Most of the context-sensitive access functions acquire an implicit lock if they are started in a transaction-context. The granularity of a lock can either be a single record or an entire table.
The normal use is to call the function without checking the return value, as it exits if it fails and the transaction is restarted by the transaction manager. It returns all the locked nodes if a write lock is acquired and ok if it was a read lock.
The function mnesia:lock/2
is intended to support explicit locking on tables, but is also intended for
situations when locks need to be acquired regardless of how tables are replicated.
Currently, two kinds of LockKind are supported:
:write
Write locks are exclusive. This means that if one transaction manages to acquire a write lock on an item, no other transaction can acquire any kind of lock on the same item.read
Read locks can be shared. This means that if one transaction manages to acquire a read lock on an item, other transactions can also acquire a read lock on the same item. However, if someone has a read lock, no one can acquire a write lock at the same item. If someone has a write lock, no one can acquire either a read lock or a write lock at the same item. Conflicting lock requests are automatically queued if there is no risk of a deadlock. Otherwise the transaction must be terminated and executed again. Mnesia does this automatically as long as the upper limit of the maximum retries is not reached. For details, seemnesia:transaction/3
.
For the sake of completeness, sticky write locks are also described here even if a sticky write lock is not supported by this function:
sticky_write
Sticky write locks are a mechanism that can be used to optimize write lock acquisition. If your application uses replicated tables mainly for fault tolerance (as opposed to read access optimization purpose), sticky locks can be the best option available.
When a sticky write lock is acquired, all nodes are informed which node is locked. Then, sticky lock requests from the same node are performed as a local operation without any communication with other nodes. The sticky lock lingers on the node even after the transaction ends. For details, see the User's Guide.
Currently, this function supports two kinds of LockItem:
{table, Tab}
This acquires a lock of type LockKind on the entire table Tab.
{global, GlobalKey, Nodes}
This acquires a lock of type LockKind on the global resource GlobalKey.
The lock is acquired on all active nodes in the Nodes list.
Locks are released when the outermost transaction ends. The semantics of this function is context-sensitive.
For details, see mnesia:activity/4
. In transaction-context, it acquires locks, otherwise it ignores the request.
Example:
MnesiaAssistant.Table.lock({:table, Person}, :load)
Moves the copy of table Tab from node From
to node To
.
The storage type is preserved. For example, a RAM table moved from one node remains a RAM on the new node. Other transactions can still read and write in the table while it is being moved.
This function cannot be used on local_content
tables.
Example:
MnesiaAssistant.Table.add_table_copy(Person, A_NODE, B_NODE)
Calls the function lock({:table, Person}, :read)
Example:
MnesiaAssistant.Table.read_lock_table(Person)
Erlang document:
For each table Mnesia determines its replica nodes (TabNodes
) and starts mnesia:set_master_nodes(Tab, TabMasterNodes)
.
where TabMasterNodes
is the intersection of MasterNodes
and TabNodes. For semantics, see mnesia:set_master_nodes/2
.
Example:
MnesiaAssistant.Table.set_master_nodes([node()])
Erlang document:
If the application detects a communication failure (in a potentially partitioned network) that can
have caused an inconsistent database, it can use the function mnesia:set_master_nodes(Tab, MasterNodes)
to define from which nodes each table is to be loaded. At startup, the Mnesia
normal table load
algorithm is bypassed and the table is loaded from one of the master nodes defined for the table,
regardless of when and if Mnesia terminated on other nodes. MasterNodes
can only contain
nodes where the table has a replica. If the MasterNodes
list is empty,
the master node recovery mechanism for the particular table is reset, and the normal load
mechanism is used at the next restart.
The master node setting is always local. It can be changed regardless if Mnesia
is started or not.
The database can also become inconsistent if configuration parameter max_wait_for_decision
is used or
if mnesia:force_load_table/1
is used.
Example:
MnesiaAssistant.Table.set_master_nodes(Person, [node()])
start_table(start_data, module, database_config, identifier, suc_fn \\ nil)
View SourceErlang document:
Returns a Query List Comprehension (QLC
) query handle, see the qlc(3)
manual page in STDLIB.
The module qlc implements a query language that can use Mnesia tables as sources of data.
Calling mnesia:table/1,2
is the means to make the mnesia table Tab usable to QLC
.
Option can contain Mnesia options or QLC options. Mnesia recognizes the following options (any other option is forwarded to QLC).
{lock, Lock}
, where lock can be read or write. Default is read.{n_objects,Number}
, where n_objects specifies (roughly) the number of objects returned from Mnesia to QLC. Queries to remote tables can need a larger chunk to reduce network overhead. By default, 100 objects at a time are returned.{traverse, SelectMethod}
, where traverse determines the method to traverse the whole table (if needed). The default method is select.
There are two alternatives for select:
select
. The table is traversed by callingmnesia:select/4
andmnesia:select/1
. The match specification (the second argument of select/3) is assembled by QLC: simple filters are translated into equivalent match specifications. More complicated filters need to be applied to all objects returned by select/3 given a match specification that matches all objects.{select, MatchSpec}
. As for select, the table is traversed by callingmnesia:select/3
andmnesia:select/1
. The difference is that the match specification is explicitly given. This is how to state match specifications that cannot easily be expressed within the syntax provided by QLC.
# Options = Option | [Option]
# Option = MnesiaOpt | QlcOption
# MnesiaOpt = {traverse, SelectOp} | {lock, lock_kind()} | {n_objects, integer() >= 0}
# SelectOp = select | {select, ets:match_spec()}
# QlcOption = {key_equality, '==' | '=:='}
table(Tab :: table()) -> qlc:query_handle()
table(Tab :: table(), Options) -> qlc:query_handle()
TODO: We need to support qlc
interface, Query interface to Mnesia, ETS, Dets, and so on.
Example:
MnesiaAssistant.Table.table(Person)
Read table/1
document.
You can use this function to see the information of a table.
The table_info/2
function takes two arguments. The first is the name of a Mnesia table.
The second is one of the following keys:
:all
Returns a list of all local table information. Each element is a {InfoKey, ItemVal} tuple.
New InfoItems can be added and old undocumented InfoItems can be removed without notice.
:access_mode
Returns the access mode of the table. The access mode can be read_only or read_write.:arity
Returns the arity of records in the table as specified in the schema.:attributes
Returns the table attribute names that are specified in the schema.:checkpoints
Returns the names of the currently active checkpoints, which involve this table on this node.:cookie
Returns a table cookie, which is a unique system-generated identifier for the table. The cookie is used internally to ensure that two different table definitions using the same table name cannot accidentally be intermixed. The cookie is generated when the table is created initially.:disc_copies
Returns the nodes where a disc_copy of the table resides according to the schema.:disc_only_copies
Returns the nodes where a disc_only_copy of the table resides according to the schema.:index
Returns the list of index position integers for the table.:load_node
Returns the name of the node that Mnesia loaded the table from. The structure of the returned value is unspecified, but can be useful for debugging purposes.:load_order
Returns the load order priority of the table. It is an integer and defaults to 0 (zero).:load_reason
Returns the reason of why Mnesia decided to load the table. The structure of the returned value is unspecified, but can be useful for debugging purposes.:local_content
Returns true or false to indicate if the table is configured to have locally unique content on each node.:master_nodes
Returns the master nodes of a table.:memory
Returns for ram_copies and disc_copies tables the number of words allocated in memory to the table on this node. For disc_only_copies tables the number of bytes stored on disc is returned.:ram_copies
Returns the nodes where a ram_copy of the table resides according to the schema.:record_name
Returns the record name, common for all records in the table.:size
Returns the number of records inserted in the table.:snmp
Returns the SNMP struct. [] means that the table currently has no SNMP properties.:storage_type
Returns the local storage type of the table. It can be disc_copies, ram_copies, disc_only_copies, or the atom unknown. unknown is returned for all tables that only reside remotely.:subscribers
Returns a list of local processes currently subscribing to local table events that involve this table on this node.:type
Returns the table type, which is bag, set, or ordered_set.:user_properties
Returns the user-associated table properties of the table. It is a list of the stored property records.:version
Returns the current version of the table definition. The table version is incremented when the table definition is changed. The table definition can be incremented directly when it has been changed in a schema transaction, or when a committed table definition is merged with table definitions from other nodes during startup.:where_to_read
Returns the node where the table can be read. If value nowhere is returned, either the table is not loaded or it resides at a remote node that is not running.:where_to_write
Returns a list of the nodes that currently hold an active replica of the table.:wild_pattern
Returns a structure that can be given to the various match functions for a certain table. A record tuple is where all record fields have value '_'.
Example:
MnesiaAssistant.Table.table_info(:attributes)
# OR
MnesiaAssistant.Table.table_info(:all)
When continuing or beginning to call a table from Mnesia
, it is possible that you will be required to
use an anonymous function in order to convert the previous data into the new data.
Erlang document:
Applies argument Fun to all records in the table. Fun is a function that takes a record of the old
type and
returns a transformed record of the new
type.
Argument Fun can also be the atom ignore, which indicates that only the metadata about
the table is updated. Use of ignore is not recommended, but included as a possibility for the user
do to an own transformation.
NewAttributeList and NewRecordName specify the attributes and the new record type of the converted table.
Table name always remains unchanged. If record_name
is changed, only the Mnesia
functions that use table
identifiers work, for example, mnesia:write/3
works, but not mnesia:write/1
.
Example:
transform_fun = fn ({id, name}) ->
# Return the new structure with a default age
{id, name, 30}
end
MnesiaAssistant.Transaction.transaction(fn ->
MnesiaAssistant.Table.transform_table(Person, transform_fun, [:id, :name, :age])
end)
# OR
# MnesiaAssistant.Table.transform_table(Person, transform_fun, [:id, :name, :age])
# OR
MnesiaAssistant.Table.transform_table(Person, transform_fun, [:id, :name, :age], NewPerson)
Some applications need to wait for certain tables to be accessible to do useful work.
mnesia:wait_for_tables/2
either hangs until all tables in TabList are accessible, or until timeout
is reached.
Example:
MnesiaAssistant.Table.wait_for_tables(Person, 5000)
Calls the function mnesia:lock({table, Tab}, write)
. Read lock/2
document.
Example:
MnesiaAssistant.Table.write_lock_table(Person)