Skip to content

Commit 250a91c

Browse files
committed
Releasing 0.9.1
2 parents e3eca0c + 2d8bdca commit 250a91c

File tree

3 files changed

+319
-19
lines changed

3 files changed

+319
-19
lines changed

README.md

Lines changed: 256 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -25,47 +25,146 @@ You can download the source code packages from [GitHub Release Page](https://git
2525

2626
## Creating a Database object
2727

28+
Create a configuration array and pass it to the constructor:
29+
2830
```
31+
$config = array(
32+
'host' => 'database-hostname',
33+
'port' => 3306,
34+
'dbname' => 'my-db-name',
35+
'tablePrefix' => 'test_',
36+
'user' => 'user',
37+
'pass' => 'password',
38+
);
2939
$db = \TgDatabase\Database($config);
3040
```
3141

42+
Please notice that we provide a table prefix. It is a common practice to prefix all your
43+
tablenames like `test_`. This way, you can keep several "namespaces" in your database.
44+
The prefix will later be added to your query statements whenever you use `#__` in the
45+
table name (see examples below).
46+
47+
Instead of holding the credentials with the configuration, you could use a `TgUtils\Auth\CredentialsProvider`
48+
that holds these data. `Database`will ignore credentials in the config array then.
49+
3250
```
3351
$db = \TgDatabase\Database($config, $credentialsProvider);
3452
```
3553

3654
## Querying objects
3755

3856
```
39-
TBD
57+
// Query a list of objects
58+
$arr = $db->queryList('SELECT * FROM #__devtest');
59+
60+
// Querying a single object
61+
$obj = $db->querySingle('SELECT * FROM #__devtest WHERE uid='.$uid);
62+
```
63+
64+
The interface usually delivers `stdClass` objects by default. However, you can name
65+
your own data class so the data will be populated in such a class:
66+
67+
```
68+
$arr = $db->queryList('SELECT * FROM #__devtest', 'MyNamespace\MyDataClass');
69+
$obj = $db->querySingle('SELECT * FROM #__devtest WHERE uid='.$uid, 'MyNamespace\MyDataClass');
4070
```
4171

4272
## Inserting, Updating and deleting objects
4373

74+
You can insert your own data classes or simply use `stdClass` objects or arrays:
75+
76+
```
77+
// Use a standard class object
78+
$obj = new stdClass;
79+
$obj->name = 'test-name';
80+
$obj->email = 'test-email';
81+
$uid = $db->insert('#__devtest', $obj);
82+
83+
// Use your own data class
84+
$obj = new MyNamespace\MyDataClass($initialData);
85+
$uid = $db->insert('#__devtest', $obj);
86+
87+
// Use an array
88+
$arr = array(
89+
'name' => 'test-name',
90+
'email' => 'test-email'
91+
);
92+
$uid = $db->insert('#__devtest', $arr);
93+
```
94+
95+
The `Database` will automatically escape and quote strings that appear as values in your new objects.
96+
97+
Updating your rows is accordingly easy. You will need the table name, the new values (as object or array) and a WHERE condition:
98+
99+
```
100+
// Save all object values
101+
$obj->name = 'Some other name';
102+
$db->update('#__devtest', $obj, 'uid='.$obj->uid);
103+
104+
// Save values from array only
105+
$arr = array('name' => 'Another name');
106+
$db->update('#__devtest', $arr, 'uid='.$uid);
107+
```
108+
109+
If you want to change a single object only, you also can use `updateSingle()` which can give you back the
110+
changed object (as `stdClass`)
111+
44112
```
45-
TBD
113+
// Update a single row
114+
$updated = $db->updateSingle('#__devtest', array('name' => 'test-value2'), 'uid='.$uid);
46115
```
47116

48-
# How to use the higher leveled Database Access Object
117+
And finally you can delete objects. You will need the table name and the WHERE condition:
49118

50-
TBD
119+
```
120+
// Delete a single row
121+
$db->delete('#__devtest', 'uid='.$uid);
122+
```
123+
124+
# How to use a Database Access Object (DAO)
125+
126+
The low-level `Database` abstraction makes object-relational mappings already simple. However,
127+
it is still a lot of boilerplate to write, such as table names, WHERE clauses etc. A better way
128+
is provided by the `DAO` object. It simplifies the usage with databases a lot more.
51129

52130
## Creating the DAO
53131

132+
Create a DAO by giving it the `Database` instance and the table name:
133+
54134
```
55-
$userDao = \TgDatabase\DAO($db, '#__users');
135+
$dao = \TgDatabase\DAO($db, '#__users');
136+
```
137+
138+
The default constructor as above makes assumptions about your table:
139+
140+
1. It always returns `stdClass` objects.
141+
1. It assumes that your table has an `int auto-increment` primary key that is names `uid`.
142+
143+
However, you can tell `DAO` your specifics:
144+
56145
```
146+
// Uses a specific class for the data
147+
$dao = \TgDatabase\DAO($db, '#__users', 'MyNamespace\User`);
148+
149+
// Uses a specific class and another primary key attribute
150+
$dao = \TgDatabase\DAO($db, '#__users', 'MyNamespace\User`, 'id');
151+
```
152+
153+
`DAO` can actually handle non-numeric primary keys. The usage is not recommended though.
57154

58155
## Finding objects
59156

157+
Finding objects will be much easier now:
158+
60159
```
61160
// Get user with specific ID
62-
$user = $userDao->get(3);
161+
$user = $dao->get(3);
63162
64163
// Find a singe user with a specific email address
65-
$user = $userDao->findSingle(array('email' => $email));
164+
$user = $dao->findSingle(array('email' => $email));
66165
67166
// Find all active admin users, ordered by name and email in ascending order
68-
$users = $userDao->find(array('group' => 'admin', 'active' => 1), array('name', 'email));
167+
$users = $dao->find(array('group' => 'admin', 'active' => 1), array('name', 'email));
69168
```
70169

71170
## Creating, saving and deleting objects
@@ -78,33 +177,173 @@ $newUser->email = 'john.doe@example.com';
78177
$newUser->password = '123456';
79178
$newUser->group = 'webusers';
80179
$newUser->active = 1;
180+
$newId = $dao->create($newUser);
81181
82-
$newId = $userDao->create($newUser);
83-
84-
// Updating a user
85-
$user = $userDao->get($newId);
182+
// Updating an existing user
183+
$user = $dao->get($newId);
86184
$user->name = 'Jane Doe';
87-
$userDao->save($user);
185+
$dao->save($user);
88186
89187
// Deleting a user
90-
$userDao->delete($user);
188+
$dao->delete($user);
91189
// or
92-
$userDao->delete($user->uid);
190+
$dao->delete($user->uid);
191+
```
192+
193+
## WHERE clauses in DAO interface
194+
195+
The most simple form of a WHERE clause is the condition itself:
196+
197+
```
198+
$users = $dao->find('group=\'admin\'');
199+
```
200+
201+
But you would need to do the quoting and escaping your self. That's why you can have an array
202+
of all conditions that are concatenated with an `AND`:
203+
204+
```
205+
$users = $dao->find(array('group' => 'admin', 'active' => 1));
206+
```
207+
208+
Or, when an equals (`=`) operation is not what you need:
93209

210+
```
211+
$users $dao->find(array(
212+
array('group', 'admin', '!='),
213+
array('active' , 1)
214+
));
94215
```
95216

217+
The default operator is equals (`=`), but you also can use `!=`, `<=`, `>=`, `<`, `>`, `IN` and `NOT IN`. Latter two
218+
require arrays of values at the second position of the array:
219+
220+
```
221+
$users = $dao->find(array(
222+
array('group', array('admin'), 'NOT IN'),
223+
array('active' , 1)
224+
));
225+
```
226+
227+
## ORDER clauses in DAO interface
228+
229+
Wherever an ORDER clause can be given, there are two types:
230+
231+
```
232+
// As string
233+
$users = $dao->find('', 'name');
234+
$users = $dao->find('', 'name DESC');
235+
$users = $dao->find('', 'name DESC, email ASC');
236+
237+
// As array
238+
$users = $dao->find('', array('name'));
239+
$users = $dao->find('', array('name DESC'));
240+
$users = $dao->find('', array('name DESC', 'email ASC'));
241+
```
242+
243+
Default order sequence is ascending (`ASC`) if not specified.
244+
96245
## Extending DAO
97246

247+
It is a good practice not to use `DAO` class directly but derive from it in your project.
248+
That way you can further abstract data access, e.g.
249+
98250
```
99-
TBD
251+
class Users extends DAO {
252+
253+
public function __construct($database) {
254+
parent::__construct($database, '#__users', 'MyNamespace\User');
255+
}
256+
257+
public function findByEmail($email) {
258+
return $this->findSingle(array('email' => $email));
259+
}
260+
261+
public function findByDepartment($department, $order = NULL) {
262+
return $this->find(array('department' => $email), $order);
263+
}
264+
}
100265
```
101266

102267
## Using Data Objects with DAOs
103268

269+
As above mentioned, you can use your own data classes. There are actually no
270+
restrictions other than the class needs a no-argument constructor. The main
271+
advantage is that this class can have additional methods that have some
272+
logic. You can even define additional attributes that will not be saved in
273+
the database by a DAO. These attributes start with an underscore (_).
274+
275+
Here is an example:
276+
277+
```
278+
class User {
279+
280+
// will not be saved
281+
private $_derivedAttribute;
282+
283+
public function __construct() {
284+
// You can initialize here
285+
}
286+
287+
public function getDerivedAttribute() {
288+
// Have your logic for the attribute here
289+
// or do something completely different
290+
291+
// Return something
292+
return $this->_derivedAttribute;
293+
}
294+
}
295+
```
296+
297+
# Using a DataModel
298+
299+
Finally, we bring everything together. The last thing we need is a central location
300+
for all our `DAO`s. Here comes the `DataModel`:
301+
104302
```
105-
TBD
303+
304+
// Setup the model
305+
$model = new \TGDatabase\DataModel($database);
306+
$model->register('users', $userDAO);
307+
$model->register('products', $productDAO);
308+
309+
// And use it:
310+
$products = $model->get('products')->find();
106311
```
107312

313+
Of course, a better idea is to encapsulate this in your own `DataModel` subclass:
314+
315+
```
316+
class MyDataModel extends \TGDatabase\DataModel {
317+
318+
public function __construct($database) {
319+
parent::__construct($database);
320+
}
321+
322+
protected function init($database) {
323+
// Optional step: call the parent method (it's empty, but could change)
324+
parent::init($database);
325+
326+
// No create your DAOs
327+
$this->register('users', new UserDAO($database));
328+
$this->register('products', new ProductDAO($database));
329+
}
330+
}
331+
```
332+
333+
You only need to implement the `init()` method. Now your final application code looks
334+
much cleaner and can be read easily:
335+
336+
```
337+
// Setup...
338+
$database = new Database($config);
339+
$myModel = new MyDataModel($database);
340+
341+
// ...and use
342+
$users = $myModel->get('users')->find();
343+
```
344+
345+
Imagine, how much error-proned code you would have to write yourself!
346+
108347
# Contribution
109348
Report a bug, request an enhancement or pull request at the [GitHub Issue Tracker](https://github.com/technicalguru/php-database/issues).
110349

src/TgDatabase/DataModel.php

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
3+
namespace TgDatabase;
4+
5+
/**
6+
* A simple class to keep all DAOs in one place
7+
*
8+
* @author ralph
9+
*
10+
*/
11+
class DataModel {
12+
13+
private $database;
14+
15+
private $models;
16+
17+
/**
18+
* Constructor.
19+
* @param Database $database - the database instance
20+
*/
21+
public function __construct($database) {
22+
$this->database = $database;
23+
$this->models = array();
24+
$this->init($database);
25+
}
26+
27+
/**
28+
* Initializes all DAOs.
29+
* <p>This method does nothing. Descendants shall override here and create and register their DAOs.</p>
30+
* @param Database $database - the database object
31+
*/
32+
protected function init($database) {
33+
}
34+
35+
/**
36+
* Returns a DAO registered under a certain name.
37+
* @param String name - name of model
38+
* return DAO the DAO registered or NULL
39+
*/
40+
public function get($name) {
41+
return $this->models[$name];
42+
}
43+
44+
/**
45+
* Returns the database object.
46+
* @return Database the database object.
47+
*/
48+
public function getDatabase() {
49+
return $this->database;
50+
}
51+
52+
/**
53+
* Registers a DAO under a name.
54+
* @param string $name - the name of the model
55+
* @param DAO $dao - the DAO to be registered
56+
*/
57+
public function register($name, $dao) {
58+
$this->models[$name] = $dao;
59+
}
60+
}
61+

0 commit comments

Comments
 (0)