Re: [Banshee-List] Some preliminary work in trunk - opinions needed



In no particular order:

Which is the preferred suffix: Adapter or Provider. Provider seems to be the .NET convention (i.e. IQueryProvider).

I'm going to move DatabaseModelProvider into a Hyena library. In it's present form it uses Mono.Data.Sqlite.SqlCommand (well, it actually uses BansheeDbCommand, which is more or less the same thing). Hyena.dll only has a reference to mscorlib. Solutions are: (1) add a reference to Mono.Data.Sqlite (which I'm sure is not desirable), (2) use strings instead of SqlCommands (which means that SqlCommands will need to be newed up each time we touch the db), or (3) create a new Hyena.Sql.dll library which does have a reference to Mono.Data.Sqlite.

Here is one possible object hierarchy (the Provider suffix is used here):

// Hyena.Data:
public class CacheableModelProvider<T>
public class DatabaseModelProvider<T> : CacheableModelProvider<T>
// Banshee.Collection.Database:
public class BansheeDatabaseModelProvider<T> : DatabaseModelProvider<T>
public class TrackListDatabaseModel : (other stuff)
{
    public class Provider : BansheeDatabaseModelProvider<TrackInfo>
}

Here is another

// Hyena.Data:
public class CacheableModelProvider<T>
public class DatabaseModelProvider<T>
// Obviously C# doesn't have multiple inheritance, but we'd make this work somehow
public class CacheableDatabaseModelProvider<T> : CacheableModelProvider<T>, DatabaseModelProvider<T>
// Banshee.Collection.Database:
public class BansheeDatabaseModelProvider<T> : CacheableDatabaseModelProvider<T>
public class TrackListDatabaseModel : (other stuff)
{
    public class Provider : BansheeDatabaseModelProvider<TrackInfo>
}

The benefit to the second option is that DatabaseModelProvider does not inhert from the CacheableModelProvider, so someone could use a DB without caching if they so desired.

On Dec 31, 2007 5:20 PM, Scott Peterson <lunchtimemama gmail com> wrote:
Apologies if this is a dupe email - I sent this to the list before and it didn't seem to make it.

So as I was looking over the LibraryTrackInfo-related code yesterday, I became increasingly concerned with the separation of concerns. If a database column were to be added, changed, or removed, multiple files would need to be edited in multiple places. Yesterday and today I prototyped a new design which drastically simplifies the architecture. The design is this: in a class which is bound to a db table ( i.e. LibraryTrackInfo), fields and properties have attributes which describe the way in which those members map to database columns. That is the only place in the code where the db columns are explicitly referenced. The general way it works is this: when the application starts, reflection is used to identify which members map to which columns and how. This information is then used to build SQL commands which will be used for interacting with the db. Since all commands are built on start-up, performance is essentially the same (although profiling is obviously in order).

So far I've just hacked together a prototype. It's limited:
  • It only applies to the LibraryTrackInfo stack right now.
  • It's not properly situated in the object hierarchy. I'd like to discuss exactly where and how this code should fit into the existing system.
  • It doesn't subsume all references to database columns (columns are still referenced in other places for things like creating the tables, sorting, &c.). Ideally it will. For instance, if you add a new property with a binding attribute to a db-bound class, a corresponding column will be created in the db on the next startup.
Since I just wrote this, I'd like to get some quick feedback so I can keep massaging the idea to see if it will be a viable solution. Give the patch a look if you're interested. It should give you a rough idea of what I have in mind. Comments, questions, critiques are welcome.

--
Scott.


--
Scott.



--
Scott.

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]