How to read a class parameter using Caché SQL? - sql

How do I read a class parameter using Caché SQL?
select * from table does not list any class parameters.

Parameters are specific to the class definition, not specific to the object or row. Therefore, you cannot find them by querying the class table. Rather, you need to query the Class Definition tables. These reside in the %Dictionary classes.
For this particular query, you can use
SELECT * FROM %Dictionary.ParameterDefinition WHERE parent='Sample.Person'
In the SAMPLES namespace, this should yield results for all Parameters that are a part of Sample.Person - in this case, only EXTENTQUERYSPEC.

Related

How to do Projection in "GraphQL.Net"?

I have problem with using GraphQL.Net, and that is what I need.
I specify four fields in aType Class, when I try to fetch only two fields with a query on GraphQL, the executing query on database contains all four fields that defined in Type class but I expect query to be something look like this :
Select field1,field2 from someEntity
How to do this projection ?!
I'm using GraphQL.Net version 7.2.2

Does jOOQ support parsing of nested rows?

I am evaluating if we can migrate from plain JDBC to jOOQ for our project. Most of it looks promising, but I am wondering currently about one specific flow: nested rows. Let me explain.
Say you have the following two tables:
class(id, name)
student(id, name, class_id)
(We assume that a student can only be part of one class.)
Let's create a response type for these tables. I will be using these in the queries below.
create type type_student as(id integer, name text);
create type type_class as(id integer, name text, students type_student[]);
Now let's fetch all classes with its student by using nested rows:
select row(class.id, class.name, array
(
select row(student.id, student.name)::type_student
from student
where student.class_id = class.id
))::type_class
from class
A useful variant is to use only nested rows in arrays:
select class.id, class.name, array
(
select row(student.id, student.name)::type_student
from student
where student.class_id = class.id
) as students
from class
I am wondering if jOOQ has an elegant approach to parse such results containing nested rows?
Your usage of the word "parse" could mean several things, and I'll answer them all in case anyone finds this question looking for "jOOQ" / "parse" / "row".
Does the org.jooq.Parser support row value expressions?
Not yet (as of jOOQ 3.10 and 3.11). jOOQ ships with a SQL parser that parses (almost) anything that can be represented using the jOOQ API. This has various benefits, including:
Being able to reverse engineer DDL scripts for the code generator
Translating SQL between dialects (see an online version here: https://www.jooq.org/translate)
Unfortunately, it cannot parse row value expressions in the projection yet i.e. in the SELECT clause.
Does the jOOQ API support ("parse") row value expressions?
Yes, you can use them using the various DSL.row() constructors, mainly for predicates, but also for projections by wrapping them in a Field using DSL.rowField(). As of jOOQ 3.11, this is still a bit experimental as there are many edge cases in PostgreSQL itself, related to what is allowed and what isn't. But in principle, queries like yours should be possible
Does jOOQ support parsing the serialised version of a PostgreSQL record
PostgreSQL supports these anonymous record types, as well as named "composite" types. And arrays thereof. And nesting of arrays and composite types. jOOQ can serialise and deserialise these types if type information is available to jOOQ, i.e. if you're using the code generator. For instance, if your query is stored as a view
create view test as
select row(class.id, class.name, array
(
select row(student.id, student.name)::type_student
from student
where student.class_id = class.id
))::type_class
from class
Then, the code generator will produce the appropriate types, including:
TypeStudentRecord
TypeClassRecord
Which can be serialised as expected. In principle, this would be possible also without the code generator, but you'd have to create the above types yourself, manually, so why not just use the code generator.
Yes it does: https://www.jooq.org/doc/latest/manual/sql-building/table-expressions/nested-selects/
Field<Object> records =
create.select(student.id, student.name)
.from(student)
.where(student.class_id.eq(class.id)
.asField("students");
create.select(class.id, class.name, array, records)
.from(class)
.fetch();
The above example might not work directly as I have not tried, but just wanted to give a general idea.
Note: that the object records is not executed alone. When fetch is called in the second statement, JOOQ should create one SQL statement internally.

Execute some arbitrary sql in the current transaction in JPA 2.0

I am new to JPA 2.0/EclipseLink/Glassfish/JEE6, and have kind of a basic question.
I have a DAO in which most of the entities are mapped directly to columns using JPA annotations, so I use the EntityManager, and it works great with no issues.
However there are some tables in which I am constructing the SQL statements myself b/c they use oracle-specific functions (spatial), and I want very fine-grained control of the SQL. So I am building it with string concatenation. I would like to be able to enroll my SQL executions in the current transaction, if there is one already underway.
So naturally I don't want to go directly to the DriverManager and create my own connection, I was looking for some kind of EntityManager.executeArbitrarySQL(String) function that would find the current connection and make my SQL part of the current transaction. Am I off my rocker?
One can use the EntityManager.createNativeQuery() methods to execute native SQL queries within the context of the same EntityManager that you are using. There are two three different types of these methods, and they differ in the arguments provided.
The first, createNativeQuery(String sqlString, Class resultClass) expects you to provide the Class object representing the type of the values that will be returned by the query. This is to be used in case you are returning a set of values that can be mapped to the class of another entity definiton in your persistence unit.
The second createNativeQuery(String sqlString, String resultSetMapping) expects you to provide the name of the result set mapping. The result set mapping ought to be defined using the #SqlResultSetMapping annotation.
The last createNativeQuery(String sqlString) is apparently meant to be used in scenarios where no result set will be returned, i.e. in execution of INSERT, UPDATE and DELETE statements.
You can also define native queries using the #NamedNativeQuery annotation or the named-native-query element in your persistence.xml file, but these are better suited for scenarios where you know the structure of the query during development. You can however, create multiple such named native queries to represent all varieties of the SQL statement you intend to execute, and then execute different ones at runtime based on the user inputs. Annotated native queries are executed using the EntityManager.createNamedQuery() methods. One will need to use positional parameters (defined using the ? placeholder) to supply values to the native queries at runtime.

Yii CSqlDataProvider confusion

I am having some trouble understanding CSqlDataProvider and how it works.
When I am using CActiveDataProvider, the results can be accessed as follows:
$data->userProfile['first_name'];
However, when I use CSqlDataProvider, I understand that the results are returned as an array not an object. However, the structure of the array is flat. In other words, I am seeing the following array:
$data['first_name']
instead of
$data['userProfile']['first_name']
But the problem here is what if I have another joined table (let's call it 'author') in my sql code that also contains a first_name field? With CActiveDataProvider, the two fields are disambiguated, so I can do the following to access the two fields:
$data->userProfile['first_name'];
$data->author['first_name'];
But with CSqlDataProvider, there doesn't seem to be anyway I can access the data as follows:
$data['userProfile']['first_name'];
$data['author']['first_name'];
So, outside of assigning a unique name to those fields directly inside my SQL, by doing something like this:
select author.first_name as author_first_name, userProfile.first_name as user_first_name
And then referring to them like this:
$data['author_first_name'];
$data['user_first_name']
is there anyway to get CSqlDataProvider to automatically structure the arrays so they are nested in the same way that CActiveDataProvider objects are? So that I can call them by using $data['userProfile']['first_name']
Or is there another class I should be using to obtain these kinds of nested arrays?
Many thanks!
As far as I can tell, no Yii DB methods break out JOIN query results in to 2D arrays like you are looking for. I think you will need to - as you suggest - alias the column names in your select statement.
MySql returns a single row of data when you JOIN tables in a query, and CSqlDataProvider returns exactly what MySql does: single tabular array representation indexed/keyed by the column names, just like your query returns.
If you want to break apart your results into a multi-dimensional array I would either alias the columns, or use a regular CActiveDataProvider (which you can still pass complex queries and joins in via CDbCritiera).

How to find table related with an alias in Doctrine ORM query?

I'm using Doctrine ORM 1.2 and Symfony 1.4 and I want to create method in myUser class which will extend Doctrine_Query instance passed as an argument with some additional left joins and conditions. The trick is that I don't always want these these left joins to be made with root component of the query and I need to know with what table (record class) the alias corresponds - in some cases I would like to pass an alias of another component and expect it to be supplemented with some extra left joins and conditions.
My question is how can I check what component (essentially table) represents given alias? Suppose I create a Doctrine_Query instance:
$query = Doctrine_Query::create();
$query->from('Folder f')->leftJoin('f.ChildFolders cf');
Now I want my method in myUser class to add some joins to the table with alias 'cf' but varying depending on table which 'cf' aliases. I want to call it this way:
$this->getUser()->limitQueryResultsWithSomeCondition($query, 'cf');
That should return query with additional elements. How can I find out what table is symbolized by 'cf' alias and whether it exists at all in given query?
It is quite straightforward when it is root table of a query that needs to be extended, but I cannot find a way to do it in other cases.
I guess I found my own solution to the problem. To find out to which table/record given alias corresponds one has to use getQueryComponent method. Suppose the query is same as in question above. The solution then reads as follows:
$alias = 'cf';
$query->getSqlQuery();
$component = $query->getQueryComponent($alias);
$recordClass = get_class($component['table']->getRecordInstance());
The trick is that before method getSqlQuery (or some method which is called inside of this method) is called the component will not be found and exception will be thrown.