/** * Importa una personalizacion, tiene 2 modos de accion: * Transaccion Global, se importa todo o nada. * Transaccion a nivel de componente, se importa solo lo que no da error. */ function aplicar() { if (!$this->existe()) { throw new toba_error("PERSONALIZACION: No existe la carpeta de personalización"); } //Instancio ambos importadores $importador_tablas = new toba_importador_tablas($this->dir_tablas . self::nombre_plan, $this->db); $importador_componentes = new toba_importador_componentes($this->dir_componentes . self::nombre_plan, $this->db); //Empiezo haciendo el chequeo de conflictos para los componentes //En una transaccion destinada a abortar //------------------------------------------------------------------------------------------// $this->db->abrir_transaccion(); $this->analizar_conflictos($importador_tablas, false); $this->analizar_conflictos($importador_componentes, false); $this->db->abortar_transaccion(); //------------------------------------------------------------------------------------------// //Comienzo la importacion propiamente dicha if ($this->ejecutar_en_transaccion_global()) { $this->db->abrir_transaccion(); $this->db->retrazar_constraints(); //Retraso los triggers para evitar problemas de fk } //Aplico la personalizacion a tablas y componentes try { $this->aplicar_cambios($importador_tablas); $this->aplicar_cambios($importador_componentes); } catch (toba_error_db $e) { $this->db->abortar_transaccion(); //Hubo problemas de SQL, aborto todo if ($this->consola) { $this->consola->mensaje("Ocurrio un error en la importacion \n"); } } catch (toba_error_usuario $e) { $this->db->abortar_transaccion(); //El usuario decidio no continuar, saco mensaje por pantalla if ($this->consola) { $this->consola->mensaje($e->getMessage()); } } if ($this->db->transaccion_abierta() && $this->ejecutar_en_transaccion_global()) { $this->db->cerrar_transaccion(); //Cierro la transaccion si aun esta abierta. Esto es, se ejecuto sin problemas } }
/** * Intenta ejecutar una tarea, si hay conflicto el usuario decide si se guarda o no. * En modo transaccion local, se aborta a pedido del usuario o por error de SQL * En modo global, se dispara excepcion a pedido del usuario */ function ejecutar(consola $consola = null) { if (!$this->ejecuta_en_transaccion_global()) { //Se usan transacciones a nivel local. $this->db->abrir_transaccion(); } foreach ($this->datos as $registro) { /** @todo Agregar llamada al migrador con $this->datos para que modifique los campos que tenga que modificar */ //Tomo en cuenta la postura del usuario segun el tipo de conflicto if (!is_null($consola) && $registro->tiene_conflictos()) { $conflicto = $registro->get_conflicto_irresoluble(); if (!is_null($conflicto)) { $this->io_conflicto_irresoluble($consola, $conflicto); $this->elegir_camino_accion(false); return; } $conflictos = $registro->get_conflictos_solubles(); foreach ($conflictos as $conflicto) { $continuar = $this->io_conflicto_soluble($consola, $conflicto); $this->elegir_camino_accion($continuar); if (!$continuar) { return; } } } //Ejecuto la SQL que representa el registro try { $registro->grabar(); } catch (toba_error_db $e) { if ($this->ejecuta_en_transaccion_global()) { throw $e; } //Si la transaccion esta afuera tiro para arriba la excepcion. $this->db->abortar_transaccion(); return; } } if (!$this->ejecuta_en_transaccion_global()) { //Si ejecuta con transaccion local $this->db->cerrar_transaccion(); } }