Agile Data (http://git.io/ad) is my new open-source framework that fills the growing gap between ORM and Raw SQL queries. In this presentation I explain why have I started Agile Data project and how can it enable PHP developer to generate more sophisticated queries when they need them.
4. Myself
‣ Love Web Apps
‣ 25 years of coding
‣ Entrepreneur
‣ I buy Software
My PHP Startup
‣ Helps developers
‣ Open-source
‣ PHP in Enterprise
‣ Code Sharing
About Me
5. Query
‣ Control
‣ Advanced Features
‣ Multi-Record
ORM
‣ 10+ tables
‣ SoftDelete, Audit
‣ Domain Model
Database Interaction
Today
21. Fields in Agile Data
$book->addField('total_cost', ['type'=>'money']);
Like properties, but smarter.
22. Property
‣ Handy and Native
‣ No type
‣ No logic
‣ No meta-info
Field
‣ Array-access
‣ Type enforcing
‣ Extensible logic
‣ Meta-info
Fields
23. Fields
class Document extends atk4dataModel
{
public $table = 'document';
function init() {
parent::init();
$this->addField('ref_no', ['type'=>'string']);
$this->addField('date', ['type'=>'date']);
$this->addField('type', ['enum'=>['invoice','payment']]);
$this->hasOne('contact_id', new Contact());
$this->addField('is_archived', ['type'=>'boolean']);
}
}
24. Generic UI
$form = new uiForm();
$form->setModel(new smboModel_Job($db));
echo $form->render();
Fastest imaginable way to build
good looking data entry form?
32. Record Mapping
‣ Active Record and ORM map individual records
‣ Multiple records require Multiple objects in memory
Model_Client object
user type=client
user type=client
user type=client
user type=client
user type=admin
user type=admin
tableuser
Model_Client object
33. DataSet Mapping
‣ Agile Data works with DataSets
‣ Multiple records require Single objects in memory
Model_Client object
user type=client
user type=client
user type=client
user type=client
user type=admin
user type=admin
tableuser
35. Conditions
class Client extend User {
function init() {
parent::init();
$this->addCondition('type', 'client');
}
}
Narrow the scope of accessible
records
36. Conditions
$client = new Client($db);
$client->load(12);
$client['type'] = 'admin';
$client->save(); // <== Exception
Prevent human error
46. foreach (Client::all() as $client) {
foreach($client->orders() as $order){
$sum += $order->amount;
}
}
N+1 problem
‣ 20 users in database
‣ 20 extra queries to fetch orders
47. foreach (Client::all() as $client) {
foreach($client->orders() as $order){
$sum += $order->amount;
}
}
Memory Problem
‣ 20 users in database
‣ array of 20 objects
‣ other properties are also fetched
48. foreach (Client::all() as $client) {
foreach($client->orders() as $order){
$sum += $order->amount;
}
}
Lazy-loading; ID Stuffing
‣ only load IDs
‣ trigger loading on property access
‣ select from `order` where user in (1,2,3,…)
49. Action
$client = new Client($db);
$sum = $client->ref('Order')
->action('fx', ['sum', 'amount'])
->execute();
Event from Domain Model to your
database
54. ORM
‣ Emit query-builder
‣ Limited scope
support
‣ SQL only
‣ Fully Persistence
logic
Agile Actions
‣ Emit DSQL
‣ All conditions
applied
‣ Extensible to
NoSQL
‣ Domain model
support
Multi-record operations
55. Agile Data
Model (DataSet
)
Field Operations
Query ❤️ ❤️ ❤️
Condition ❤️ ❤️ ❤️
Statements ❤️ ❤️ ❤️
Expression ❤️ ❤️ ❤️
ORM Components
QueryComponents
56. Summary
‣ ORM and Query Builders has a bumpy relationship
‣ Luckily there are other patterns
‣ Consider query latency
‣ Consider flexibility
‣ Consider abstraction
57. Execute less queries Design a beautiful API
Friendly with UIExtensions
Agile Data
61. git.io/ad
✓ Works in any framework / PHP app
✓ Lightweight and Agile
✓ Integrates with UI frameworks (like
ATK)
✓ Commercial Support
Agile Data is Open-
Source
62. Join my OSS project
‣ Agile Data v1.1.5
git.io/ad
‣ Agile UI (developing)
github.com/atk4/ui
My other topics
‣ Agile Toolkit
Full-stack PHP UI
65. Join on Expression
$invoice->hasOne('client_id', new Client())
->addField('client_country_id', 'country_id');
$invoice->join('country', 'client_country_id')
->addFields([
'country_short_code'=>'short_code',
'country_is_eu'=>'is_eu',
'country'=>'name'
]);
If you need country data inside
your Invoice report, but country_id
is defined through Client.