Queries: Difference between revisions

From Sunhill Framework Documentation
+ Writing own queries
Rewrite of Getting the records
 
(8 intermediate revisions by the same user not shown)
Line 1: Line 1:
== Queries ==
Queries are a unified way to access different kinds of information of the Sunhill Framework. The query system is intended to be similar to database queries of laravel. The main difference is, that its possible to query entities that are not stored in a database. All queries are performed on a [[Pooled record properies|Pooled record property]].  
Queries are a unified way to access different kinds of information of the Sunhill Framework. The query system is intended to be similar to database queries of laravel. The main difference is, that its possible to query entities that are not stored in a database.  


=== General usage ===
== General usage ==
All queries have to define some standardized methods. These are described in general in the following. For details see the different types of queries.
Due the fact that all queries are performed on pooled record properties, the searching process has to be performed by the storage. Normally it should be transparent to the user although there might be some missing functionallity in some features. Internally the queries use the [[Parser]]-subsystem. See [[Writing own queries]].  


=== Terminology ===
== Common query functions ==
As in QueryBuilder it is possible to build chains of request elements (like <code>->where('this','=','that')->orderBy('something')->offset(2)->limit(2)</code>).
 
== Terminology ==
Due the fact that queries could be performed on many entities there are some terms that are used:
Due the fact that queries could be performed on many entities there are some terms that are used:
* '''record''' is a single entity (like a database entry, a tag, a class, a plugin, etc.)
* '''record''' is a single entity (like a database entry, a tag, a class, a plugin, etc.)
* '''records''' are all entities (or at least those that fit a certain criteria)
* '''records''' are all entities (or at least those that fit a certain criteria)


==== Finalizing calls ====
== Building a query ==
=== Finalizing call ==
All queries need a finalizing call, that indicates what information should be retrieved or what action should be performed.  
All queries need a finalizing call, that indicates what information should be retrieved or what action should be performed.  


===== count() =====
=== Retrieving data ===
One main aspect of using queries is to retrieve data. Due the fact that queries are performed on pooled record properties there are always several ways to get data:
 
==== count() ====
Count returns the number of records of the given query.
Count returns the number of records of the given query.


Line 25: Line 31:
returns the number of SampleEntity Records that have the name 'test'
returns the number of SampleEntity Records that have the name 'test'


==== Getting the records ====
===== first() =====
===== first() =====
Returns the first record of the given query. Note: When there is no <code>order()</code> statement, the result could be unpredictable. If the given query return no records at all an exception is raised.  
This method returns an instance of PooledRecordProperty and fills it with the fields of the first found record that matches the condition.
If not record exists it raises an exception.
 
===== firstIfExists() =====
Like first() it returns the first record matching the conditions. If none exists null is returned.
 
===== only() =====
This method expects excactly one result for the query. If there is none or more than one, an exception is raised.
 
===== get() =====
 
==== Getting the ids ====
===== firstID() =====
 
===== firstIDIfExists() =====
 
===== onlyID() =====
 
===== getIDs() =====
 
==== Getting the fields ====
When using the fields() statement in the query only these columns are returned when using first(), firstIfExists(), only() and get().
Note: When using firstID(), firstIDIfExists(), onlyID() and getIDs() with a fields() statement, the fields() statement is ignored and no warning is yielded.
 
Example:
SampleEntity::query()->fields('id')->first();
Returns for example 1
 
==== A general note on first(), firstIfExists(), only() and get() ====
===== Return type =====
first() and get() return the entity or a list of entities respectively. Normally a single entity is a StdClass with the givel columns as elements. In some cases it is useful to retun a different object.
 
===== Column list =====
There is an optional parameter $fields to first() that could either take a single string or an array of strings.
If $fields is a string only the result of that field is returned.
 
Example:
SampleEntity::query()->first('id');
Returns for example 1
 
If $fields is an array of strings a StdClass object is returned where the elements represent the given fields.
 
Example:
SampleEntity::query()->first(['id','name']);
Returns {id: 1, name: 'test'}
 
==== first(?string|?array $column_list = null) ====
Returns the first record of the given query.  
 
{{Warning|When there is no <code>order()</code> statement, the result could be unpredictable.}}
 
If the given query return no records at all an exception is raised.  


Example:
Example:
Line 38: Line 96:
Throws an exception when no record has the name 'non existing'.
Throws an exception when no record has the name 'non existing'.


====== Column list ======
==== firstIfExists(?string|?array $column_list = null) ====
There is an optional parameter $fields to first() that could either take a single string or an array of strings.  
Returns the first record of the given query or null if none exists.
If $fields is a string only the result of that field is returned.
 
{{Warning|When there is no <code>order()</code> statement, the result could be unpredictable.}}
 
If the given query return no records at all null is returned.
 
Example:
SampleEntity::query()->first();
Returns the first record of SampleEntity.
 
SampleEntity::query()->where('name','test')->first();
Returns the first record of SampleEntity where the name is 'test';
 
SampleEntity::query()->where('name','not existing')->first();
Null is returned.
 
==== get(?string|?array $column_list = null) ====
Returns all entities that match the given condition.
 
==== only(?string|?array $column_list = null) ====
The query must return exactly one result and this result is returned. Same as first() except that it raises an exception when no or more than one result is returned.  


Example:
Example:
  SampleEntity::query()->first('id');
  SampleEntity()::where('id','=',1)->only();
Returns for example 1
 
Returns the entity with the id 1 (or raises an exception when this id does not exist.


If $fields is an array of strings a Collection object is returned where the elements represent the given fields.  
==== delete() ====
Deletes all entries that match the given condition or throws an exception if the entity is read only.


Example:
Example:
  SampleEntity::query()->first(['id','name']);
  SampleEntity()::where('id','=',1)->delete();
Returns [1, 'test']
 
Deletes the entity with the id 1.
 
{{Note|If no entity matches the given condition nothing is done an no exception is raised}}
 
==== update(array $fields) ====
Updates all entries that match the given condition or throws an exception if the entity is read only.


=== Writing own queries ===
Example:
Own queries have to be derrived from BasicQuery and some abstract methods have to be overwritten:
SampleEntity()::where('id','=',1)->update(['payload'=>'abc']);


==== assembleQuery() ====
Sets the field ''payload'' to "abc" on the entity with the id 1 .
This method takes no parameters and builds an internal query structure that could be used to perform the finalizing methods on. The method can return whatever you want you just have to make sure that the remaining abstract methods can use this result to return the desired value or action.  


==== doGetCount($assembled_query) ====
{{Note|If no entity matches the given condition nothing is done an no exception is raised}}
This function takes the result of the previous function assembleQuery() and uses it to count the number of records that match the given criteria.
 
<!--


= Queries =
==== insert(array $fields) ====
The ORM-frameworks defines queries so that all entities (like tags, classes, attributes and so on) can be accessed the same way. The structure is oriented to the laravel QueryBuilder with some minor additions for dealing with the single entities.
Inserts a new record in the list.


== Common query functions ==
== List of Queries ==
As in QueryBuilder it is possible to build chains of request elements (like ->where('this','=','that')->orderBy('something')->offset(2)->limit(2)).
* [[ORM Query]]
* [[Classes Query]]
* [[Tags Query]]
* [[Attributes Query]]
* [[Properties Query]]


=== Finishing methods ===
== Writing own queries ==
Normally there must be a finishing method. All queries should define at least:
For details about writing own queries see [[Writing own queries|here]].  


==== count(): int ====
<!--
returns the count of entries that match a given condition


==== first() ====
Returns the first entry that match a given condition. This method should normally return a StdClass objects with the expcetion of object queries that return the appropriate object.


==== get(): Collection ====
Return all entries that match a given condition. The method returns an Illuminate\Support\Collection object. The entries of this collection are normally StdClasses with the exception of object queries that consist of the appropriate objects.


=== Query building ===
=== Query building ===
Line 86: Line 166:
==== where()/whereNot()/orWhere()/orWhereNot() ====
==== where()/whereNot()/orWhere()/orWhereNot() ====
The same method as the QueryBuilder of laravel provides. These methods can take up to three parameters (key, relation and value). If the last one is omitted it is assumed that the relation is "=" and the second parameter means the value (Example ->where('id',2) is the same as ->where('id','=',2)
The same method as the QueryBuilder of laravel provides. These methods can take up to three parameters (key, relation and value). If the last one is omitted it is assumed that the relation is "=" and the second parameter means the value (Example ->where('id',2) is the same as ->where('id','=',2)
==== offset(int $offset) ====
The same method as the QueryBuilder of laravel provides. The list starts with the $offet-th entry.
==== limit(int $limit) ====
The same method as the QueryBuilder of laravel provides. The list consists of $limit entries maximum.
==== order($key, $direction = 'asc') ====
The same method as the QueryBuilder of laravel provides. The list is ordered by $key in the direction $direction. $direction only may take 'asc' for ascending sort and 'desc' for descending.


== Classes::query() ==
== Classes::query() ==
Line 175: Line 246:
=== Fields/pseudo fields ===
=== Fields/pseudo fields ===
-->
-->
[[Category:Queries]]

Latest revision as of 13:32, 27 March 2025

Queries are a unified way to access different kinds of information of the Sunhill Framework. The query system is intended to be similar to database queries of laravel. The main difference is, that its possible to query entities that are not stored in a database. All queries are performed on a Pooled record property.

General usage

Due the fact that all queries are performed on pooled record properties, the searching process has to be performed by the storage. Normally it should be transparent to the user although there might be some missing functionallity in some features. Internally the queries use the Parser-subsystem. See Writing own queries.

Common query functions

As in QueryBuilder it is possible to build chains of request elements (like ->where('this','=','that')->orderBy('something')->offset(2)->limit(2)).

Terminology

Due the fact that queries could be performed on many entities there are some terms that are used:

  • record is a single entity (like a database entry, a tag, a class, a plugin, etc.)
  • records are all entities (or at least those that fit a certain criteria)

Building a query

= Finalizing call

All queries need a finalizing call, that indicates what information should be retrieved or what action should be performed.

Retrieving data

One main aspect of using queries is to retrieve data. Due the fact that queries are performed on pooled record properties there are always several ways to get data:

count()

Count returns the number of records of the given query.

Example:

SampleEntity::query()->count();

returns the number of all records of SampleEntity.

Example:

SampleEntity::query()->where('name','test')->count();

returns the number of SampleEntity Records that have the name 'test'

Getting the records

first()

This method returns an instance of PooledRecordProperty and fills it with the fields of the first found record that matches the condition. If not record exists it raises an exception.

firstIfExists()

Like first() it returns the first record matching the conditions. If none exists null is returned.

only()

This method expects excactly one result for the query. If there is none or more than one, an exception is raised.

get()

Getting the ids

firstID()
firstIDIfExists()
onlyID()
getIDs()

Getting the fields

When using the fields() statement in the query only these columns are returned when using first(), firstIfExists(), only() and get(). Note: When using firstID(), firstIDIfExists(), onlyID() and getIDs() with a fields() statement, the fields() statement is ignored and no warning is yielded.

Example:

SampleEntity::query()->fields('id')->first();

Returns for example 1

A general note on first(), firstIfExists(), only() and get()

Return type

first() and get() return the entity or a list of entities respectively. Normally a single entity is a StdClass with the givel columns as elements. In some cases it is useful to retun a different object.

Column list

There is an optional parameter $fields to first() that could either take a single string or an array of strings. If $fields is a string only the result of that field is returned.

Example:

SampleEntity::query()->first('id');

Returns for example 1

If $fields is an array of strings a StdClass object is returned where the elements represent the given fields.

Example:

SampleEntity::query()->first(['id','name']);

Returns {id: 1, name: 'test'}

first(?string|?array $column_list = null)

Returns the first record of the given query.

Warning: When there is no order() statement, the result could be unpredictable.

If the given query return no records at all an exception is raised.

Example:

SampleEntity::query()->first();

Returns the first record of SampleEntity.

SampleEntity::query()->where('name','test')->first();

Returns the first record of SampleEntity where the name is 'test';

SampleEntity::query()->where('name','not existing')->first();

Throws an exception when no record has the name 'non existing'.

firstIfExists(?string|?array $column_list = null)

Returns the first record of the given query or null if none exists.

Warning: When there is no order() statement, the result could be unpredictable.

If the given query return no records at all null is returned.

Example:

SampleEntity::query()->first();

Returns the first record of SampleEntity.

SampleEntity::query()->where('name','test')->first();

Returns the first record of SampleEntity where the name is 'test';

SampleEntity::query()->where('name','not existing')->first();

Null is returned.

get(?string|?array $column_list = null)

Returns all entities that match the given condition.

only(?string|?array $column_list = null)

The query must return exactly one result and this result is returned. Same as first() except that it raises an exception when no or more than one result is returned.

Example:

SampleEntity()::where('id','=',1)->only();

Returns the entity with the id 1 (or raises an exception when this id does not exist.

delete()

Deletes all entries that match the given condition or throws an exception if the entity is read only.

Example:

SampleEntity()::where('id','=',1)->delete();

Deletes the entity with the id 1.

Note: If no entity matches the given condition nothing is done an no exception is raised

update(array $fields)

Updates all entries that match the given condition or throws an exception if the entity is read only.

Example:

SampleEntity()::where('id','=',1)->update(['payload'=>'abc']);

Sets the field payload to "abc" on the entity with the id 1 .

Note: If no entity matches the given condition nothing is done an no exception is raised

insert(array $fields)

Inserts a new record in the list.

List of Queries

Writing own queries

For details about writing own queries see here.