PageRenderTime 52ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/components/charcoal/db/SmartGateway.class.php

https://bitbucket.org/stk2k/charcoalphp2.1
PHP | 1489 lines | 909 code | 277 blank | 303 comment | 42 complexity | 81959cdf8110579620aa64360b2669c5 MD5 | raw file
  1. <?php
  2. /**
  3. * SmartGateway???
  4. *
  5. * PHP version 5
  6. *
  7. * @package core
  8. * @author CharcoalPHP Development Team
  9. * @copyright 2008 - 2012 CharcoalPHP Development Team
  10. */
  11. class Charcoal_SmartGateway extends Charcoal_CharcoalComponent implements Charcoal_IComponent
  12. {
  13. private $_source;
  14. private $_builder;
  15. /*
  16. * ???????
  17. */
  18. public function __construct()
  19. {
  20. parent::__construct();
  21. }
  22. /*
  23. * Initialize instance
  24. *
  25. * @param Charcoal_Config $config configuration data
  26. */
  27. public function configure( Charcoal_Config $config )
  28. {
  29. log_info( "smart_gateway", "???????????????" );
  30. // ?????????????
  31. $data_source_name = Charcoal_Profile::getString( s('DB_DATA_SOURCE') );
  32. log_info( "smart_gateway", "???????: $data_source_name" );
  33. $this->_source = Charcoal_Factory::createObject( s($data_source_name), s('data_source') );
  34. log_info( "smart_gateway", "??????????????" );
  35. // SQL??????????
  36. $builder_name = $this->_source->getBackend();
  37. log_info( "smart_gateway", "SQL????: $builder_name" );
  38. $this->_builder = Charcoal_Factory::createObject( s($builder_name), s('sql_builder') );
  39. log_info( "smart_gateway", "???????????????????" );
  40. }
  41. /*
  42. * ?????????
  43. */
  44. public function initDataSource()
  45. {
  46. // ?????????????
  47. if ( !$this->_source ){
  48. $data_source_name = Charcoal_Profile::getString( s('DB_DATA_SOURCE') );
  49. $this->_source = Charcoal_Factory::createObject( s($data_source_name), s('data_source') );
  50. }
  51. }
  52. /*
  53. * SQL??????
  54. */
  55. public function initSQLBuilder()
  56. {
  57. // SQL??????????
  58. if ( !$this->_builder ){
  59. $builder_name = $this->_source->getBackend();
  60. $this->_builder = Charcoal_Factory::createObject( s($builder_name), s('sql_builder') );
  61. }
  62. }
  63. /*
  64. * ?????????
  65. */
  66. public function getDataSource()
  67. {
  68. return $this->_source;
  69. }
  70. /*
  71. * ?????????
  72. */
  73. public function setDataSource( Charcoal_IDataSource $source )
  74. {
  75. $this->_source = $source;
  76. }
  77. /*
  78. * SQL???
  79. */
  80. public function getSQLBuilder()
  81. {
  82. return $this->_builder;
  83. }
  84. /*
  85. * ?????????ON/OFF
  86. */
  87. public function autoCommit( Charcoal_Boolean $onoff = NULL )
  88. {
  89. list( $file, $line ) = Charcoal_System::caller(0);
  90. log_debug( "debug, smart_gateway", "SmartGateway#" . __METHOD__ . "() called from: $file($line)" );
  91. try{
  92. if ( $onoff ){
  93. $this->_source->autoCommit($onoff);
  94. }
  95. else{
  96. $this->_source->autoCommit();
  97. }
  98. log_debug( "debug, smart_gateway", "done: autoCommit" );
  99. }
  100. catch ( Exception $e )
  101. {
  102. _catch( $e );
  103. _throw( new Charcoal_DBAutoCommitException( s(__METHOD__." Failed."), $e ) );
  104. }
  105. }
  106. /*
  107. * ???????????
  108. */
  109. public function beginTrans()
  110. {
  111. list( $file, $line ) = Charcoal_System::caller(0);
  112. log_debug( "debug, smart_gateway", "SmartGateway#" . __METHOD__ . "() called from: $file($line)" );
  113. try{
  114. $this->_source->beginTrans();
  115. log_debug( "debug, smart_gateway", "done: beginTrans" );
  116. }
  117. catch ( Exception $e )
  118. {
  119. _catch( $e );
  120. _throw( new Charcoal_DBBeginTransactionException( s(__METHOD__." Failed."), $e ) );
  121. }
  122. }
  123. /*
  124. * ???????
  125. */
  126. public function commitTrans()
  127. {
  128. list( $file, $line ) = Charcoal_System::caller(0);
  129. log_debug( "debug, smart_gateway", "SmartGateway#" . __METHOD__ . "() called from: $file($line)" );
  130. try{
  131. $this->_source->commitTrans();
  132. log_debug( "debug, smart_gateway", "done: commitTrans" );
  133. }
  134. catch ( Exception $e )
  135. {
  136. _catch( $e );
  137. _throw( new Charcoal_DBCommitTransactionException( s(__METHOD__." Failed."), $e ) );
  138. }
  139. }
  140. /*
  141. * ?????????
  142. */
  143. public function rollbackTrans()
  144. {
  145. list( $file, $line ) = Charcoal_System::caller(0);
  146. log_debug( "debug, smart_gateway", "SmartGateway#" . __METHOD__ . "() called from: $file($line)" );
  147. try{
  148. $this->_source->rollbackTrans();
  149. log_debug( "debug, smart_gateway", "done: rollbackTrans" );
  150. }
  151. catch ( Exception $e )
  152. {
  153. _catch( $e );
  154. _throw( new Charcoal_DBRollbackTransactionException( s(__METHOD__." Failed."), $e ) );
  155. }
  156. }
  157. /*
  158. * ???????????????????
  159. */
  160. public function updateAll( Charcoal_String $model_name, Charcoal_TableDTO $data, Charcoal_SQLCriteria $criteria = NULL, Charcoal_IRecordSaveFilter $filter = NULL )
  161. {
  162. list( $file, $line ) = Charcoal_System::caller(0);
  163. log_debug( "debug, smart_gateway", "SmartGateway#" . __METHOD__ . "() called from: $file($line)" );
  164. // ?????????
  165. $this->initDataSource();
  166. // SQL??????
  167. $this->initSQLBuilder();
  168. // ?????????
  169. $model = Charcoal_TableModelCache::get( $model_name );
  170. try{
  171. list( $sql, $params ) = $this->_builder->buildUpdateSQL( $model, $data, $criteria );
  172. log_debug( "debug, smart_gateway", "sql:$sql" );
  173. log_debug( "debug, smart_gateway", "params:" . print_r($params,true) );
  174. // ???????
  175. if ( $filter ){
  176. $filter->beforeSave( $data );
  177. }
  178. // SQL??
  179. $this->_source->prepareExecute( s($sql), v($params) );
  180. }
  181. catch ( Exception $e )
  182. {
  183. _catch( $e );
  184. _throw( new Charcoal_DBException( s(__METHOD__." Failed."), $e ) );
  185. }
  186. }
  187. /*
  188. * ???????????
  189. */
  190. public function updateField( Charcoal_String $model_name, Charcoal_Integer $data_id, Charcoal_String $field, $value )
  191. {
  192. list( $file, $line ) = Charcoal_System::caller(0);
  193. log_debug( "debug, smart_gateway", "SmartGateway#" . __METHOD__ . "() called from: $file($line)" );
  194. // ?????????
  195. $this->initDataSource();
  196. // SQL??????
  197. $this->initSQLBuilder();
  198. // ?????????
  199. $model = Charcoal_TableModelCache::get( $model_name );
  200. try{
  201. // DTO
  202. $dto = $model->createDTO();
  203. $dto->$field = us($value);
  204. // log_debug( "debug, smart_gateway", "dto:" . print_r($dto,true) );
  205. log_debug( "debug, smart_gateway", "sql:$sql" );
  206. log_debug( "debug, smart_gateway", "params:" . print_r($params,true) );
  207. // ??
  208. $pk = $model->getPrimaryKey();
  209. $where = "$pk = ?";
  210. $params = array( ui($data_id) );
  211. $criteria = new Charcoal_SQLCriteria( s($where), v($params) );
  212. // SQL????????
  213. list( $sql, $params ) = $this->_builder->buildUpdateSQL( $model, $dto, $criteria );
  214. log_debug( "debug, smart_gateway", "sql:$sql" );
  215. log_debug( "debug, smart_gateway", "params:" . print_r($params,true) );
  216. // SQL??
  217. $this->_source->prepareExecute( s($sql), v($params) );
  218. }
  219. catch ( Exception $e )
  220. {
  221. _catch( $e );
  222. _throw( new Charcoal_DBException( s(__METHOD__." Failed."), $e ) );
  223. }
  224. }
  225. /*
  226. * ?????????????(NOW)???
  227. */
  228. public function updateFieldNow( Charcoal_String $model_name, Charcoal_Integer $data_id, Charcoal_String $field )
  229. {
  230. list( $file, $line ) = Charcoal_System::caller(0);
  231. log_debug( "debug, smart_gateway", "SmartGateway#" . __METHOD__ . "() called from: $file($line)" );
  232. // ?????????
  233. $this->initDataSource();
  234. // SQL??????
  235. $this->initSQLBuilder();
  236. // ?????????
  237. $model = Charcoal_TableModelCache::get( $model_name );
  238. try{
  239. $field = us($field);
  240. // ??????????????
  241. $override[$field]['update'] = new Charcoal_AnnotationValue( $model, s('update'), s('function'), v(array('now')) );
  242. // log_debug( "debug, smart_gateway", "override:" . print_r($override,true) );
  243. // ??
  244. $pk = $model->getPrimaryKey();
  245. $where = "$pk = ?";
  246. $params = array( ui($data_id) );
  247. $criteria = new Charcoal_SQLCriteria( s($where), v($params) );
  248. // SQL????????
  249. list( $sql, $params ) = $this->_builder->buildUpdateSQL( $model, $model->createDTO(), $criteria, p($override) );
  250. log_debug( "debug, smart_gateway", "sql:$sql" );
  251. log_debug( "debug, smart_gateway", "params:" . print_r($params,true) );
  252. // SQL??
  253. $this->_source->prepareExecute( s($sql), v($params) );
  254. }
  255. catch ( Exception $e )
  256. {
  257. _catch( $e );
  258. _throw( new Charcoal_DBException( s(__METHOD__." Failed."), $e ) );
  259. }
  260. }
  261. /*
  262. * ??????????????
  263. */
  264. public function updateFields( Charcoal_String $model_name, Charcoal_Integer $data_id, Charcoal_Properties $data )
  265. {
  266. list( $file, $line ) = Charcoal_System::caller(0);
  267. log_debug( "debug, smart_gateway", "SmartGateway#" . __METHOD__ . "() called from: $file($line)" );
  268. // ?????????
  269. $this->initDataSource();
  270. // SQL??????
  271. $this->initSQLBuilder();
  272. // ?????????
  273. $model = Charcoal_TableModelCache::get( $model_name );
  274. try{
  275. // DTO
  276. $dto = $model->createDTO();
  277. $data = up($data);
  278. foreach( $data as $field => $value ){
  279. $dto->$field = $value;
  280. }
  281. log_debug( "debug, smart_gateway", "dto:" . print_r($dto,true) );
  282. // ??
  283. $pk = $model->getPrimaryKey();
  284. $where = "$pk = ?";
  285. $params = array( ui($data_id) );
  286. $criteria = new Charcoal_SQLCriteria( s($where), v($params) );
  287. // SQL????????
  288. list( $sql, $params ) = $this->_builder->buildUpdateSQL( $model, $dto, $criteria );
  289. log_debug( "debug, smart_gateway", "sql:$sql" );
  290. log_debug( "debug, smart_gateway", "params:" . print_r($params,true) );
  291. // SQL??
  292. $this->_source->prepareExecute( s($sql), v($params) );
  293. }
  294. catch ( Exception $e )
  295. {
  296. _catch( $e );
  297. _throw( new Charcoal_DBException( s(__METHOD__." Failed."), $e ) );
  298. }
  299. }
  300. /*
  301. * ??
  302. */
  303. public function insert( Charcoal_String $model_name, Charcoal_TableDTO $save_data, Charcoal_IRecordSaveFilter $filter = NULL )
  304. {
  305. list( $file, $line ) = Charcoal_System::caller(0);
  306. log_debug( "debug, smart_gateway", "SmartGateway#" . __METHOD__ . "() called from: $file($line)" );
  307. $dto = clone $save_data;
  308. // ?????????
  309. $this->initDataSource();
  310. // SQL??????
  311. $this->initSQLBuilder();
  312. // ?????????
  313. $model = Charcoal_TableModelCache::get( $model_name );
  314. try{
  315. // ???????
  316. if ( $filter ){
  317. $filter->beforeSave( $dto );
  318. }
  319. // SQL???
  320. list( $sql, $params ) = $this->_builder->buildInsertSQL( $model, $dto );
  321. log_debug( "debug, smart_gateway", "sql:$sql" );
  322. log_debug( "debug, smart_gateway", "params:" . print_r($params,true) );
  323. // SQL??
  324. $this->_source->prepareExecute( s($sql), v($params) );
  325. // ID???
  326. $sql = $this->_builder->buildLastIdSQL();
  327. // ??
  328. $result = $this->_source->prepareExecute( s($sql) );
  329. // ????
  330. $row = $this->_source->fetchArray( $result );
  331. $new_id = $row[0];
  332. log_debug( "debug, smart_gateway", "new_id:$new_id" );
  333. return $new_id;
  334. }
  335. catch ( Exception $e )
  336. {
  337. _catch( $e );
  338. _throw( new Charcoal_DBException( s(__METHOD__." Failed."), $e ) );
  339. }
  340. }
  341. /*
  342. * ??
  343. */
  344. public function save( Charcoal_String $model_name, Charcoal_TableDTO $save_data, Charcoal_IRecordSaveFilter $filter = NULL )
  345. {
  346. list( $file, $line ) = Charcoal_System::caller(0);
  347. log_debug( "debug, smart_gateway", "SmartGateway#" . __METHOD__ . "() called from: $file($line)" );
  348. $dto = clone $save_data;
  349. // ?????????
  350. $this->initDataSource();
  351. // SQL??????
  352. $this->initSQLBuilder();
  353. // ?????????
  354. $model = Charcoal_TableModelCache::get( $model_name );
  355. try{
  356. // UPDATE?INSERT???
  357. $pk = us($model->getPrimaryKey());
  358. if ( isset($dto->$pk) ){
  359. // ???????????????????????INSERT????UPDATE
  360. $db_dto = $this->findByID( $model_name, s($dto->$pk) );
  361. $is_new = ($db_dto === NULL);
  362. }
  363. else{
  364. // ????????????????????INSERT
  365. $is_new = TRUE;
  366. }
  367. // ???????
  368. if ( $filter ){
  369. $filter->beforeSave( $dto );
  370. }
  371. // SQL???
  372. if ( $is_new ){
  373. list( $sql, $params ) = $this->_builder->buildInsertSQL( $model, $dto );
  374. }
  375. else{
  376. list( $sql, $params ) = $this->_builder->buildUpdateSQL( $model, $dto );
  377. }
  378. log_debug( "debug, smart_gateway", "sql:$sql" );
  379. log_debug( "debug, smart_gateway", "params:" . print_r($params,true) );
  380. // SQL??
  381. $this->_source->prepareExecute( s($sql), v($params) );
  382. // ID???
  383. if ( $is_new ){
  384. $sql = $this->_builder->buildLastIdSQL();
  385. log_debug( "debug, smart_gateway", "sql:$sql" );
  386. // ??
  387. $result = $this->_source->prepareExecute( s($sql) );
  388. // ????
  389. $row = $this->_source->fetchArray( $result );
  390. $new_id = $row[0];
  391. }
  392. else{
  393. $new_id = $dto->$pk;
  394. }
  395. log_debug( "debug, smart_gateway", "new_id:$new_id" );
  396. return $new_id;
  397. }
  398. catch ( Exception $e )
  399. {
  400. _catch( $e );
  401. _throw( new Charcoal_DBException( s(__METHOD__." Failed."), $e ) );
  402. }
  403. }
  404. /*
  405. * SQL??(INSERT/DELETE/UPDATE)
  406. */
  407. public function execute( Charcoal_String $sql, Charcoal_Vector $params = NULL )
  408. {
  409. list( $file, $line ) = Charcoal_System::caller(0);
  410. log_debug( "debug, smart_gateway", "SmartGateway#" . __METHOD__ . "() called from: $file($line)" );
  411. // ?????????
  412. $this->initDataSource();
  413. // SQL??????
  414. $this->initSQLBuilder();
  415. try{
  416. // ??
  417. $this->_source->prepareExecute( $sql, $params );
  418. }
  419. catch ( Exception $e )
  420. {
  421. _catch( $e );
  422. _throw( new Charcoal_DBException( s(__METHOD__." Failed."), $e ) );
  423. }
  424. }
  425. /*
  426. * SQL??(SELECT)
  427. */
  428. public function queryValue( Charcoal_String $sql, Charcoal_Vector $params = NULL )
  429. {
  430. list( $file, $line ) = Charcoal_System::caller(0);
  431. log_debug( "debug, smart_gateway", "SmartGateway#" . __METHOD__ . "() called from: $file($line)" );
  432. // ?????????
  433. $this->initDataSource();
  434. // SQL??????
  435. $this->initSQLBuilder();
  436. try{
  437. // DataSource??????????
  438. $ds = $this->_source;
  439. // ??
  440. $result = $ds->prepareExecute( $sql, $params );
  441. // ????
  442. $a = array();
  443. while( $row = $ds->fetchAssoc( $result ) ){
  444. $value = array_shift($row);
  445. log_debug( "debug, smart_gateway", "queryValue:$value" );
  446. return $value;
  447. }
  448. return NULL;
  449. }
  450. catch ( Exception $e )
  451. {
  452. _catch( $e );
  453. _throw( new Charcoal_DBException( s(__METHOD__." Failed."), $e ) );
  454. }
  455. }
  456. /*
  457. * SQL??(SELECT)
  458. */
  459. public function query( Charcoal_String $sql, Charcoal_Vector $params = NULL )
  460. {
  461. list( $file, $line ) = Charcoal_System::caller(0);
  462. log_debug( "debug, smart_gateway", "SmartGateway#" . __METHOD__ . "() called from: $file($line)" );
  463. // ?????????
  464. $this->initDataSource();
  465. // SQL??????
  466. $this->initSQLBuilder();
  467. try{
  468. // DataSource??????????
  469. $ds = $this->_source;
  470. // ??
  471. $result = $ds->prepareExecute( $sql, $params );
  472. // ????
  473. $a = array();
  474. while( $row = $ds->fetchAssoc( $result ) ){
  475. $a[] = $row;
  476. }
  477. return $a;
  478. }
  479. catch ( Exception $e )
  480. {
  481. _catch( $e );
  482. _throw( new Charcoal_DBException( s(__METHOD__." Failed."), $e ) );
  483. }
  484. }
  485. /*
  486. * SQL??
  487. */
  488. public function recursiveFindBySQL( Charcoal_String $model_name, Charcoal_String $sql, Charcoal_Vector $params = NULL, Charcoal_IRecordFindFilter $filter = NULL )
  489. {
  490. list( $file, $line ) = Charcoal_System::caller(0);
  491. log_debug( "debug, smart_gateway", "SmartGateway#" . __METHOD__ . "() called from: $file($line)" );
  492. $ret_val = array();
  493. // ?????????
  494. $this->initDataSource();
  495. // SQL??????
  496. $this->initSQLBuilder();
  497. // DataSource???
  498. $ds = $this->_source;
  499. try{
  500. // ?????????
  501. $model_name_list = $model_name->split( s(',') );
  502. if ( $model_name_list->size() < 1 ){
  503. _throw( new Charcoal_DBException( "current model is not specified(model name empty?)" ) );
  504. }
  505. $current_model = trim($model_name_list[0]);
  506. $current_model = Charcoal_TableModelCache::get( s($current_model) );
  507. $model_name_list->removeHead();
  508. // ???????
  509. $relation_list = $current_model->getRelationList();
  510. // ???????
  511. $field_list = $current_model->getFieldList();
  512. // ??
  513. $result = $ds->prepareExecute( s($sql), $params );
  514. // ????????
  515. $num_rows = $ds->numRows( $result );
  516. // ????
  517. while( $row = $ds->fetchAssoc( $result ) )
  518. {
  519. $dto = $current_model->createDTO();
  520. // SQL???????DTO??????
  521. foreach ($field_list as $name)
  522. {
  523. // ??????
  524. $value = isset($row[$name]) ? $row[ $name ] : NULL;
  525. // ????????
  526. if ( !property_exists($dto,$name) ){
  527. $clazz = get_class($dto);
  528. log_error( "error", "DTO[$clazz] does not have property[$name]. properties are:" . print_r(get_object_vars($dto),true) );
  529. _throw( new Charcoal_DBException( s("Field[$name] is not defined on DTO[$clazz]") ) );
  530. }
  531. $dto->$name = $value;
  532. }
  533. // ?????????
  534. if ( $filter ){
  535. $filter->afterFind( $dto );
  536. }
  537. // ?????
  538. foreach ($relation_list as $field => $relation)
  539. {
  540. $target = $relation->target; // ??????????
  541. $foreign_key = $relation->foreign_key; // ?????
  542. $key_field = $relation->key_field; // ????????
  543. $linkage = $relation->linkage; // ???????
  544. $order_by = $relation->order_by; // ????
  545. $extract = $relation->extract; // ???????
  546. $restrict = $relation->restrict; // ??
  547. $table_name = $target->getTableName(); // ???????
  548. // SQL??
  549. $params = array();
  550. switch ( $linkage->getValue() ){
  551. case 'inner':
  552. {
  553. // ??????? : ????????????????
  554. $params[] = isset($row[ $foreign_key ]) ? $row[ $foreign_key ] : NULL;
  555. $sql = "select * from $table_name where $key_field = ?";
  556. }
  557. break;
  558. case 'outer':
  559. {
  560. // ??????? : ???????????????
  561. $params[] = isset($row[ $key_field ]) ? $row[ $key_field ] : NULL;
  562. $sql = "select * from $table_name where $foreign_key = ?";
  563. }
  564. break;
  565. default:
  566. {
  567. // ?????????
  568. _throw( new Charcoal_DBException( "Invalid linkage anottation : $linkage" ) );
  569. }
  570. break;
  571. }
  572. // ????????@restrict
  573. if ( $restrict ){
  574. if ( $restrict instanceof Charcoal_AnnotationValue ){
  575. $restrict_value = $restrict->getValue();
  576. $restrict_params = $restrict->getParameters();
  577. switch( count($restrict_params) ){
  578. case 1:
  579. {
  580. $p = $restrict_params[0];
  581. $sql .= " and $restrict_value = ?";
  582. $params[] = ($p == 'NULL') ? NULL : $p;
  583. }
  584. break;
  585. case 2:
  586. {
  587. $op = $restrict_params[0];
  588. $p = $restrict_params[1];
  589. if ( stripos($p,'NOW') === 0 ){
  590. $sql .= " and $restrict_value $op NOW()";
  591. }
  592. else{
  593. $sql .= " and $restrict_value $op ?";
  594. $params[] = ($p == 'NULL') ? NULL : $p;
  595. }
  596. }
  597. break;
  598. }
  599. }
  600. else if ( is_array($restrict) ){
  601. foreach( $restrict as $restrict_item )
  602. {
  603. $restrict_value = $restrict_item->getValue();
  604. $restrict_params = $restrict_item->getParameters();
  605. switch( count($restrict_params) ){
  606. case 1:
  607. {
  608. $p = $restrict_params[0];
  609. $sql .= " and $restrict_value = ?";
  610. $params[] = ($p == 'NULL') ? NULL : $p;
  611. }
  612. break;
  613. case 2:
  614. {
  615. $op = $restrict_params[0];
  616. $p = $restrict_params[1];
  617. if ( stripos($p,'NOW') === 0 ){
  618. $sql .= " and $restrict_value $op NOW()";
  619. }
  620. else{
  621. $sql .= " and $restrict_value $op ?";
  622. $params[] = ($p == 'NULL') ? NULL : $p;
  623. }
  624. }
  625. break;
  626. }
  627. }
  628. }
  629. }
  630. // ????
  631. if ( !empty($order_by) ){
  632. $sql .= " order by " . $order_by->getValue();
  633. }
  634. // ?????????
  635. $index = -1;
  636. $target_model_id = trim( us($target->getModelID()) );
  637. if ( $model_name_list instanceof Charcoal_Vector ){
  638. foreach( $model_name_list as $key => $model_id ){
  639. if ( trim($model_id) == $target_model_id ){
  640. $index = $key;
  641. }
  642. }
  643. }
  644. if ( $index >= 0 ){
  645. // ????????????????????????
  646. $related_model_name_list = clone $model_name_list;
  647. list( $related_model_name ) = $related_model_name_list->remove( i($index) );
  648. $join = $related_model_name_list->join( s(',') );
  649. $related_model_name = $join ? $related_model_name . ',' . $join : $related_model_name;
  650. // ???DTO????
  651. switch ( $extract->getValue() ){
  652. case 'field':
  653. {
  654. $sql .= " limit 1";
  655. $child_result = $this->recursiveFindBySQL( s($related_model_name), s($sql), v($params), $filter );
  656. // ????????
  657. if ( $child_result ){
  658. // ???????????
  659. $child = array_shift( $child_result );
  660. if ( $child ){
  661. // ????????????????DTO????
  662. $dto->$field = $child;
  663. }
  664. }
  665. }
  666. break;
  667. case 'array':
  668. {
  669. $child_result = $this->recursiveFindBySQL( s($related_model_name), s($sql), v($params), $filter );
  670. // ??????
  671. $dto->$field = $child_result;
  672. }
  673. break;
  674. }
  675. }
  676. else{
  677. $dto->$field = NULL;
  678. }
  679. }
  680. $ret_val[] = $dto;
  681. }
  682. }
  683. catch ( Exception $e )
  684. {
  685. _catch( $e );
  686. _throw( new Charcoal_DBException( s(__METHOD__." Failed."), $e ) );
  687. }
  688. return $ret_val;
  689. }
  690. /*
  691. * ???????
  692. */
  693. public function findFirst( Charcoal_String $model_name, Charcoal_SQLCriteria $criteria = NULL, Charcoal_IRecordFindFilter $filter = NULL )
  694. {
  695. list( $file, $line ) = Charcoal_System::caller(0);
  696. log_debug( "debug, smart_gateway", "SmartGateway#" . __METHOD__ . "() called from: $file($line)" );
  697. try{
  698. if ( !$criteria ){
  699. $criteria = new Charcoal_SQLCriteria();
  700. }
  701. // LIMIT=1?
  702. $criteria->setLimit( i(1) );
  703. // ????
  704. $result = $this->findAll( $model_name, $criteria, $filter );
  705. return $result ? array_shift($result) : NULL;
  706. }
  707. catch ( Exception $e )
  708. {
  709. _catch( $e );
  710. _throw( new Charcoal_DBException( s(__METHOD__." Failed."), $e ) );
  711. }
  712. }
  713. /*
  714. * ????????????
  715. */
  716. public function findFirstForUpdate( Charcoal_String $model_name, Charcoal_SQLCriteria $criteria = NULL, Charcoal_IRecordFindFilter $filter = NULL )
  717. {
  718. list( $file, $line ) = Charcoal_System::caller(0);
  719. log_debug( "debug, smart_gateway", "SmartGateway#" . __METHOD__ . "() called from: $file($line)" );
  720. try{
  721. if ( !$criteria ){
  722. $criteria = new Charcoal_SQLCriteria();
  723. }
  724. // LIMIT=1?
  725. $criteria->setLimit( i(1) );
  726. // ????
  727. $result = $this->findAllForUpdate( $model_name, $criteria, $filter );
  728. return $result ? array_shift($result) : NULL;
  729. }
  730. catch ( Exception $e )
  731. {
  732. _catch( $e );
  733. _throw( new Charcoal_DBException( s(__METHOD__." Failed."), $e ) );
  734. }
  735. }
  736. /*
  737. * ????
  738. */
  739. public function findAll( Charcoal_String $model_name, Charcoal_SQLCriteria $criteria = NULL, Charcoal_IRecordFindFilter $filter = NULL )
  740. {
  741. list( $file, $line ) = Charcoal_System::caller(0);
  742. log_debug( "debug, smart_gateway", "SmartGateway#" . __METHOD__ . "() called from: $file($line)" );
  743. // ?????????
  744. $this->initDataSource();
  745. // SQL??????
  746. $this->initSQLBuilder();
  747. try{
  748. // ?????????
  749. $model_name_list = $model_name->split( s(',') );
  750. if ( $model_name_list->size() < 1 ){
  751. _throw( new Charcoal_DBException( "current model is not specified(model name empty?)" ) );
  752. }
  753. $current_model = trim($model_name_list[0]);
  754. $current_model = Charcoal_TableModelCache::get( s($current_model) );
  755. // ?????
  756. $table = $current_model->getTableName();
  757. // SQL??????
  758. $builder = $this->_builder;
  759. // SQL???
  760. $sql = $builder->buildSelectSQL( $current_model, $criteria );
  761. // ?????
  762. $params = $criteria ? $criteria->getParams() : NULL;
  763. log_debug( "debug, smart_gateway", "sql:$sql" );
  764. log_debug( "debug, smart_gateway", "params:" . print_r($params,true) );
  765. // ????
  766. $result = $this->recursiveFindBySQL( s($model_name), s($sql), v($params), $filter );
  767. return $result;
  768. }
  769. catch ( Exception $e )
  770. {
  771. _catch( $e );
  772. _throw( new Charcoal_DBException( s(__METHOD__." Failed."), $e ) );
  773. }
  774. }
  775. /*
  776. * ?????????
  777. */
  778. public function findAllForUpdate( Charcoal_String $model_name, Charcoal_SQLCriteria $criteria = NULL, Charcoal_IRecordFindFilter $filter = NULL )
  779. {
  780. list( $file, $line ) = Charcoal_System::caller(0);
  781. log_debug( "debug, smart_gateway", "SmartGateway#" . __METHOD__ . "() called from: $file($line)" );
  782. // ?????????
  783. $this->initDataSource();
  784. // SQL??????
  785. $this->initSQLBuilder();
  786. try{
  787. // ?????????
  788. $model_name_list = $model_name->split( s(',') );
  789. if ( $model_name_list->size() < 1 ){
  790. _throw( new Charcoal_DBException( "current model is not specified(model name empty?)" ) );
  791. }
  792. $current_model = trim($model_name_list[0]);
  793. $current_model = Charcoal_TableModelCache::get( s($current_model) );
  794. // ?????
  795. $table = $current_model->getTableName();
  796. // SQL??????
  797. $builder = $this->_builder;
  798. // SQL???
  799. $sql = $builder->buildSelectSQLForUpdate( $current_model, $criteria );
  800. // ?????
  801. $params = $criteria ? $criteria->getParams() : NULL;
  802. log_debug( "debug, smart_gateway", "sql:$sql" );
  803. log_debug( "debug, smart_gateway", "params:" . print_r($params,true) );
  804. // ????
  805. $result = $this->recursiveFindBySQL( s($model_name), s($sql), v($params), $filter );
  806. return $result;
  807. }
  808. catch ( Exception $e )
  809. {
  810. _catch( $e );
  811. _throw( new Charcoal_DBException( s(__METHOD__." Failed."), $e ) );
  812. }
  813. }
  814. /*
  815. * ??????????
  816. */
  817. public function findDistinct( Charcoal_String $model_name, Charcoal_Vector $fields, Charcoal_SQLCriteria $criteria = NULL, Charcoal_IRecordFindFilter $filter = NULL )
  818. {
  819. list( $file, $line ) = Charcoal_System::caller(0);
  820. log_debug( "debug, smart_gateway", "SmartGateway#" . __METHOD__ . "() called from: $file($line)" );
  821. // ?????????
  822. $this->initDataSource();
  823. // SQL??????
  824. $this->initSQLBuilder();
  825. try{
  826. // ?????????
  827. $model_name_list = $model_name->split( s(',') );
  828. if ( $model_name_list->size() < 1 ){
  829. _throw( new Charcoal_DBException( "current model is not specified(model name empty?)" ) );
  830. }
  831. $current_model = Charcoal_TableModelCache::get( s($model_name_list[0]) );
  832. // ?????
  833. $table = $current_model->getTableName();
  834. // SQL??????
  835. $builder = $this->_builder;
  836. // SQL???
  837. $sql = $builder->buildSelectDistinctSQL( $current_model, $fields, $criteria );
  838. // ?????
  839. $params = $criteria ? $criteria->getParams() : NULL;
  840. log_debug( "debug, smart_gateway", "sql:$sql" );
  841. log_debug( "debug, smart_gateway", "params:" . print_r($params,true) );
  842. // ????
  843. $result = $this->recursiveFindBySQL( s($model_name), s($sql), v($params), $filter );
  844. return $result;
  845. }
  846. catch ( Exception $e )
  847. {
  848. _catch( $e );
  849. _throw( new Charcoal_DBException( s(__METHOD__." Failed."), $e ) );
  850. }
  851. }
  852. /*
  853. * ?????????????
  854. */
  855. public function findAllBy( Charcoal_String $model_name, Charcoal_String $field, Charcoal_String $value, Charcoal_SQLCriteria $criteria = NULL, Charcoal_IRecordFindFilter $filter = NULL )
  856. {
  857. list( $file, $line ) = Charcoal_System::caller(0);
  858. log_debug( "debug, smart_gateway", "SmartGateway#" . __METHOD__ . "() called from: $file($line)" );
  859. // ?????????
  860. $this->initDataSource();
  861. // SQL??????
  862. $this->initSQLBuilder();
  863. try{
  864. if ( !$criteria ){
  865. $criteria = new Charcoal_SQLCriteria();
  866. }
  867. $field = us( $field );
  868. $criteria->setWhere( $field . ' = ?' );
  869. $criteria->setParams( array( $value ) );
  870. $a = $this->findAll( $model_name, $criteria, $filter );
  871. return $a;
  872. }
  873. catch ( Exception $e )
  874. {
  875. _catch( $e );
  876. _throw( new Charcoal_DBException( s(__METHOD__." Failed."), $e ) );
  877. }
  878. }
  879. /*
  880. * ID????(??????????)
  881. */
  882. public function findByID( Charcoal_String $model_name, Charcoal_String$id, Charcoal_IRecordFindFilter $filter = NULL )
  883. {
  884. list( $file, $line ) = Charcoal_System::caller(0);
  885. log_debug( "debug, smart_gateway", "SmartGateway#" . __METHOD__ . "() called from: $file($line)" );
  886. // ?????????
  887. $this->initDataSource();
  888. // SQL??????
  889. $this->initSQLBuilder();
  890. try{
  891. // ?????????
  892. $model_name_list = $model_name->split( s(',') );
  893. if ( $model_name_list->size() < 1 ){
  894. _throw( new Charcoal_DBException( "current model is not specified(model name empty?)" ) );
  895. }
  896. $current_model = Charcoal_TableModelCache::get( s($model_name_list[0]) );
  897. $model_name_list->removeHead();
  898. // ????????????????
  899. $pk = $current_model->getPrimaryKey();
  900. // ??????????
  901. $where_clause = s( $pk . ' = ?');
  902. $params = v(array( Charcoal_System::toString($id) ));
  903. $criteria = new Charcoal_SQLCriteria( $where_clause, $params );
  904. $result = $this->findAll( $model_name, $criteria, $filter );
  905. return $result ? array_shift( $result ) : NULL;
  906. }
  907. catch ( Exception $e )
  908. {
  909. _catch( $e );
  910. _throw( new Charcoal_DBException( s(__METHOD__." Failed."), $e ) );
  911. }
  912. }
  913. /*
  914. * ID????
  915. */
  916. public function findAllByID( Charcoal_String $model_name, Charcoal_Vector $id_array, Charcoal_IRecordFindFilter $filter = NULL )
  917. {
  918. list( $file, $line ) = Charcoal_System::caller(0);
  919. log_debug( "debug, smart_gateway", "SmartGateway#" . __METHOD__ . "() called from: $file($line)" );
  920. // ?????????
  921. $this->initDataSource();
  922. // SQL??????
  923. $this->initSQLBuilder();
  924. try{
  925. // ?????????
  926. $model_name_list = $model_name->split( s(',') );
  927. if ( $model_name_list->size() < 1 ){
  928. _throw( new Charcoal_DBException( "current model is not specified(model name empty?)" ) );
  929. }
  930. $current_model = Charcoal_TableModelCache::get( s($model_name_list[0]) );
  931. $model_name_list->removeHead();
  932. // ?????????
  933. $where = array();
  934. $params = array();
  935. foreach( $id_array as $id ){
  936. $where[] = "?";
  937. $params[] = $id;
  938. }
  939. $pk = $current_model->getPrimaryKey();
  940. $where_clause = "$pk in (" . implode(",",$where) . ")";
  941. $criteria = new Charcoal_SQLCriteria( s($where_clause), v($params) );
  942. $a = $this->findAll( $model_name, $criteria, $filter );
  943. return $a;
  944. }
  945. catch ( Exception $e )
  946. {
  947. _catch( $e );
  948. _throw( new Charcoal_DBException( s(__METHOD__." Failed."), $e ) );
  949. }
  950. }
  951. /*
  952. * ??????????????
  953. */
  954. public function destroyById( Charcoal_String $model_name, Charcoal_Integer $id )
  955. {
  956. list( $file, $line ) = Charcoal_System::caller(0);
  957. log_debug( "debug, smart_gateway", "SmartGateway#" . __METHOD__ . "() called from: $file($line)" );
  958. // ?????????
  959. $this->initDataSource();
  960. // SQL??????
  961. $this->initSQLBuilder();
  962. try{
  963. $id = us( $id );
  964. // ?????????
  965. $model = Charcoal_TableModelCache::get( $model_name );
  966. // ????????
  967. $pk = us($model->getPrimaryKey());
  968. // SQL?????
  969. $params = array( ui($id) );
  970. // ??
  971. $criteria = new Charcoal_SQLCriteria();
  972. $criteria->setWhere( s($pk . ' = ?') );
  973. $criteria->setParams( v($params) );
  974. // SQL??????SQL???
  975. $sql = $this->_builder->buildDeleteSQL( $model, $criteria );
  976. log_debug( "debug, smart_gateway", "sql:$sql" );
  977. log_debug( "debug, smart_gateway", "params:" . print_r($params,true) );
  978. $this->execute( s($sql), v($params) );
  979. }
  980. catch ( Exception $e )
  981. {
  982. _catch( $e );
  983. _throw( new Charcoal_DBException( s(__METHOD__." Failed."), $e ) );
  984. }
  985. }
  986. /*
  987. * ?????????????
  988. */
  989. public function destroyAllById( Charcoal_String $model_name, Charcoal_Vector $id_array )
  990. {
  991. list( $file, $line ) = Charcoal_System::caller(0);
  992. log_debug( "debug, smart_gateway", "SmartGateway#" . __METHOD__ . "() called from: $file($line)" );
  993. // ?????????
  994. $this->initDataSource();
  995. // SQL??????
  996. $this->initSQLBuilder();
  997. try{
  998. // ?????????
  999. $model = Charcoal_TableModelCache::get( $model_name );
  1000. // ?????
  1001. $table = $model->getTableName();
  1002. // ?????????
  1003. $where = array();
  1004. $params = array();
  1005. foreach( $id_array as $id ){
  1006. $where[] = "?";
  1007. $params[] = $id;
  1008. }
  1009. $sql = "delete from $table where id in (" . implode(",",$where) . ")";
  1010. log_debug( "debug, smart_gateway", "sql:$sql" );
  1011. log_debug( "debug, smart_gateway", "params:" . print_r($params,true) );
  1012. $this->execute( $sql, $params );
  1013. }
  1014. catch ( Exception $e )
  1015. {
  1016. _catch( $e );
  1017. _throw( new Charcoal_DBException( s(__METHOD__." Failed."), $e ) );
  1018. }
  1019. }
  1020. /*
  1021. * ?????????????????????
  1022. */
  1023. public function destroyBy( Charcoal_String $model_name, Charcoal_String $field, Charcoal_String $value )
  1024. {
  1025. list( $file, $line ) = Charcoal_System::caller(0);
  1026. log_debug( "debug, smart_gateway", "SmartGateway#" . __METHOD__ . "() called from: $file($line)" );
  1027. // ?????????
  1028. $this->initDataSource();
  1029. // SQL??????
  1030. $this->initSQLBuilder();
  1031. try{
  1032. $where = us($field) . ' = ?';
  1033. $params = array( us($value) );
  1034. $criteria = new Charcoal_SQLCriteria( s($where), v($params) );
  1035. $this->destroyAll( $model_name, $criteria );
  1036. }
  1037. catch ( Exception $e )
  1038. {
  1039. _catch( $e );
  1040. _throw( new Charcoal_DBException( s(__METHOD__." Failed."), $e ) );
  1041. }
  1042. }
  1043. /*
  1044. * ???????????????
  1045. */
  1046. public function destroyAll( Charcoal_String $model_name, Charcoal_SQLCriteria $criteria = NULL )
  1047. {
  1048. list( $file, $line ) = Charcoal_System::caller(0);
  1049. log_debug( "debug, smart_gateway", "SmartGateway#" . __METHOD__ . "() called from: $file($line)" );
  1050. // ?????????
  1051. $this->initDataSource();
  1052. // SQL??????
  1053. $this->initSQLBuilder();
  1054. try{
  1055. // ?????????
  1056. $model = Charcoal_TableModelCache::get( $model_name );
  1057. // ????????
  1058. // $pk = $model->getPrimaryKey();
  1059. // SQL??????SQL???
  1060. $sql = $this->_builder->buildDeleteSQL( $model, $criteria );
  1061. // ?????
  1062. $params = $criteria ? $criteria->getParams() : NULL;
  1063. log_debug( "debug, smart_gateway", "sql:$sql" );
  1064. log_debug( "debug, smart_gateway", "params:" . print_r($params,true) );
  1065. // SQL???
  1066. $this->execute( s($sql), v($params) );
  1067. }
  1068. catch ( Exception $e )
  1069. {
  1070. _catch( $e );
  1071. _throw( new Charcoal_DBException( s(__METHOD__." Failed."), $e ) );
  1072. }
  1073. }
  1074. /*
  1075. * Check SQL Builder Instance
  1076. */
  1077. private function _checkSQLBuilder()
  1078. {
  1079. if ( !$this->_builder ){
  1080. _throw( new Charcoal_DBException( 'No SQL Builder Specified' ) );
  1081. }
  1082. }
  1083. /*
  1084. * ?????????????
  1085. */
  1086. public function count( Charcoal_String $model_name, Charcoal_SQLCriteria $criteria = NULL )
  1087. {
  1088. list( $file, $line ) = Charcoal_System::caller(0);
  1089. log_debug( "debug, smart_gateway", "SmartGateway#" . __METHOD__ . "() called from: $file($line)" );
  1090. // ?????????
  1091. $this->initDataSource();
  1092. // SQL??????
  1093. $this->initSQLBuilder();
  1094. try{
  1095. // ?????????
  1096. $model_name_list = $model_name->split( s(',') );
  1097. if ( $model_name_list->size() < 1 ){
  1098. _throw( new Charcoal_DBException( "current model is not specified(model name empty?)" ) );
  1099. }
  1100. $current_model = Charcoal_TableModelCache::get( s($model_name_list[0]) );
  1101. // SQL????????
  1102. $this->_checkSQLBuilder();
  1103. // SQL
  1104. $sql = $this->_builder->buildCountSQL( $current_model, $criteria );
  1105. // ?????
  1106. $params = $criteria ? $criteria->getParams() : NULL;
  1107. log_debug( "debug, smart_gateway", "sql:$sql" );
  1108. log_debug( "debug, smart_gateway", "params:" . print_r($params,true) );
  1109. // SQL??
  1110. $result = $this->_source->prepareExecute( s($sql), v($params) );
  1111. // ????
  1112. $rows = $this->_source->fetchArray( $result );
  1113. // ????
  1114. $cnt = $rows[0] ? intval($rows[0]) : 0;
  1115. log_debug( "debug, smart_gateway", "count:$cnt" );
  1116. return i($cnt);
  1117. }
  1118. catch ( Exception $e )
  1119. {
  1120. _catch( $e );
  1121. _throw( new Charcoal_DBException( s(__METHOD__." Failed."), $e ) );
  1122. }
  1123. }
  1124. /*
  1125. * ??????????????
  1126. */
  1127. public function max( Charcoal_String $model_name, Charcoal_String $field, Charcoal_String $where_clause = NULL, Charcoal_Vector $params = NULL )
  1128. {
  1129. list( $file, $line ) = Charcoal_System::caller(0);
  1130. log_debug( "debug, smart_gateway", "SmartGateway#" . __METHOD__ . "() called from: $file($line)" );
  1131. // ?????????
  1132. $this->initDataSource();
  1133. // SQL??????
  1134. $this->initSQLBuilder();
  1135. try{
  1136. // ?????????
  1137. $model = Charcoal_TableModelCache::get( $model_name );
  1138. if ( $where_clause ){
  1139. $criteria = new Charcoal_SQLCriteria();
  1140. $criteria->setWhere( $where_clause );
  1141. $criteria->setParams( $params );
  1142. }
  1143. else{
  1144. $criteria = NULL;
  1145. }
  1146. // SQL
  1147. $sql = $this->_builder->buildMaxSQL( $model, $field, $criteria );
  1148. log_debug( "debug, smart_gateway", "sql:$sql" );
  1149. log_debug( "debug, smart_gateway", "params:" . print_r($params,true) );
  1150. // SQL??
  1151. $result = $this->_source->prepareExecute( $sql, $params );
  1152. // ????
  1153. $rows = $this->_source->fetchArray( $result );
  1154. return $rows[0];
  1155. }
  1156. catch ( Exception $e )
  1157. {
  1158. _catch( $e );
  1159. _throw( new Charcoal_DBException( s(__METHOD__." Failed."), $e ) );
  1160. }
  1161. }
  1162. /*
  1163. * DB???
  1164. */
  1165. public function createDatabase( Charcoal_String $db_name, Charcoal_String $charset )
  1166. {
  1167. list( $file, $line ) = Charcoal_System::caller(0);
  1168. log_debug( "debug, smart_gateway", "SmartGateway#" . __METHOD__ . "() called from: $file($line)" );
  1169. // ?????????
  1170. $this->initDataSource();
  1171. // SQL??????
  1172. $this->initSQLBuilder();
  1173. try{
  1174. // SQL??????SQL???
  1175. $sql = $this->_builder->buildCreateDatabaseSQL( $db_name, $charset );
  1176. log_debug( "debug, smart_gateway", "sql:$sql" );
  1177. // SQL??
  1178. $this->_source->execute( s($sql) );
  1179. }
  1180. catch ( Exception $e )
  1181. {
  1182. _catch( $e );
  1183. _throw( new Charcoal_DBException( s(__METHOD__." Failed."), $e ) );
  1184. }
  1185. }
  1186. /*
  1187. * ???????
  1188. */
  1189. public function createTable( Charcoal_String $model_name )
  1190. {
  1191. list( $file, $line ) = Charcoal_System::caller(0);
  1192. log_debug( "debug, smart_gateway", "SmartGateway#" . __METHOD__ . "() called from: $file($line)" );
  1193. // ?????????
  1194. $this->initDataSource();
  1195. // SQL??????
  1196. $this->initSQLBuilder();
  1197. try{
  1198. // ?????????
  1199. $model = Charcoal_TableModelCache::get( $model_name );
  1200. // SQL??????SQL???
  1201. $sql = $this->_builder->buildCreateTableSQL( $model );
  1202. // SQL??
  1203. $this->_source->execute( s($sql) );
  1204. }
  1205. catch ( Exception $e )
  1206. {
  1207. _catch( $e );
  1208. _throw( new Charcoal_DBException( s(__METHOD__." Failed."), $e ) );
  1209. }
  1210. }
  1211. }
  1212. return __FILE__;