1: <?php
2: 3: 4: 5: 6: 7: 8: 9:
10:
11: namespace Kotchasan\Orm;
12:
13: use Kotchasan\ArrayTool;
14: use Kotchasan\Database\Query;
15: use Kotchasan\Database\Schema;
16:
17: 18: 19: 20: 21: 22: 23:
24: class Recordset extends Query implements \Iterator
25: {
26: 27: 28: 29: 30:
31: private $datas;
32: 33: 34: 35: 36:
37: private $field;
38: 39: 40: 41: 42:
43: private $fields = array();
44: 45: 46: 47: 48:
49: private $firstRecord;
50: 51: 52: 53: 54:
55: private $perPage;
56: 57: 58: 59: 60: 61: 62:
63: private $toArray = false;
64: 65: 66: 67: 68:
69: private $values;
70:
71: 72: 73: 74: 75:
76: public function __construct($field)
77: {
78: $this->field = new $field();
79: parent::__construct($this->field->getConn());
80: $this->sqls = array();
81: $this->values = array();
82: $this->field->initTableName($this->db);
83: if (method_exists($this->field, 'getConfig')) {
84: foreach ($this->field->getConfig() as $key => $value) {
85: $this->buildQuery($key, $value);
86: }
87: }
88: }
89:
90: 91: 92: 93: 94: 95: 96: 97:
98: public function all($fields = null)
99: {
100: if (!empty($fields)) {
101: $qs = array();
102: foreach (func_get_args() as $item) {
103: if (!empty($item)) {
104: $qs[] = $this->fieldName($item);
105: }
106: }
107: $this->sqls['select'] = empty($qs) ? '*' : implode(', ', $qs);
108: } elseif (empty($this->sqls['select'])) {
109: $this->sqls['select'] = '*';
110: }
111:
112: return $this->doExecute(0, 0);
113: }
114:
115: 116: 117: 118: 119: 120: 121: 122:
123: public function cacheOn($auto_save = true)
124: {
125: $this->cache->cacheOn($auto_save);
126:
127: return $this;
128: }
129:
130: 131: 132: 133: 134:
135: public function count()
136: {
137: $old_sqls = $this->sqls;
138: $old_values = $this->values;
139: $this->sqls = array();
140: $this->sqls['select'] = 'COUNT(*) AS `count`';
141: foreach ($old_sqls as $key => $value) {
142: if ($key !== 'order' && $key !== 'limit' && $key !== 'select') {
143: $this->sqls[$key] = $value;
144: }
145: }
146: $sql = $this->createQuery(0, 0);
147: $result = $this->db()->customQuery($sql, true, $this->values);
148: $count = empty($result) ? 0 : (int) $result[0]['count'];
149: $this->sqls = $old_sqls;
150: $this->values = $old_values;
151:
152: return $count;
153: }
154:
155: 156: 157: 158: 159: 160: 161:
162: public static function create($filed)
163: {
164: return new static($filed);
165: }
166:
167: 168: 169: 170: 171:
172: public function createQuery($start, $count)
173: {
174: $this->sqls['from'] = $this->field->getTableWithAlias();
175: if (!empty($start) || !empty($count)) {
176: $this->sqls['limit'] = $count;
177: $this->sqls['start'] = $start;
178: }
179:
180: return $this->db()->makeQuery($this->sqls);
181: }
182:
183: 184: 185:
186: public function current()
187: {
188: $var = current($this->datas);
189:
190: return $var;
191: }
192:
193: 194: 195: 196: 197: 198: 199: 200: 201: 202:
203: public function customQuery($sql, $toArray = true, $values = array())
204: {
205: return $this->db()->customQuery($sql, $toArray, $values);
206: }
207:
208: 209: 210: 211: 212: 213: 214: 215: 216: 217:
218: public function delete($condition = array(), $all = false, $oprator = 'AND')
219: {
220: $ret = $this->buildWhereValues($condition, $oprator, $this->field->getPrimarykey());
221: $sqls = array(
222: 'delete' => $this->field->table_name,
223: 'where' => $ret[0],
224: );
225: if (!$all) {
226: $sqls['limit'] = 1;
227: }
228: $sql = $this->db()->makeQuery($sqls);
229:
230: return $this->db()->query($sql, $ret[1]);
231: }
232:
233: 234: 235: 236: 237: 238:
239: public function emptyTable()
240: {
241: return $this->db()->emptyTable($this->field->table_name);
242: }
243:
244: 245: 246: 247: 248: 249: 250: 251:
252: public function execute($fields = null)
253: {
254: if (!empty($fields)) {
255: $qs = array();
256: foreach (func_get_args() as $item) {
257: if (!empty($item)) {
258: $qs[] = $this->fieldName($item);
259: }
260: }
261: $this->sqls['select'] = empty($qs) ? '*' : implode(', ', $qs);
262: } elseif (empty($this->sqls['select'])) {
263: $this->sqls['select'] = '*';
264: }
265:
266: return $this->doExecute($this->firstRecord, $this->perPage);
267: }
268:
269: 270: 271: 272: 273: 274: 275: 276:
277: public function fieldExists($field)
278: {
279: if (empty($this->fields)) {
280: $this->fields = Schema::create($this->db())->fields($this->field->table_name);
281: }
282:
283: return in_array($field, $this->fields);
284: }
285:
286: 287: 288: 289: 290: 291: 292:
293: public function find($id)
294: {
295: return $this->where((int) $id)->first();
296: }
297:
298: 299: 300: 301: 302: 303: 304: 305: 306:
307: public function first($fields = null)
308: {
309: $sqls = array(
310: 'from' => $this->field->getTableWithAlias(),
311: 'limit' => 1,
312: );
313: if (!empty($fields)) {
314: $qs = array();
315: foreach (func_get_args() as $item) {
316: if (!empty($item)) {
317: $qs[] = $this->fieldName($item);
318: }
319: }
320: $sqls['select'] = empty($qs) ? '*' : implode(', ', $qs);
321: } elseif (empty($this->sqls['select'])) {
322: $sqls['select'] = '*';
323: }
324: $sqls = ArrayTool::replace($this->sqls, $sqls);
325: $sql = $this->db()->makeQuery($sqls);
326: $this->datas = $this->db()->customQuery($sql, true, $this->values);
327: if (empty($this->datas)) {
328: return false;
329: } elseif ($this->toArray) {
330: return $this->datas[0];
331: } else {
332: $class = get_class($this->field);
333:
334: return new $class($this->datas[0]);
335: }
336: }
337:
338: 339: 340: 341: 342:
343: public function getField()
344: {
345: return $this->field;
346: }
347:
348: 349: 350: 351: 352:
353: public function getFields()
354: {
355: if (empty($this->datas)) {
356: $this->first();
357: }
358:
359: return $this->db()->getFields();
360: }
361:
362: 363: 364: 365: 366:
367: public function getValues()
368: {
369: return $this->values;
370: }
371:
372: 373: 374: 375: 376: 377: 378: 379: 380:
381: public function group($params, $oprator = 'AND')
382: {
383: switch (strtoupper($oprator)) {
384: case 'AND':
385: return $this->groupAnd($params);
386: break;
387: case 'OR':
388: return $this->groupOr($params);
389: break;
390: }
391: }
392:
393: 394: 395: 396: 397: 398: 399: 400:
401: public function insert(Field $field)
402: {
403: $save = array();
404: foreach (Schema::create($this->db())->fields($this->field->table_name) as $item) {
405: if (isset($field->$item)) {
406: $save[$item] = $field->$item;
407: }
408: }
409: if (empty($save)) {
410: $result = false;
411: } else {
412: $result = $this->db()->insert($this->field->table_name, $save);
413: }
414:
415: return $result;
416: }
417:
418: 419: 420: 421: 422: 423: 424: 425: 426:
427: public function join($field, $type, $on)
428: {
429: return $this->doJoin($field, $type, $on);
430: }
431:
432: 433: 434:
435: public function key()
436: {
437: $var = key($this->datas);
438:
439: return $var;
440: }
441:
442: 443: 444: 445: 446: 447: 448: 449:
450: public function limit($count, $start = 0)
451: {
452: if (!empty($start)) {
453: $this->sqls['start'] = (int) $start;
454: }
455: $this->sqls['limit'] = (int) $count;
456:
457: return $this;
458: }
459:
460: 461: 462:
463: public function next()
464: {
465: $var = next($this->datas);
466:
467: return $var;
468: }
469:
470: 471: 472: 473: 474: 475: 476:
477: public function order($sorts)
478: {
479: $sorts = is_array($sorts) ? $sorts : func_get_args();
480: $ret = $this->buildOrder($sorts);
481: if (!empty($ret)) {
482: $this->sqls['order'] = $ret;
483: }
484:
485: return $this;
486: }
487:
488: 489: 490: 491: 492: 493: 494: 495: 496:
497: public function query($sql, $values = array())
498: {
499: $this->db()->query($sql, $values);
500: }
501:
502: 503: 504: 505: 506:
507: public function recordCount()
508: {
509: return count($this->datas);
510: }
511:
512: 513: 514:
515: public function rewind()
516: {
517: reset($this->datas);
518: }
519:
520: 521: 522: 523: 524: 525: 526: 527: 528:
529: public function take()
530: {
531: $count = func_num_args();
532: if ($count == 1) {
533: $this->perPage = (int) func_get_arg(0);
534: $this->firstRecord = 0;
535: } elseif ($count == 2) {
536: $this->perPage = (int) func_get_arg(1);
537: $this->firstRecord = (int) func_get_arg(0);
538: }
539:
540: return $this;
541: }
542:
543: 544: 545: 546: 547: 548:
549: public function toArray()
550: {
551: $this->toArray = true;
552:
553: return $this;
554: }
555:
556: 557: 558: 559: 560:
561: public function toQueryBuilder()
562: {
563: return $this->db()->createQuery()->assignment($this);
564: }
565:
566: 567: 568: 569: 570: 571: 572: 573: 574:
575: public function update($condition, $save)
576: {
577: $db = $this->db();
578: $schema = Schema::create($db);
579: $datas = array();
580: if ($save instanceof Field) {
581: foreach ($schema->fields($this->field->table_name) as $field) {
582: if (isset($save->$field)) {
583: $datas[$field] = $save->$field;
584: }
585: }
586: } else {
587: foreach ($schema->fields($this->field->table_name) as $field) {
588: if (isset($save[$field])) {
589: $datas[$field] = $save[$field];
590: }
591: }
592: }
593: if (empty($datas)) {
594: $result = false;
595: } else {
596: $result = $db->update($this->field->table_name, $condition, $datas);
597: if ($db->cacheGetAction() == 1) {
598: $db->cacheSave($datas);
599: }
600: }
601:
602: return $result;
603: }
604:
605: 606: 607: 608: 609: 610: 611: 612:
613: public function updateAll($save)
614: {
615: return $this->db()->updateAll($this->field->table_name, $save);
616: }
617:
618: 619: 620:
621: public function valid()
622: {
623: $key = key($this->datas);
624: $var = ($key !== null && $key !== false);
625:
626: return $var;
627: }
628:
629: 630: 631: 632: 633: 634: 635: 636: 637: 638: 639: 640: 641:
642: public function where($where = array(), $oprator = 'AND')
643: {
644: if (is_int($where) || (is_string($where) && $where != '') || (is_array($where) && !empty($where))) {
645: $where = $this->buildWhere($where, $oprator, $this->field->table_alias.'.'.$this->field->getPrimarykey());
646: if (is_array($where)) {
647: $this->values = ArrayTool::replace($this->values, $where[1]);
648: $where = $where[0];
649: }
650: $this->sqls['where'] = $where;
651: }
652:
653: return $this;
654: }
655:
656: 657: 658: 659: 660: 661:
662: private function buildQuery($method, $param)
663: {
664: if ($method == 'join') {
665: foreach ($param as $item) {
666: $this->doJoin($item[1], $item[0], $item[2]);
667: }
668: } else {
669: $func = 'build'.ucfirst($method);
670: if (method_exists($this, $func)) {
671: $ret = $this->{$func}($param);
672: if (is_array($ret)) {
673: $this->sqls[$method] = $ret[0];
674: $this->values = ArrayTool::replace($this->values, $ret[1]);
675: } else {
676: $this->sqls[$method] = $ret;
677: }
678: }
679: }
680: }
681:
682: 683: 684: 685: 686: 687: 688: 689: 690:
691: private function doExecute($start, $end)
692: {
693: $sql = $this->createQuery($start, $end);
694: $result = $this->db()->customQuery($sql, true, $this->values);
695: if ($this->toArray) {
696: return $result;
697: } else {
698: $class = get_class($this->field);
699: $this->datas = array();
700: foreach ($result as $item) {
701: $this->datas[] = new $class($item);
702: }
703:
704: return $this;
705: }
706: }
707:
708: 709: 710: 711: 712: 713: 714: 715: 716:
717: private function doJoin($field, $type, $on)
718: {
719: if (preg_match('/^([a-zA-Z0-9\\\\]+)(\s+(as|AS))?[\s]+([A-Z0-9]{1,2})?$/', $field, $match)) {
720: $field = $match[1];
721: }
722: $rs = new self($field);
723: $table = $rs->field->getTableWithAlias(isset($match[4]) ? $match[4] : null);
724: $ret = $rs->buildJoin($table, $type, $on);
725: if (is_array($ret)) {
726: $this->sqls['join'][] = $ret[0];
727: $this->values = ArrayTool::replace($this->values, $ret[1]);
728: } else {
729: $this->sqls['join'][] = $ret;
730: }
731:
732: return $this;
733: }
734: }
735: