Skip to content

Commit

Permalink
Named parameters / place-holder now being used in all LeanORM generat…
Browse files Browse the repository at this point in the history
…ed queries
  • Loading branch information
rotimi committed Jun 6, 2024
1 parent 4c9f57f commit 432ab18
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 35 deletions.
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ PHP 7.4+ for versions 2.x & 3.x

[Composer](https://getcomposer.org/)

Version 2.x & 3.x of this package have been rigorously tested against sqlite 3.7.11+, MySQL 8.0.29+ & Postgresql 15.1+.
Versions 2.x & 3.x of this package have been rigorously tested against sqlite 3.7.11+, MySQL 8.0.29+ & Postgresql 15.1+.

Version 4.x has been rigorously tested against:
- Sqlite 3.34.1+
Expand Down Expand Up @@ -105,7 +105,9 @@ Documentation for version 2.x version can be found [here](https://github.com/rot

Documentation for version 3.x+ can be found [here](https://github.com/rotexsoft/leanorm/blob/3.x/docs/index.md).

Documentation for version 4.x+ can be found [here](https://github.com/rotexsoft/leanorm/blob/master/docs/index.md).
Documentation for version 4.0.x+ can be found [here](https://github.com/rotexsoft/leanorm/blob/4.0.x/docs/index.md).

Documentation for version 4.1.x+ can be found [here](https://github.com/rotexsoft/leanorm/blob/master/docs/index.md).

Please submit an issue (preferably with a pull request) to address mistakes or omissions in the documentation or to propose improvements to the documentation.

Expand All @@ -123,7 +125,8 @@ New Test files must be manually added to the phpunit.xml.dist file in order for

These are the branches in this repository:

- **master:** contains code for the latest major version of this package.
- **master:** contains code for the latest major version (4.1.x) of this package.
- **4.0.x:** contains code for the 4.0.x versions of this package. Only bug fixes should be added to this branch. This branch is feature complete.
- **3.x:** contains code for the 3.x versions of this package. Only bug fixes should be added to this branch. This branch is feature complete.
- **2.2.x:** contains code for the 2.2.x versions of this package. Only bug fixes should be added to this branch. This branch is feature complete.
- **1.X:** contains code for the **1.X** versions of this package. This branch is abandoned.
Expand Down
47 changes: 20 additions & 27 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,8 @@ The following methods for fetching data from the database are defined in **\GDAO
All these fetch methods accept a first argument which is a query object. LeanOrm uses [Aura\SqlQuery](https://github.com/auraphp/Aura.SqlQuery/blob/3.x/docs/select.md) as its query object. You can create a query object to inject into each fetch method using the **getSelect(): \Aura\SqlQuery\Common\Select** method in **\LeanOrm\Model**. Read the documentation for [Aura\SqlQuery](https://github.com/auraphp/Aura.SqlQuery/blob/3.x/docs/select.md) to figure out how to customize the sql queries executed by each fetch method. Some examples will be shown later on below.

> NOTE: Please ALWAYS use named parameters / place-holders in all your queries, [Aura\SqlQuery](https://github.com/auraphp/Aura.SqlQuery/blob/3.x/docs/select.md) version 3.x was designed to work with named parameters / place-holders. DO NOT use question mark parameters / place-holders in your queries.
Some of these fetch methods also accept a second argument called **$relations_to_include**. It is basically an array of relationship names for related data defined in the Model class. When you specify these relationship names in a fetch method, the fetch method will eager load the related data which would eliminate the need to issues N queries to fetch the related data for a specified defined relation for each fetched record which leads to the N+1 problem. For example, when fetching records from the authors table via the AuthorsModel, each author record / row can have one or more posts associated with it. If you do not specify that the posts for the author records be eager fetched during a fetch, then when you loop through the returned author records, additional queries will be issued to fetch the posts for each author. If we have 3 authors in the database, then doing a fetch without eager loading posts will lead to the following queries being issued when you loop through the authors and try to access the posts associated with each of them:

```sql
Expand Down Expand Up @@ -399,7 +401,7 @@ $colVals = $authorsModel->fetchCol();
$colVals = $authorsModel->fetchCol(
$authorsModel->getSelect()
->cols(['name'])
->where(' author_id <= ? ', [5])
->where(' author_id <= :author_id_val ', ['author_id_val' => 5])
);
```

Expand All @@ -420,7 +422,7 @@ $record = $authorsModel->fetchOneRecord();
$record = $authorsModel->fetchOneRecord(
$authorsModel->getSelect()
->cols(['author_id', 'name'])
->where(' author_id = ? ', [5])
->where(' author_id = :author_id_val ', ['author_id_val' => 5])
);

// $record will contain the first row of data returned by
Expand All @@ -431,7 +433,7 @@ $record = $authorsModel->fetchOneRecord(
$record = $authorsModel->fetchOneRecord(
$authorsModel->getSelect()
->cols(['author_id', 'name'])
->where(' author_id = ? ', [5]),
->where(' author_id = :author_id_val ', ['author_id_val' => 5]),
['posts'] // eager fetch posts for the author
);
```
Expand Down Expand Up @@ -478,7 +480,7 @@ $keyValPairs = $authorsModel->fetchPairs();
$keyValPairs = $authorsModel->fetchPairs(
$authorsModel->getSelect()
->cols(['author_id', 'date_created'])
->where(' author_id <= ? ', [5])
->where(' author_id <= :author_id_val ', ['author_id_val' => 5])
);

// Similar to example above, except that the second specified column is an expression
Expand All @@ -490,7 +492,7 @@ $keyValPairs = $authorsModel->fetchPairs(
$keyValPairs = $authorsModel->fetchPairs(
$authorsModel->getSelect()
->cols(['author_id', " concat(author_id, '-', 'name') "])
->where(' author_id <= ? ', [5])
->where(' author_id <= :author_id_val ', ['author_id_val' => 5])
);
```

Expand All @@ -513,7 +515,7 @@ $records = $authorsModel->fetchRecordsIntoArray();
$records = $authorsModel->fetchRecordsIntoArray(
$authorsModel->getSelect()
->cols(['author_id', 'name'])
->where(' author_id <= ? ', [5])
->where(' author_id <= :author_id_val ', ['author_id_val' => 5])
);

// $records is an array containing the all rows of data as record objects returned by
Expand All @@ -525,7 +527,7 @@ $records = $authorsModel->fetchRecordsIntoArray(
$records = $authorsModel->fetchRecordsIntoArray(
$authorsModel->getSelect()
->cols(['author_id', 'name'])
->where(' author_id <= ? ', [5]),
->where(' author_id <= :author_id_val ', ['author_id_val' => 5]),
['posts'] // eager fetch posts for all the matching authors
);
```
Expand Down Expand Up @@ -557,7 +559,7 @@ $records = $authorsModel->fetchRecordsIntoCollection();
$records = $authorsModel->fetchRecordsIntoCollection(
$authorsModel->getSelect()
->cols(['author_id', 'name'])
->where(' author_id <= ? ', [5])
->where(' author_id <= :author_id_val ', ['author_id_val' => 5])
);

// $records is a collection object containing the all rows of data as record objects returned by
Expand All @@ -569,7 +571,7 @@ $records = $authorsModel->fetchRecordsIntoCollection(
$records = $authorsModel->fetchRecordsIntoCollection(
$authorsModel->getSelect()
->cols(['author_id', 'name'])
->where(' author_id <= ? ', [5]),
->where(' author_id <= :author_id_val ', ['author_id_val' => 5]),
['posts'] // eager fetch posts for all the matching authors
);
```
Expand Down Expand Up @@ -603,7 +605,7 @@ $records = $authorsModel->fetchRowsIntoArray();
$records = $authorsModel->fetchRowsIntoArray(
$authorsModel->getSelect()
->cols(['author_id', 'name'])
->where(' author_id <= ? ', [5])
->where(' author_id <= :author_id_val ', ['author_id_val' => 5])
);

// $records is an array containing the all rows of data as record objects returned by
Expand All @@ -615,7 +617,7 @@ $records = $authorsModel->fetchRowsIntoArray(
$records = $authorsModel->fetchRowsIntoArray(
$authorsModel->getSelect()
->cols(['author_id', 'name'])
->where(' author_id <= ? ', [5]),
->where(' author_id <= :author_id_val ', ['author_id_val' => 5]),
['posts'] // eager fetch posts for all the matching authors
);
```
Expand Down Expand Up @@ -660,7 +662,7 @@ $value = $authorsModel->fetchValue(
$value = $authorsModel->fetchValue(
$authorsModel->getSelect()
->cols(['max(author_id)'])
->where(' author_id <= ? ', [5])
->where(' author_id <= :author_id_val ', ['author_id_val' => 5])
);

// NOTE: if the database table is empty or the select query returns no row(s) of
Expand Down Expand Up @@ -719,7 +721,7 @@ $authorsModel = new AuthorsModel('mysql:host=hostname;dbname=blog', 'user', 'pwd
///////////////////////////////////////////////////////////////////
$joeBlowRecord = $authorsModel->fetchOneRecord(
$authorsModel->getSelect()
->where(' name = ? ', ['Joe Blow'])
->where(' name = :name_val ', [ 'name_val' => 'Joe Blow'])
);
// - Deletes record from the database table
// - Flags the record object as new
Expand All @@ -733,23 +735,14 @@ $joeBlowRecord->delete(false);
///////////////////////////////////////////////////////////////////
$jillBlowRecord = $authorsModel->fetchOneRecord(
$authorsModel->getSelect()
->where(' name = ? ', ['Jill Blow'])
->where(' name = :name_val ', [ 'name_val' => 'Jill Blow'])
);
// - Deletes record from the database table
// - Flags the record object as new
// - Clears all data associated with the record object
$jillBlowRecord->delete(true);

///////////////////////////////////////////////////////////////////
$jackAndJaneDoe = $authorsModel->fetchRecordsIntoCollection(
$authorsModel->getSelect()
->where(
' name IN (?, ?) ',
[ 'Jack Doe', 'Jane Doe' ]
)
);
// OR

$jackAndJaneDoe = $authorsModel->fetchRecordsIntoCollection(
$authorsModel->getSelect()
->where(
Expand Down Expand Up @@ -828,7 +821,7 @@ $authorsModel = new AuthorsModel('mysql:host=hostname;dbname=blog', 'user', 'pwd
///////////////////////////////////////////////////////////////////
$joeBlowRecord = $authorsModel->fetchOneRecord(
$authorsModel->getSelect()
->where(' name = ? ', ['Joe Blow'])
->where(' name = :name_val ', ['name_val' => 'Joe Blow'])
);

// Prepend a title to Joe Blow's name
Expand All @@ -839,8 +832,8 @@ $joeBlowRecord->save(); // update the record
$jackAndJaneDoe = $authorsModel->fetchRecordsIntoCollection(
$authorsModel->getSelect()
->where(
' name IN (?, ?) ',
[ 'Jack Doe', 'Jane Doe' ]
' name IN (:bar) ',
[ 'bar' => ['Jack Doe', 'Jane Doe'] ]
)
);

Expand All @@ -856,7 +849,7 @@ $jackAndJaneDoe->saveAll();
///////////////////////////////////////////////////////////////////
$jillBlowRecord = $authorsModel->fetchOneRecord(
$authorsModel->getSelect()
->where(' name = ? ', ['Jill Blow'])
->where(' name = :name_val ', ['name_val' => 'Jill Blow'])
);

// reverse the name for this record
Expand Down
14 changes: 9 additions & 5 deletions src/LeanOrm/Model.php
Original file line number Diff line number Diff line change
Expand Up @@ -754,8 +754,8 @@ protected function loadHasManyThrough(
if ( $parent_data instanceof \GDAO\Model\RecordInterface ) {

$query_obj->where(
" {$join_table_name}.{$col_in_join_table_linked_to_my_models_table} = ? ",
[$parent_data->$fkey_col_in_my_table]
" {$join_table_name}.{$col_in_join_table_linked_to_my_models_table} = :leanorm_col_in_join_table_linked_to_my_models_table_val ",
['leanorm_col_in_join_table_linked_to_my_models_table_val' => $parent_data->$fkey_col_in_my_table]
);

} else {
Expand Down Expand Up @@ -1151,8 +1151,8 @@ protected function getBelongsToOrHasOneOrHasManyData(
if ( $parent_data instanceof \GDAO\Model\RecordInterface ) {

$query_obj->where(
" {$foreign_table_name}.{$fkey_col_in_foreign_table} = ? ",
[$parent_data->$fkey_col_in_my_table]
" {$foreign_table_name}.{$fkey_col_in_foreign_table} = :leanorm_fkey_col_in_foreign_table_val ",
['leanorm_fkey_col_in_foreign_table_val' => $parent_data->$fkey_col_in_my_table]
);

} else {
Expand Down Expand Up @@ -1869,7 +1869,11 @@ public function fetchOneRecord(?object $query=null, array $relations_to_include=
public function fetchOneByPkey(string|int $id, array $relations_to_include = []): ?\GDAO\Model\RecordInterface {

$select = $this->getSelect();
$select->where(" {$this->getPrimaryCol()} = ? ", [$id]);
$query_placeholder = "leanorm_{$this->getTableName()}_{$this->getPrimaryCol()}_val";
$select->where(
" {$this->getPrimaryCol()} = :{$query_placeholder} ",
[ $query_placeholder => $id]
);

return $this->fetchOneRecord($select, $relations_to_include);
}
Expand Down

0 comments on commit 432ab18

Please sign in to comment.