I have checked in the first semi-working code base of Gentle 2.0:
In the following I'll try to summarize the changes made so far, list the
remaining issues before 2.0 can be released, and give some perspectives
on the roadmap and backwards compatibility. This is a lengthy email, so
go get a fresh cup of coffee first ;)
The project layout has been reworked. The code is now much better
organized, and separate components are not entangled with each other.
Also, all external libraries (that are not provider-specific) have been
moved to a separate folder in the solution base.
Gentle.Configuration is the improved configuration subsystem, which has
mostly been back-ported to Gentle 1.x. It is capable of handling
multiple stores (so you can have multiple data sources), automatic
best-callback method detection, single items and lists, automatic type
Gentle.Reflection contains a set of Meta-classes (and helpers) that
encapsulate the reflection code. These provide seamless access to
"dynamic functionality", such as invoking a method using a set of
unordered parameters. The project also contains the core of the new
unified type system, which allows Gentle to work with a single type
descriptor across all providers. This has paved the way for mixing
providers, and centralized all null handling and type conversion logic
(which should result in a lot more robust code). Thanks to Josh Carlson
for contributing the bulk of the code for this!
Gentle.Persistence contains the persistence code which used to be in
Gentle.Framework. The code has been severely reorganized to accomodate
the new infrastructure classes. Many classes have been renamed or
altered so severely that they have little in common with their old
counterpart, others have been dropped or replaced entirely. Despite all
of these changes I am hopeful that backwards compatibility won't be an
issue (more on this later).
Changes and Improvements
A database provider now has its own registries for types, schema
metadata, and type mappings. The type registry is configuration file
driven, which means that adding support for new types will be very easy.
Type mappings can now reference multiple tables, which permits complex
mappings of all sorts.
SqlBuilder has been replaced by a new set of classes. Various classes
are provided for query construction, and these permit you to build a
type-less semi-graph of what you want to do. Upon execution, this
semi-graph is transformed into another graph (where all the bits have
been placed at the location they should be rendered). This
transformation also determines the type of fields/expressions, so that
the correct type can be used with associated parameters. All values are
transformed to parameters, and parameters are assigned a unique name.
Next comes the rendering phase, which traverses the graph and emits the
actual query string. The result is a QueryExecutable (replaces
SqlStatement) which is essentially a provider-specific representation of
the original query. Other classes have been added or reorganized, but
overall this should provide for a much more flexible, maintainable,
robust and just plain better query backend. (As a side note on this,
I've tried 2 graph frameworks and 3 template engines before finally
coming up with this custom solution; it's been the key obstactly to
Gentle moving forward for the last 12 months, and it's finally there! -
A QueryFactory class has been added for generating provider-independent
queries or query fragments (such as an expression for use in a where
clause). It returns a QueryChain (a collection of Query instances)
because a type may map to multiple tables (and as such, multiple queries
may be needed to operator on the type). Execution of queries is handled
by a new QueryExecutor class.
PersistenceBroker has been renamed to GentleSession, however, this is
mostly legacy from before the project was renamed and the old code
dropped. It is now possible to select a type using an expression as a
filter, and the request interface has generally been improved a lot
(e.g. you can modify Gentles behavior using flags).
Last, I've added a sample project called Gentle.KarmaCalculator, whose
database schema has been designed to test and exercise both new and old
features. Existing test cases will be migrated where relevant and as the
code base stabilizes. KarmaCalculator is intended as a small application
for managing the karma of individuals subscribing to a particular belief
system (religious or otherwise). I'll be using this as a theme
throughout the tests, primarily based on the belief system called
"Mortens Coding Guidelines", in which it is easy to commit a sin ;-)
While I'm sure there have been many other improvements, let's proceed to
have a look at the (almost certainly incomplete) todo-list.
Before Gentle 2 becomes a viable replacement for 1.x the following key
issues must be fixed:
o Reserved words handling in the renderer (at least now its centralized
and easy to address)
o NULL equals comparisons (= is not translated into IS)
o Implement object idenity management facility (compute cache keys,
o Add IIdentityProvider for identity providers; implement providers
for Guid, int, etc.
o Add events (for stats, caching, logging, etc.)
o Rework GentleList into GentleCollectionBase, CollectionManager,
o Add missing stuff to TypeMap, QueryFactory and ObjectFactory
o Add ability to merge queries into one (QueryExecutor)
o Fix parameter code in QueryChain (obsolete?)
o Add transaction code to GentleSession
o Port the remaining providers (only SQL Server supported at this time)
o All the little things here and there, including TODO items in the code
o Much more testing and bugfixing
o Documentation (code and otherwise)
I believe that when these items have been completed, Gentle 2.x is ready
to be released. Following this I would like to see the following features:
o Documentation (upgrade documentation)
o Templates (updated MyGeneration template)
o Paged queries (current 2.x code base does not handle paged queries)
o Plugin subsystem (for better code separation and easier extensibility)
o Create/drop/alter support
o Implement a GUI for KarmaCalculator
o Add a setup/installer project
If there is demand for it, backwards compatibility could be addressed by
implementing Gentle.Framework as a stub (using Gentle.Persistence for
any data access operations). The fact that the two use separate
namespaces makes it much easier to decide what code to keep in the new
project, and should also permit this solution as an upgrade path.
Some things will not be supported by such a stub library. Most likely
there would be no mapping subsystem, so any direct calls to
ObjectFactory or references to ObjectMap would fail. Base classes would
need to reference the new library, otherwise any interfaces and
attributes will not get picked up. GentleList and ObjectView would also
not work. GentleList is available in the new project, and the code for
ObjectView could be refactored out into separate helper classes (either
provided as such or in a Gentle.Web project as part of the solution).
It's difficult to say without trying how much effort this will be, or
whether it can succeed at all, but it's the best option I've been able
to think of.
Nothing is set in stone at this time, and there is still a lot of work
ahead. However, the main obstacles have all been overcome and as such
I'm starting to be optimisitic about a release some time late this summer.
As always, any comments or questions are welcome. I for one would love
to know what you think of all the changes :-)