Mike5050
Mike5050

Reputation: 605

Using Erlang mnesia:read/2 Returns Nothing

I have a ram_copies mnesia set up and I can insert the records, and I can print the them using the following code located here: How to read all the records of mnesia database in erlang?

Start Record:

-record(someRecord, {a=null, b=null}).

Table:

mnesia:create_table(someRecord,
    [{attributes, record_info(fields, someRecord)},
      {index, [#someRecord.b]},
      {ram_copies, Nodes},
      {type, set}]),

Inserting:

i(rA, rB) ->
  F = fun() -> mnesia:write(#someRecord{a=rA, b=rB}) end,
  mnesia:transaction(F).

Reading:

r(rB) ->
  F = fun() -> mnesia:read({someRecord, rB}) end,
  mnesia:transaction(F).

This returns {atomic, Result} and Result is empty.

Wondering what I am doing wrong.

Thanks!

Update: It turns out that if I use the record "a" as they key it works. But why? I have it set to record "b" for key.

Upvotes: 1

Views: 274

Answers (1)

Dogbert
Dogbert

Reputation: 222388

The {index, List} option specifies which of the elements of the tuple mnesia should index. It does not change the behavior of mnesia:read to search those fields. The first field of the record is treated as the primary key and indexed automatically and is the one mnesia:read searches. To make a query against any other element, you need to use mnesia:index_read and specify the index of the element:

mnesia:index_read(someRecord, B, #someRecord.b)

Also note that since the type your table is set, and the first field of the record is the primary key, you will not be able to store more than one record with the same value of a. If you want b to be the primary key and the key on which the set detects duplicates, you'll have to reorder the fields of the record and move b to before a. If you do that, you don't need to specify any index option and you'll also be able to use mnesia:read instead of mnesia:index_read. This should be more efficient as well since mnesia won't have to maintain an extra index.

Upvotes: 1

Related Questions