Thursday, October 13, 2005

Sequence = Firebird Generator in NHibernate 1.0

Code below shows how to use "sequence" to have an auto-incremental field in NHibernate 1.0 with Firebird.
I use Generator(Class="sequence") to make a field to be autoinc, and if you want to specify a generator name, you can use a Param(Name="sequence", Content) attribute.


namespace TestNHibernate
{
[Serializable]
[Class(NameType=typeof(TestClass))]
public class TestClass {

private int _id;
private string _name;

public TestClass() {
}

[Id(1, Name="Id")]
[Generator(2, Class="sequence")]
[Param(3, Name="sequence", Content="TestClass_Id_Gen")]

public int Id {
get{ return _id;}
set{ _id = value; }
}

[Property(Name="Name", Length=10)]
public string Name {
get { return _name; }
set { _name = value; }
}
}
}

NHibernate 1.0 and Firebird

I've some experiences with Hibernate 2.1 but never touch NHibernate.
It's first time I play around NHibernate, just because I want to test it.
I found that NHibernate meets my all criterias (create DDL, gen mapping on the fly, etc.) to enable MDA.
I use mapping attributes from NHibernateContrib to model a domain class (see below).


// new configuration
Configuration config = new Configuration();
// set properties
IDictionary props = new Hashtable();
props["hibernate.connection.provider"] =
"NHibernate.Connection.DriverConnectionProvider";
props["hibernate.dialect" ] =
"NHibernate.Dialect.FirebirdDialect";
props["hibernate.connection.driver_class"] =
"NHibernate.Driver.FirebirdDriver" ;
props["hibernate.connection.connection_string"] =
"User=SYSDBA;Password=masterkey;" +
"Database=C:\\workspace\\FirebirdNET\\test.fdb;" +
"DataSource=;Port=3050;Dialect=3;Charset=NONE;Role=;" +
"Connection lifetime=0;Connection timeout=15;" +
"Pooling=True;Packet Size=8192;Server Type=0";
config.AddProperties(props);

// auto-generate Hbm on-the-fly
using( MemoryStream stream = new MemoryStream() ) {
HbmSerializer.Default.Serialize(stream, typeof(TestClass));
stream.Position = 0;
config.AddInputStream(stream);
}

// create database schema
SchemaExport s = new SchemaExport(config);
s.Create(true, true);

sf = config.BuildSessionFactory();

// create an object, then save
using(ISession ss = sf.OpenSession()) {
ITransaction tx = ss.BeginTransaction();
TestClass tc = new TestClass();
tc.Id = 1;
ss.Save(tc);
tx.Commit();
ss.Close();
}

// try find the object as IList
using(ISession ss = sf.OpenSession()) {
IList a = ss.Find("from TestClass");
Text = a.Count.ToString();
ss.Close();
}



A sample domain class:


using System;
using NHibernate.Mapping.Attributes;

namespace TestNHibernate {

[Serializable]
[Class(NameType=typeof(TestClass))]
public class TestClass {

public TestClass() {
}

private int id;

[Id(-2, Name="Id")]
[Generator(-1, Class="assigned")]
public int Id {
get{ return id;}
set{ id = value; }
}

}
}

Friday, September 30, 2005

ECO objects cannot be serialized !!!

I just understand that why Borland didnot promote enough their use of ECO for Web Services. I also realize that why there are only few discussion about Web Services issue on ECO news group. It is because we cannot directly use ECO types as WS complex types.


Here is my simple code:


[WebMethod]
public SystemUser[] ListAllUsers() {
SystemUserEA ea = (SystemUserEA)AccessFactory.Create(EcoSpace,
typeof(SystemUserEA));
return ea.FindAll();
}



However, I've already got the idea and trick how to make ECO fully support Web Services :).

Monday, September 26, 2005

Released EcoAccess 1.0 Final

I'm pround to present version 1.0 of EcoAccess, a free proxy-based declarative DAO library for Borland ECO.

I also updated a website to include one more tutorial - Query as List, and a special report to show that you can save many line of codes using EcoAccess.

You can download EcoAccess v.1.0 Final from http://www.centillex.com/ecoaccess/

Saturday, September 24, 2005

Considering Briefcase Model for ECO

After playing around ECO II, I found that it is quite difficult to make ECO's elements serialized with BinaryFormatter. So, I looked back to DTO pattern, and tried to make a utility to generate simple DTO for wrapping ECO objects.

I named this utility ETO - ECO Transfer Object, and I found that it can work correctly to clone my simple ECO object graph. But I hope it to work with more complicated graph.
If anyone'd like to try this utility please contact me.

Moreover, I also try to make generated ETO objects to be compatible with CompactFormatter and hope that it could work on .NET Compact Framework. That's right, I wanna see ECO working on Pocket PC :).

Monday, August 08, 2005

Eco on Rails

I've successfully tested ECO with EcoAccess on MonoRail Web application framework.
It worked great, and I have some codes to show here.

/// EcoController.cs
using Castle.MonoRail.Framework;
using Centillex.EcoAccess;
using User;

namespace EcoRailsSample
{
public class EcoController : SmartDispatcherController {

UserEcoSpace eco = new UserEcoSpace();

public void List() {
}

public void Edit(int id) {
}

public void View(int id) {
if(eco.Active == false) eco.Active = true;
ISystemUserEA si;
si = (ISystemUserEA) AccessFactory.Create(eco, typeof(ISystemUserEA));
PropertyBag["system_user"] = si.FindById(id);
}
}
}


I set a simple HTML in View.vm (NVelocity template) like this:

## View.vm
<h3>System User</h3>

Name : $system_user.FirstName <br/>
Last Name: $system_user.LastName <br/>



Here is the screenshot of the above codes:

Tuesday, August 02, 2005

EcoAccess v.1.0 M1 Released

EcoAccess is now available to download from Centillex.com
This is very early access version. However, you can use many exciting features of it.

Please download it from this page.

Sunday, July 31, 2005

EcoAccess: A Declarative DAO for ECO

I'd like to introduce my work for Borland ECO.
It was inspired by many Java projects such as Beehive and Hibernate.
This project "EcoAccess" is based on Dynamic Proxy from Castle to enable a declarative programming model to Borland ECO.
Obviously, it utilise many ECO services and let you easy to have OCL access methods.
I'd like to thank many articles from ECO section of HowToDoThings.com that guide me on ECO.

The most intesting concept I implemented into EcoAccess is that it provides a pure interface programming model like this:

[AccessEcoSpace(typeof (UserEcoSpace))]
public interface ISystemUserDAO {

[Ocl("SystemUser.allInstances->select(s|s.id = id)->first")]
SystemUser FindById(int id);
}


You can read the first tutorial here.

Wednesday, April 13, 2005

First get in touch with Comega

Test.cw


using System;

public class Test {

class Address {
struct {
string text;
};
}

static void Main() {
Address a = <Address><text>test</text></Address>;
Console.WriteLine("Comega says hello!");
Console.WriteLine(a.text);
Console.ReadLine();
}
}


The above code results:

Comega says hello!
test

Wednesday, March 30, 2005

@Inherited won't work with Interface (JDK 1.5)

In my early code of SQLWarp, I created the annotation ConnectionInfo to be annotated on an interface, and I need it for an interface, not a class.


@Retention(RUNTIME)
@Inherited
public @interface ConnectionInfo {
public String driver();
public String url();
public String userID() default "";
public String password() default "";
}


The JDK doc says that @Inherited won't work with an Interface, so this is my work around to get annotation from the class that implements the interface which is annotated by @ConnectionInfo.


ConnectionInfo c = (ConnectionInfo)obj
.getClass()
.getInterfaces()[0]
.getAnnotation(ConnectionInfo.class);

Annotion-Based SQL Maps: Part II (JDK 1.5)

I show you the code sample from iBatis SQL Maps 2.0 last post.
I continue realizing the idea:


public interface MyDAO {

@Sql(expr="
SELECT
ADR_ID as id,
ADR_DESCRIPTION as description,
ADR_STREET as street,
ADR_CITY as city,
ADR_PROVINCE as province,
ADR_POSTAL_CODE as postalCode
FROM ADDRESS
WHERE ADR_ID = ?value
")
public Address getAddress(int value);

}


Q: We need code genraotor to create a class from the SQL expression.
A: MiddleGen could help.
Q: Implement the above method using a proxy class, a runtime class-wrapper.
A: CGLIB or Javassist.
Q: Need parsing parameters in the SQL expression, and bind to method's parameters.
A: I think this can be done using in-house parser, or hacked from iBatis SQL Maps.

Tuesday, March 29, 2005

My Draft Notes on Class Versioning, O/R Mapping and Separation of Concerns

Review Rashid's works:


class Person<2.0> {
private String firstName;
private String surName;
}

class Person<1.0> {
private String firstName;
private String lastName;
}


Next step?
Separate, then later weave.
this means
+ We seperate when design --> yield easier design
+ We weave when use --> it must be complex enough to serve all business logics
+ Modification to EJB3 should be great (it's same to OODBMS, dont care RDBMS layer)

Why?
+ It's not possible to change all RBMS invesment to OODB
+ It seems that implementing virtual databases over the tranditional RDBMs is better
+ A virtual database (in my case OR/mapping - Hibernate, Ejb3) can be fully applied with AOSD
+ class versioning schema manager (Rashid 2002-2004)
+ annotation
+ concern
+ data alignment concern

This is an idea for separating Object and Relation concerns:


// teacher data concern
@Entity("Teacher", "1.0")
class Teacher {
private int teacherID;
private String firstName;
private String lastName;
}

@Entity("Student", "1.0")
class Student {
private studentID;
private firstName;
private lastName;
}

// separate advisor concern
@Entity("Teacher", "2.0")
class Advisor {
private List adviseeLists;
}

// separate advisor concern
@Entity("Student", "2.0")
class Advisee {
private Advisor advisor;
}

Teacher t = entityManager.load(Teacher.class,
new Integer(1));
Advisor a = versioningManager.morph(t,
Advisor.class);




This is a new idea for field substitution
How the developer access this code?
possible answer: IoC?


@Version(2.0)
class Student {
@Substitute(version="1.0", name="lastName")
private surName;
}

class StudentDAO {

public Student findById(int id) {
// codes go here ...
}

@Conform("th.ac.sut.ent.Student", "2.0")
public static void main(String args[]) {

Student s = new StudentDAO().findById(10);
// not found, throw exception
System.out.println(s.getLastName());
// should be ok
System.out.println(s.getSurName());
}
}

Monday, March 28, 2005

Idea on Annotaion-based iBATIS SQLMaps (JDK 1.5)

This is my proposal for hacking iBATIS SQLMaps to be annotation-based version.
After looking at the example, I saw the following code:


<select
id="getAddress" parameterClass="int"
resultClass="examples.domain.Address">
select
ADR_ID as id,
ADR_DESCRIPTION as description,
ADR_STREET as street,
ADR_CITY as city,
ADR_PROVINCE as province,
ADR_POSTAL_CODE as postalCode
from ADDRESS
where ADR_ID = #value#
</select>


can be changed to annotation attaching on a method of a Java interface.
#value# should be able to bind with the parameter, like this:


@Sql("select ... ")
public Address getAttress(int value);


Proxy-based AOP is enough for this implementation. A proxy class can be geneated at runtime, using the technique I proposed in SQLWarp.

later...

Wednesday, March 23, 2005

Refactored Suranaree.Galvanium (.NET/Java)

It is completely my fault trying to integrate some GUI features into my Galvanium framework. Now I refactor all GUI-related features out of the framework, and upgrade its dependencies (IKVM from 0.8 to 0.12, and lastest Hessian 3.0.8). The new binary will be posted soon. This version will be 1.0 M3.
Features

  • At least 250% faster than XML Web Services
  • Lightweight Protocol based on Hessian
  • Seamless Integration of J2EE objects and .NET GUI
  • Direct .NET/Java type mapping
  • Display/Edit Java objects in Databinding Controls of .NET
  • Works behind Firewall
  • Support Mock Object via ClientProxyFactory

Components
  • ClientProxyFactory
  • BeanDescriptor
  • BeanCollection

with additional 2 samples.

Tuesday, March 22, 2005

Annotion-Based Embedded SQL (JDK 1.5)

I wanna learn how to create and use annotations in JDK 1.5, so I got some idea from voruta.sf.net.
Voruta is an embedded SQL framework using Javadoc's style annotation. Based on the same idea, but mine is more dirty :), I implement data access framework for embedding SQL statement with JDK 1.5 annotation. I call it the SQLWarp. You can download and try it here.

UIB dbExpress Broker Patch for InstantObjects (Delphi)

I've submitted the patch to include UIB dbExpress driver for InstantObjects DBX broker to InstantObjects dev team.
It supports UIB Firebird15 driver, which is compatible with Firebird 1.5.x.
I tested this patch with Firebird 1.5.2 for Windows.

You can download the patched version from here (InstantDBX.pas) and replace it to [Brokers/DBX/InstantDBX.pas] under the InstantObjects folder.

Monday, January 03, 2005

Happy new Year and Welcome ECO II

Long time I was away from Borland's ECO (Enterprise Core Objects) aka Bold for Delphi in Delphi 7.
Now I'm playing around it in the new Borland IDE - Delphi 2005.
I downloaded the architect trial version, and recalled my OCL ability.

ECO II impressed me, however there are some bugs in the IDE when I try to make complex EcoSpace with .NET's namespaces and Eco's packages. The Delphi 2005's Model View doesnot refresh properly. I hope this is fixed by the update 1 patch :), but I cannot test it because there is no update 1 of Delphi trial version.

I did not follow the first version of ECO which is bundled with Delphi 8, thus I dont know its improvements. But comparing with Bold for Delphi, I found that ECO has been simplified very much. The coolest feature found in ECO II is the ability to use EcoSpace in distributed environment, and now it's time for me to try it.

Great job!! the Borland MDA team :)