-- Por si las moscas borramos los procesos
DROP PROCEDURE IF EXISTS `createField`;
DROP PROCEDURE IF EXISTS `updateField`;
DROP PROCEDURE IF EXISTS `createIndex`;
-- Vamos a añadir el "procedure" que se encargará de crear campos si si procede:
delimiter //
-- ------------------------------------------------------------
-- Crear campo 
-- Parámetros opcionales dbName, por defecto coge el de la actual
-- ------------------------------------------------------------
CREATE PROCEDURE `createField` (
OUT _exists BOOLEAN,      -- return value
IN tableName CHAR(255),   -- name of table to look for
IN columnName CHAR(255),  -- name of column to look for
IN dbName CHAR(255),       -- optional specific db
IN columnType CHAR(255),		  -- Tipo de campo
IN notNull CHAR(255),		-- indicamos si es nulo o no
IN defalultValue CHAR(255),	-- Valor por defecto
IN fieldComment CHAR(255),		-- Comentario
IN afterField CHAR(255)	-- Campo después del que valor`
) BEGIN
-- Variables que vamos a usar en el proceso

-- try to lookup db if none provided
SET @_dbName := IF(dbName IS NULL, database(), dbName);

IF CHAR_LENGTH(@_dbName) = 0 THEN -- no specific or current db to check against
  SELECT FALSE INTO _exists;
ELSE -- we have a db to work with
  SELECT IF(count(*) > 0, TRUE, FALSE) INTO _exists
  FROM information_schema.COLUMNS c
  WHERE 
  c.TABLE_SCHEMA    = @_dbName
  AND c.TABLE_NAME  = tableName
  AND c.COLUMN_NAME = columnName;
  IF NOT _exists THEN
	SET @_sentence = CONCAT('ALTER TABLE `', tableName, '` ADD `', columnName, '` ', columnType, ' ', notNull);
	IF (defalultValue IS NOT NULL) THEN
		SET @_sentence = CONCAT(@_sentence, ' ', defalultValue);
	END IF;
	IF (fieldComment IS NOT NULL) THEN
		SET @_sentence = CONCAT(@_sentence, ' COMMENT \'', fieldComment, '\'');
	END IF;
	IF (afterField IS NOT NULL) THEN
		SET @_sentence = CONCAT(@_sentence, ' after ', afterField);
	END IF;
	PREPARE stmt1 FROM @_sentence;
	EXECUTE stmt1;
	DEALLOCATE PREPARE stmt1;
  END IF;
END IF;
END //
-- ------------------------------------------------------------
-- Actualizamos un campo
-- Parámetros opcionales dbName, por defecto coge el de la actual
-- ------------------------------------------------------------
-- Función que añade un campo a una tabla si no existe:
CREATE PROCEDURE `updateField` (
OUT _exists BOOLEAN,      -- return value
IN tableName CHAR(255),   -- name of table to look for
IN oldName CHAR(255),  -- Nombre actual de la columna
IN newName CHAR(255),  -- Nuevo nombre que le daremos a la columna
IN dbName CHAR(255),       -- optional specific db
IN columnType CHAR(255),		  -- Tipo de campo
IN notNull CHAR(255),		-- indicamos si es nulo o no
IN defalultValue CHAR(255),	-- Valor por defecto
IN fieldComment CHAR(255)
) BEGIN
-- Variables del proceso
DECLARE _makeSentence BOOLEAN DEFAULT FALSE;
DECLARE _existeViejo BOOLEAN DEFAULT FALSE;
DECLARE _existeNuevo BOOLEAN DEFAULT FALSE;
DECLARE _oldName VARCHAR(500) DEFAULT oldName;
DECLARE _newName VARCHAR(500) DEFAULT newName;

-- try to lookup db if none provided
SET @_dbName := IF(dbName IS NULL, database(), dbName);

IF CHAR_LENGTH(@_dbName) = 0 THEN -- no specific or current db to check against
  SELECT FALSE INTO _exists;
ELSE -- Tenemos base de datos
  -- Aquí hay un problema, por un lado puede que exista el nombre nuevo, en cuyo caso hacemos el update:
  SELECT IF(count(*) > 0, TRUE, FALSE) INTO _existeViejo
  FROM information_schema.COLUMNS c
  WHERE 
  c.TABLE_SCHEMA    = @_dbName
  AND c.TABLE_NAME  = tableName
  AND c.COLUMN_NAME = oldName;
  --
  SELECT IF(count(*) > 0, TRUE, FALSE) INTO _existeNuevo
  FROM information_schema.COLUMNS c
  WHERE 
  c.TABLE_SCHEMA    = @_dbName
  AND c.TABLE_NAME  = tableName
  AND c.COLUMN_NAME = newName;
  -- Casos posibles:
  IF _existeViejo AND _existeNuevo THEN
  	-- Existen los dos campos, vamos a modificar el nuevo sólo por si algún tipo ha cambiado. Del viejo, nos olvidamos
	SET _oldName = newName;
	SET _makeSentence = TRUE;
  ELSEIF _existeNuevo THEN
   -- Al igual que antes, sólo hay que modificar el campo nuevo, porque no existe el viejo
  	SET _oldName = newName;
	SET _makeSentence = TRUE;
  ELSEIF _existeViejo THEN
   -- Este es el funcionamiento normal, existe el campo viejo, pero no el nuevo hay que ejecutar la sentencia sin más
	SET _makeSentence = TRUE;
  ELSE
  	-- No existe ni el nuevo ni el viejo, hay que crear el campo nuevo sólo
  	CALL createField (_exists, tableName, _newName, dbName, columnType, notNull, defalultValue, fieldComment, NULL);
  END IF;
  
  -- Si procede, ejecutamos la sentencia
  IF _makeSentence THEN
    SET @_sentence = CONCAT('ALTER TABLE `', tableName, '` CHANGE `', _oldName, '` `', _newName,'` ', columnType, ' ', notNull);
	IF (defalultValue IS NOT NULL) THEN
		SET @_sentence = CONCAT(@_sentence, ' ', defalultValue);
	END IF;
	IF (fieldComment IS NOT NULL) THEN
		SET @_sentence = CONCAT(@_sentence, ' COMMENT \'', fieldComment, '\'');
	END IF;
	PREPARE stmt1 FROM @_sentence;
	EXECUTE stmt1;
	DEALLOCATE PREPARE stmt1;
  END IF;
END IF;
END //

-- ------------------------------------------------------------
-- Añadimos un índice si no existe
-- Parámetros opcionales dbName, por defecto coge el de la actual
-- ------------------------------------------------------------
CREATE PROCEDURE `createIndex`(
	IN tableName    VARCHAR(64),
	IN givenIndex    VARCHAR(64),
	IN givenColumns  VARCHAR(64),
	IN dbName VARCHAR(64)
)BEGIN
	DECLARE IndexIsThere INTEGER;

	-- try to lookup db if none provided
	SET @_dbName := IF(dbName IS NULL, database(), dbName);

	SELECT COUNT(1) INTO IndexIsThere
	FROM INFORMATION_SCHEMA.STATISTICS
	WHERE table_schema = @_dbName
	AND   table_name   = tableName
	AND   index_name   = givenIndex;

	IF IndexIsThere = 0 THEN
		SET @sqlstmt = CONCAT('CREATE INDEX ',givenIndex,' ON ',
		@_dbName,'.',tableName,' (',givenColumns,')');
		PREPARE st FROM @sqlstmt;
		EXECUTE st;
		DEALLOCATE PREPARE st;
	END IF;

END //

DELIMITER ;
-- ********************************************************************************************************************************

-- Tabla de URL de Fotos de artículo
CREATE TABLE IF NOT EXISTS `url_fotos_articulo`  ( `codigo` BIGINT NOT NULL , `articulo` INT NOT NULL , `url` VARCHAR(512) NOT NULL , PRIMARY KEY (`codigo`), INDEX `articulo` (`articulo`)) ENGINE = MyISAM;
-- Tabla de líneas de promoción
CREATE TABLE IF NOT EXISTS `lin_promocion` ( `promocion` INT NOT NULL , `codigo` BIGINT NOT NULL , `articulo` BIGINT NOT NULL , `pvp` DECIMAL(7,3) NOT NULL , `tariarti` BIGINT NOT NULL , INDEX `articulo` (`articulo`), UNIQUE `codigo` (`promocion`, `codigo`)) ENGINE = MyISAM;

-- Aádimos un par de índices a la tabla de lotes para optimizar la carga
CALL createIndex ('mc_lotes', 'visible_web', 'visible_web', NULL);


-- ********************************************************************************************************************************
-- Eliminamos todos los procesos
DROP PROCEDURE IF EXISTS `createField`;
DROP PROCEDURE IF EXISTS `updateField`;
DROP PROCEDURE IF EXISTS `createIndex`;