IQueryable Extension to Generate Temporal Table "AS OF" Queries - sql

Having failed to find a satisfying solution, let me post this here:
We're using NHibernate as our ORM and are just beginning to use Sql Server temporal tables. We therefore need some kind of extension to IQueryable (or the HQL Builder or an InterceptingProvider or something) that will allow us to add the "AS OF" clause to our queries, something like
var results = session.Query<Company>
.Where(c => c.Name == "FogCreek")
.AsOf(DateTime.Today.AddYears(-1));

I've been struggling with it too and gave up as I lost too much time trying to find better approach...
So far I've injected FOR SYSTEM_TIME AS OF into SQL using custom HqlGeneratorForMethod but this gave me invalid SQL expression. So I had to fix it in OnPrepareStatement. This is hacky and not elegant solution but works for most simple cases.
Please look at my solution here and feel free to reply if you find better solution

Related

Pure SQL queries in Rails view?

I am asked to display some sort of data in my Rails App view with pure SQL query without help of ActiveRecord. This is done for the Application owner to be able to implement some third-party reporting tool (Pentaho or something).
I am bad in SQL and I am not really sure if that is even possible to do something similar. Does anyone have any suggestions?
If you must drop down to pure SQL, you can make life more pleasant by using 'find by sql':
bundy = MyModel.find_by_sql("SELECT my_models.id as id, my_articles.title as title from my_models, my_articles WHERE foo = 3 AND ... ...")
or similar. This will give you familiar objects which you can access using dot notation as you'd expect. The elements in the SELECT clause are available, as long as you use 'as' with compound parameters to give them a handle:
puts bundy.id
puts bundy.title
To find out what all the results are for a row, you can use 'attributes':
bundy.first.attributes
Also you can construct your queries using ActiveRecord, then call 'to_sql' to give you the raw SQL you're using.
sql = MyModel.joins(:my_article).where(id: [1,2,3,4,5]).to_sql
for example.
Then you could call:
MyModel.find_by_sql(sql)
Better, though, may be to just use ActiveRecord, then pass the result of 'to_sql' into whatever the reporting tool is that you need to use with it. Then your code maintains its portability and maintainability.

Doctrine - strange moved parenthesis in the query

I have tested and done quite some research online, but still no luck. Did anyone ever encounter this problem ?
Say, I have a doctrine query set up like:
$q = Doctrine_Query::create()
->update('PckFolder')
->set('id_path', "CONCAT(?, RIGHT(id_path, LENGTH(id_path)-?))", array($newPath, $lenOld))
->where("id_path like '$oldPath%'");
// and I print the query out
$qstr = $q->getSqlQuery(array($newPath, $lenOld));
Instead of giving me:
UPDATE pck_folder SET id_path = CONCAT(?, RIGHT(id_path, LENGTH(id_path)-?)) WHERE (id_path like '1/2//%')
Doctrine gave me:
UPDATE pck_folder SET id_path = CONCAT(?, RIGHT(id_path, LENGTH(id_path-?))) WHERE (id_path like '1/2//%')
please note this part RIGHT(id_path, LENGTH(id_path)-?)
(Note: I'm assuming you're using Doctrine 1.2. I haven't used Doctrine 2.0 yet.)
I had not encountered that specific bug before, but I have found numerous problems with the implementation of update() in Doctrine_Query. Essentially anything but the most very straightforward update queries will cause the parser to generate wrong or invalid queries. For example, it can't handle sub-selects within an update.
Try writing a Raw SQL query, or else use a less efficient but fully-functional workaround: Select the records you want to update using Doctrine_Query, then iterate over them and set the field in PHP, then call save() on each one.
By the way, there's a big GOTCHA inherent with use of UPDATE queries and Doctrine that sort of forces you to use that workaround in many cases anyway. That is, if you or your plugins have made use of the nifty Doctrine hook methods within your models but you execute a SQL-level update that affects those records, the hooks will get silently circumvented. Depending on your application, that may wreck your business logic processing.

Nhibernate : QueryOver equivalent for ICriteria's SetComment?

Is is possible to add a comment to generated by queryover query in Visual Studio's output?
Previously when we were using ICriteria, there was simple SetComment method and we could set the query name so it was much easier to find specific query in output full of long (almost the same) queries. If it is possible we would prefere to add such comments without converting query to ICriteria.
I don't think there is a direct way of doinf it, but you can try with:
QueryOver<Entity>()
.Where(...
.UnderlyingCriteria.SetComment("....")

Hibernate and dynamic SQL

do you know anything about Hibernate and its ability to generate dynamic sql queries with HQL?
I you have any links I would appreciate posting, I can't find nothing about it in Hibernate`s documentation.
Best regards
Gabe
//edit
so maybe I will precise what I mean. I am wondering if some HQL code generates SQL queries which uses something like EXECUTE (for postgres)
Not sure what you're aiming for here? HQL in Hibernate will always generate SQL, and you can put your HQL together differently based on input. It will always generate new SQL for each permutation and run. You can make Hibernate precompile/cache queries but that's just a performance optimization and shouldn't be your first concern.
I would also consider looking into the Criteria API which lets you stay a lot more object oriented instead of working with tons of strings.
If you're talking about static queries using dynamic arguments, the syntax is
select f from Foo f where f.bar = ? and f.zim = ?
or, with named parameters
select f from Foo f where f.bar = :bar and f.zim = :zim
If you're talking about completely dynamically created queries based on a set of criteria, then the API to use is... the Criteria API.
Both are largely covered in the Hibernate reference documentation.

Is there a way to combine results from two IQueryable<T> using NHibernate & Linq?

I have two separate queries that both return the same IQueryable, and I'd like to combine them prior to projection. It looks like neither Union or Concat are implemented in Linq to NHibernate? Does anyone know how I might go about achieving this?
It's not possible. You'll have to do it on the client.
Example:
var allItems = queryable1.AsEnumerable().Concat(queryable2)
#Diago Mijelshon gives a good answer, but I would like to add that depending on what you're doing with the data, you may need to first cast it to an array or list so that NHibernate doesn't try to do any funny stuff with your operations.
I've used Entity Framework for years and I'm well familiar with this, and I've only used NHibernate a little bit, but the two tools appear to be similar in this regard.