/lib/xmldb/xmldb_table.php

https://github.com/viggof/moodle · PHP · 846 lines · 540 code · 80 blank · 226 comment · 113 complexity · 6d8bbfbc815b3ca59b793d2c9af68329 MD5 · raw file

  1. <?php
  2. ///////////////////////////////////////////////////////////////////////////
  3. // //
  4. // NOTICE OF COPYRIGHT //
  5. // //
  6. // Moodle - Modular Object-Oriented Dynamic Learning Environment //
  7. // http://moodle.com //
  8. // //
  9. // Copyright (C) 1999 onwards Martin Dougiamas http://dougiamas.com //
  10. // (C) 2001-3001 Eloy Lafuente (stronk7) http://contiento.com //
  11. // //
  12. // This program is free software; you can redistribute it and/or modify //
  13. // it under the terms of the GNU General Public License as published by //
  14. // the Free Software Foundation; either version 2 of the License, or //
  15. // (at your option) any later version. //
  16. // //
  17. // This program is distributed in the hope that it will be useful, //
  18. // but WITHOUT ANY WARRANTY; without even the implied warranty of //
  19. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
  20. // GNU General Public License for more details: //
  21. // //
  22. // http://www.gnu.org/copyleft/gpl.html //
  23. // //
  24. ///////////////////////////////////////////////////////////////////////////
  25. /// This class represent one XMLDB table
  26. class xmldb_table extends xmldb_object {
  27. var $fields;
  28. var $keys;
  29. var $indexes;
  30. /**
  31. * Creates one new xmldb_table
  32. */
  33. function __construct($name) {
  34. parent::__construct($name);
  35. $this->fields = array();
  36. $this->keys = array();
  37. $this->indexes = array();
  38. }
  39. /**
  40. * Add one field to the table, allowing to specify the desired order
  41. * If it's not specified, then the field is added at the end
  42. */
  43. function addField(&$field, $after=NULL) {
  44. /// Detect duplicates first
  45. if ($this->getField($field->getName())) {
  46. throw new coding_exception('Duplicate field '.$field->getName().' specified in table '.$this->getName());
  47. }
  48. /// Calculate the previous and next fields
  49. $prevfield = NULL;
  50. $nextfield = NULL;
  51. if (!$after) {
  52. $allfields =& $this->getFields();
  53. if (!empty($allfields)) {
  54. end($allfields);
  55. $prevfield =& $allfields[key($allfields)];
  56. }
  57. } else {
  58. $prevfield =& $this->getField($after);
  59. }
  60. if ($prevfield && $prevfield->getNext()) {
  61. $nextfield =& $this->getField($prevfield->getNext());
  62. }
  63. /// Set current field previous and next attributes
  64. if ($prevfield) {
  65. $field->setPrevious($prevfield->getName());
  66. $prevfield->setNext($field->getName());
  67. }
  68. if ($nextfield) {
  69. $field->setNext($nextfield->getName());
  70. $nextfield->setPrevious($field->getName());
  71. }
  72. /// Some more attributes
  73. $field->setLoaded(true);
  74. $field->setChanged(true);
  75. /// Add the new field
  76. $this->fields[] = $field;
  77. /// Reorder the field
  78. $this->orderFields($this->fields);
  79. /// Recalculate the hash
  80. $this->calculateHash(true);
  81. /// We have one new field, so the table has changed
  82. $this->setChanged(true);
  83. return $field;
  84. }
  85. /**
  86. * Add one key to the table, allowing to specify the desired order
  87. * If it's not specified, then the key is added at the end
  88. */
  89. function addKey(&$key, $after=NULL) {
  90. /// Detect duplicates first
  91. if ($this->getKey($key->getName())) {
  92. throw new coding_exception('Duplicate key '.$key->getName().' specified in table '.$this->getName());
  93. }
  94. /// Calculate the previous and next keys
  95. $prevkey = NULL;
  96. $nextkey = NULL;
  97. if (!$after) {
  98. $allkeys =& $this->getKeys();
  99. if (!empty($allkeys)) {
  100. end($allkeys);
  101. $prevkey =& $allkeys[key($allkeys)];
  102. }
  103. } else {
  104. $prevkey =& $this->getKey($after);
  105. }
  106. if ($prevkey && $prevkey->getNext()) {
  107. $nextkey =& $this->getKey($prevkey->getNext());
  108. }
  109. /// Set current key previous and next attributes
  110. if ($prevkey) {
  111. $key->setPrevious($prevkey->getName());
  112. $prevkey->setNext($key->getName());
  113. }
  114. if ($nextkey) {
  115. $key->setNext($nextkey->getName());
  116. $nextkey->setPrevious($key->getName());
  117. }
  118. /// Some more attributes
  119. $key->setLoaded(true);
  120. $key->setChanged(true);
  121. /// Add the new key
  122. $this->keys[] = $key;
  123. /// Reorder the keys
  124. $this->orderKeys($this->keys);
  125. /// Recalculate the hash
  126. $this->calculateHash(true);
  127. /// We have one new field, so the table has changed
  128. $this->setChanged(true);
  129. }
  130. /**
  131. * Add one index to the table, allowing to specify the desired order
  132. * If it's not specified, then the index is added at the end
  133. */
  134. function addIndex(&$index, $after=NULL) {
  135. /// Detect duplicates first
  136. if ($this->getIndex($index->getName())) {
  137. throw new coding_exception('Duplicate index '.$index->getName().' specified in table '.$this->getName());
  138. }
  139. /// Calculate the previous and next indexes
  140. $previndex = NULL;
  141. $nextindex = NULL;
  142. if (!$after) {
  143. $allindexes =& $this->getIndexes();
  144. if (!empty($allindexes)) {
  145. end($allindexes);
  146. $previndex =& $allindexes[key($allindexes)];
  147. }
  148. } else {
  149. $previndex =& $this->getIndex($after);
  150. }
  151. if ($previndex && $previndex->getNext()) {
  152. $nextindex =& $this->getIndex($previndex->getNext());
  153. }
  154. /// Set current index previous and next attributes
  155. if ($previndex) {
  156. $index->setPrevious($previndex->getName());
  157. $previndex->setNext($index->getName());
  158. }
  159. if ($nextindex) {
  160. $index->setNext($nextindex->getName());
  161. $nextindex->setPrevious($index->getName());
  162. }
  163. /// Some more attributes
  164. $index->setLoaded(true);
  165. $index->setChanged(true);
  166. /// Add the new index
  167. $this->indexes[] = $index;
  168. /// Reorder the indexes
  169. $this->orderIndexes($this->indexes);
  170. /// Recalculate the hash
  171. $this->calculateHash(true);
  172. /// We have one new index, so the table has changed
  173. $this->setChanged(true);
  174. }
  175. /**
  176. * This function will return the array of fields in the table
  177. */
  178. function &getFields() {
  179. return $this->fields;
  180. }
  181. /**
  182. * This function will return the array of keys in the table
  183. */
  184. function &getKeys() {
  185. return $this->keys;
  186. }
  187. /**
  188. * This function will return the array of indexes in the table
  189. */
  190. function &getIndexes() {
  191. return $this->indexes;
  192. }
  193. /**
  194. * Returns one xmldb_field
  195. */
  196. function &getField($fieldname) {
  197. $i = $this->findFieldInArray($fieldname);
  198. if ($i !== NULL) {
  199. return $this->fields[$i];
  200. }
  201. $null = NULL;
  202. return $null;
  203. }
  204. /**
  205. * Returns the position of one field in the array.
  206. */
  207. function &findFieldInArray($fieldname) {
  208. foreach ($this->fields as $i => $field) {
  209. if ($fieldname == $field->getName()) {
  210. return $i;
  211. }
  212. }
  213. $null = NULL;
  214. return $null;
  215. }
  216. /**
  217. * This function will reorder the array of fields
  218. */
  219. function orderFields() {
  220. $result = $this->orderElements($this->fields);
  221. if ($result) {
  222. $this->setFields($result);
  223. return true;
  224. } else {
  225. return false;
  226. }
  227. }
  228. /**
  229. * Returns one xmldb_key
  230. */
  231. function &getKey($keyname) {
  232. $i = $this->findKeyInArray($keyname);
  233. if ($i !== NULL) {
  234. return $this->keys[$i];
  235. }
  236. $null = NULL;
  237. return $null;
  238. }
  239. /**
  240. * Returns the position of one key in the array.
  241. */
  242. function &findKeyInArray($keyname) {
  243. foreach ($this->keys as $i => $key) {
  244. if ($keyname == $key->getName()) {
  245. return $i;
  246. }
  247. }
  248. $null = NULL;
  249. return $null;
  250. }
  251. /**
  252. * This function will reorder the array of keys
  253. */
  254. function orderKeys() {
  255. $result = $this->orderElements($this->keys);
  256. if ($result) {
  257. $this->setKeys($result);
  258. return true;
  259. } else {
  260. return false;
  261. }
  262. }
  263. /**
  264. * Returns one xmldb_index
  265. */
  266. function &getIndex($indexname) {
  267. $i = $this->findIndexInArray($indexname);
  268. if ($i !== NULL) {
  269. return $this->indexes[$i];
  270. }
  271. $null = NULL;
  272. return $null;
  273. }
  274. /**
  275. * Returns the position of one index in the array.
  276. */
  277. function &findIndexInArray($indexname) {
  278. foreach ($this->indexes as $i => $index) {
  279. if ($indexname == $index->getName()) {
  280. return $i;
  281. }
  282. }
  283. $null = NULL;
  284. return $null;
  285. }
  286. /**
  287. * This function will reorder the array of indexes
  288. */
  289. function orderIndexes() {
  290. $result = $this->orderElements($this->indexes);
  291. if ($result) {
  292. $this->setIndexes($result);
  293. return true;
  294. } else {
  295. return false;
  296. }
  297. }
  298. /**
  299. * This function will set the array of fields in the table
  300. */
  301. function setFields($fields) {
  302. $this->fields = $fields;
  303. }
  304. /**
  305. * This function will set the array of keys in the table
  306. */
  307. function setKeys($keys) {
  308. $this->keys = $keys;
  309. }
  310. /**
  311. * This function will set the array of indexes in the table
  312. */
  313. function setIndexes($indexes) {
  314. $this->indexes = $indexes;
  315. }
  316. /**
  317. * Delete one field from the table
  318. */
  319. function deleteField($fieldname) {
  320. $field =& $this->getField($fieldname);
  321. if ($field) {
  322. $i = $this->findFieldInArray($fieldname);
  323. /// Look for prev and next field
  324. $prevfield =& $this->getField($field->getPrevious());
  325. $nextfield =& $this->getField($field->getNext());
  326. /// Change their previous and next attributes
  327. if ($prevfield) {
  328. $prevfield->setNext($field->getNext());
  329. }
  330. if ($nextfield) {
  331. $nextfield->setPrevious($field->getPrevious());
  332. }
  333. /// Delete the field
  334. unset($this->fields[$i]);
  335. /// Reorder the whole structure
  336. $this->orderFields($this->fields);
  337. /// Recalculate the hash
  338. $this->calculateHash(true);
  339. /// We have one deleted field, so the table has changed
  340. $this->setChanged(true);
  341. }
  342. }
  343. /**
  344. * Delete one key from the table
  345. */
  346. function deleteKey($keyname) {
  347. $key =& $this->getKey($keyname);
  348. if ($key) {
  349. $i = $this->findKeyInArray($keyname);
  350. /// Look for prev and next key
  351. $prevkey =& $this->getKey($key->getPrevious());
  352. $nextkey =& $this->getKey($key->getNext());
  353. /// Change their previous and next attributes
  354. if ($prevkey) {
  355. $prevkey->setNext($key->getNext());
  356. }
  357. if ($nextkey) {
  358. $nextkey->setPrevious($key->getPrevious());
  359. }
  360. /// Delete the key
  361. unset($this->keys[$i]);
  362. /// Reorder the Keys
  363. $this->orderKeys($this->keys);
  364. /// Recalculate the hash
  365. $this->calculateHash(true);
  366. /// We have one deleted key, so the table has changed
  367. $this->setChanged(true);
  368. }
  369. }
  370. /**
  371. * Delete one index from the table
  372. */
  373. function deleteIndex($indexname) {
  374. $index =& $this->getIndex($indexname);
  375. if ($index) {
  376. $i = $this->findIndexInArray($indexname);
  377. /// Look for prev and next index
  378. $previndex =& $this->getIndex($index->getPrevious());
  379. $nextindex =& $this->getIndex($index->getNext());
  380. /// Change their previous and next attributes
  381. if ($previndex) {
  382. $previndex->setNext($index->getNext());
  383. }
  384. if ($nextindex) {
  385. $nextindex->setPrevious($index->getPrevious());
  386. }
  387. /// Delete the index
  388. unset($this->indexes[$i]);
  389. /// Reorder the indexes
  390. $this->orderIndexes($this->indexes);
  391. /// Recalculate the hash
  392. $this->calculateHash(true);
  393. /// We have one deleted index, so the table has changed
  394. $this->setChanged(true);
  395. }
  396. }
  397. /**
  398. * Load data from XML to the table
  399. */
  400. function arr2xmldb_table($xmlarr) {
  401. global $CFG;
  402. $result = true;
  403. /// Debug the table
  404. /// traverse_xmlize($xmlarr); //Debug
  405. /// print_object ($GLOBALS['traverse_array']); //Debug
  406. /// $GLOBALS['traverse_array']=""; //Debug
  407. /// Process table attributes (name, comment, previoustable and nexttable)
  408. if (isset($xmlarr['@']['NAME'])) {
  409. $this->name = trim($xmlarr['@']['NAME']);
  410. } else {
  411. $this->errormsg = 'Missing NAME attribute';
  412. $this->debug($this->errormsg);
  413. $result = false;
  414. }
  415. if (isset($xmlarr['@']['COMMENT'])) {
  416. $this->comment = trim($xmlarr['@']['COMMENT']);
  417. } else if (!empty($CFG->xmldbdisablecommentchecking)) {
  418. $this->comment = '';
  419. } else {
  420. $this->errormsg = 'Missing COMMENT attribute';
  421. $this->debug($this->errormsg);
  422. $result = false;
  423. }
  424. if (isset($xmlarr['@']['PREVIOUS'])) {
  425. $this->previous = trim($xmlarr['@']['PREVIOUS']);
  426. }
  427. if (isset($xmlarr['@']['NEXT'])) {
  428. $this->next = trim($xmlarr['@']['NEXT']);
  429. }
  430. /// Iterate over fields
  431. if (isset($xmlarr['#']['FIELDS']['0']['#']['FIELD'])) {
  432. foreach ($xmlarr['#']['FIELDS']['0']['#']['FIELD'] as $xmlfield) {
  433. if (!$result) { //Skip on error
  434. continue;
  435. }
  436. $name = trim($xmlfield['@']['NAME']);
  437. $field = new xmldb_field($name);
  438. $field->arr2xmldb_field($xmlfield);
  439. $this->fields[] = $field;
  440. if (!$field->isLoaded()) {
  441. $this->errormsg = 'Problem loading field ' . $name;
  442. $this->debug($this->errormsg);
  443. $result = false;
  444. }
  445. }
  446. } else {
  447. $this->errormsg = 'Missing FIELDS section';
  448. $this->debug($this->errormsg);
  449. $result = false;
  450. }
  451. /// Perform some general checks over fields
  452. if ($result && $this->fields) {
  453. /// Check field names are ok (lowercase, a-z _-)
  454. if (!$this->checkNameValues($this->fields)) {
  455. $this->errormsg = 'Some FIELDS name values are incorrect';
  456. $this->debug($this->errormsg);
  457. $result = false;
  458. }
  459. /// Check previous & next are ok (duplicates and existing fields)
  460. $this->fixPrevNext($this->fields);
  461. if ($result && !$this->checkPreviousNextValues($this->fields)) {
  462. $this->errormsg = 'Some FIELDS previous/next values are incorrect';
  463. $this->debug($this->errormsg);
  464. $result = false;
  465. }
  466. /// Order fields
  467. if ($result && !$this->orderFields($this->fields)) {
  468. $this->errormsg = 'Error ordering the fields';
  469. $this->debug($this->errormsg);
  470. $result = false;
  471. }
  472. }
  473. /// Iterate over keys
  474. if (isset($xmlarr['#']['KEYS']['0']['#']['KEY'])) {
  475. foreach ($xmlarr['#']['KEYS']['0']['#']['KEY'] as $xmlkey) {
  476. if (!$result) { //Skip on error
  477. continue;
  478. }
  479. $name = trim($xmlkey['@']['NAME']);
  480. $key = new xmldb_key($name);
  481. $key->arr2xmldb_key($xmlkey);
  482. $this->keys[] = $key;
  483. if (!$key->isLoaded()) {
  484. $this->errormsg = 'Problem loading key ' . $name;
  485. $this->debug($this->errormsg);
  486. $result = false;
  487. }
  488. }
  489. } else {
  490. $this->errormsg = 'Missing KEYS section (at least one PK must exist)';
  491. $this->debug($this->errormsg);
  492. $result = false;
  493. }
  494. /// Perform some general checks over keys
  495. if ($result && $this->keys) {
  496. /// Check keys names are ok (lowercase, a-z _-)
  497. if (!$this->checkNameValues($this->keys)) {
  498. $this->errormsg = 'Some KEYS name values are incorrect';
  499. $this->debug($this->errormsg);
  500. $result = false;
  501. }
  502. /// Check previous & next are ok (duplicates and existing keys)
  503. $this->fixPrevNext($this->keys);
  504. if ($result && !$this->checkPreviousNextValues($this->keys)) {
  505. $this->errormsg = 'Some KEYS previous/next values are incorrect';
  506. $this->debug($this->errormsg);
  507. $result = false;
  508. }
  509. /// Order keys
  510. if ($result && !$this->orderKeys($this->keys)) {
  511. $this->errormsg = 'Error ordering the keys';
  512. $this->debug($this->errormsg);
  513. $result = false;
  514. }
  515. /// TODO: Only one PK
  516. /// TODO: Not keys with repeated fields
  517. /// TODO: Check fields and reffieds exist in table
  518. }
  519. /// Iterate over indexes
  520. if (isset($xmlarr['#']['INDEXES']['0']['#']['INDEX'])) {
  521. foreach ($xmlarr['#']['INDEXES']['0']['#']['INDEX'] as $xmlindex) {
  522. if (!$result) { //Skip on error
  523. continue;
  524. }
  525. $name = trim($xmlindex['@']['NAME']);
  526. $index = new xmldb_index($name);
  527. $index->arr2xmldb_index($xmlindex);
  528. $this->indexes[] = $index;
  529. if (!$index->isLoaded()) {
  530. $this->errormsg = 'Problem loading index ' . $name;
  531. $this->debug($this->errormsg);
  532. $result = false;
  533. }
  534. }
  535. }
  536. /// Perform some general checks over indexes
  537. if ($result && $this->indexes) {
  538. /// Check field names are ok (lowercase, a-z _-)
  539. if (!$this->checkNameValues($this->indexes)) {
  540. $this->errormsg = 'Some INDEXES name values are incorrect';
  541. $this->debug($this->errormsg);
  542. $result = false;
  543. }
  544. /// Check previous & next are ok (duplicates and existing INDEXES)
  545. $this->fixPrevNext($this->indexes);
  546. if ($result && !$this->checkPreviousNextValues($this->indexes)) {
  547. $this->errormsg = 'Some INDEXES previous/next values are incorrect';
  548. $this->debug($this->errormsg);
  549. $result = false;
  550. }
  551. /// Order indexes
  552. if ($result && !$this->orderIndexes($this->indexes)) {
  553. $this->errormsg = 'Error ordering the indexes';
  554. $this->debug($this->errormsg);
  555. $result = false;
  556. }
  557. /// TODO: Not indexes with repeated fields
  558. /// TODO: Check fields exist in table
  559. }
  560. /// Set some attributes
  561. if ($result) {
  562. $this->loaded = true;
  563. }
  564. $this->calculateHash();
  565. return $result;
  566. }
  567. /**
  568. * This function calculate and set the hash of one xmldb_table
  569. */
  570. function calculateHash($recursive = false) {
  571. if (!$this->loaded) {
  572. $this->hash = NULL;
  573. } else {
  574. $key = $this->name . $this->comment;
  575. if ($this->fields) {
  576. foreach ($this->fields as $fie) {
  577. $field =& $this->getField($fie->getName());
  578. if ($recursive) {
  579. $field->calculateHash($recursive);
  580. }
  581. $key .= $field->getHash();
  582. }
  583. }
  584. if ($this->keys) {
  585. foreach ($this->keys as $ke) {
  586. $k =& $this->getKey($ke->getName());
  587. if ($recursive) {
  588. $k->calculateHash($recursive);
  589. }
  590. $key .= $k->getHash();
  591. }
  592. }
  593. if ($this->indexes) {
  594. foreach ($this->indexes as $in) {
  595. $index =& $this->getIndex($in->getName());
  596. if ($recursive) {
  597. $index->calculateHash($recursive);
  598. }
  599. $key .= $index->getHash();
  600. }
  601. }
  602. $this->hash = md5($key);
  603. }
  604. }
  605. /**
  606. * This function will output the XML text for one table
  607. */
  608. function xmlOutput() {
  609. $o = '';
  610. $o.= ' <TABLE NAME="' . $this->name . '"';
  611. if ($this->comment) {
  612. $o.= ' COMMENT="' . htmlspecialchars($this->comment) . '"';
  613. }
  614. if ($this->previous) {
  615. $o.= ' PREVIOUS="' . $this->previous . '"';
  616. }
  617. if ($this->next) {
  618. $o.= ' NEXT="' . $this->next . '"';
  619. }
  620. $o.= '>' . "\n";
  621. /// Now the fields
  622. if ($this->fields) {
  623. $o.= ' <FIELDS>' . "\n";
  624. foreach ($this->fields as $field) {
  625. $o.= $field->xmlOutput();
  626. }
  627. $o.= ' </FIELDS>' . "\n";
  628. }
  629. /// Now the keys
  630. if ($this->keys) {
  631. $o.= ' <KEYS>' . "\n";
  632. foreach ($this->keys as $key) {
  633. $o.= $key->xmlOutput();
  634. }
  635. $o.= ' </KEYS>' . "\n";
  636. }
  637. /// Now the indexes
  638. if ($this->indexes) {
  639. $o.= ' <INDEXES>' . "\n";
  640. foreach ($this->indexes as $index) {
  641. $o.= $index->xmlOutput();
  642. }
  643. $o.= ' </INDEXES>' . "\n";
  644. }
  645. $o.= ' </TABLE>' . "\n";
  646. return $o;
  647. }
  648. /// TODO: Delete for 2.1 (deprecated in 2.0).
  649. /// Deprecated API starts here
  650. function addFieldInfo($name, $type, $precision=null, $unsigned=null, $notnull=null, $sequence=null, $enum=null, $enumvalues=null, $default=null, $previous=null) {
  651. debugging('XMLDBTable->addFieldInfo() has been deprecated in Moodle 2.0. Will be out in Moodle 2.1. Please use xmldb_table->add_field() instead', DEBUG_DEVELOPER);
  652. if ($enum) {
  653. debugging('Also, ENUMs support has been dropped in Moodle 2.0. Your fields specs are incorrect because you are trying to introduce one new ENUM. Created DB estructures will ignore that.');
  654. }
  655. return $this->add_field($name, $type, $precision, $unsigned, $notnull, $sequence, $default, $previous);
  656. }
  657. /// Deprecated API ends here
  658. /**
  659. * This function will add one new field to the table with all
  660. * its attributes defined
  661. *
  662. * @param string name name of the field
  663. * @param string type XMLDB_TYPE_INTEGER, XMLDB_TYPE_NUMBER, XMLDB_TYPE_CHAR, XMLDB_TYPE_TEXT, XMLDB_TYPE_BINARY
  664. * @param string precision length for integers and chars, two-comma separated numbers for numbers and 'small', 'medium', 'big' for texts and binaries
  665. * @param string unsigned XMLDB_UNSIGNED or null (or false)
  666. * @param string notnull XMLDB_NOTNULL or null (or false)
  667. * @param string sequence XMLDB_SEQUENCE or null (or false)
  668. * @param string default meaningful default o null (or false)
  669. * @param string previous name of the previous field in the table or null (or false)
  670. */
  671. function add_field($name, $type, $precision=null, $unsigned=null, $notnull=null, $sequence=null, $default=null, $previous=null) {
  672. $field = new xmldb_field($name, $type, $precision, $unsigned, $notnull, $sequence, $default);
  673. $this->addField($field, $previous);
  674. return $field;
  675. }
  676. /// TODO: Delete for 2.1 (deprecated in 2.0).
  677. /// Deprecated API starts here
  678. function addKeyInfo($name, $type, $fields, $reftable=null, $reffields=null) {
  679. debugging('XMLDBTable->addKeyInfo() has been deprecated in Moodle 2.0. Will be out in Moodle 2.1. Please use xmldb_table->add_key() instead', DEBUG_DEVELOPER);
  680. return $this->add_key($name, $type, $fields, $reftable, $reffields);
  681. }
  682. /// Deprecated API ends here
  683. /**
  684. * This function will add one new key to the table with all
  685. * its attributes defined
  686. *
  687. * @param string name name of the key
  688. * @param string type XMLDB_KEY_PRIMARY, XMLDB_KEY_UNIQUE, XMLDB_KEY_FOREIGN
  689. * @param array fields an array of fieldnames to build the key over
  690. * @param string reftable name of the table the FK points to or null
  691. * @param array reffields an array of fieldnames in the FK table or null
  692. */
  693. function add_key($name, $type, $fields, $reftable=null, $reffields=null) {
  694. $key = new xmldb_key($name, $type, $fields, $reftable, $reffields);
  695. $this->addKey($key);
  696. }
  697. /// TODO: Delete for 2.1 (deprecated in 2.0).
  698. /// Deprecated API starts here
  699. function addIndexInfo($name, $type, $fields) {
  700. debugging('XMLDBTable->addIndexInfo() has been deprecated in Moodle 2.0. Will be out in Moodle 2.1. Please use xmldb_table->add_index() instead', DEBUG_DEVELOPER);
  701. return $this->add_index($name, $type, $fields);
  702. }
  703. /// Deprecated API ends here
  704. /**
  705. * This function will add one new index to the table with all
  706. * its attributes defined
  707. *
  708. * @param string name name of the index
  709. * @param string type XMLDB_INDEX_UNIQUE, XMLDB_INDEX_NOTUNIQUE
  710. * @param array fields an array of fieldnames to build the index over
  711. */
  712. function add_index($name, $type, $fields) {
  713. $index = new xmldb_index($name, $type, $fields);
  714. $this->addIndex($index);
  715. }
  716. /**
  717. * This function will return all the errors found in one table
  718. * looking recursively inside each field/key/index. Returns
  719. * an array of errors or false
  720. */
  721. function getAllErrors() {
  722. $errors = array();
  723. /// First the table itself
  724. if ($this->getError()) {
  725. $errors[] = $this->getError();
  726. }
  727. /// Delegate to fields
  728. if ($fields = $this->getFields()) {
  729. foreach ($fields as $field) {
  730. if ($field->getError()) {
  731. $errors[] = $field->getError();
  732. }
  733. }
  734. }
  735. /// Delegate to keys
  736. if ($keys = $this->getKeys()) {
  737. foreach ($keys as $key) {
  738. if ($key->getError()) {
  739. $errors[] = $key->getError();
  740. }
  741. }
  742. }
  743. /// Delegate to indexes
  744. if ($indexes = $this->getIndexes()) {
  745. foreach ($indexes as $index) {
  746. if ($index->getError()) {
  747. $errors[] = $index->getError();
  748. }
  749. }
  750. }
  751. /// Return decision
  752. if (count($errors)) {
  753. return $errors;
  754. } else {
  755. return false;
  756. }
  757. }
  758. }
  759. /// TODO: Delete for 2.1 (deeprecated in 2.0).
  760. /// Deprecated API starts here
  761. class XMLDBTable extends xmldb_table {
  762. function __construct($name) {
  763. parent::__construct($name);
  764. }
  765. }
  766. /// Deprecated API ends here