Following is a simplified example of a client written in Erlang to access Mnesia
via
the CORBA session interface. The type definitions are the same as in the
previous chapter.
To begin with include the necessary files.
%% Include to get the mnesia types, used in create table -include_lib("mnesia_session/include/mnesia.hrl"). %% Include to get the corba types i.e. any -include_lib("orber/include/corba.hrl"). %% Include my own types -include("persons.hrl").
Find the connector and create a private session.
start_corba_session(Host, Port) -> %% Lookup the inital corba name sever Addr = "iiop://" ++ atom_to_list(Host) ++ ":" ++ integer_to_list(Port), NS = corba:resolve_initial_references_remote("NameService", [Addr]), %% Create a corba name object NC = lname_component:set_id(lname_component:create(), "mnesia_corba_connector"), N = lname:insert_component(lname:create(), 1, NC), %% Lookup the object reference to the factory mnesia_corba_connector Cok = 'CosNaming_NamingContext':resolve(NS, N), %% Use the factory to create a session Sok = mnesia_corba_connector:connect(Cok), {Cok, Sok}.
In Erlang, objects are represented as processes. To access the method
of the object, call the method where the first argument is the object
reference, as in mnesia_connector:connect(ConnPid)
. All functions
in the IDL specification have an additional first argument which is
the object reference, more information is given in the IC
and Orber
documentation.
To create a table with the structure defined in the IDL definition, we use the function create_person_table.
Define the table properties and call the function:
create_person_table(ObjKey) -> %% Define the table properties Attrs = [atom_to_list(F) || F <- record_info(fields, persons_person)], TabDef = #mnesia_TableDef{type = bag, mode = read_write, ram_copies = [], disc_copies = [], disc_only_copies = [], index_list = [4], %% Index on married_to attributes = Attrs, %% NOTE that the record name must be exactly %% the same as the name of the %% structure/record to be used. record_name = "persons_person"}, Res = mnesia_corba_session:create_table(ObjKey, "persons", TabDef), case Res of {ok, ""} -> ok; Else -> io:format("ERROR: ~s~n", [Else]) end.
In this example the insert and a read operation looks like:
insert_person(SessionKey, Name, Sex, Age, Phone, Mt, Ch) -> Data = #persons_data{sex = Sex, age = Age, phone = Phone}, Person = #persons_person{name = Name, personData = Data, married_to = Mt, children = Ch}, Any = #any{typecode = persons_person:tc(), value = Person}, {ok, ""} = mnesia_corba_session:dirty_write(SessionKey, "persons", Any), Person.
get_person(SessionKey, Name) -> Obj = #any{typecode = {tk_string, 0}, value = Name}, {ok, RObjs, ""} = mnesia_corba_session:dirty_read(SessionKey, "persons", Obj), RObj = hd(RObjs), RObj#any.value.
Notice the usage of the any
type in both the read and write operations.
erlang::term
in the IDL specification is represented as the
CORBA type any
when using the CORBA session interface. The
any
type is represented as a 2-tuple containing type-code and
value, the user must in Erlang insert the type-code.
This example is the same but using Java and OrbixWeb.
For this example to work, the following specifications need to be compiled:
Import CORBA and CosNaming Classes:
import CosNaming._NamingContextRef; import CosNaming.Name; import IE.Iona.Orbix2._CORBA; import IE.Iona.Orbix2.CORBA.*;
Find the connector and create a private session.
public static mnesia._corba_sessionRef start_corba_session(String args[]) { mnesia._corba_sessionRef mcsRef = null; mnesia._corba_connectorRef mccRef = null; CORBA._InitialReferencesRef init; _NamingContextRef nsContext; Name name; _ObjectRef initRef, nsRef, objRef; Orber.InitialReference ir = new Orber.InitialReference(); String srvHost = new String(args[0]); Integer srvPort = new Integer(args[1]); try { // For an explanation about initial reference handling see // the "Interoperable Naming Service" specification. // Create Initial reference (objectkey "INIT"). String s = ir.stringified_ior(srvHost, srvPort.intValue()); initRef = _CORBA.Orbix.string_to_object(s); init = CORBA.InitialReferences._narrow(initRef); // Fetch name service reference. nsRef = init.get("NameService"); nsContext = CosNaming.NamingContext._narrow(nsRef); // Create a name name = new Name(1); name.buffer[0] = new CosNaming.NameComponent("mnesia_corba_connector", ""); try { objRef = nsContext.resolve(name); } catch(UserException n) { System.out.println("Unexpected exception: " + n.toString()); return null; } mccRef = mnesia.corba_connector._narrow(objRef); // Create and return the session reference mcsRef = mccRef.connect(); return mcsRef; } catch(SystemException se) { System.out.println("Unexpected exception: " + se.toString()); se.printStackTrace(); return null; } }
Create the person table
public static void create_person_table(mnesia._corba_sessionRef mcsRef) { String name = "persons"; mnesia.TableDef def = new mnesia.TableDef(); def.type = mnesia.SetOrBag.bag; def.mode = mnesia.AccessMode.read_write; def.ram_copies = new mnesia.NodeList(0); def.disc_copies = new mnesia.NodeList(0); def.disc_only_copies = new mnesia.NodeList(0); mnesia.Indices idxs = new mnesia.Indices(1); idxs.buffer[0] = 4; def.index_list = idxs; mnesia.AttrNames attrs = new mnesia.AttrNames(4); attrs.buffer[0] = "name"; attrs.buffer[1] = "personData"; attrs.buffer[2] = "married_to"; attrs.buffer[3] = "children"; def.attributes = attrs; def.record_name = "persons_person"; // The used IDL type StringHolder reason; reason = new StringHolder(); try { if(mnesia.Status.ok != mcsRef.create_table(name, def, reason)) System.out.println("Create Table Error " + reason.value); } catch( SystemException se) { System.out.println("Unexpected exception: " + se.toString()); return; } }
The insert operation. Observe the encapsulation of person in the
mnesia.Record
. Java or OrbixWeb will handle the type encoding.
public static void insert_person(mnesia._corba_sessionRef mcsRef, String name, int sex, int age, int phone, String mt, _sequence_String children) { persons.data data; data = new persons.data(sex, age, phone); persons.person person = new persons.person(); person.name = name; person.personData = data; person.married_to = mt; person.children = children; try { StringHolder reason = new StringHolder(); mnesia.Record object = new mnesia.Record(); object.insert(person); if(mnesia.Status.ok != mcsRef.dirty_write("persons", object, reason)) System.out.println("Insert person Error " + reason.value); } catch(SystemException se) { System.out.println("Unexpected exception: " + se.toString()); return; } }
A read operation. Observe the extraction of person from the received
mnesia.Recordlist
and the key
object handling.
public static persons.person get_person(mnesia._corba_sessionRef mcsRef, String name) { try { StringHolder reason = new StringHolder(); mnesia.Key key = new mnesia.Key(); mnesia.Recordlist res = new mnesia.Recordlist(); key.insertString(name); if(mnesia.Status.ok == mcsRef.dirty_read("persons", key, res, reason)) { if(res.length > 0) { persons.person rec1 = new persons.person(); res.buffer[0].extract(rec1); return rec1; } else return null; } else { System.out.println("Insert person Error " + reason.value); return null; } } catch(SystemException se) { System.out.println("Unexpected exception: " + se.toString()); return null; } }