Option 1 : Subclass Enummapping class

But that forces us to create several meaningless little classes just for the sake of mapping and if its always the string name of the enum why go through all that ?

Option 2 : Create a Generic Enum mapping usertype ..which might look like …

public class EnumMappingType : IEnhancedUserType , IParameterizedType
    {
        private Type enumClass;

        public  string Name
        {
            get { return "enumstring - " + enumClass.Name; }
        }

        public  Type ReturnedClass
        {
            get { return enumClass; }
        }
        public object StringToObject(string xml)
        {
            return null;
        }

        public object FromXMLString(string xml)
        {
            throw new NotImplementedException();
        }

        public string ObjectToSQLString(object value)
        {
            return GetValue(value).ToString();
        }
        public virtual object GetValue(object code)
        {
            //code is an enum instance.
            return code == null ? string.Empty : code.ToString();
        }

        public void SetParameterValues(IDictionary parameters)
        {
           enumClass = Type.GetType((string) parameters["enumClass"],true);
        }

        public  object FromStringValue(string xml)
        {
            return GetInstance(xml);
        }
        public virtual object GetInstance(object code)
        {
            //code is an named constants defined for the enumeration.
            try
            {
                return Enum.Parse(enumClass, code as string, true);
            }
            catch (ArgumentException ae)
            {
                throw new HibernateException(string.Format("Can't Parse {0} as {1}", code, enumClass.Name), ae);
            }
        }

        public  string ToString(object value)
        {
            return (value == null) ? null : GetValue(value).ToString();
        }

        public  bool Equals(object x, object y)
        {
            return (x == y) || (x != null && y != null && x.Equals(y));
        }

        public int GetHashCode(object x)
        {
            throw new NotImplementedException();
        }

        public object NullSafeGet(IDataReader rs, string[] names, object owner)
        {
            object code = rs[rs.GetOrdinal(names[0])];
            if (code == DBNull.Value || code == null)
            {
                return null;
            }
            return GetInstance(code);
        }

        public void NullSafeSet(IDbCommand cmd, object value, int index)
        {
            IDataParameter par = (IDataParameter)cmd.Parameters[index];
            if (value == null)
            {
                par.Value = DBNull.Value;
            }
            else
            {
                par.Value = Enum.Format(this.enumClass, value, "G");
            }
        }

        public object DeepCopy(object value)
        {
            return value;
        }

        public object Replace(object original, object target, object owner)
        {
            return original;
        }

        public object Assemble(object cached, object owner)
        {
            return cached;
        }

        public object Disassemble(object value)
        {
            return value;
        }

        public SqlType[] SqlTypes
        {
            get { return new[] { SqlTypeFactory.GetString(10) }; }
        }

        public Type ReturnedType
        {
            get { return enumClass; }
        }

        public bool IsMutable
        {
            get {return false; }
        }
    }
 

And the corresponding mapping file can be ( you can also create shortcut typedef’s btw )

<property  name="EnumPropertyName">
      <column name="EnumPropertyName" sql-type="nvarchar(50)" not-null="true"/>
      <type name ="....EnumMappingType, Assembly.Name">
        <param name ="enumClass">Your.Enum.ClassName</param>
      </type>
</property>

Hope that helps someone out there !!!


This  is a cookbook for creating Python extensions in C/C++ under Windows with SWIG, distutils and gcc (MinGW version).
I am using to the following versions

1 . SWIG Version 1.3.24

2 . Python 2.3.4

3.mingw 3.0.0

1. Get and install MinGW gcc
Download the compiler from http://www.mingw.org. This GCC compiler runs under Windows and compiled programs do not require support DLL like CygWin GCC.

You only need to download MinGW-1.1.tar.gz (roughly 10,6 Mb). It contains the whole compiler, support utilities, documentation, librairies and header files.

Once decompressed, you should add the \bin directory of MinGW to your path environment variable.
(Example : Under Windows 95/98/ME, if you installed MinGW to c:\gcc, you would add SET PATH=c:\gcc\bin;%PATH% to your AUTOEXEC.BAT.)

If installed properly, you should be able to run gcc –version anywhere. (Mine displays : 2.95.3-6).

2 . Get and install Python
Download the executable from http://www.python.org . As usually set the path to run python from anywhere.

3 . Create libpython23.a
To create Python extensions, you need to link against the Python library. Unfortunately, most Python distributions are provided with Python23.lib, a library in Microsoft Visual C++ format. GCC expects a .a file (libpython23.a to be precise.). Here’s how to convert python23.lib to libpython23.a:

Download pexport (from here or http://starship.python.net/crew/kernr/mingw32/pexports-0.42h.zip).
Get Python23.dll (it should be somewhere on your harddrive).
Run : pexports python23.dll > python23.def
This will extract all symbols from python23.dll and write them into python23.def.
Run : dlltool –dllname python23.dll –def python23.def –output-lib libpython23.a
This will create libpython23.a (dlltool is part of MinGW utilities).
Copy libpython23.a to c:\python23\libs\ (in the same directory as python23.lib).
This trick should work for all Python versions, including future releases of Python. You can also use this trick to convert other libraries.

4. Get and install SWIG
SWIG is a wrapper for C/C++ sources. It allows you to use C/C++ functions and classes to Python with a minimum effort.

Download SWIG binaries for Window ( Swigwin ) from http://www.swig.org, decompress them and add swig directory to your path (the directory where swig.exe is located).

5 . Write .i files
Write the .i files corresponding to your c++ files ( for more on how to write these files visit http://www.swig.org )

6 . Use the following commands to get it going

A . swig –python –c++ example.i

output: example.py & example_wrap.cxx
B. g++ -c *.c++

output: .o files corresponding to your C++
C. g++ -c example_wrap.cxx -Ic:\python23\include

output: example_wrap.o
D. g++ -shared *.o -o _example.pyd -Lc:\python23\libs -lpython23

output: _example.pyd

Hopefully this worked . Now you can do an “ import example “ in python .


I finally managed to get a 0.1 release out of the door for my breakable toy itunes-importer .

This is a windows only release , I still have to iron out few kinks for the Mac version .

You can choose the providers which get queried and can edit ( or paste your own) lyrics before applying them to a track.

The UI is primitive ( but usable ) , on which I plan to work after I get the mac version working.

lyrics importer 0.1


Inevitably, every  few months someone over at DDD ( domain driven design ) mailing list seems to ask the question ..

“Should domain objects call service methods ?” .  There are few people who seem to think that domain model should be a pristine place where only rightyworthy  get to live (Classes have to earn this right by being an parallel to something  in real world) . And there are few others who believe in making concessions to make domain model richer and self contained , and if your domain code is never going to be packaged on its own and used outside of the application for which it was originally designed why make this artificial divide .

The pros and cons to such approach can be breifly summried as ,

Pros :

  1. Makes domain model richer by hiding underlying data retrival logic .

  Cons :

  1. Model objects aren’t serializable .
  2. May break transactional data access semantics in some cases .
  3. Calling Methods on Domain models involves overhead of data retrieval which may not be obvious if not documented.
  4. domain model should be “concerned” only with modeling the business domain.
  5. May contribute to “Knowledge leak” from domain objects into service laye

references :

  1.  http://blog.hibernate.org/cgi-bin/blosxom.cgi/2004/08/10#v3-filters
  2. http://www.almaer.com/blog/archives/000966.html
  3. Discussion on spring forum http://forum.springframework.org/archive/index.php/t-9874.html

warning : Narrowly focussed techy ( boring ) post

What is a long running session and why is it useful ?

[ This is mostly focussed on using hibernate session in a desktop app but most of it might be applicable to web app too ]

As the name suggests the whole user interaction with the app would consist of one single long living session and all ( main) the communication with the database would be through this session. Your “unit of work” would now encompass all the user interaction with the application …meaning your “application transaction ” ( ref 7 ) is the whole life of the application.

Why ? 1. The Biggest driver for doing this seems to be ablity to use hibernate’s lazyintialization capabilities , for example a dialog displaying Book information can dynamically populate author information when the drop down combo box is selected.

2. Since all the modifications to underlying data is done through this single long running session , you can explicitly demarcate transaction boundries at convinient locations .

3. Take advantage of session cache without having to load/unload object each time from the DB.

How :

If you perform all the major work in GUI thread ( almost all java GUI systems are single event threaded( ref 4 ) you can use tweak thread local pattern to get the main session from a GUI thread .

Issues:

Above advantages might paint a rosy picture but using long running sessions without much forethought might cause some serious problems that might not really be apparent untill the application get big or complex enough .

  1. Your app might suffer from ” bloated session cache ” phenomenon..with each your application getting slower and slower with as the session cache grows bigger and bigger as hibernate has to go through all the objects in the session cache for every query ( with huge session this might slow you down ,If the session gets big, flushing it will take more and more time, even if there are no changes). Essentially advantage no 3 above can become a disadvantage ( due to hibernates transactional write-behind ) if session in allowed to grow big. A workaround that might be useful in some cases might be to use query.setReadOnly(true) , session.setReadOnly() for queries/ entities which load up readonly objects into the session.
  2. Manual “eviction” to keep session consistent, You might have use sql queries for various reasons in various places in the app to perform updates/deletes in such case you have do manual evicts in order to keep session from being corrupted.
  3. Transactional write-behind might come in your way ( depending on how you manage long running session ) if you plan to access data from “other sessions” .
  4. User might experience GUI freezing when hibernate is doing its lazyloading magic.
  5. Classic lazy loading n+1 query problems ( see links below)
  6. Stale data problems .if the data is updated by some background job or thread not using the main session ..your main session will not be up to date with the changes.

References:

  1. Hibernate wiki on this topic :http://www.hibernate.org/333.html
  2. http://blog.xebia.com/2006/10/02/golden-hibernate/
  3. Multi threaded GUI’s , failed computer science dream http://weblogs.java.net/blog/kgh/archive/2004/10/multithreaded_t.html
  4. http://www.zorched.net/2006/08/23/hibernate-hql-and-performance/
  5. http://www.jroller.com/page/tfenne?entry=hibernate_understand_flushmode_never
  6. Quick description of hibernate flush modes : http://static.springframework.org/spring/docs/1.1.5/api/org/springframework/orm/hibernate/HibernateAccessor.html
  7. A very old ( but still relavent) blog on hibernate team blog http://blog.hibernate.org/cgi-bin/blosxom.cgi/2004/01/27

Tumblr feed

14Feb08

I am one of those annoying  ” sing along ” types when I listen to music . Since the new iphone  update  added lyrics capability to iphone i was looking for an easy way to add lyrics to my tracks .  After hours of googling ..surprisingly I couldnt find a single decent  app to do that.

So I’ve decided to roll my own app to do that ..

itunes lyrics importer screenshot

http://code.google.com/p/lyricstune/

Application basically  queries iTunes for tracks ( 5 at a time ) and hits few lyrics apis to fetch the lyrics ,

I’ve found two such apis till now ,

  1.   http://www.leoslyrics.com/ [ This one also give you alternate suggestions if it cannot find exact match ]
  2. http://lyricwiki.org/Main_Page  [ Gives you exact matches only ]

I’ve not created any installers yet for either windows or mac ( hoping to do that soon ) and ui is also rough . Hopefully , I can get to those in few days.