bingo/sqlserver/sql/bingo_create.sql (180 lines of code) (raw):
-- Enable CLR
USE master
GO
sp_configure 'clr enabled', 1;
GO
RECONFIGURE
GO
IF (select is_broker_enabled from sys.databases where name='$(database)') = 0
BEGIN
-- It is necessary to generate new service_broker_guid when any other database has identical active service_broker_guid
-- (target database might be used as a template and be created via backup, so that's why duplications are possible
-- and in addition the same service_broker_guid might be enabled on another db)
IF (
select count(*) has_service_broker_guid_conflicts
from sys.databases
where name = '$(database)' and service_broker_guid = ANY
(
select service_broker_guid
from sys.databases
group by service_broker_guid
-- check for duplicates with enabled service broker
having count(*) > 1 and max(convert(int, is_broker_enabled)) = 1
)
) = 1
ALTER DATABASE $(database) SET NEW_BROKER WITH ROLLBACK IMMEDIATE
ELSE
-- otherwise enable service broker for event notification purposes
ALTER DATABASE $(database) SET ENABLE_BROKER
END
go
-- Create key for adding unsafe assembly. It might be already created for different installation
BEGIN TRY
CREATE ASYMMETRIC KEY bingo_assembly_key FROM EXECUTABLE FILE = '$(bingo_assembly_path).dll'
CREATE LOGIN bingo_assembly_login FROM ASYMMETRIC KEY bingo_assembly_key
GRANT UNSAFE ASSEMBLY TO bingo_assembly_login
END TRY
BEGIN CATCH
PRINT ERROR_NUMBER();
PRINT ERROR_MESSAGE();
END CATCH;
GO
use $(database)
go
PRINT 'Creating certificate...';
CREATE CERTIFICATE $(bingo)_certificate
ENCRYPTION BY PASSWORD = '$(bingo_pass)'
WITH SUBJECT = 'Certificate for bingo procedures executions',
START_DATE = '20020101', EXPIRY_DATE = '21000101'
GO
-- Create a bingo user
PRINT 'Creating bingo user with schema...';
CREATE USER $(bingo) FROM CERTIFICATE $(bingo)_certificate;
go
CREATE SCHEMA $(bingo);
go
ALTER AUTHORIZATION ON SCHEMA::$(bingo) TO $(bingo)
go
GRANT create table TO $(bingo);
go
-- Create tables for bingo user
create table [$(bingo)].CONFIG (n int not null, name varchar(100) not null, value varchar(4000), primary key(n, name));
create index CONFIG_N on [$(bingo)].CONFIG(n);
insert into [$(bingo)].CONFIG values(0, 'treat-x-as-pseudoatom', '0');
insert into [$(bingo)].CONFIG values(0, 'ignore-closing-bond-direction-mismatch', '0');
insert into [$(bingo)].CONFIG values(0, 'nthreads', '-1');
insert into [$(bingo)].CONFIG values(0, 'ignore-stereocenter-errors', 0);
insert into [$(bingo)].CONFIG values(0, 'ignore-cistrans-errors', 0);
insert into [$(bingo)].CONFIG values(0, 'allow-non-unique-dearomatization', 0);
insert into [$(bingo)].CONFIG values(0, 'zero-unknown-aromatic-hydrogens', 0);
insert into [$(bingo)].CONFIG values(0, 'stereochemistry-bidirectional-mode', 0);
insert into [$(bingo)].CONFIG values(0, 'stereochemistry-detect-haworth-projection', 0);
insert into [$(bingo)].CONFIG values(0, 'reject-invalid-structures', 0);
insert into [$(bingo)].CONFIG values(0, 'ignore-bad-valence', 0);
go
insert into [$(bingo)].CONFIG values(0, 'FP_ORD_SIZE', '25');
insert into [$(bingo)].CONFIG values(0, 'FP_ANY_SIZE', '15');
insert into [$(bingo)].CONFIG values(0, 'FP_TAU_SIZE', '10');
insert into [$(bingo)].CONFIG values(0, 'FP_SIM_SIZE', '8');
insert into [$(bingo)].CONFIG values(0, 'SUB_SCREENING_MAX_BITS', '8');
insert into [$(bingo)].CONFIG values(0, 'KEEP_CACHE', '0');
insert into [$(bingo)].CONFIG values(0, 'SIM_SCREENING_PASS_MARK', '128');
insert into [$(bingo)].CONFIG values(0, 'SIMILARITY_TYPE', 'SIM');
insert into [$(bingo)].CONFIG values(0, 'CT_FORMAT_SAVE_DATE', '1');
insert into [$(bingo)].CONFIG values(0, 'CT_FORMAT_MODE', 'AUTO');
go
create table [$(bingo)].CONFIG_BIN (n int not null, name varchar(100) not null, value varbinary(max), primary key(n, name));
create index CONFIG_BIN_N on [$(bingo)].CONFIG_BIN(n);
go
-- Create context
create table [$(bingo)].CONTEXT (obj_id int not null, database_id int not null, full_table_name varchar(100), id_column varchar(100), data_column varchar(100), type varchar(100), primary key (obj_id, database_id));
create index CONTEXT_ID on [$(bingo)].CONTEXT(obj_id);
go
-- Create table with tautomer rules
create table [$(bingo)].TAUTOMER_RULES (id int identity primary key, begg varchar(100), endd varchar(100));
insert into [$(bingo)].TAUTOMER_RULES(begg, endd) values ('N,O,P,S,As,Se,Sb,Te', 'N,O,P,S,As,Se,Sb,Te');
insert into [$(bingo)].TAUTOMER_RULES(begg, endd) values ('0C', 'N,O,P,S');
insert into [$(bingo)].TAUTOMER_RULES(begg, endd) values ('1C', 'N,O');
go
-- Create roles
CREATE ROLE $(bingo)_reader;
GO
CREATE ROLE $(bingo)_operator;
GO
-- Operator role inherts reader role
EXEC sp_addrolemember $(bingo)_reader, $(bingo)_operator
GO
--
-- Create assembly
--
CREATE ASSEMBLY $(bingo)_assembly from '$(bingo_assembly_path).dll' WITH PERMISSION_SET = UNSAFE;
GO
--
-- Create functions and procedures
--
:r bingo_create_methods.sql
--
-- Create notification queue for OnSessionClose()
--
SET quoted_identifier on;
GO
CREATE PROCEDURE [$(bingo)].log_events
AS
SET NOCOUNT ON;
DECLARE @message_body XML,
@message_type_name NVARCHAR(256),
@dialog UNIQUEIDENTIFIER
-- This procedure continues to process messages in the queue until the queue is empty.
WHILE (1 = 1)
BEGIN
BEGIN TRANSACTION ;
-- Receive the next available message
WAITFOR (
RECEIVE TOP(1) -- just handle one message at a time
@message_type_name=message_type_name, --the type of message received
@message_body=message_body, -- the message contents
@dialog = conversation_handle -- the identifier of the dialog this message was received on
FROM [$(bingo)].notify_queue
), TIMEOUT 1000; -- if the queue is empty for one seconds, give up and go away
-- If RECEIVE did not return a message, roll back the transaction
-- and break out of the while loop, exiting the procedure.
IF (@@ROWCOUNT = 0)
BEGIN
ROLLBACK TRANSACTION ;
BREAK ;
END ;
-- Check to see if the message is an end dialog message.
IF (@message_type_name = 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog')
BEGIN
END CONVERSATION @dialog ;
END ;
ELSE
BEGIN
DECLARE @event_type NVARCHAR(max);
SET @event_type = CAST(@message_body.query('/EVENT_INSTANCE/EventType/text()') AS nvarchar(max));
-- Release session
IF (@event_type = 'AUDIT_LOGOUT')
BEGIN
DECLARE @spid nvarchar(max);
SET @spid = @message_body.value('(/EVENT_INSTANCE/SPID)[1]', 'int')
EXECUTE [$(bingo)].OnSessionClose @spid;
END
-- Delete Bingo index if table has been deleted
IF (@event_type = 'OBJECT_DELETED')
BEGIN
DECLARE @obj_id int, @database_id int;
SET @obj_id = @message_body.value('(/EVENT_INSTANCE/ObjectID)[1]', 'int')
SET @database_id = @message_body.value('(/EVENT_INSTANCE/DatabaseID)[1]', 'int')
EXECUTE [$(bingo)]._DropIndexByID @obj_id, @database_id
END
END ;
COMMIT TRANSACTION ;
END ;
GO
create queue [$(bingo)].notify_queue with activation (
status = on, procedure_name = [$(bingo)].log_events, max_queue_readers = 1, execute as self);
GO
create service $(bingo)_notify_service on queue [$(bingo)].notify_queue
(
[http://schemas.microsoft.com/SQL/Notifications/PostEventNotification]
);
GO
-- ALTER AUTHORIZATION ON SERVICE::$(bingo)_notify_service TO $(bingo)
-- go
CREATE ROUTE $(bingo)_notify_route AUTHORIZATION dbo
WITH SERVICE_NAME = N'$(bingo)_notify_service', ADDRESS = N'LOCAL';
GO
-- Creating server-global triggers and events
IF (select count(*) from sys.server_event_notifications where name = '$(bingo)_$(database)_logout_notify') = 1
-- event notification for the database may exist when db was restored from backup with different service_broker_guid
drop event notification $(bingo)_$(database)_logout_notify on server;
GO
create event notification $(bingo)_$(database)_logout_notify on server for
AUDIT_LOGOUT, OBJECT_DELETED to service '$(bingo)_notify_service', 'current database';
GO
-- Trigger to prevent manual database drop operation with Bingo installed
if (select count(*) from sys.server_triggers where name = '$(bingo)_$(database)_prevent_db_drop') = 1
DROP TRIGGER $(bingo)_$(database)_prevent_db_drop ON ALL SERVER;
GO
CREATE TRIGGER $(bingo)_$(database)_prevent_db_drop
ON ALL SERVER
FOR DROP_DATABASE
AS
DECLARE @database_name NVARCHAR(128),
@event_data XML
SET @event_data = EVENTDATA()
SELECT @database_name = @event_data.value('(/EVENT_INSTANCE/DatabaseName)[1]', 'nvarchar(128)')
IF @database_name = '$(database)'
BEGIN
PRINT 'You must uninstall Bingo first to drop database!'
ROLLBACK;
END
GO
PRINT 'Done.'
GO