1<?php
2
3namespace DDDBL;
4
5$objQueue = Singleton::getInstance('\DDDBL\Queue');
6
7#############################
8### db-connection handler ###
9#############################
10
11# get (or first establish) connection to database
12# and store the DataObject of the connection in the Queue-State
13
14$cloStoreDBConnection = function(\DDDBL\Queue $objQueue, array $arrParameter) {
15
16  if(!isConnected())
17    connect();
18
19  $objQueue->getState()->update(array('DB' => getDBDataObject()));
20
21};
22
23$objQueue->addHandler(QUEUE_GET_DB_CONNECTION_POSITION, $cloStoreDBConnection);
24
25###############################
26### query-definition-loader ###
27###############################
28
29# get the DataObject of the query and store it in the queue
30
31$cloGetQuery = function(\DDDBL\Queue $objQueue, array $arrParameter) {
32
33  $objDataObjectPool = new DataObjectPool('Query-Definition');
34
35  # get the first entry of the parameter-list; this is the query-alias
36  $strAlias = array_shift($arrParameter);
37
38  if(empty($strAlias) || !is_string($strAlias))
39    throw new \Exception('no query-alias defined!');
40
41  if(!$objDataObjectPool->exists($strAlias))
42    throw new \Exception("given query alias is unknown: $strAlias");
43
44  $objQueue->getState()->update(array('QUERY' => $objDataObjectPool->get($strAlias)));
45
46};
47
48$objQueue->addHandler(QUEUE_GET_QUERY_POSITION, $cloGetQuery);
49
50#################################
51### set BIND-DATA-TYPE option ###
52#################################
53
54# check if the query has a BIND-DATA-TYPE config.
55# if not check if there is one given for the database-connection.
56# if yes, store it as setting for the query, otherwise
57# set false for this option
58
59$cloSetBindDataTypeConfig = function(\DDDBL\Queue $objQueue, array $arrParameter) {
60
61  $objDB    = $objQueue->getState()->get('DB');
62  $objQuery = $objQueue->getState()->get('QUERY');
63
64  # skip this step, if the query itselfs has its own
65  if($objQuery->exists('BIND-DATA-TYPE')) {
66    $objQuery->update(array('BIND-DATA-TYPE' => (bool) $objQuery->get('BIND-DATA-TYPE'))); #bugfix for php-bug #38409
67    return;
68  }
69
70  # set type to false, if no config is available, otherwise use the given config
71  if(!$objDB->exists('BIND-DATA-TYPE'))
72    $objQuery->update(array('BIND-DATA-TYPE' => false));
73  else
74    $objQuery->update(array('BIND-DATA-TYPE' => (bool) $objDB->get('BIND-DATA-TYPE')));
75
76};
77
78$objQueue->addHandler(QUEUE_BIND_DATA_TYPE_POSITION, $cloSetBindDataTypeConfig);
79
80#####################
81### prepare query ###
82#####################
83
84# get the stored query and prepare() it for the given database-connection
85# store the resulting PDOStatement
86
87$cloPrepareQuery = function(\DDDBL\Queue $objQueue, array $arrParameter) {
88
89  # if query is not prepared yet, do this now
90  if(!$objQueue->getState()->get('QUERY')->exists('PDOStatement')) {
91    $objPDO = $objQueue->getState()->get('DB')->get('PDO');
92    $objPDO = $objPDO->prepare($objQueue->getState()->get('QUERY')->get('QUERY'));
93    $objQueue->getState()->get('QUERY')->update(array('PDOStatement' => $objPDO));
94  }
95
96  # copy reference of prepared statement into queue for execution
97  $objQueue->getState()->update(array('PDOStatement' => $objQueue->getState()->get('QUERY')->get('PDOStatement')));
98
99};
100
101$objQueue->addHandler(QUEUE_PREPARE_QUERY_POSITION, $cloPrepareQuery);
102
103#########################
104### execute the query ###
105#########################
106
107# handler, which maps the data-type of a variable to the PDO-constants
108
109$cloMapDataType = function($mixedParameter) {
110
111  $arrDataTypeMap = array('NULL'    => \PDO::PARAM_NULL,
112                          'boolean' => \PDO::PARAM_BOOL,
113                          'integer' => \PDO::PARAM_INT,
114                          'string'  => \PDO::PARAM_STR);
115
116  $strDataType = gettype($mixedParameter);
117
118  if(!isset($arrDataTypeMap[$strDataType]))
119    throw new \Exception ("could not bind parameters data type - type is not supported by PDO: $strDataType");
120
121  return $arrDataTypeMap[$strDataType];
122
123};
124
125# bind the given parameter to the prepared statement,
126# then set the fetch mode and execute the query
127
128$cloQueryExcecute = function(\DDDBL\Queue $objQueue, array $arrParameter) use ($cloMapDataType) {
129
130  $objPDO = $objQueue->getState()->get('PDOStatement');
131
132  # remove the alias from the parameter list
133  array_shift($arrParameter);
134
135  $objQuery = $objQueue->getState()->get('QUERY');
136
137  if(true === $objQuery->get('BIND-DATA-TYPE')) {
138
139    foreach($arrParameter AS $intIndex => $mixedParameter)
140      $objPDO->bindValue($intIndex + 1, $mixedParameter, $cloMapDataType($mixedParameter));
141
142  } else {
143
144    foreach($arrParameter AS $intIndex => $mixedParameter)
145      $objPDO->bindValue($intIndex + 1, $mixedParameter);
146
147  }
148
149  $objPDO->setFetchMode(\PDO::FETCH_ASSOC);
150
151  # execute the query. if execution fails, throw an exception
152  if(!$objPDO->execute())
153    throw new QueryException($objPDO, $objQuery->getAll());
154
155};
156
157$objQueue->addHandler(QUEUE_EXECUTE_QUERY_POSITION, $cloQueryExcecute);
158
159###############################
160### format the query result ###
161###############################
162
163# if a result-handler for the query is configured, call it
164
165$cloFormatQueryResult = function(\DDDBL\Queue $objQueue, array $arrParameter) {
166
167  $objQuery = $objQueue->getState()->get('QUERY');
168
169  if(!$objQuery->exists('HANDLER'))
170    return ;
171
172  # get the handler and its config
173  $strHandlerConfig = $objQuery->get('HANDLER');
174  $arrHandlerConfig = preg_split('/\s+/', $strHandlerConfig);
175  $strHandler       = array_shift($arrHandlerConfig);
176
177  # remove handler-name from config
178  $strHandlerConfig = trim(str_replace($strHandler, '', $strHandlerConfig));
179
180  $objDataObjectPool = new DataObjectPool('Result-Handler');
181
182  if(!$objDataObjectPool->exists($strHandler))
183    throw new \Exception ("unknown result-handler: $strHandler");
184
185  $objHandler = $objDataObjectPool->get($strHandler);
186  $cloHandler = $objHandler->get('HANDLER');
187
188  $cloHandler($objQueue, $strHandlerConfig);
189
190};
191
192$objQueue->addHandler(QUEUE_FORMAT_RESULT_POSITION, $cloFormatQueryResult);
193
194####################
195### close cursor ###
196####################
197
198# closing the cursor of the PDOStatement. this will free
199# the result and enable the connection to execute the next query
200
201$cloCloseCursor = function(\DDDBL\Queue $objQueue, array $arrParameter) {
202
203  $objQueryResult = $objQueue->getState()->get('PDOStatement');
204  $objQueryResult->closeCursor();
205
206};
207
208$objQueue->addHandler(QUEUE_CLOSE_CURSOR_POSITION, $cloCloseCursor);
209