-- Por si las moscas borramos los procesos
DROP PROCEDURE IF EXISTS createField;
DROP PROCEDURE IF EXISTS updateField;
-- Vamos a añadir el "procedure" que se encargará de crear campos si si procede:
delimiter //
-- ------------------------------------------------------------
-- Use the inforamtion_schema to tell if a field exists.
-- Optional param dbName, defaults to current database
-- ------------------------------------------------------------
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 //

-- 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 //

delimiter ;
-- ********************************************************************************************************************************


-- añadimos el número de prensa a la tabla de índices
-- ALTER TABLE `search_index` ADD `prensa` INT NOT NULL AFTER `articulo`;
CALL createField (@_exists, 'search_index', 'prensa', NULL, 'INT', 'NOT NULL', 'DEFAULT 0', NULL, 'pendiente_indexar');

ALTER TABLE `search_index` DROP PRIMARY KEY, ADD PRIMARY KEY (`articulo`, `prensa`, `valor`, `idioma`) USING BTREE;
-- Tabla de números de prensa
CREATE TABLE IF NOT EXISTS `prensa` ( 
	`articulo` BIGINT NOT NULL , `numero` INT NOT NULL , `nombre` VARCHAR(60) NOT NULL , 
	`autor` VARCHAR(50) NOT NULL , `pvp` DECIMAL(10,4) NOT NULL , `precio_costo` DECIMAL(10,4) NOT NULL , 
	`ventas` INT NOT NULL DEFAULT '0' , `compras` INT NOT NULL DEFAULT '0' , `devoluciones` INT NOT NULL DEFAULT '0' , 
	`abonos` INT NOT NULL DEFAULT '0' , `descuento_compra` DECIMAL(5,2) NOT NULL , `iva` SMALLINT NOT NULL , 
	`regularizados` INT NOT NULL DEFAULT '0' , `prestado` INT NOT NULL DEFAULT '0' , `reservado` INT NOT NULL DEFAULT '0' , 
	`fecha_alta` DATE NOT NULL , `stock_calculado` INT NOT NULL DEFAULT '0' , `pendientes_emitir` INT NOT NULL DEFAULT '0' , 
	`pendientes_recibir` INT NOT NULL DEFAULT '0' , `pedidos_cliente` INT NOT NULL DEFAULT '0' , `pendientes_devolver` INT NOT NULL DEFAULT '0' , 
	`suscripciones_pendientes_retirar` INT NOT NULL DEFAULT '0' ,
	PRIMARY KEY (`articulo`, `numero`)) 
	ENGINE = MyISAM CHARSET=utf8mb4 COLLATE utf8mb4_general_ci COMMENT = 'Tabla que almacena los números de prensa';

-- Añadimos el campo que indica si al lote hay que mostrarle un texto predefinido o nombre`
-- ALTER TABLE `mc_lotes` ADD `mostrar_texto_anticipo` BOOLEAN NOT NULL COMMENT 'Indica si hay que mostrar un texto fijo en los lotes' AFTER `no_enviar_domicilio`;
CALL createField (@_exists, 'mc_lotes', 'mostrar_texto_anticipo', NULL, 'BOOLEAN', 'NOT NULL', NULL, 'Indica si hay que mostrar un texto fijo en los lotes', 'no_enviar_domicilio');

-- Añadimos la exclusión de un rango de envío:
CALL createField (@_exists, 'rango_envio', 'excluido', NULL, 'BOOLEAN', 'NOT NULL', 'DEFAULT 0', 'Excluido para mostrarse en el desplagable', 'zona');


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