USE [YourDatabaseName]
GO

SET ANSI_NULLS ON;
GO
SET QUOTED_IDENTIFIER ON;
GO

CREATE TABLE [dbo].[tblCCTemplateScripts](
	[tstamp] [timestamp] NOT NULL,
	[ID_TemplateScript] [int] IDENTITY(1,1) NOT NULL,
	[F_TemplateName] [nvarchar](80) NOT NULL,
	[F_TemplateDescription] [nvarchar](200) NOT NULL,
	[F_TemplateCode] [nvarchar](max) NOT NULL,
 CONSTRAINT [PK_tblCCTemplateScripts] PRIMARY KEY CLUSTERED 
(
	[ID_TemplateScript] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Only for developers to save scripts for creating objects with a template configurable in the CCTemplateScripts frontend' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'tblCCTemplateScripts';
GO

CREATE TABLE [dbo].[tblCCTemplateVariables](
	[tstamp] [timestamp] NOT NULL,
	[ID_TemplateVariable] [int] IDENTITY(1,1) NOT NULL,
	[F_VariableName] [nvarchar](128) NOT NULL,
	[F_ConvertToUpperCase] [bit] NOT NULL CONSTRAINT [DF_tblCCTemplateVariables_F_ConvertToUpperCase]  DEFAULT ((0)),
	[F_ConvertToLowerCase] [bit] NOT NULL CONSTRAINT [DF_tblCCTemplateVariables_F_ConvertToLowerCase]  DEFAULT ((0)),
	[F_Prefix] [nvarchar](30) NULL,
	[F_Suffix] [nvarchar](30) NULL,
	[F_ValueSELECT] [nvarchar](max) NULL,
	[F_ValueSELECTColumns] [int] NULL,
	[F_ValueSELECTColumnWidths] [nvarchar](200) NULL,
	[F_DefaultValue] [nvarchar](max) NULL,
	[F_Comment] [nvarchar](200) NULL,
 CONSTRAINT [PK_tblCCTemplateVariables] PRIMARY KEY CLUSTERED 
(
	[ID_TemplateVariable] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Contains the usable variable names insertable into the templates' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'tblCCTemplateVariables';
GO

SET XACT_ABORT ON;
GO

SET IDENTITY_INSERT [dbo].[tblCCTemplateScripts] ON;

BEGIN TRANSACTION;
INSERT INTO [dbo].[tblCCTemplateScripts]([ID_TemplateScript], [F_TemplateName], [F_TemplateDescription], [F_TemplateCode])
SELECT 1, N'Simple Table', N'Table with ID Field, ID FK, Name and Description fields, indexed', N'SET ANSI_NULLS ON;
                SET QUOTED_IDENTIFIER ON;
                CREATE TABLE [{Schema}].[tbl{Area}_{TableName}]
                (
                               [tstamp] [timestamp] NOT NULL,
                               [{IDFieldName}] [int] IDENTITY(1,1) NOT NULL,
                               [{ID Foreign Key 1}] int NOT NULL,
                               [{NameField}] nvarchar(80) NOT NULL,
                               [F_Comment] nvarchar(200) NULL
                CONSTRAINT [PK_tbl{Area}_{TableName}] PRIMARY KEY CLUSTERED
                (
                               [{IDFieldName}] ASC
                )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
                ) ON [PRIMARY];

                CREATE UNIQUE NONCLUSTERED INDEX [UQ_tbl{Area}_{TableName}_{NameField}] ON [{Schema}].[tbl{Area}_{TableName}]
                (
                               [{NameField}] ASC
                )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY];

                               CREATE UNIQUE NONCLUSTERED INDEX [UQ_tbl{Area}_{TableName}_{ID Foreign Key 1}] ON [{Schema}].[tbl{Area}_{TableName}]
                (
                               [{ID Foreign Key 1}] ASC
                )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY];

                EXEC sys.sp_addextendedproperty @name=N''MS_Description'', @value=N''{TableDescription}'' ,
                                @level0type=N''SCHEMA'',@level0name=N''{Schema}'',
                                @level1type=N''TABLE'',@level1name=N''tbl{Area}_{TableName}''' UNION ALL
SELECT 2, N'M to N Table', N'm to n table construct containing the PK ID Field and two additional foreign key fields and also a "NoDuplicate" index', N'SET ANSI_NULLS ON;
                SET QUOTED_IDENTIFIER ON;
                CREATE TABLE [{Schema}].[tbl{Area}_{TableName}]
                (
                               [tstamp] [timestamp] NOT NULL,
                               [{IDFieldName}] [int] IDENTITY(1,1) NOT NULL,
                               [{ID Foreign Key 1}] int NOT NULL,
                                                               [{ID Foreign Key 2}] int NOT NULL
CONSTRAINT [PK_tbl{Area}_{TableName}] PRIMARY KEY CLUSTERED
                (
                               [{IDFieldName}] ASC
                )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
                ) ON [PRIMARY];

                CREATE UNIQUE NONCLUSTERED INDEX [UQ_tbl{Area}_{TableName}_NoDuplicate] ON [{Schema}].[tbl{Area}_{TableName}]
                (
                               [{ID Foreign Key 1}] ASC,
                               [{ID Foreign Key 2}] ASC
                )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY];

                EXEC sys.sp_addextendedproperty @name=N''MS_Description'', @value=N''{TableDescription}'' ,
                                @level0type=N''SCHEMA'',@level0name=N''{Schema}'',
                                @level1type=N''TABLE'',@level1name=N''tbl{Area}_{TableName}''' UNION ALL
SELECT 3, N'Lookup Table', N'Simple Lookup Table with PK, Name and Comment, unique index on Name column', N'SET ANSI_NULLS ON;
                SET QUOTED_IDENTIFIER ON;
                CREATE TABLE [{Schema}].[tbl{Area}_{TableName}]
                (
                               [tstamp] [timestamp] NOT NULL,
                               [{IDFieldName}] [int] IDENTITY(1,1) NOT NULL,
                               [{NameField}] nvarchar(80) NOT NULL,
                               [F_Comment] nvarchar(200) NULL
                CONSTRAINT [PK_tbl{Area}_{TableName}] PRIMARY KEY CLUSTERED
                (
                               [{IDFieldName}] ASC
                )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
                ) ON [PRIMARY];

                CREATE UNIQUE NONCLUSTERED INDEX [UQ_tbl{Area}_{TableName}_{NameField}] ON [{Schema}].[tbl{Area}_{TableName}]
                (
                               [{NameField}] ASC
                )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY];

                EXEC sys.sp_addextendedproperty @name=N''MS_Description'', @value=N''{TableDescription}'' ,
                                @level0type=N''SCHEMA'',@level0name=N''{Schema}'',
                                @level1type=N''TABLE'',@level1name=N''tbl{Area}_{TableName}'''
COMMIT;
RAISERROR (N'[dbo].[tblCCTemplateScripts]: Insert Batch: 1.....Done!', 10, 1) WITH NOWAIT;
GO

SET IDENTITY_INSERT [dbo].[tblCCTemplateScripts] OFF;
SET IDENTITY_INSERT [dbo].[tblCCTemplateVariables] ON;

BEGIN TRANSACTION;
INSERT INTO [dbo].[tblCCTemplateVariables]([ID_TemplateVariable], [F_VariableName], [F_ConvertToUpperCase], [F_ConvertToLowerCase], [F_Prefix], [F_Suffix], [F_ValueSELECT], [F_ValueSELECTColumns], [F_ValueSELECTColumnWidths], [F_DefaultValue], [F_Comment])
SELECT 1, N'Schema', 0, 0, NULL, NULL, N'SELECT SCHEMA_NAME, SCHEMA_OWNER FROM dbo.viewADMIN_CTLSchemas ORDER BY SCHEMA_NAME;', 2, N'4cm;3cm', N'dbo', N'SQL Server Schema name' UNION ALL
SELECT 2, N'Area', 1, 0, NULL, NULL, N'SELECT Area FROM dbo.viewADMIN_CTLAreas ORDER BY Area;', 1, N'3,5cm', NULL, N'Area name (converted to uppercase) to be inserted after i.e. "tbl" prefix' UNION ALL
SELECT 3, N'TableName', 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, N'Table name without area and "tbl" Prefix' UNION ALL
SELECT 4, N'ViewName', 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, N'View name without "view" and area prefix' UNION ALL
SELECT 5, N'IDFieldName', 0, 0, N'ID_', NULL, NULL, NULL, NULL, NULL, N'Name of the PK ID Field, "ID_" will automatically be added' UNION ALL
SELECT 6, N'TableDescription', 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, N' Table description text for the table which will be added as extended property' UNION ALL
SELECT 7, N'ID Foreign Key 1', 0, 0, N'ID_', NULL, NULL, NULL, NULL, N'FK1', N'First foreign key fieldname' UNION ALL
SELECT 8, N'ID Foreign Key 2', 0, 0, N'ID_', NULL, NULL, NULL, NULL, N'FK2', N'Second foreign key field' UNION ALL
SELECT 9, N'NameField', 0, 0, N'F_', NULL, NULL, NULL, NULL, N'Name', N'Standard name field i.e. for use in lookup tables'
COMMIT;
RAISERROR (N'[dbo].[tblCCTemplateVariables]: Insert Batch: 1.....Done!', 10, 1) WITH NOWAIT;
GO
SET IDENTITY_INSERT [dbo].[tblCCTemplateVariables] OFF;
GO

-- These views are used in the demo variables only, you don't need them if you use own views for other variables
CREATE VIEW [dbo].[viewADMIN_CTLAreas]
AS
SELECT DISTINCT SUBSTRING(RIGHT(TABLE_NAME,LEN(TABLE_NAME)-3),1,CHARINDEX('_',TABLE_NAME) - 4) AS [Area]
  FROM CCForumTestDB.[INFORMATION_SCHEMA].[TABLES]
WHERE TABLE_NAME LIKE 'tbl%' AND CHARINDEX('_',TABLE_NAME) > 2

GO

CREATE VIEW [dbo].[viewADMIN_CTLSchemas]
AS
SELECT [SCHEMA_NAME],[SCHEMA_OWNER]
  FROM CCForumTestDB.[INFORMATION_SCHEMA].[SCHEMATA]
WHERE SCHEMA_NAME NOT LIKE 'db__%'
  AND SCHEMA_NAME <> 'guest'
  AND SCHEMA_NAME <> 'sys'
  AND SCHEMA_NAME <> 'INFORMATION_SCHEMA'

GO

-- =============================================
-- Author:		Christian Coppes
-- Create date: 28.01.2014
-- Description:	Finds variables surrounded by the 
--				specified brackets in a text, groups 
--				them and returns a table with the values
-- =============================================
ALTER FUNCTION [dbo].[fnCCFindVariables] 
(
	@strBrackets	nvarchar(2), 
	@strText		nvarchar(MAX)
)
RETURNS 
@tblReturn TABLE 
(
	F_VariableName nvarchar(128) PRIMARY KEY
)
AS
BEGIN

	DECLARE @intPos			AS	INT;
	DECLARE @strBracket1	AS	NCHAR(1);
	DECLARE @strBracket2	AS	NCHAR(1);
	DECLARE @strValue		AS	NVARCHAR(MAX);

	SET @intPos = 0;
	SET @strBracket1 = '{';
	SET @strBracket2 = '}';
	SET @strValue = '';

	IF ISNULL(@strBrackets,'') <> '' AND LEN(ISNULL(@strBrackets,'')) = 2
	BEGIN
		SET @strBracket1 =  LEFT(@strBrackets,1);
		SET @strBracket2 = RIGHT(@strBrackets,1);
	END

	SET @intPos = PATINDEX('%' +@strBracket1 + '%' + @strBracket2 + '%',@strText);

	WHILE @intPos > 0
	BEGIN
		SET @strValue = SUBSTRING(@strText, @intPos + 1, 
								  CHARINDEX(@strBracket2,@strText,@intPos + 1) - (@intPos + 1)
								 );
	
		INSERT INTO @tblReturn (F_VariableName)
		SELECT @strValue
		 WHERE NOT EXISTS (SELECT F_VariableName FROM @tblReturn WHERE F_VariableName = @strValue);

		SET @strText = RIGHT(@strText,LEN(@strText) - (@intPos + 1));
		SET @intPos = PATINDEX('%' +@strBracket1 + '%' + @strBracket2 + '%',@strText);
	END
	
	RETURN 
END

GO

-- =============================================
-- Author:		Christian Coppes
-- Create date: 28.01.2014
-- Description:	Creates a table using templates and variables
--				defined in dbo.tblCCTemplates
--				and dbo.tblCCTemplateVariables
-- Parameters:  @intTemplateID = The template which should be used
--				@strVariables = |-separated list of variable names
--				@strValues = |-separated list of values
-- =============================================
ALTER PROCEDURE [dbo].[procCCCreateObjectFromTemplate]
(
	@intTemplateID		AS INT,
	@strVariables		AS NVARCHAR(MAX),
	@strValues			AS NVARCHAR(MAX)
)
AS
BEGIN
	-- SET NOCOUNT ON added to prevent extra result sets from
	-- interfering with SELECT statements.
	SET NOCOUNT ON;

	DECLARE @intPosName		AS INT;
	DECLARE @intPosValue	AS INT;
	DECLARE @strName		AS NVARCHAR(128);
	DECLARE @strValue		AS NVARCHAR(MAX);
	DECLARE @strSQL			AS NVARCHAR(MAX);
	DECLARE @bitUCase		AS BIT;
	DECLARE @bitLCase		AS BIT;
	DECLARE @strPrefix		AS NVARCHAR(30);
	DECLARE @strSuffix		AS NVARCHAR(30);

	SET @intPosName  = 1;
	SET @intPosValue = 1;
	
	IF NOT (ISNULL(@strVariables,'')='' OR ISNULL(@strValues,'')='')
	BEGIN
	
		SET @strSQL = (SELECT F_TemplateCode 
						 FROM dbo.tblCCTemplateScripts
						WHERE ID_TemplateScript = @intTemplateID);

		IF NOT ISNULL(@strSQL,'')=''
		BEGIN
			WHILE @intPosName > 0
			BEGIN
				SET @intPosName = CHARINDEX('|', @strVariables);
				SET @intPosValue = CHARINDEX('|',@strValues);
				
				IF @intPosName = 0
				BEGIN
					SET @strName = @strVariables;
					SET @strValue = @strValues;
				END
				ELSE
				BEGIN
					SET @strName = LEFT(@strVariables,@intPosName - 1);
					SET @strValue = LEFT(@strValues, @intPosValue - 1);
					
					SET @strVariables = RIGHT(@strVariables,LEN(@strVariables) - (LEN(@strName) + 1));
					SET @strValues = RIGHT(@strValues,LEN(@strValues) - (LEN(@strValue) + 1));
				END -- IF @intPosName = 0

				SELECT @bitLCase = F_ConvertToLowerCase,
					   @bitUCase = F_ConvertToUpperCase,
					   @strPrefix = F_Prefix,
					   @strSuffix = F_Suffix
				  FROM dbo.tblCCTemplateVariables AS TV
				 WHERE F_VariableName = @strName;

				SET @strValue = LTRIM(RTRIM(ISNULL(@strValue,'')));
				SET @strValue = ISNULL(@strPrefix,'') + @strValue + ISNULL(@strSuffix,'')
				IF @bitLCase = 1 SET @strValue = LOWER(@strValue);
				IF @bitUCase = 1 SET @strValue = UPPER(@strValue);
				
				SET @strSQL = REPLACE(@strSQL,'{' + @strName + '}', @strValue);
			END -- WHILE @intPosName > 0
		END	-- IF NOT ISNULL(@strSQL,'')=''	
	END -- IF NOT (ISNULL(@strVariables,'')='' OR ISNULL(@strValues,'')='')
	
	BEGIN TRY
		EXECUTE sp_executesql @strSQL;
		RAISERROR (N'Creation of table was successfully performed.',16,1);
	END TRY
	BEGIN CATCH
		DECLARE @ErrorMessage NVARCHAR(4000);
		DECLARE @ErrorSeverity INT;
		DECLARE @ErrorState INT;

		SELECT 
			@ErrorMessage = ERROR_MESSAGE(),
			@ErrorSeverity = ERROR_SEVERITY(),
			@ErrorState = ERROR_STATE();

		-- Use RAISERROR inside the CATCH block to return error
		-- information about the original error that caused
		-- execution to jump to the CATCH block.
		RAISERROR (@ErrorMessage, -- Message text.
				   @ErrorSeverity, -- Severity.
				   @ErrorState -- State.
				   );

	END CATCH
END

GO

-- =============================================
-- Author:		Christian Coppes
-- Create date: 28.01.2014
-- Description:	Create temp table to edit variables
-- =============================================
ALTER PROCEDURE [dbo].[procCCCreateObjectHelper] 
	@intTemplateID INT = 0 
AS
BEGIN
	SET NOCOUNT ON;

	DECLARE @tblOut	AS	TABLE	(	ID_TemplateVariable			INT NOT NULL,
									F_VariableName				NVARCHAR(128) NOT NULL,
									F_ConvertToUpperCase		BIT NOT NULL,
									F_ConvertToLowerCase		BIT NOT NULL,
									F_Prefix					NVARCHAR(30) NULL,
									F_Suffix					NVARCHAR(30) NULL,
									F_ValueSELECT				NVARCHAR(MAX) NULL,
									F_ValueSELECTColumns		INT NULL,
									F_ValueSELECTColumnWidths	NVARCHAR(200) NULL,
									F_DefaultValue				NVARCHAR(MAX) NULL,
									F_Comment					NVARCHAR(200) NULL,
									F_Value						NVARCHAR(200) NULL
								);

	INSERT INTO @tblOut
			(ID_TemplateVariable, F_VariableName,
			 F_ConvertToUpperCase, F_ConvertToLowerCase,
			 F_Prefix, F_Suffix, F_ValueSELECT,
			 F_ValueSELECTColumns, F_ValueSELECTColumnWidths,
			 F_DefaultValue, F_Comment)
	SELECT ID_TemplateVariable, F_VariableName,
		   F_ConvertToUpperCase, F_ConvertToLowerCase,
		   F_Prefix, F_Suffix, F_ValueSELECT,
		   F_ValueSELECTColumns, F_ValueSELECTColumnWidths,
		   F_DefaultValue, F_Comment
	  FROM dbo.tblCCTemplateVariables
	 WHERE F_VariableName IN (SELECT fn.F_VariableName
								FROM dbo.fnCCFindVariables('{}',
														   (SELECT F_TemplateCode
														      FROM dbo.tblCCTemplateScripts
														     WHERE ID_TemplateScript = @intTemplateID)) AS fn);
	
	SELECT	ID_TemplateVariable, F_VariableName,
			F_ConvertToUpperCase, F_ConvertToLowerCase,
			F_Prefix, F_Suffix, F_ValueSELECT,
			F_ValueSELECTColumns, F_ValueSELECTColumnWidths,
			F_DefaultValue, F_Comment
	  FROM @tblOut;
END

GO

