Implementing a counter using xslt - xslt-1.0

I have this xml
<?xml version="1.0" encoding="UTF-8"?>
<Input>
<Properties>
<Type Name="Type1">
<Property NAME="Prop1"/>
<Property NAME="Prop2"/>
<Property NAME="Prop3"/>
</Type>
<Type Name="Type2">
<Property NAME="Prop4"/>
<Property NAME="Prop5"/>
</Type>
<Type Name="Type3">
<Property NAME="Prop6"/>
</Type>
<Type Name="Type4">
<Property NAME="Prop7"/>
<Property NAME="Prop8"/>
</Type>
<Type Name="Type5">
<Property NAME="Prop9"/>
</Type>
</Properties>
</Input>
I need to implement a counter using xslt that will give me the total Property count under all types (in this case 9 ). Can it be done in xslt?

I need to implement a counter using xslt that will give me the total
Property count under all types (in this case 9 ).
No, you don't need to implement a counter.
Just use:
count(/*/*/Type/Property)
To answer your next question:
Can it be done in xslt?
No, mutable variables are not possible in a functional language (a category to which XSLT belongs) -- by definition. And having mutable variables is not necessary.
Any problem that can be solved in an imperative way (with mutable variables), can also be solved in a functional way -- without using mutable variables.

Related

NHibernate and Integer Columns as Version

I'm trying to create a DB Table, using an NHibernate *hbm.xml mapping file, that will have a Versioning Column for concurrency check. The Versioning column should be a nullable Integer.
Although the Database is created just fine, using the mapping file as reference, the following happen:
* The first record is inserted with a NULL value as the Version
* The update of the previously inserted records fails with a "Stale Data" exception
In other words, no matter what I do, the Version column is always NULL.
I'm somewhat new to the Concurrency Control using NHibernate, so I don't quite understand what I'm doing wrong..
If I use a Timestamp as a Version, everything works just fine. However, my requirement is to use an Integer.. Hence my problem.
This is my Mapping File:
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-lazy="true" auto-import="false" assembly="New1.Backend" namespace="New1.BO">
<class name="Natrio" table="`Natrios`" schema="`dbo`">
<cache usage="read-write" />
<id name="Id" column="`Id`" type="System.Int32">
<generator class="NHibernate.Id.Enhanced.TableGenerator">
<param name="increment_size">200</param>
<param name="segment_value">Natrios</param>
<param name="optimizer">pooled-lo</param>
</generator>
</id>
<version name="Version" column="`Version`" type="System.Nullable`1[[System.Int32, mscorlib]], mscorlib" generated="always" unsaved-value="0">
<column name="`Version`" not-null="false" sql-type="int" />
</version>
<property name="Attribute" column="`Attribute`" type="String" not-null="false" length="100" />
</class>
</hibernate-mapping>
Any thoughts and/or suggestions would be greatly appreciated!
Why do you need nullable version column? In any case I believe the issue is caused by unsaved-value="0" in your mapping. As default value for nullable column is null - NHibernate thinks that value is already generated and so it's never assigned. You need to set it to null - unsaved-value="null" to make it work with nullable columns. And unsaved-value="0" makes sense for not-nullable types. But better omit this attribute completely and let NHibernate to s
Another issue with generated attribute. It's about DB generation - so always means that this value is generated automatically by DB. You should remove it or specify it as generated="never".
I believe the following mapping should work for you:
<version name="Version">
<column name="`Version`" not-null="false" sql-type="int" />
</version>

Handle sqlplus substitution variables (&&vars) in Liquibase

my project is trying to migrate to liquibase but the lack of support for bind variables is making this difficult.
During our deployment we have sql scripts containing sqlplus substitution variables, like for example.
-- load_seed.sql ---
insert into <table>
values('&&host', '&&port', '&&user');
The value of these variables is different per environment, therefore we define profiles like these.
<DEV_profile.sql>
DEFINE host='dev.company.org'
DEFINE port=4008
..
<UAT_profile.sql>
DEFINE host='uat.company.org'
...
and the we run the deployment like this:
./deploy.ksh DEV
---- deploy.ksh ---
sqlplus <<END
<connection>
#$1_profile
#load_seed
The correct profile is picked up at execution time and the variables replaced.
Could you please suggest how to handle a case like this with Liquibase?
The equivalent functionality in Liquibase is provided by changelog parameters.
In your changelog, you define parameters, which are basically key-value pairs, and liquibase decides which value to use based on the value of a context or a label or a dbms.
When you want to apply the changeset to a given environment, you specify the context or label on the command line or in the liquibase.properties. Liquibase can determine the dbms based on the connection URL.
Here's an example that is somewhat similar to what you describe:
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
<property name="host" value="dev.company.org" context="DEV"/>
<property name="port" value="4008" context="DEV"/>
<property name="user" value="DEV_USER" context="DEV"/>
<property name="host" value="uat.company.org" context="UAT"/>
<property name="port" value="4321" context="UAT"/>
<property name="user" value="UAT_USER" context="UAT"/>
<changeSet id="1" author="joe">
<insert tableName="someTableName">
<column name="host" type="varchar(255)" value="${host}"/>
<column name="port" type="varchar(8)" value="${port}"/>
<column name="user" type="varchar(255)" value="${user}"/>
</insert>
</changeSet>
</databaseChangeLog>
https://docs.liquibase.com/concepts/basic/changelog-property-substitution.html
does not support sql changelog property substitution. you would have to migrate to (xml, yaml, json)

Using nHibernate secondary cache for a many-to-one reference

I'm trying to get nHibernate to use second-level cache with a many-to-one relationship, however I can't find any clear explanation on how to set it up correctly. I found this How to get nhibernate to cache tables referenced via many-to-one - is my config correct?, but the example sJHonny provided is for one-to-many and it's not working for me when I adopt it. There are other posts going over this subject, but none of them are specific enough.
The XML config I provide works (I had to edit dramatically, so "hopefully" works), but lookup objects are being cached only when they are retrieved as DataObject is queried. I'd like to know 1) where/how to preload the LookupObject collection? 2) what if I assign this collection to a region and set expiration, then where/how do I reload the cache again? 3) how to change the DataObject's hbm.xml such that nHibernate doesn't generate a join with the LOOKUP table, i.e. such that lookup objects always come from the secondary cache, only getting the DATA.LOOKUP_ID from the db, not the LOOKUP.NAME?
LookupObject.hbm.xml
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="BusinessObjects" assembly="BusinessObjects">
<class name="LookupObject" table="LOOKUP" mutable="false" batch-size="20">
<cache usage="read-only" />
<id name="Id" column="ID" />
<property name="Name" column="NAME" />
</class>
</hibernate-mapping>
DataObject.hbm.xml
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="BusinessObjects" assembly="BusinessObjects">
<class name="DataObject"
table="DATA" mutable="false">
<composite-id>
<key-property name="Id" column="ID"/>
<key-property name="Date" column="DATE" type="Date"/>
</composite-id>
<many-to-one name="LookupObject" not-null="true" column="LOOKUP_ID" fetch="join">
</class>
</hibernate-mapping>
I believe I answered my own questions. 1) For preloading the entire collection, I just needed to change my code such that the entire list of lookups is always pulled from the DB and cached, then I get the individual object by ID with LINQ. 2) Same as before. 3) I haven't tested this yet, but I need to remove fetch="join" from many-to-one element because otherwise the SQL join will still be generated and data will be still returned. Then set the lookup object without nHibernate by getting it from cache.

Change nhibernate config with nant xmlpoke

How can I change the connection string from nhibernate.config file using nant
the problem is that all examples are about changing attribute value, but nhibernate has inner text
eq:
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="connection.connection_string">Data Source.\server;Database=UnitTestDb;UID=user;pwd=pass;</property>
<property name="dialect">NHibernate.Dialect.MsSql2008Dialect</property>
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
<property name="show_sql">true</property>
<property name="connection.release_mode">auto</property>
<property name="adonet.batch_size">500</property>
....
I need to change property connection.connection_string
<xmlpoke file="${nhibernate.file}"
xpath="/hibernate-configuration/session-factory/add[#key='connection.connection_string']/#value"
value="${connection.string}">
</xmlpoke>
this does not work in this case.
Thanks
The sample xpath you're using refers to elements named add with attributes called key. In your case you are looking for property elements with attributes called name.
Next, since you want to change the inner text and not the #value attribute on the property element you should remove the trailing attribute reference.
And finally, since the NHibernate xml has a specific namespace you will have to inform xmlpoke to use the correct namespace.
So the task should look like this:
<xmlpoke file="${nhibernate.file}"
xpath="/nhc:hibernate-configuration/nhc:session-factory/nhc:property[#name='connection.connection_string']"
value="${connection.string}">
<namespaces>
<namespace prefix="nhc" uri="urn:nhibernate-configuration-2.2" />
</namespaces>
</xmlpoke>
Note: I've not tested this out, but general xml/xpath rules are in work here so I hope it works. Also, it could be that there is a way to indicate to xmlpoke that the specified namespace should be the default and thus eliminate the need to namespace prefix all the various parts in the xpath.
Good luck!

Inheritance: Criterion on entity type and sub class properties

I have a inheritance hierarchy which I have mapped in NHibernate using Table-per-class. My mappping file looks like the one below (lots of properties omitted).
To query this hierarchy, I am building a dynamic DetachedCriteria for Message based on filter input from the user. Messages (of any type in the hierarchy) should be returned to the user in one list.
I would like to build a criteria based on the type of message, ie. the user could specify to get all messages of type SMSMessage or EmailMessage with a ReceivedDate > '2009-01-01'. How would I go about to do that?
In the same query, the user could specify that if the Message is an InternalMessage, it should have Priority = 2. How would I specify such type-specific predicates?
All this is possible to do in LINQ, so I am hoping I can do it in NHibernate as well.
<class name="Message" table="Message" abstract="true" discriminator-value="null">
<id name="MessageId">
<generator class="identity" />
</id>
<discriminator column="Type" type="byte" />
<property name="ParentId" />
<property name="ReceivedDate" />
...
<subclass name="SMSMessage" discriminator-value="0">
<property name="Text" column="Text" />
...
</subclass>
<subclass name="MMSMessage" discriminator-value="1">
<property name="Subject" />
...
</subclass>
<subclass name="EmailMessage" discriminator-value="2">
<property name="BodyPlainText" />
...
</subclass>
<subclass name="InternalMessage" discriminator-value="4">
<property name="Priority" />
...
</subclass>
</class>
I kind of figured this out myself, but in the end I ended up reverting to pure SQL since I hit too many roadblocks with HQL/Criterias. Anyways, I can share how I did this.
Maybe not pretty, but I solved it by adding the discriminator column as a regular property to the top level class in the hierarchy (Message) and employed restrictions against that column.
It turns out that you can specify restrictions against properties for subclasses even in the top-level query, so this was easier than I thought. It was just a matter of specifying the restrictions.