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:
UNIX: , Windows: )
UNIX: , Windows: )
UNIX: , Windows: )
UNIX: , Windows: )
UNIX: , Windows: )
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;
}
}