1: <?php
2:
3: namespace PHPixie\ORM\Mappers;
4:
5: class Query
6: {
7: protected $mappers;
8: protected $loaders;
9: protected $models;
10: protected $plans;
11: protected $steps;
12:
13: protected $databaseModel;
14:
15: public function __construct($mappers, $loaders, $models, $plans, $steps)
16: {
17: $this->mappers = $mappers;
18: $this->loaders = $loaders;
19: $this->models = $models;
20: $this->plans = $plans;
21: $this->steps = $steps;
22:
23: $this->databaseModel = $models->database();
24: }
25:
26: public function mapCount($query)
27: {
28: $modelName = $query->modelName();
29: $repository = $this->databaseModel->repository($modelName);
30: $databaseQuery = $repository->databaseCountQuery();
31: $step = $this->steps->count($databaseQuery);
32: $plan = $this->plans->count($step);
33:
34: $this->mapCommon($query, $databaseQuery, $plan);
35:
36: return $plan;
37: }
38:
39: public function mapUpdate($query, $update)
40: {
41: $modelName = $query->modelName();
42: $repository = $this->databaseModel->repository($modelName);
43: $databaseQuery = $repository->databaseUpdateQuery();
44:
45: $step = $this->steps->query($databaseQuery);
46: $plan = $this->plans->query($step);
47:
48: $this->mapCommon($query, $databaseQuery, $plan);
49: $this->mappers->update()->map($databaseQuery, $update);
50:
51: return $plan;
52: }
53:
54: public function mapFind($query, $preload = null)
55: {
56: $modelName = $query->modelName();
57: $repository = $this->databaseModel->repository($modelName);
58: $databaseQuery = $repository->databaseSelectQuery();
59:
60: $resultStep = $this->steps->reusableResult($databaseQuery);
61: $loader = $this->loaders->reusableResult($repository, $resultStep);
62:
63: $preloadingProxy = null;
64:
65: if($preload !== null) {
66: $preloadingProxy = $this->loaders->preloadingProxy($loader);
67: $loader = $preloadingProxy;
68: }
69:
70: $loader = $this->loaders->cachingProxy($loader);
71:
72: $plan = $this->plans->loader($resultStep, $loader);
73: $this->mapCommon($query, $databaseQuery, $plan);
74:
75: if($preload !== null) {
76: $preloadPlan = $plan->preloadPlan();
77: $preloadMapper = $this->mappers->preload();
78: $preloadMapper->map($preloadingProxy, $modelName, $preload, $resultStep, $preloadPlan);
79: }
80:
81: return $plan;
82: }
83:
84: protected function mapCommon($query, $databaseQuery, $queryPlan)
85: {
86: $modelName = $query->modelName();
87: $conditions = $query->getConditions();
88: $requiredPlan = $queryPlan->requiredPlan();
89:
90: $this->mappers->conditions()->map(
91: $databaseQuery,
92: $modelName,
93: $conditions,
94: $requiredPlan
95: );
96:
97: $offset = $query->getOffset();
98: if($offset !== null) {
99: $databaseQuery->offset($offset);
100: }
101:
102: $limit = $query->getLimit();
103: if($limit !== null) {
104: $databaseQuery->limit($limit);
105: }
106:
107: foreach($query->getOrderBy() as $orderBy) {
108: if($orderBy->direction() === 'asc') {
109: $databaseQuery->orderAscendingBy(
110: $orderBy->field()
111: );
112: }else{
113: $databaseQuery->orderDescendingBy(
114: $orderBy->field()
115: );
116: }
117: }
118: }
119:
120:
121: public function mapDelete($query)
122: {
123: $deleteMapper = $this->mappers->cascadeDelete();
124: $modelName = $query->modelName();
125: $repository = $this->databaseModel->repository($modelName);
126:
127: $deleteQuery = $repository->databaseDeleteQuery();
128: $step = $this->steps->query($deleteQuery);
129: $plan = $this->plans->query($step);
130:
131: if($deleteMapper->isModelHandled($modelName)) {
132: $selectQuery = $repository->databaseSelectQuery();
133: $this->mapCommon($query, $selectQuery, $plan);
134: $requiredPlan = $plan->requiredPlan();
135: $deleteMapper->map($deleteQuery, $selectQuery, $modelName, $requiredPlan);
136:
137: }else{
138: $this->mapCommon($query, $deleteQuery, $plan);
139: }
140:
141: return $plan;
142: }
143:
144: }
145: