77
88namespace bashkarev \clickhouse ;
99
10+ use ClickHouseDB \Exception \DatabaseException ;
11+ use ClickHouseDB \Statement ;
1012use Yii ;
13+ use yii \db \Exception ;
1114
1215/**
1316 * @property Connection $db
@@ -23,12 +26,6 @@ protected function queryInternal($method, $fetchMode = null)
2326 {
2427 $ rawSql = $ this ->getRawSql ();
2528
26- // Add LIMIT 1 for single result SELECT queries to save transmission bandwidth and properly reuse socket
27- if (in_array ($ fetchMode , ['fetch ' , 'fetchColumn ' ]) && !preg_match ('/LIMIT\s+\d+$/i ' , $ rawSql )) {
28- Yii::trace ('LIMIT 1 added for single result query explicitly! Try to add LIMIT 1 manually ' , 'bashkarev\clickhouse\Command::query ' );
29- $ rawSql = $ rawSql .' LIMIT 1 ' ;
30- }
31-
3229 Yii::info ($ rawSql , 'bashkarev\clickhouse\Command::query ' );
3330 if ($ method !== '' ) {
3431 $ info = $ this ->db ->getQueryCacheInfo ($ this ->queryCacheDuration , $ this ->queryCacheDependency );
@@ -50,17 +47,19 @@ protected function queryInternal($method, $fetchMode = null)
5047 }
5148 }
5249 }
53- $ generator = $ this -> db -> execute ();
50+
5451 $ token = $ rawSql ;
5552 try {
5653 Yii::beginProfile ($ token , 'bashkarev\clickhouse\Command::query ' );
57- $ generator ->send ($ this ->createRequest ($ rawSql , true ));
58- $ generator ->send (false );
54+ $ statement = $ this ->db ->executeSelect ($ rawSql );
5955 if ($ method === '' ) {
60- return $ generator ;
56+ return $ statement -> rows () ;
6157 }
62- $ result = call_user_func_array ([$ this , $ method ], [$ generator , $ fetchMode ]);
58+ $ result = call_user_func_array ([$ this , $ method ], [$ statement , $ fetchMode ]);
59+ Yii::endProfile ($ token , 'bashkarev\clickhouse\Command::query ' );
60+ } catch (DatabaseException $ e ) {
6361 Yii::endProfile ($ token , 'bashkarev\clickhouse\Command::query ' );
62+ throw new Exception ($ e ->getMessage ());
6463 } catch (\Exception $ e ) {
6564 Yii::endProfile ($ token , 'bashkarev\clickhouse\Command::query ' );
6665 throw $ e ;
@@ -85,18 +84,16 @@ public function execute()
8584 if ($ this ->sql == '' ) {
8685 return 0 ;
8786 }
88- $ generator = $ this -> db -> execute ();
87+
8988 $ token = $ rawSql ;
9089 try {
9190 Yii::beginProfile ($ token , __METHOD__ );
92- $ generator ->send ($ this ->createRequest ($ rawSql , false ));
93- $ generator ->send (false );
94- while ($ generator ->valid ()) {
95- $ generator ->next ();
96- }
97- Yii::endProfile ($ token , __METHOD__ );
91+ $ statement = $ this ->db ->execute ($ rawSql );
9892 $ this ->refreshTableSchema ();
99- return 1 ;
93+ return (int )(!$ statement ->isError ());
94+ } catch (DatabaseException $ e ) {
95+ Yii::endProfile ($ token , __METHOD__ );
96+ throw new Exception ($ e ->getMessage ());
10097 } catch (\Exception $ e ) {
10198 Yii::endProfile ($ token , __METHOD__ );
10299 throw $ e ;
@@ -110,128 +107,79 @@ public function execute()
110107 */
111108 public function queryBatchInternal ($ size )
112109 {
113- $ rawSql = $ this ->getRawSql ();
110+ // TODO: real batch select
111+ $ allRows = $ this ->queryAll ();
112+
114113 $ count = 0 ;
114+ $ index = 0 ;
115115 $ rows = [];
116- Yii::info ($ rawSql , 'bashkarev\clickhouse\Command::query ' );
117- $ generator = $ this ->db ->execute ();
118- $ token = $ rawSql ;
119- try {
120- Yii::beginProfile ($ token , 'bashkarev\clickhouse\Command::query ' );
121- $ generator ->send ($ this ->createRequest ($ rawSql , true ));
122- $ generator ->send (false );
123- $ index = 0 ;
124- while ($ generator ->valid ()) {
125- $ count ++;
126- $ rows [$ index ] = $ generator ->current ();
127- if ($ count >= $ size ) {
128- yield $ rows ;
129- $ rows = [];
130- $ count = 0 ;
131- }
132- ++$ index ;
133- $ generator ->next ();
134- }
135- if ($ rows !== []) {
116+ foreach ($ allRows as $ row ) {
117+ $ count ++;
118+ $ rows [$ index ] = $ row ;
119+ if ($ count >= $ size ) {
136120 yield $ rows ;
121+ $ rows = [];
122+ $ count = 0 ;
137123 }
138- Yii::endProfile ($ token , 'bashkarev\clickhouse\Command::query ' );
139- } catch (\Exception $ e ) {
140- Yii::endProfile ($ token , 'bashkarev\clickhouse\Command::query ' );
141- throw $ e ;
124+ $ index ++;
142125 }
143- }
144-
145- /**
146- * @param string $table
147- * @param array $files
148- * @param array $columns
149- * @return InsertFiles
150- */
151- public function batchInsertFiles ($ table , $ files = [], $ columns = [])
152- {
153- return new InsertFiles ($ this ->db , $ table , $ files , $ columns );
154- }
155126
156- /**
157- * @param string $sql
158- * @param bool $forRead
159- * @return string
160- */
161- protected function createRequest ($ sql , $ forRead )
162- {
163- $ data = $ sql ;
164- $ url = $ this ->db ->getConfiguration ()->prepareUrl ();
165- if ($ forRead === true ) {
166- $ data .= ' FORMAT JSONEachRow ' ;
127+ if ($ rows !== []) {
128+ yield $ rows ;
167129 }
168- $ header = "POST $ url HTTP/1.1 \r\n" ;
169- $ header .= "Content-Length: " . strlen ($ data ) . "\r\n" ;
170- $ header .= "\r\n" ;
171- $ header .= $ data ;
172-
173- return $ header ;
174130 }
175131
176132 /**
177- * @param \Generator $generator
133+ * @param \ClickHouseDB\Statement $statement
178134 * @param int $mode
179135 * @return array
180136 */
181- protected function fetchAll (\ Generator $ generator , $ mode )
137+ protected function fetchAll (Statement $ statement , $ mode )
182138 {
183- $ result = [];
184- if ($ mode === \PDO ::FETCH_COLUMN ) {
185- while ($ generator ->valid ()) {
186- $ result [] = current ($ generator ->current ());
187- $ generator ->next ();
188- }
189- } else {
190- while ($ generator ->valid ()) {
191- $ result [] = $ generator ->current ();
192- $ generator ->next ();
193- }
139+ $ result = $ statement ->rows ();
140+
141+ if ($ result === null ) {
142+ return [];
194143 }
195- return $ result ;
144+
145+ if ($ mode !== \PDO ::FETCH_COLUMN ) {
146+ return $ result ;
147+ }
148+
149+ $ firstRow = current ($ result );
150+ if ($ firstRow === false ) {
151+ return [];
152+ }
153+
154+ $ firstKey = current (array_keys ($ firstRow ));
155+
156+ return array_column ($ result , $ firstKey );
157+
196158 }
197159
198160 /**
199- * @param \Generator $generator
161+ * @param \ClickHouseDB\Statement $statement
200162 * @param $mode
201163 * @return bool|mixed
202164 */
203- protected function fetchColumn (\ Generator $ generator , $ mode )
165+ protected function fetchColumn (Statement $ statement , $ mode )
204166 {
205- if (!$ generator ->valid ()) {
167+ $ row = $ statement ->fetchOne ();
168+
169+ if ($ row === null ) {
206170 return false ;
207171 }
208- $ result = current ($ generator ->current ());
209- $ this ->readRest ($ generator );
210172
211- return $ result ;
173+ return current ( $ row ) ;
212174 }
213175
214176 /**
215- * @param \Generator $generator
177+ * @param \ClickHouseDB\Statement $statement
216178 * @param $mode
217179 * @return bool|mixed
218180 */
219- protected function fetch (\ Generator $ generator , $ mode )
181+ protected function fetch (Statement $ statement , $ mode )
220182 {
221- if (!$ generator ->valid ()) {
222- return false ;
223- }
224- $ result = $ generator ->current ();
225- $ this ->readRest ($ generator );
226-
227- return $ result ;
228- }
229-
230- private function readRest (\Generator $ generator )
231- {
232- while ($ generator ->valid ()) {
233- $ generator ->next ();
234- }
183+ return $ statement ->fetchOne ()??false ;
235184 }
236-
237185}
0 commit comments