MigrationsBase.php 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771
  1. <?php
  2. namespace MigrationsBundle\Migrations;
  3. use Doctrine\DBAL\Migrations\AbstractMigration;
  4. use Doctrine\DBAL\Schema\Schema;
  5. use Symfony\Component\DependencyInjection\ContainerAwareInterface;
  6. use Symfony\Component\DependencyInjection\ContainerInterface;
  7. use Symfony\Component\Yaml\Yaml;
  8. /**
  9. * Clase de migracion de base.
  10. * Orden de ejecucion de metodos.
  11. * 1- preUp
  12. * 2- up
  13. * 3- postUp
  14. * 4- preDown
  15. * 5- down
  16. * 6- postDown
  17. */
  18. class MigrationsBase extends AbstractMigration implements ContainerAwareInterface
  19. {
  20. /**
  21. * Tipo de senetencia sql insert.
  22. */
  23. const INSERT = "INSERT";
  24. /**
  25. * Tipo de sentencia sql update.
  26. */
  27. const UPDATE = "UPDATE";
  28. /**
  29. * Tipo de sentenca sql delete.
  30. */
  31. const DELETE = "DELETE";
  32. /**
  33. * @var int $line Contiene el numero de linea que estoy ejecutando.
  34. */
  35. private $line = 0;
  36. /**
  37. * @var bool Me dice si tengo que mostrar los parametros en las consultas.
  38. */
  39. private $showParameters = false;
  40. /**
  41. * @var array $errorLineExecution Contiene una descripcion del error que ocaciono una linea del script YAML.
  42. */
  43. private $errorLineExecution = array();
  44. /**
  45. * @var array $lineExecution Contiene una descripcion de como se ejecuto cada linea del script YAML.
  46. */
  47. private $lineExecution = array();
  48. /**
  49. * @var ContainerInterface $container Contiene el contenedor.
  50. */
  51. private $container;
  52. /**
  53. * @param ContainerInterface|null $container Contiene un objeto que implementa "ContainerInterface".
  54. * @return ContainerInterface Retorna un objeto que implementa la interfaz "ContainerInterface".
  55. */
  56. public function setContainer(ContainerInterface $container = null)
  57. {
  58. $this->container = $container;
  59. return $this->container;
  60. }
  61. /**
  62. * @return ContainerInterface Retorna un objeto que implementa la interfaz "ContainerInterface".
  63. */
  64. public function getContainer()
  65. {
  66. return $this->container;
  67. }
  68. /**
  69. * @return bool Retorna el valor de la variable showParameters.
  70. */
  71. public function isShowParameters()
  72. {
  73. return $this->showParameters;
  74. }
  75. /**
  76. * @param bool $showParameters Si esta en TRUE muestra los parametros en las consultas.
  77. */
  78. public function setShowParameters($showParameters)
  79. {
  80. $this->showParameters = $showParameters;
  81. }
  82. /**
  83. * @return int Retorna el numero de linea que estoy analizando.
  84. */
  85. public function getLine()
  86. {
  87. return $this->line;
  88. }
  89. /**
  90. * @param int $line Setea el numero de linea.
  91. */
  92. private function setLine($line)
  93. {
  94. $this->line = $line;
  95. }
  96. /**
  97. * Funcion que suma 1 a la variable line.
  98. */
  99. private function sumLine()
  100. {
  101. $this->line = $this->line + 1;
  102. }
  103. /**
  104. * @return array Retorna un array con las lineas que produjeron errores.
  105. */
  106. public function getErrorLineExecution()
  107. {
  108. return $this->errorLineExecution;
  109. }
  110. /**
  111. * @param array $errorLineExecution Setea un array con las lineas que produjeron errores.
  112. */
  113. public function setErrorLineExecution($errorLineExecution)
  114. {
  115. $this->errorLineExecution = $errorLineExecution;
  116. }
  117. /**
  118. * Agrega una linea de error.
  119. * @param string $type Contiene el tipo de sentencia sql.
  120. * @param \Throwable $ex Contiene una excepcion.
  121. */
  122. private function addErrorLineExecution($type, \Throwable $ex)
  123. {
  124. if (!array_key_exists($type, $this->errorLineExecution)) {
  125. $this->errorLineExecution[$type] = array();
  126. }
  127. array_push($this->errorLineExecution[$type], "Line: " . $this->getLine() . " => [" . $ex->getCode() . "] = " . $ex->getMessage());
  128. }
  129. /**
  130. * @return array Retorna una array con el valor de la ejecucion de cada linea.
  131. */
  132. public function getLineExecution()
  133. {
  134. return $this->lineExecution;
  135. }
  136. /**
  137. * @param array $lineExecution Setea un array con las lineas de ejecucion.
  138. */
  139. public function setLineExecution($lineExecution)
  140. {
  141. $this->lineExecution = $lineExecution;
  142. }
  143. /**
  144. * Agrega el valor de la ejecucion.
  145. * @param string $type Contiene el tipo de sentencia sql.
  146. * @param string $value Contiene el valor de la ejecucion.
  147. */
  148. private function addLineExecution($type, $value)
  149. {
  150. if (!array_key_exists($type, $this->lineExecution)) {
  151. $this->lineExecution[$type] = array();
  152. }
  153. array_push($this->lineExecution[$type], "Line: " . $this->getLine() . " => " . $value);
  154. }
  155. /**
  156. * Realiza un up de la modificaciones DDL. Siempre son agregados.
  157. * Para realizar sentencias DML utilizarlos metodos preUp y postUp.
  158. * @param Schema $schema Contiene el objeto esquema.
  159. */
  160. public function up(Schema $schema)
  161. {
  162. }
  163. /**
  164. * Realiza un up de la modificaciones DDL. Siempre son eliminacion.
  165. * Para realizar sentencias DML utilizarlos metodos preDown y postDown.
  166. * @param Schema $schema Contiene el objeto esquema.
  167. */
  168. public function down(Schema $schema)
  169. {
  170. }
  171. /**
  172. * Procesa un yaml para generar las sentencias DML que luego seran ejecutadas en la base de datos.
  173. * El directorio origen es <code>app/DoctrineMigrations</code> en adelante.
  174. * @param string $dir Contiene el nombre del directorio a leer.
  175. * @param string $fileName Contiene el nombre del archivo a incorporar.
  176. */
  177. public function interpretYaml($dir, $fileName)
  178. {
  179. $dir = trim($dir);
  180. if (!(substr($dir, count($dir) - 2, count($dir) - 2) == "\\" ||
  181. substr($dir, count($dir) - 2, count($dir) - 2) == "/")
  182. ) {
  183. $dir = $dir . "/";
  184. }
  185. // leo el yaml
  186. $value = $this->readYaml($dir, $fileName);
  187. if ($value != null && count($value) > 0) {
  188. // paso las key a mayusculas
  189. foreach ($value as $key => $val) {
  190. unset($value[$key]);
  191. $value[strtoupper($key)] = $val;
  192. }
  193. // reemplazo las keys que poseen importkey
  194. $value = $this->replaceImportsKey($dir, $value);
  195. // reemplazo los valores que poseen import
  196. $value = $this->replaceImportsValue($dir, $value);
  197. // lo hago de esta forma para que se ejecuten de acuerdo a como se escribe el yaml.
  198. $this->setLine(0);
  199. foreach ($value as $key => $val) {
  200. if (strtoupper($key) === MigrationsBase::INSERT) {
  201. $this->createInserts($value[MigrationsBase::INSERT]);
  202. } else if (strtoupper($key) === MigrationsBase::UPDATE) {
  203. $this->createUpdates($value[MigrationsBase::UPDATE]);
  204. } else if (strtoupper($key) === MigrationsBase::DELETE) {
  205. $this->createDeletes($value[MigrationsBase::DELETE]);
  206. } else {
  207. die("Valor no esperado");
  208. }
  209. }
  210. }
  211. }
  212. /**
  213. * Crea los insert a partir de una estructura yaml. Se puede utilizar la palabra clave "ignore", "replace" o "orupdate".
  214. * El "replace" sobreescribe al "ignore" y el "orupdate" sobreescribe al "replace".
  215. * @param array $arrayInsert Contiene la estructura yaml para los insert.
  216. */
  217. private function createInserts($arrayInsert)
  218. {
  219. foreach ($arrayInsert as $table => $inserts) {
  220. // recorro las tablas
  221. foreach ($inserts as $key => $valueKey) {
  222. // recorro cada uno de los insert que quiero hacer
  223. // almacena los campos
  224. $fields = "";
  225. // almacena el valor de los campos
  226. $valuesFields = "";
  227. // me dice si tengo que utilizar la palabra ignore
  228. $ignore = " ";
  229. // contiene la primer palabra de la sentencia (INSERT/REPLACE)
  230. $insert = "INSERT";
  231. // me dice si es un insert or update
  232. $orUpdate = false;
  233. // contiene los valores del insert or update
  234. $orUpdateValues = "";
  235. // contiene los valores para el bind del stament
  236. $arrayPrepare = array();
  237. foreach ($valueKey as $field => $value) {
  238. // recorro los datos a insertar
  239. $field = strtolower(trim($field));
  240. $value = trim($value);
  241. if (strlen($field) > 0 && strlen($value) > 0) {
  242. if ($field === 'ignore') {
  243. $value = strtolower($value);
  244. if ($value === '1' || $value === 'true') {
  245. if ($insert === 'INSERT') {
  246. $ignore = " IGNORE ";
  247. }
  248. }
  249. } else if ($field === 'replace') {
  250. $value = strtolower($value);
  251. if ($value === '1' || $value === 'true') {
  252. $insert = "REPLACE";
  253. $ignore = " ";
  254. }
  255. } else if ($field === 'orupdate') {
  256. $value = strtolower($value);
  257. if ($value === '1' || $value === 'true') {
  258. $orUpdate = true;
  259. $ignore = " ";
  260. $insert = "INSERT";
  261. }
  262. } else {
  263. $arrayPrepare[':' . $field] = $value;
  264. $fields = $fields . $field . ", ";
  265. $valuesFields = $valuesFields . ":" . $field . ", ";
  266. $orUpdateValues = $orUpdateValues . $field . " = " . ":" . $field . ", ";
  267. }
  268. }
  269. }
  270. if (strlen($fields) > 1) {
  271. $fields = substr($fields, 0, strlen($fields) - 2);
  272. }
  273. if (strlen($valuesFields) > 1) {
  274. $valuesFields = substr($valuesFields, 0, strlen($valuesFields) - 2);
  275. }
  276. if (strlen($orUpdateValues) > 1) {
  277. $orUpdateValues = substr($orUpdateValues, 0, strlen($orUpdateValues) - 2);
  278. }
  279. if (strlen($fields) > 1 && strlen($valuesFields) > 1) {
  280. $sql = $insert . $ignore . "INTO " . $table . " (" . $fields . ") VALUES (" . $valuesFields . ")";
  281. if ($orUpdate) {
  282. $sql .= " ON DUPLICATE KEY UPDATE " . $orUpdateValues . ";";
  283. } else {
  284. $sql .= ";";
  285. }
  286. $this->executeSQL($sql, MigrationsBase::INSERT, $arrayPrepare);
  287. }
  288. }
  289. }
  290. }
  291. /**
  292. * Crea los update a partir de una estructura yaml.
  293. * @param array $arrayInsert Contiene la estructura yaml para los insert.
  294. */
  295. private function createUpdates($arrayInsert)
  296. {
  297. foreach ($arrayInsert as $table => $inserts) {
  298. // recorro las tablas
  299. foreach ($inserts as $key => $valueKey) {
  300. // recorro cada uno de los insert que quiero hacer
  301. $set = "";
  302. $where = "";
  303. // contiene los valores para el bind del stament
  304. $arrayPrepare = array();
  305. foreach ($valueKey as $field => $value) {
  306. // recorro los datos a realizar un update
  307. if (strlen(trim($field)) > 0 && strlen(trim($value)) > 0) {
  308. if ($field === "where") {
  309. $where = $value;
  310. } else {
  311. $arrayPrepare[':' . $field] = $value;
  312. $set = $set . $field . " = :" . $field . ", ";
  313. }
  314. }
  315. }
  316. if (strlen($set) > 1) {
  317. $set = substr($set, 0, strlen($set) - 2);
  318. }
  319. if (strlen($set) > 1) {
  320. $sql = "UPDATE " . $table . " SET " . $set . " WHERE " . $where . ";";
  321. $this->executeSQL($sql, MigrationsBase::UPDATE, $arrayPrepare);
  322. }
  323. }
  324. }
  325. }
  326. /**
  327. * Crea los delete a partir de una estructura yaml.
  328. * @param array $arrayInsert Contiene la estructura yaml para los insert.
  329. */
  330. private function createDeletes($arrayInsert)
  331. {
  332. foreach ($arrayInsert as $table => $inserts) {
  333. // recorro las tablas
  334. foreach ($inserts as $key => $valueKey) {
  335. // recorro cada uno de los insert que quiero hacer
  336. $where = "";
  337. foreach ($valueKey as $field => $value) {
  338. // recorro los datos a realizar un update
  339. if (strlen(trim($field)) > 0 && strlen(trim($value)) > 0) {
  340. if ($field === "where") {
  341. $where = $value;
  342. }
  343. }
  344. }
  345. $sql = "DELETE FROM " . $table . " WHERE " . $where . ";";
  346. $this->executeSQL($sql, MigrationsBase::DELETE);
  347. }
  348. }
  349. }
  350. /**
  351. * Obtiene el contenido de un archivo yaml.
  352. * @param string $dir Contiene el directorio de trabajo. Por defecto "DoctrineMigrations".
  353. * @param string $archivo Contiene el nombre del archivo a incorporar.
  354. * @return bool|string Retorna el contenido del archivo.
  355. */
  356. private function readYaml($dir, $archivo)
  357. {
  358. return Yaml::parse(file_get_contents($dir . $archivo));
  359. }
  360. /**
  361. * Obtiene el contenido de un archivo.
  362. * @param string $dir Contiene el directorio de trabajo. Por defecto "DoctrineMigrations".
  363. * @param string $archivo Contiene el nombre del archivo a incorporar.
  364. * @return bool|string Retorna el contenido del archivo.
  365. */
  366. private function readImportInValues($dir, $archivo)
  367. {
  368. return file_get_contents($dir . $archivo);
  369. }
  370. /**
  371. * Reemplaza el contenido de los imports dentro de los values.
  372. * @param string $dir Contiene el directorio de trabajo. Por defecto "DoctrineMigrations".
  373. * @param array $valores Contiene el array el contenido del yaml.
  374. * @return array Retorna el array con los valores cambiados.
  375. */
  376. private function replaceImportsValue($dir, $valores)
  377. {
  378. try {
  379. foreach ($valores as $key => $value) {
  380. if (is_array($value)) {
  381. if (count($value) == 1 && array_key_exists("import", $value)) {
  382. if (file_exists($dir . $value["import"])) {
  383. $valores[$key] = $this->readImportInValues($dir, $value["import"]);
  384. } else {
  385. $valores[$key] = "FILE NOT FOUND";
  386. }
  387. } else {
  388. $valores[$key] = $this->replaceImportsValue($dir, $value);
  389. }
  390. }
  391. }
  392. } catch (\Symfony\Component\Debug\Exception\ContextErrorException $e) {
  393. var_dump($e);
  394. }
  395. return $valores;
  396. }
  397. /**
  398. * Reemplaza el contenido de los imports dentro de las key.
  399. * @param string $dir Contiene el directorio de trabajo. Por defecto "DoctrineMigrations".
  400. * @param array $valores Contiene el array el contenido del yaml.
  401. * @return array Retorna el array con los valores cambiados.
  402. */
  403. private function replaceImportsKey($dir, $valores)
  404. {
  405. try {
  406. foreach ($valores as $key => $value) {
  407. if (is_array($value)) {
  408. $valores[$key] = $this->replaceImportsKey($dir, $value);
  409. } else {
  410. if (trim($key) === "importkey") {
  411. if (file_exists($dir . $value)) {
  412. $valores = $this->readYaml($dir, $value);
  413. } else {
  414. $valores[$key] = "FILE NOT FOUND";
  415. }
  416. }
  417. }
  418. }
  419. } catch (\Symfony\Component\Debug\Exception\ContextErrorException $e) {
  420. var_dump($e);
  421. }
  422. return $valores;
  423. }
  424. /**
  425. * Funcion ejecuta el YAML en la base de datos dentro de una transaccion.
  426. * @param string $dir Contiene el path del directorio donde se encuentra el archio a leer.
  427. * @param string $file Contiene el nombre de archivo a procesar.
  428. */
  429. public function executeYaml($dir, $file)
  430. {
  431. try {
  432. $tmp = explode("\\", get_class($this));
  433. if ($tmp != null && count($tmp) > 0) {
  434. $version = $tmp[count($tmp) - 1];
  435. } else {
  436. $version = "";
  437. }
  438. echo "\n\tInicio del procesamiento de la migracion: " . $version;
  439. $this->connection->beginTransaction();
  440. try {
  441. $this->interpretYaml($dir, $file);
  442. if (count($this->getErrorLineExecution()) > 0) {
  443. //se produjeron errores
  444. echo "\n\t\tSe produjeron errores de sql.\n";
  445. } else {
  446. $this->connection->commit();
  447. echo "\n\t\tMigracion correcta.\n";
  448. }
  449. } catch (\Throwable $ex) {
  450. $this->connection->rollBack();
  451. echo "\n\t\tSe produjeron errores por una excepcion. " . $ex->getMessage() . "\n";
  452. }
  453. } catch (\Throwable $e) {
  454. echo "\n\t\tSe produjeron errores genericos. " . $e->getMessage() . "\n";
  455. }
  456. }
  457. /**
  458. * Funcion que ejecuta una sentencia sql.
  459. * @param string $sql Contiene el sql a ejecutar.
  460. * @param string $type Contiene el tipo de sentencia.
  461. * @param array $arrayPrepare Contiene un array con los valores. La key contiene el valor a
  462. * buscar en la sentencia sql y el value es el valor.
  463. */
  464. public function executeSQL($sql, $type, $arrayPrepare = null)
  465. {
  466. $this->connection->executeUpdate($sql, (array)$arrayPrepare);
  467. $this->sumLine();
  468. }
  469. /**
  470. * Funcion que obtiene el numero de version.
  471. * @param mixed $obj Contiene el objeto de ejecucion.
  472. * @return string Retorna el numero de version que estoy ejecutando.
  473. */
  474. public function getMigrationNumber($obj)
  475. {
  476. $arr = explode("\\", get_class($obj));
  477. return str_ireplace("version", "", $arr[count($arr) - 1]);
  478. }
  479. /**
  480. * Borra la migracion de la tabla de migraciones.
  481. * @param string $obj Contiene el objeto this.
  482. */
  483. public function deleteMigrationsVersion($obj)
  484. {
  485. if ($this->existTable("migration_versions")) {
  486. $this->connection->beginTransaction();
  487. $stmt = $this->connection->prepare(
  488. "DELETE FROM migration_versions " .
  489. "WHERE migration_versions.version = '" . $this->getMigrationNumber($obj) . "'");
  490. $stmt->execute();
  491. $this->connection->commit();
  492. }
  493. }
  494. /**
  495. * Verifica si la migracion ya se incorporo.
  496. * @param string $obj Contiene el objeto this.
  497. * @return bool Retorna TRUE si ya se realizo la migracion.
  498. */
  499. public function verifyMigrationsVersion($obj)
  500. {
  501. $existe = false;
  502. try {
  503. if ($this->existTable("migration_versions")) {
  504. $nroVersion = $this->getMigrationNumber($obj);
  505. $base = $this->getDataBaseName();
  506. $sql =
  507. "SELECT ifnull(version, '') as nombre " .
  508. "FROM migration_versions " .
  509. "WHERE " .
  510. $base . ".migration_versions.version = '" . $nroVersion . "';";
  511. $stmt = $this->connection->prepare($sql);
  512. $stmt->execute();
  513. $resp = $stmt->fetchAll();
  514. foreach ($resp as $key => $value) {
  515. if (strtolower($value["nombre"]) === strtolower($nroVersion)) {
  516. $existe = true;
  517. break;
  518. }
  519. }
  520. }
  521. return $existe;
  522. } catch (\Throwable $e) {
  523. return $existe;
  524. }
  525. }
  526. /**
  527. * Funcion que muestra por pantalla el resultado de la ejecucion y de los errores.
  528. */
  529. public function showResult()
  530. {
  531. if (count($this->getLineExecution()) > 0) {
  532. echo "-----------------------------------------------\n";
  533. echo " EJECUCIONES\n";
  534. echo "-----------------------------------------------\n";
  535. foreach ($this->getLineExecution() as $key => $value) {
  536. echo $key . "\n";
  537. foreach ($this->getLineExecution()[$key] as $k => $v) {
  538. echo "\t" . $v . "\n";
  539. }
  540. }
  541. }
  542. if (count($this->getErrorLineExecution()) > 0) {
  543. echo "-----------------------------------------------\n";
  544. echo " ERRORES\n";
  545. echo "-----------------------------------------------\n";
  546. foreach ($this->getErrorLineExecution() as $key => $value) {
  547. echo $key . "\n";
  548. foreach ($this->getErrorLineExecution()[$key] as $k => $v) {
  549. echo "\t" . $v . "\n";
  550. }
  551. }
  552. }
  553. }
  554. /**
  555. * Funcion que verifica si existe un campo de una tabla.
  556. * @param string $table Contiene el nombre de la tabla.
  557. * @param string $field Contiene el nombre el campo.
  558. * @return bool Retorna true si el campo existe.
  559. */
  560. public function existFieldInTable($table, $field)
  561. {
  562. $existe = false;
  563. try {
  564. $base = $this->getDataBaseName();
  565. $sql = "SELECT ifnull(COLUMN_NAME, '') as nombre " .
  566. "FROM information_schema.columns " .
  567. "WHERE TABLE_SCHEMA = '" . $base . "' AND " .
  568. " TABLE_NAME = '" . $table . "' AND " .
  569. " COLUMN_NAME = '" . $field . "'; ";
  570. $stmt = $this->connection->prepare($sql);
  571. $stmt->execute();
  572. $resp = $stmt->fetchAll();
  573. foreach ($resp as $key => $value) {
  574. if (strtolower($value["nombre"]) === strtolower($field)) {
  575. $existe = true;
  576. break;
  577. }
  578. }
  579. return $existe;
  580. } catch (\Throwable $e) {
  581. return $existe;
  582. }
  583. }
  584. /**
  585. * Funcion que verifica si existe un valor dentro de una tabla.
  586. * @param string $table Contiene el nombre de la tabla.
  587. * @param string $field Contiene el/los campos a mostrar.
  588. * @param string $where Contiene el where de la consulta. Solo los campos con los valores. SIN
  589. * LA PALABRA CLAVE.
  590. * @return array Retorna el array con los datos encontrados. O NULL en caso de error.
  591. */
  592. public function existValueInTable($table, $field, $where)
  593. {
  594. try {
  595. $sql = "SELECT " . $field . " " .
  596. "FROM " . $table . " " .
  597. "WHERE " . $where . "; ";
  598. $stmt = $this->connection->prepare($sql);
  599. $stmt->execute();
  600. $resp = $stmt->fetchAll();
  601. return $resp;
  602. } catch (\Throwable $e) {
  603. return null;
  604. }
  605. }
  606. /**
  607. * Funcion que verifica si existe un campo de una tabla.
  608. * @param string $table Contiene el nombre de la tabla.
  609. * @param string $field Contiene el nombre el campo.
  610. * @param string $type Contiene el typo de dato.
  611. * @return bool Retorna true si el campo existe.
  612. */
  613. public function existFieldType($table, $field, $type)
  614. {
  615. $existe = false;
  616. try {
  617. $base = $this->getDataBaseName();
  618. $sql = "SELECT ifnull(DATA_TYPE, '') as nombre " .
  619. "FROM information_schema.columns " .
  620. "WHERE TABLE_SCHEMA = '" . $base . "' AND " .
  621. " TABLE_NAME = '" . $table . "' AND " .
  622. " COLUMN_NAME = '" . $field . "' " .
  623. "LIMIT 1;";
  624. $stmt = $this->connection->prepare($sql);
  625. $stmt->execute();
  626. $resp = $stmt->fetchAll();
  627. foreach ($resp as $key => $value) {
  628. if (strtolower($value["nombre"]) === strtolower($type)) {
  629. $existe = true;
  630. break;
  631. }
  632. }
  633. return $existe;
  634. } catch (\Throwable $e) {
  635. return $existe;
  636. }
  637. }
  638. /**
  639. * Funcion que verifica si existe una tabla.
  640. * @param string $table Contiene el nombre de la tabla.
  641. * @return bool Retorna true si la tabla existe.
  642. */
  643. public function existTable($table)
  644. {
  645. $existe = false;
  646. try {
  647. $base = $this->getDataBaseName();
  648. $sql = "SELECT ifnull(TABLE_NAME, '') as nombre " .
  649. "FROM information_schema.columns " .
  650. "WHERE TABLE_SCHEMA = '" . $base . "' AND " .
  651. " TABLE_NAME = '" . $table . "' " .
  652. "LIMIT 1;";
  653. $stmt = $this->connection->prepare($sql);
  654. $stmt->execute();
  655. $resp = $stmt->fetchAll();
  656. foreach ($resp as $key => $value) {
  657. if (strtolower($value["nombre"]) === strtolower($table)) {
  658. $existe = true;
  659. break;
  660. }
  661. }
  662. return $existe;
  663. } catch (\Throwable $e) {
  664. return $existe;
  665. }
  666. }
  667. /**
  668. * Funcion que obtiene el nombre de la base de datos a la cual estoy conectado.
  669. * @return string Retorna el nombre de la base de datos o NULL en caso de error.
  670. */
  671. public function getDataBaseName()
  672. {
  673. $resp = null;
  674. try {
  675. $stmt = $this->connection->prepare("SELECT DATABASE() as base;");
  676. $stmt->execute();
  677. $resp = $stmt->fetchAll();
  678. foreach ($resp as $key => $value) {
  679. $resp = $value["base"];
  680. break;
  681. }
  682. return $resp;
  683. } catch (\Throwable $e) {
  684. return $resp;
  685. }
  686. }
  687. /**
  688. * Funcion que obtiene el valor del auto_increment.
  689. * @param string $table Contiene el nombre de la tabla.
  690. * @return array Retorna el array con los datos encontrados. O NULL en caso de error.
  691. */
  692. public function getAutoIncrementValue($table)
  693. {
  694. $autoIncrement = 1;
  695. try {
  696. $base = $this->getDataBaseName();
  697. $sql = "SELECT `AUTO_INCREMENT` " .
  698. "FROM INFORMATION_SCHEMA.TABLES " .
  699. "WHERE TABLE_SCHEMA = '" . $base . "' AND " .
  700. " TABLE_NAME = '" . $table . "';";
  701. $stmt = $this->connection->prepare($sql);
  702. $stmt->execute();
  703. $resp = $stmt->fetchAll();
  704. foreach ($resp as $key => $value) {
  705. if (isset($value["AUTO_INCREMENT"])) {
  706. $autoIncrement = $value["AUTO_INCREMENT"];
  707. }
  708. }
  709. } catch (\Throwable $e) {
  710. }
  711. return $autoIncrement;
  712. }
  713. /**
  714. * Funcion que setea el valor del auto_increment.
  715. * @param string $table Contiene el nombre de la tabla.
  716. * @param int $value Contiene el proximo numero autilizar.
  717. */
  718. public function setAutoIncrementValue($table, $value)
  719. {
  720. try {
  721. $base = $this->getDataBaseName();
  722. $stmt = $this->connection->prepare("ALTER TABLE " . $base . "." . $table . " AUTO_INCREMENT=" . $value . ";");
  723. $stmt->execute();
  724. } catch (\Throwable $e) {
  725. }
  726. }
  727. }