if (select top 1 0 from sys.databases where name = 'AnP') is null create database AnP collate Latin1_General_100_CI_AS_SC_UTF8
go
use AnP

if object_id(N'dbo.common_tables_drop', N'P') is not null drop procedure dbo.common_tables_drop
go
create procedure dbo.common_tables_drop as begin set nocount on 

    if object_id(N'dbo.Procedures', N'U') is not null drop table dbo.Procedures
    if object_id(N'dbo.Databases', N'U') is not null drop table dbo.Databases

end
go

if object_id(N'dbo.common_tables_create', N'P') is not null drop procedure dbo.common_tables_create
go
create procedure dbo.common_tables_create as begin set nocount on 

    declare @table_names varchar(max) = ''

    if object_id(N'dbo.HistoryModes', N'U') is null begin 
        create table dbo.HistoryModes(
            id integer not null identity(1, 1),
            [name] varchar(16) not null,
            [description] varchar(512), 
            date_in datetime2 not null constraint df_history_modes_date_in default getdate(), 
            date_out datetime2,
            constraint pk_history_modes primary key clustered(id), 
            constraint uq_history_modes_name unique nonclustered ([name] asc)  with (fillfactor = 90), 
            constraint ck_history_modes_name check ([name] not like '%[^a-zA-Z0-9_]%' and [name] like '[a-zA-Z_]%')
        )
        insert into dbo.HistoryModes([name]) values('insert'), ('update'), ('delete'), ('unknown')
    end

    if object_id(N'dbo.Databases', N'U') is null create table dbo.Databases(
        id integer not null identity(1, 1),
        [name] varchar(32) not null,
        [description] varchar(512), 
        date_in datetime2 not null constraint df_databases_date_in default getdate(), 
        date_out datetime2,
        constraint pk_databases primary key clustered(id), 
        constraint uq_databases_name unique nonclustered ([name] asc)  with (fillfactor = 90), 
        constraint ck_databases_name check ([name] not like '%[^a-zA-Z0-9_]%' and [name] like '[a-zA-Z_]%')
    )

    if object_id(N'dbo.Procedures', N'U') is null create table dbo.Procedures(
        id integer not null identity(1, 1),
        [database] integer not null, 
        [name] varchar(32) not null,
        [description] varchar(512), 
        date_in datetime2 not null constraint df_procedures_date_in default getdate(), 
        date_out datetime2,
        constraint pk_procedures primary key clustered(id), 
        constraint fk_procedures_database foreign key([database]) references dbo.Databases(id) 
            on update no action 
            on delete no action, 
        constraint uq_procedures_name unique nonclustered ([database] asc, [name] asc) with (fillfactor = 90), 
        constraint ck_procedures_name check ([name] not like '%[^a-zA-Z0-9_]%' and [name] like '[a-zA-Z_]%')
    )

end
go

if object_id(N'dbo.procedure_get_id', N'P') is not null drop procedure dbo.procedure_get_id
go
create procedure dbo.procedure_get_id (
    @database varchar(32), 
    @name varchar(32), 
    @id integer output
) as begin set nocount on 

    declare @database_id integer = (select id from dbo.Databases where [name] = @database)

    if @database_id is null begin 
        insert into dbo.Databases ([name]) values (@database)
        set @database_id = scope_identity()
    end

    set @id = (select id from dbo.Procedures where [database] = @database_id and [name] = @name)

    if @id is null begin 
        insert into dbo.Procedures ([database], [name]) values (@database_id, @name)
        set @id = scope_identity()
    end

end
go

execute dbo.common_tables_drop
execute dbo.common_tables_create

if object_id(N'dbo.bw', N'FN') is not null drop function dbo.bw
go
create function dbo.bw(
	@number bigint,
	@bits smallint
) returns bigint begin 
	return (case 
		when @bits > 0 then @number * power(cast(2 as bigint), @bits)
		when @bits < 0 then @number / power(cast(2 as bigint), -@bits)
	else @number end)
end
go

if object_id(N'dbo.history_mode_get', N'P') is not null drop procedure dbo.history_mode_get
go
create procedure dbo.history_mode_get(
    @insert integer output, 
    @update integer output, 
    @delete integer output,
    @unknown integer output
) as begin set nocount on 
    set @insert = (select top 1 id from dbo.HistoryModes where [name] = 'insert')
    set @update = (select top 1 id from dbo.HistoryModes where [name] = 'update')
    set @delete = (select top 1 id from dbo.HistoryModes where [name] = 'delete')
    set @unknown = (select top 1 id from dbo.HistoryModes where [name] = 'unknown')
end
go