-
Notifications
You must be signed in to change notification settings - Fork 3
/
use-result.gtw
278 lines (207 loc) · 9.25 KB
/
use-result.gtw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
~~LANG:FR@frman:recuperation-enregistrements~~
Creating, modifying and deleting records in a database is very useful. However,
it's not as useful as being able to fetch records and use them. The page on the
[[use|use of a dao factory and record]] showed you the create, the delete and the
update. This is the page on the fetch, or the "select data" part of jDao.
Depending on how and how much results are needed, the method is somewhat different.
===== Retrieve a single record =====
To retrieve a single record by specifying it's key (the primary key in the database),
the method to use is called @@M@get()@@.
There is no need to further parse the return value of the @@M@get()@@ function since
it will fetch the specified record and return it as an object. The object is design
so that each column name is the name of a variable, and the column value, the variable value.
<code php>
// instantiation of the factory
$myFactory = jDao::get("foo");
// retrieve a record whose content corresponds
// to the record with identifier = 3
$baz = $myFactory->get(3);
// the id of the record is 3, as we specified
echo $baz->id;
</code>
In the case where the primary key is several fields, declared like this in your
xml file, @@A@primarykey="key1,key2"@@, you have to give all key values at te same time:
<code php>
$myFactory = jDao::get("foo");
// 3 and 4 are values of key1 and key2
$baz = $myFactory->get(3, 4);
</code>
or
<code php>
$myFactory = jDao::get("foo");
// 3 and 4 are values of key1 and key2
$baz = $myFactory->get(array(3, 4));
</code>
Careful: the order of the value should be the same as the order of the declaration
of keys in the primarykey attribute. Eg, @@$myFactory->get(4, 3)@@ is different
from @@$myFactory->get(3, 4)@@.
The @@M@delete()@@ method works in the same way.
===== Retrieving several records =====
When all the records are needed, the @@M@findAll()@@ method is used. This method
will return a result set, (@@C@jDbResultSet@@ class) containing all the results
from the database in the order they where added to the database. Remember that
this class implements the @@C@Iterator@@ interface, so it can be used into a
foreach statement.
<code php>
// instantiation of the factory
$myFactory = jDao::get("foo");
// retrieve a complete list of the foo type records
$list = $myFactory->findAll();
foreach ($list as $row) {
// $row content a record
echo $row->id;
}
</code>
You can use also two other methods to retrieve records. The first one being @@M@fetch()@@
which fetches one row from the result set as an object and advances the internal
pointer one step.
<code php>
// fetch the records one at the time
while ($row = $list->fetch) {
// do something with the record
echo $row->id;
}
</code>
The second one being @@M@fetchAll()@@ which returns an array containing an object
for each row in the result set.
<code php>
// fetch all the records as an array of objects
$rows = $list->fetchAll();
foreach ($rows as $rowID => $row) {
// do something with the record
echo $row->id;
}
</code>
You can make other retrieving methods by specifying them in the xml file (see
[[/daos/xml_methods|Declaring methods in the XML file]] and [[/daos/php_methods|Adding PHP methods to the factory]]) .
===== Retrieve record(s) through criteria =====
To retrieve record(s) through criteria, there are three simple methods available,
@@M@findBy()@@, @@M@countBy()@@ and @@M@deleteBy()@@. These methods have one
required parameter, a @@jDaoConditions@@ object, which contains all the conditions.
<code php>
$a_name = "something";
// create the jDaoConditions object
$conditions = jDao::createConditions();
$conditions->addCondition('label', '=', $a_name);
$conditions->addCondition('status', '=', 5);
$list = $myFactory->findBy($conditions);
$count = $myFactory->countBy($conditions);
</code>
In the same way as the @@M@findAll()@@ method, @@M@findBy()@@ returns a
@@C@jDbResultSet@@ object, which gives you the list of records corresponding
to indicated criteria.
The @@M@addCondition()@@ method take as parameter a property name, an operator
(SQL), and a value.
You can specify an order of select with the method @@M@addItemOrder()@@, and group
various criterion together with @@M@startGroup()@@ and @@M@endGroup()@@:
<code php>
$conditions = jDao::createConditions();
// condition : label = $a_name AND (status=5 OR status=4) ORDER BY label desc
$conditions->addCondition('label','=',$a_name);
$conditions->startGroup('OR');
$conditions->addCondition('status','=',5);
$conditions->addCondition('status','=',4);
$conditions->endGroup();
$conditions->addItemOrder('label','desc');
$list = $myFactory->findBy($conditions);
</code>
To add a limit, you can specify additional parameters to the @@M@findBy()@@ method:
the offset and the number of records to fetch.
<code php>
$list = $myFactory->findBy($conditions, 0, 15);
</code>
As for the @@M@countBy()@@ method it takes one additional parameter: the property
name that we want to apply a DISTINCT clause.
<code php>
// SELECT COUNT(DISTINCT table.label)...
$count = $myFactory->countBy($conditions, 'label');
</code>
Lastly, the @@M@deleteBy()@@ method allow to delete records corresponding to indicated
criteria, it returns the number of deleted records:
<code php>
$nb_deleted = $myFactory->deleteBy($conditions);
</code>
You will see that you can get the same result by defining methods in the xml file.
However, you will choose @@M@findBy()@@ or a xml-defined method, depending of the context.
Criteria-based retrieving is best used when you don't know the number of criterion
and their type. This includes things such as a complex search form, where the user
can choose which criterion are applied. Criteria-based retrieving is also best used
when the query is used only one time or very rarely. This is because the xml-defined
methods are compiled to PHP, and thus are included each time you call the factory.
It may not be useful to always include some code which is seldomly used. Using
criteria-based retrieving will improve the global performances in that case.
In the other cases, it is recommended to use xml methods, especially when you know
the criteria by advance (without forcibly knowing their value of course), and when
it is an often used research. jDao generates SQL queries during the generation of
the PHP file, so this is a process it has not to do when executing the page.
For example, we often redefine the @@M@findAll@@ method in XML, to be able to specify
a retrieving order...
=== SQL operators ===
As explained before, @@M@addCondition()@@ tak a sql operator as a second parameter.
Here are the operators supported:
* LIKE, NOT LIKE, ILIKE,
* IN, NOT IN,
* IS, IS NOT,
* IS NULL, IS NOT NULL,
* MATCH, REGEXP, NOT REGEXP, RLIKE, SOUNDS LIKE
* @@~@@, @@!~@@, @@~*@@, @@!~*@@ (operators for regular expression for postgresql)
== Special case with NULL ==
To test a (non) NULL value, you can use any supported operators, even "=" or "!=".
Don't forget to pass the php @@V@null@@, not the string @@V@"NULL"@@.
<code php>
$conditions->addCondition('status','=', null); // equivalent to IS NULL
$conditions->addCondition('status','!=', null); // equivalent to IS NOT NULL
$conditions->addCondition('status','IS', null);
$conditions->addCondition('status','IS NOT', null);
$conditions->addCondition('status','IS NULL', null);
$conditions->addCondition('status','IS NOT NULL', null);
$conditions->addCondition('status','LIKE', null);
$conditions->addCondition('status','NOT LIKE', null);
...
</code>
== Regular expressions ==
Some databases like Postgresql support regular expressions. For postgresql you can then use keywords @@~@@, @@!~@@, @@~*@@, @@!~*@@.
<code php>
$conditions->addCondition('status','~', '^test');
...
</code>
Other operator like @@REGEXP@@, @@NOT REGEXP@@ are also supported. Verify first if it is compatible with your database.
==== Adding methods on record objects ====
If you need to add some PHP methods on record objects (to
calculate values from field values for example), you can
define a base class for the dao.
You have to use the @@extends@@ attribut on the @@record@@
element. Its value is the selector of your base class:
<code xml>
<!-- fichier mymodule/daos/mydao.dao.xml -->
...
<record extends="mymodule~myrecord">
...
</record>
...
</code>
Your base class should be store in a file which have the class name
and the suffix @@.daorecord.php@@, in the daos/ directory of your module.
The class should follow these rules:
* the class should be abstract
* the name of the class should have the suffix @@DaoRecord@@
(but this suffix is not indicated in the selector)
* the class should inherits from @@C@jDaoRecordBase@@
<code php>
// file mymodule/daos/myrecord.daorecord.php
abstract class myrecordDaoRecord extends jDaoRecordBase {
function calculateTotal() {
return $this->amount + $this->vat;
// ...
}
}
</code>
Then you can call this method on each records:
<code php>
$maFactory = jDao::get("mymodule~myrecord");
$list = $maFactory->findAll();
foreach ($list as $row) {
$total = $row->calculateTotal();
//...
}
</code>