22namespace Kir \MySQL \Builder ;
33
44use Closure ;
5+ use Generator ;
56use IteratorAggregate ;
67use Kir \MySQL \Builder \Helpers \DBIgnoreRow ;
78use Kir \MySQL \Builder \Helpers \FieldTypeProvider ;
89use Kir \MySQL \Builder \Helpers \FieldValueConverter ;
910use Kir \MySQL \Builder \Helpers \LazyRowGenerator ;
1011use Kir \MySQL \Builder \Helpers \YieldPolyfillIterator ;
12+ use PDO ;
1113use Traversable ;
1214
1315/**
@@ -62,7 +64,8 @@ public function setPreserveTypes($preserveTypes = true) {
6264 */
6365 public function fetchRows (Closure $ callback = null ) {
6466 return $ this ->createTempStatement (function (QueryStatement $ statement ) use ($ callback ) {
65- $ data = $ statement ->fetchAll (\PDO ::FETCH_ASSOC );
67+ $ statement ->setFetchMode (PDO ::FETCH_ASSOC );
68+ $ data = $ statement ->fetchAll ();
6669 if ($ this ->preserveTypes ) {
6770 $ columnDefinitions = FieldTypeProvider::getFieldTypes ($ statement );
6871 foreach ($ data as &$ row ) {
@@ -93,10 +96,13 @@ public function fetchRows(Closure $callback = null) {
9396 public function fetchRowsLazy (Closure $ callback = null ) {
9497 if (version_compare (PHP_VERSION , '5.5 ' , '< ' )) {
9598 return new YieldPolyfillIterator ($ callback , $ this ->preserveTypes , function () {
96- return $ this ->createStatement ();
99+ $ statement = $ this ->createStatement ();
100+ $ statement ->setFetchMode (PDO ::FETCH_ASSOC );
101+ return $ statement ;
97102 });
98103 }
99104 $ statement = $ this ->createStatement ();
105+ $ statement ->setFetchMode (PDO ::FETCH_ASSOC );
100106 $ generator = new LazyRowGenerator ($ this ->preserveTypes );
101107 return $ generator ->generate ($ statement , $ callback );
102108 }
@@ -108,7 +114,87 @@ public function fetchRowsLazy(Closure $callback = null) {
108114 */
109115 public function fetchRow (Closure $ callback = null ) {
110116 return $ this ->createTempStatement (function (QueryStatement $ statement ) use ($ callback ) {
111- $ row = $ statement ->fetch (\PDO ::FETCH_ASSOC );
117+ $ statement ->setFetchMode (PDO ::FETCH_ASSOC );
118+ $ row = $ statement ->fetch ();
119+ if (!is_array ($ row )) {
120+ return [];
121+ }
122+ if ($ this ->preserveTypes ) {
123+ $ columnDefinitions = FieldTypeProvider::getFieldTypes ($ statement );
124+ $ row = FieldValueConverter::convertValues ($ row , $ columnDefinitions );
125+ }
126+ if ($ callback !== null ) {
127+ $ result = $ callback ($ row );
128+ if ($ result !== null ) {
129+ $ row = $ result ;
130+ }
131+ }
132+ return $ row ;
133+ });
134+ }
135+
136+ /**
137+ * @param string $className
138+ * @param Closure $callback
139+ * @return \array[]
140+ * @throws \Exception
141+ */
142+ public function fetchObjects ($ className , Closure $ callback = null ) {
143+ return $ this ->createTempStatement (function (QueryStatement $ statement ) use ($ className , $ callback ) {
144+ $ statement ->setFetchMode (PDO ::FETCH_CLASS , $ className );
145+ $ data = $ statement ->fetchAll ();
146+ if ($ this ->preserveTypes ) {
147+ $ columnDefinitions = FieldTypeProvider::getFieldTypes ($ statement );
148+ foreach ($ data as &$ row ) {
149+ $ row = FieldValueConverter::convertValues ($ row , $ columnDefinitions );
150+ }
151+ }
152+ if ($ callback !== null ) {
153+ return call_user_func (function ($ resultData = []) use ($ data , $ callback ) {
154+ foreach ($ data as $ row ) {
155+ $ result = $ callback ($ row );
156+ if ($ result !== null && !($ result instanceof DBIgnoreRow)) {
157+ $ resultData [] = $ result ;
158+ } else {
159+ $ resultData [] = $ row ;
160+ }
161+ }
162+ return $ resultData ;
163+ });
164+ }
165+ return $ data ;
166+ });
167+ }
168+
169+ /**
170+ * @param string $className
171+ * @param Closure $callback
172+ * @return array[]|Generator
173+ */
174+ public function fetchObjectsLazy ($ className , Closure $ callback = null ) {
175+ if (version_compare (PHP_VERSION , '5.5 ' , '< ' )) {
176+ return new YieldPolyfillIterator ($ callback , $ this ->preserveTypes , function () use ($ className ) {
177+ $ statement = $ this ->createStatement ();
178+ $ statement ->setFetchMode (PDO ::FETCH_CLASS , $ className );
179+ return $ statement ;
180+ });
181+ }
182+ $ statement = $ this ->createStatement ();
183+ $ statement ->setFetchMode (PDO ::FETCH_CLASS , $ className );
184+ $ generator = new LazyRowGenerator ($ this ->preserveTypes );
185+ return $ generator ->generate ($ statement , $ callback );
186+ }
187+
188+ /**
189+ * @param string $className
190+ * @param Closure|null $callback
191+ * @return string[]
192+ * @throws \Exception
193+ */
194+ public function fetchObject ($ className , Closure $ callback = null ) {
195+ return $ this ->createTempStatement (function (QueryStatement $ statement ) use ($ className , $ callback ) {
196+ $ statement ->setFetchMode (PDO ::FETCH_CLASS , $ className );
197+ $ row = $ statement ->fetch ();
112198 if (!is_array ($ row )) {
113199 return [];
114200 }
0 commit comments