Mondrian doing sub-select on group by oracle - olap-cube

When I do this dimension:
<Dimension ForeignKey="ID_PROCESSO" highCardinality="false" name="Adverso Principal">
       <Hierarchy Name="Adverso Principal" hasAll="true" allMemberName="Todos the Adverse Principais">
         <level Name="Adverso Principal" table="m_entidade" column="NOME" type="string" uniqueMembers="true" levelType="Regular" hideMemberIf="Never">
         <KeyExpression>
         <SQL dialect="generic">
         (
select NAME from D_PROCESSO_PARTE
         left join M_ENTIDADE on D_PROCESSO_PARTE.ID_ENTIDADE = M_ENTIDADE.ID_ENTIDADE
         where D_PROCESSO_PARTE.CLIENTE = 'F'
         and M_PROCESSO.ID_PROCESSO = D_PROCESSO_PARTE.ID_PROCESSO
)
         </ SQL>
         </ KeyExpression>
         </ Level>
       </ Hierarchy>
     </ Dimension>
He's putting in the sub-select group by, and the oracle that is not allowed. Someone already Tave any similar problem?

This could be a bug. Mondrian uses dialects internally to figure out what is allowed on a given database. It should know that Oracle doesn't support this. You won't be able to fix this unless you change the code and recompile yourself.
You should report this on the project's bug tracking system.

Related

PropelORM+PostgreSQL: How do I define an SQL-like CHECK constraint on a column in 'schema.xml'?

A little snippet of a database schema I'm trying to define in my "schema.xml" file:
<table name="hotelroom" phpName="hotelroom">
<column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true" />
<column name="room_number" type="varchar" size="10" required="true" />
<column name="price" type="numeric" defaultValue="1000" required="true" />
<unique>
<unique-column name="room_number" />
</unique>
</table>
In PostgreSQL for that "price" column I would've written CHECK (price > 0::numeric),but I can't seem to find any way to achieve this here.I've checked the documentation (http://propelorm.org/documentation/reference/schema.html), but couldn't find anything on this.
Thank you for the time.
You're using v1, but from the doc link above, looks like you're using v2,
I think you're looking for the GreaterThan which is only available from v2 onwards.
<behavior name="validate">
<parameter name="rule1" value="{column: price, validator: GreaterThan, options: {value: 0, message=Price is not valid}}" />
</behavior>

How to load entities of which a property of type PersistentList contains one or more values from array parameter?

My model contain the following enumeration and entity:
<cf:enumeration name="Language" usePersistenceDefaultValue="false">
<cf:enumerationValue name="EN" value="1" default="true" />
<cf:enumerationValue name="NL" value="2" />
<cf:enumerationValue name="DE" value="3" />
</cf:enumeration>
<cf:entity name="Person" >
<cf:property name="Id" key="true" />
<cf:property name="Languages" typeName="CodeFluent.Runtime.Utilities.PersistentList<Language>">
<cf:message class="_doc">The languages that the person speaks</cf:message>
</cf:property>
<cf:method name="LoadPersonThatSpeaksOneOrMoreLanguages" checkLevel="None" memberAttributes="Public" >
<cf:body language="tsql" text="load(Language[] languages) from Person where Languages in (#languages)" />
</cf:method>
</cf:entity>
The method LoadPersonThatSpeaksOneOrMoreLanguages should return all persons that speak one or more of the provided languages.
The generated stored procedure for this method seems not to be correct:
ALTER PROCEDURE [dbo].[Person_LoadPersonThatSpeaksOneOrMoreLanguages]
(
#languages [dbo].[cf_type_Person_LoadPersonThatSpeaksOneOrMoreLanguages_0] READONLY,
#_orderBy0 [nvarchar] (64) = NULL,
#_orderByDirection0 [bit] = 0
)
AS
SET NOCOUNT ON
DECLARE #_c_languages int; SELECT #_c_languages= COUNT(*) FROM #languages
SELECT DISTINCT [Person].[Person_Id], ...
FROM [Person]
WHERE [Person].[Person_Languages] IN (((SELECT * FROM #languages)))
Question 1:
How can I achieve the desired result?
Should I create a Language entity and specify an 1:n association between Person and Language? I prefer not to have a Language entity.
Or can I specify that the Languages property must be converted to the same type as the table-valued-parameter (cf_type_Person_LoadPersonThatSpeaksOneOrMoreLanguages_0)?
Question 2:
The produced PersonCollection class contains the method LoadPersonThatSpeaksOneOrMoreLanguages. The parameter of this method is of type Language[]. Instead of an array I want an IEnumerable<Language>. How can I specify this in my XML model?
Question 1
The PersistentList is designed to store a collection of simple values (int, string, enum, ...), but not to query them directly in SQL. Indeed the PersistentList is translated to a NVARCHAR column in the database and this column contains values like EN|NL (pipe separated values). The database engine does not know how to extract single values from the string. Maybe you can use the cf_SplitString function to create a table from the column value and do what you want with it, but it does not seem to be the simplest solution...
Depending of your need you can use a multi-valued enumeration:
<cf:enumeration name="Language" flags="true">
<cf:enumerationValue name="Unspecified" /> <!-- value=0 -->
<cf:enumerationValue name="EN" /> <!-- value=1 -->
<cf:enumerationValue name="NL" /> <!-- value=2 -->
<cf:enumerationValue name="FR" /> <!-- value=4 -->
</cf:enumeration>
You can use them with CFQL:
-- Load Persons that speak the specified language
LOAD(Languages) WHERE (Languages & #Languages) = #Languages
-- Load Persons that speak at least one of the specified language
LOAD(Languages) WHERE (Languages & #Languages) <> 0
Of course the latest possibilities is to create a Language entity and use Table Valued Parameters.
http://blog.codefluententities.com/2014/07/16/persistent-list/
http://www.softfluent.com/documentation/Enumerations_Overview.html
Question 2
From the official blog of CodeFluent Entities:
Take what I say with a grain of salt as you are dealing with a topic I have looked into but never implemented. With that said another approach would be to use a multi-valued enumeration (flag)
http://blog.codefluententities.com/2013/05/29/using-flags-enumeration-with-aspnet-mvc-and-codefluent-entities
Using this approach you would create a relationship between the entity and the enumeration instead of making the Languages property a persistent list.
The following mostly works. When using the Modeler to create instances I was not able to select certain combinations of languages. Don't know if this was due to my inexperience in working with and setting up flag enumeration or if there is a flaw in the modeler. But I did manage to create the method and that part appears to be working.
<cf:enumeration name="Language" multivalue="true" usePersistenceDefaultValue="false" namespace="Demo1" categoryPath="/Demo1">
<cf:enumerationValue name="Unspecified" default="true" />
<cf:enumerationValue name="EN" />
<cf:enumerationValue name="NL" />
<cf:enumerationValue name="DE" />
</cf:enumeration>
<cf:entity name="Person" namespace="Demo1">
<cf:property name="Id" key="true" />
<cf:property name="Languages" usePersistenceDefaultValue="false" typeName="{0}.Language" />
<cf:property name="FirstName" />
<cf:property name="LastName" />
<cf:instance>
<cf:instanceValue name="Id">d13447c6-a709-4c87-891d-e83674821915</cf:instanceValue>
<cf:instanceValue name="FirstName">Jon</cf:instanceValue>
<cf:instanceValue name="LastName">Smith</cf:instanceValue>
</cf:instance>
<cf:instance>
<cf:instanceValue name="Id">77e3730c-2cc3-457d-8bc0-d9a5e224b96a</cf:instanceValue>
<cf:instanceValue name="FirstName">Sam</cf:instanceValue>
<cf:instanceValue name="Languages">DE, SP</cf:instanceValue>
<cf:instanceValue name="LastName">Newman</cf:instanceValue>
</cf:instance>
<cf:method name="LoadPersonThatSpeaksOneOrMoreLanguages" body="LOAD() WHERE Languages > 0" />
As I said take what I'm saying with a grain of salt. I ended up using an entity instead of an enumeration but only because that was what I was more familar with and had a deadline.

resultMap for complex query

I've got some query which returns data that does not have any object for it.
SELECT b.id,
b.publisher_id,
b.name,
b.size,
b.present,
CASE WHEN b.id in (SELECT book_id FROM downloads)
THEN true
ELSE false
END as downloading,
b.display,
b.download_date
FROM books as b
WHERE b.publisher_id = ${pId} AND b.display = true
LIMIT ${pageSize} OFFSET ${startId}
Field downloading does not have any column in database.
The mapper for object b is
<resultMap id="bookMap" type="Book">
<id column="id" property="id" />
<result column="publisher_id" property="publisherId" />
<result column="name" property="name" />
<result column="size" property="size" />
<result column="present" property="present" />
<result column="display" property="display" />
<result column="download_date" property="downloadDate" />
</resultMap>
How to create mapper for such object - where part is already existed resultMap but added new column.
One of the way is to create new class which will contain book with downloading status:
class BookWithDownloadingStatus {
private Book book;
private boolean downloading;
// I've omitted setters and getters
}
After that you can use this class to map result of the above query:
<resultMap id="bookWithDownloadingStatusMap" type="BookWithDownloadingStatus">
<result column="downloading" property="downloading"/>
<association property="book" resultMap="bookMap"/>
</resultMap>
<select id="getBookWithDownloadingStatus" resultMap="bookWithDownloadingStatusMap">
-- the above select
</select>
By the way, your query will not perform paging correctly. Database doesn't guarantee any order and without order limits and offsets are mostly useless. You should always specify ordering otherwise items may be distributed randomly between pages.

Mule and JDBC Query Result

I am using mule to connect to a Postgres database server.
I can't use the datamapper since I am using the community edition.
The object to xml transformer is not giving a good formatted result.
Any ideas of how I can transform the jdbc response into a good format for parsing.
Here is my configuration file.
This is the datasource with the connector.
<jdbc:postgresql-data-source name="PostgreSQL_Data_Source"
user="USERNAME" password="PASSWORD"
url="jdbc:postgresql://*******:***/*****"
transactionIsolation="UNSPECIFIED" doc:name="PostgreSQL Data Source" />
<jdbc:connector name="organizations" dataSource-ref="PostgreSQL_Data_Source"
validateConnections="true" queryTimeout="-1" pollingFrequency="0"
doc:name="JDBC">
<jdbc:query key="getOrganizations" value="SELECT * FROM organization" />
<jdbc:query key="getOrganizationApplications"
value="SELECT * FROM organization o,application a,organization_apps oa WHERE o.id=oa.org_id AND a.id=oa.app_id AND o.id=#[flowVars['org_id']]" />
<jdbc:query key="insertOrganization"
value="INSERT INTO organization(name, phone, email, address, website) VALUES (?, ?, ?, ?, ?)" />
<jdbc:query key="getOrganizationUsers"
value="SELECT * FROM &quot;public&quot;.user WHERE org_id=#[flowVars['org_id']]" />
</jdbc:connector>
and this is the flow:
<flow name="logixy-platform-organizations-workflow" doc:name="logixy-platform-organizations-workflow">
<http:inbound-endpoint exchange-pattern="request-response"
host="localhost" port="8082" doc:name="HTTP" path="organization" />
<set-variable variableName="choice"
value="#[message.inboundProperties['choice']]" doc:name="Set Choice" />
<choice doc:name="Choice">
<when expression="#[flowVars['choice'] == '0']">
<jdbc:outbound-endpoint exchange-pattern="request-response"
queryTimeout="-1" doc:name="getAllOrganizations" connector-ref="organizations"
queryKey="getOrganizations" />
</when>
<when expression="#[flowVars['choice'] == '2']">
<set-variable variableName="org_id"
value="#[(int)(message.inboundProperties['org_id'])]" doc:name="Set Organization ID" />
<jdbc:outbound-endpoint exchange-pattern="request-response"
queryKey="getOrganizationUsers" queryTimeout="-1" connector-ref="organizations"
doc:name="getOrganizationUsers" />
</when>
<when expression="#[flowVars['choice'] == '1']">
<set-variable variableName="#['org_id']"
value="#[(int)(message.inboundProperties['org_id'])]" doc:name="Set Organization ID" />
<jdbc:outbound-endpoint exchange-pattern="request-response"
queryKey="getOrganizationApplications" queryTimeout="-1"
connector-ref="organizations" doc:name="getOrganizationApplications" />
</when>
</choice>
<mulexml:object-to-xml-transformer
doc:name="Object to XML" />
</flow>
You should really define "a good format for parsing", but I guess you don't like the "entry", "string", etc field names.
You have plenty of options to format the XML, for example:
use XSLT to transform the generated XML to your preferred format
define a class in Java or Groovy that corresponds to your return data and then either
use object-to-json and then json-to-object with your class as return class
assign the return data to objects of your class in Java or Groovy
Once you have your data as custom objects, object-to-xml-transformer will print produce a much cleaner output.

Must Be Mapped. It has no default value and is not nullable

I'm just starting to learn EF. The problem I'm facing is with TPH. The example below is from the EF recipes by apress. The table is basically this:
CREATE TABLE [Chapter2].[Employee](
[EmployeeId] [int] IDENTITY(1,1) NOT NULL,
[EmployeeType] [int] NULL,
[FirstName] [nvarchar](50) NOT NULL,
[LastName] [nvarchar](50) NOT NULL,
[Salary] [decimal](18, 0) NOT NULL,
[Wage] [decimal](18, 0) NOT NULL,
CONSTRAINT [PK_Employee] PRIMARY KEY CLUSTERED
(
[EmployeeId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
After creating table and importing it into EF. I made two entities, one FullTimeEmployee and HourlyEmployee. I'm setting the condition under employee type to 1 for the full time one and 2 for the hourly one. I'm, of course deleting the property from the main Employee entity.
<edmx:Mappings>
<Mapping Space="C-S" xmlns="http://schemas.microsoft.com/ado/2009/11/mapping/cs">
<EntityContainerMapping StorageEntityContainer="EFRecipesModel1StoreContainer" CdmEntityContainer="EFRecipesEntities1">
<EntitySetMapping Name="Employees">
<EntityTypeMapping TypeName="IsTypeOf(EFRecipesModel1.Employee)">
<MappingFragment StoreEntitySet="Employee">
<ScalarProperty Name="EmployeeId" ColumnName="EmployeeId" />
<ScalarProperty Name="LastName" ColumnName="LastName" />
<ScalarProperty Name="FirstName" ColumnName="FirstName" />
</MappingFragment>
</EntityTypeMapping>
<EntityTypeMapping TypeName="IsTypeOf(EFRecipesModel1.FullTimeEmployee)">
<MappingFragment StoreEntitySet="Employee">
<ScalarProperty Name="EmployeeId" ColumnName="EmployeeId" />
<ScalarProperty Name="Salary" ColumnName="Salary" />
<Condition ColumnName="EmployeeType" Value="1" />
</MappingFragment>
</EntityTypeMapping>
<EntityTypeMapping TypeName="IsTypeOf(EFRecipesModel1.HourlyEmployee)">
<MappingFragment StoreEntitySet="Employee">
<ScalarProperty Name="EmployeeId" ColumnName="EmployeeId" />
<ScalarProperty Name="Wage" ColumnName="Wage" />
<Condition ColumnName="EmployeeType" Value="2" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
</EntityContainerMapping>
</Mapping>
</edmx:Mappings>
THe error I'm getting is:
Error3023: Problem in maaping fragments starting at line 51 column: Employee.Salary in table Employee must be mapped. It has no default value and is not nullable.
I read around and saw a suggestino up update the SSDL which in a way didn't make sense to me:
<edmx:StorageModels>
<Schema Namespace="EFRecipesModel1.Store" Provider="System.Data.SqlClient" ProviderManifestToken="2012" Alias="Self" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" xmlns="http://schemas.microsoft.com/ado/2009/11/edm/ssdl">
<EntityType Name="Employee">
<Key>
<PropertyRef Name="EmployeeId" />
</Key>
<Property Name="EmployeeId" Type="int" StoreGeneratedPattern="Identity" Nullable="false" />
<Property Name="EmployeeType" Type="int" Nullable ="false" DefaultValue="1"/>
<Property Name="FirstName" Type="nvarchar" MaxLength="50" Nullable="false" />
<Property Name="LastName" Type="nvarchar" MaxLength="50" Nullable="false" />
<Property Name="Salary" Type="decimal" Precision="18" Scale="0" Nullable="false" />
<Property Name="Wage" Type="decimal" Precision="18" Scale="0" Nullable="false" />
</EntityType>
<EntityContainer Name="EFRecipesModel1StoreContainer">
<EntitySet Name="Employee" EntityType="Self.Employee" Schema="Chapter2" store:Type="Tables" />
</EntityContainer>
</Schema>
</edmx:StorageModels>
note that I added the Nullable and Default value for EmployeeType. This still doesn't solve the problem.
Could I get some help as to why I'm having such a problem mapping properly?
To me it makes more sense to add DefaultValue to Salary and Wage in the store model:
<Property Name="Salary" Type="decimal" Nullable="false" DefaultValue="0"/>
<Property Name="Wage" Type="decimal" Nullable="false" DefaultValue="0"/>
And also in the conceptual model (in the edmx designer).
It would also make sense to add them as default constraints to the fields in the database (although EF does not copy these constraints to the edmx when the model is generated from the database).
Anyhow, the fields must have a default value since they are not nullable in the database, and none of the concrete entities supply values for both fields.
I ran into a similar issue and what I done was;
Right-click the "Main" entity, and select Properties. Set the Abstract attribute to true, which marked the "Main" entity as abstract.
Just thought I would share this as setting a default value for me stopped ef from complaining but the value was not available when needed in my program .