forked from fsprojects/FAKE
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSQLServer.fs
More file actions
180 lines (151 loc) · 7.05 KB
/
Copy pathSQLServer.fs
File metadata and controls
180 lines (151 loc) · 7.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
[<AutoOpen>]
module Fake.SQL.SqlServer
open Fake
open System
open System.Data.SqlClient
open Microsoft.SqlServer.Management.Smo
open Microsoft.SqlServer.Management.Common
open System.IO
type ServerInfo ={
Server: Server
ConnBuilder: SqlConnectionStringBuilder}
/// Gets a connection to the SQL server and an instance to the ConnectionStringBuilder
let getServerInfo connectionString =
let connbuilder = new SqlConnectionStringBuilder(connectionString)
let conn = new ServerConnection()
if connbuilder.UserID <> "" then
conn.LoginSecure <- false
conn.Login <- connbuilder.UserID
if connbuilder.Password <> "" then
conn.LoginSecure <- false
conn.Password <- connbuilder.Password
conn.ServerInstance <- connbuilder.DataSource
conn.Connect()
{Server = new Server(conn)
ConnBuilder = connbuilder}
/// gets the DatabaseNames from the server
let getDatabasesFromServer (serverInfo:ServerInfo) =
seq {for db in serverInfo.Server.Databases -> db}
/// gets the DatabaseNames from the server
let getDatabaseNamesFromServer (serverInfo:ServerInfo) =
getDatabasesFromServer serverInfo
|> Seq.map (fun db -> db.Name)
/// Gets the initial catalog name
let getDBName serverInfo = serverInfo.ConnBuilder.InitialCatalog
/// Gets the name of the server
let getServerName serverInfo = serverInfo.ConnBuilder.DataSource
/// Checks whether the given Database exists on the server
let existDBOnServer serverInfo dbName =
let names = getDatabaseNamesFromServer serverInfo
let searched = getDBName serverInfo
tracefn "Searching for database %s on server %s. Found: " searched (getServerName serverInfo)
names
|> Seq.iter (tracefn " - %s ")
names
|> Seq.exists ((=) dbName)
/// Gets the initial catalog as database instance
let getDatabase serverInfo = new Database(serverInfo.Server, getDBName serverInfo)
/// Checks whether the given InitialCatalog exists on the server
let intitialCatalogExistsOnServer serverInfo =
getDBName serverInfo
|> existDBOnServer serverInfo
/// Drops the given InitialCatalog from the server (if it exists)
let DropDb serverInfo =
if intitialCatalogExistsOnServer serverInfo then
logfn "Dropping database %s on server %s" (getDBName serverInfo) (getServerName serverInfo)
(getDatabase serverInfo).DropBackupHistory |> ignore
getDBName serverInfo |> serverInfo.Server.KillDatabase
serverInfo
/// Kills all processes with the given server info
let KillAllProcesses serverInfo =
let dbName = getDBName serverInfo
logfn "Killing all processes from database %s on server %s." dbName (getServerName serverInfo)
serverInfo.Server.KillAllProcesses dbName
serverInfo
/// Detaches a database
let Detach serverInfo =
serverInfo
|> KillAllProcesses
|> fun si ->
let dbName = getDBName si
logfn "Detaching database %s on server %s." dbName (getServerName serverInfo)
si.Server.DetachDatabase(dbName, true)
si
/// Attach a database
let Attach serverInfo (attachOptions:AttachOptions) files =
let sc = new Collections.Specialized.StringCollection ()
files |> Seq.iter (fun file ->
sc.Add file |> ignore
checkFileExists file)
let dbName = getDBName serverInfo
logfn "Attaching database %s on server %s." dbName (getServerName serverInfo)
serverInfo.Server.AttachDatabase(dbName,sc,attachOptions)
serverInfo
/// Creates a new db on the given server
let CreateDb serverInfo =
logfn "Creating database %s on server %s" (getDBName serverInfo) (getServerName serverInfo)
(getDatabase serverInfo).Create()
serverInfo
/// <summary>Runs a sql script on the server.</summary>
/// <param name="serverInfo">Used as a connection to the database.</param>
/// <param name="sqlFile">The script which will be run.</param>
let runScript serverInfo sqlFile =
logfn "Executing script %s" sqlFile
sqlFile
|> StringHelper.ReadFileAsString
|> (getDatabase serverInfo).ExecuteNonQuery
/// Closes the connection to the server
let Disconnect serverInfo =
logfn "Disconnecting from server %s." (getServerName serverInfo)
if serverInfo.Server = null then
failwith "Server is not configured"
if serverInfo.Server.ConnectionContext = null then
failwith "Server.ConnectionContext is not configured"
serverInfo.Server.ConnectionContext.Disconnect()
/// Replaces the database files
let internal replaceDatabaseFiles connectionString attachOptions copyF =
connectionString
|> getServerInfo
|> fun si -> if existDBOnServer si (getDBName si) then Detach si else si
|> fun si -> copyF() |> Attach si attachOptions
|> Disconnect
/// Replaces the database files
let ReplaceDatabaseFiles connectionString targetDir files attachOptions =
replaceDatabaseFiles connectionString attachOptions
(fun _ ->
files
|> Seq.map (fun fileName ->
let fi = new FileInfo(fileName)
CopyFile targetDir fileName
targetDir @@ fi.Name))
/// <summary>Replaces the database files from a cache.
/// If the files in the cache are not up to date, they will be refreshed.</summary>
/// <param name="connectionString">Used to open the connection to the database.</param>
/// <param name="targetDir">The directory where the attached files will live.</param>
/// <param name="cacheDir">The file cache. If the files in the cache are not up to date, they will be refreshed.</param>
/// <param name="files">The original database files.</param>
/// <param name="attachOptions">AttachOptions for Sql server.</param>
let ReplaceDatabaseFilesWithCache connectionString targetDir cacheDir files attachOptions =
replaceDatabaseFiles connectionString attachOptions
(fun _ -> CopyCached targetDir cacheDir files)
/// <summary>Drops and creates the database (dropped if db exists. created nonetheless)</summary>
/// <param name="connectionString">Used to open the connection to the database.</param>
let DropAndCreateDatabase connectionString =
connectionString
|> getServerInfo
|> DropDb
|> CreateDb
|> Disconnect
/// <summary>Runs the given sql scripts on the server.</summary>
/// <param name="connectionString">Used to open the connection to the database.</param>
/// <param name="scripts">The scripts which will be run.</param>
let RunScripts connectionString scripts =
let serverInfo = getServerInfo connectionString
scripts |> Seq.iter (runScript serverInfo)
Disconnect serverInfo
/// <summary>Runs all sql scripts from the given directory on the server.</summary>
/// <param name="connectionString">Used to open the connection to the database.</param>
/// <param name="scriptDirectory">All *.sql files inside this directory and all subdirectories will be run.</param>
let RunScriptsFromDirectory connectionString scriptDirectory =
Directory.GetFiles(scriptDirectory, "*.sql", SearchOption.AllDirectories)
|> RunScripts connectionString