-
Notifications
You must be signed in to change notification settings - Fork 505
Expand file tree
/
Copy pathwriteDDL.R
More file actions
155 lines (126 loc) · 7.02 KB
/
Copy pathwriteDDL.R
File metadata and controls
155 lines (126 loc) · 7.02 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
# Copyright 2019 Observational Health Data Sciences and Informatics
#
# This file is part of DDLGeneratr
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#' Write DDL script
#'
#' Write the DDL to a SQL file. The SQL will be rendered (parameters replaced) and translated to the target SQL
#' dialect. By default the @cdmDatabaseSchema parameter is kept in the SQL file and needs to be replaced before
#' execution.
#'
#' @param targetDialect The dialect of the target database. Support dialects are specified by SqlRender::listSupportedDialects
#' @param cdmVersion The version of the CDM you are creating, e.g. 5.3, 5.4
#' @param outputfolder The directory or folder where the SQL file should be saved.
#' @param cdmDatabaseSchema The schema of the CDM instance where the DDL will be run. For example, this would be "ohdsi.dbo" when testing on sql server.
#' Defaults to "@cdmDatabaseSchema"
#' @return Writes SQL file with the OMOP CDM DDL for the specified CDM version and target dialect in the output folder.
#'
#' @export
writeDdl <- function(targetDialect, cdmVersion, outputfolder, cdmDatabaseSchema = "@cdmDatabaseSchema") {
# argument checks
stopifnot(targetDialect %in% listSupportedDialects())
stopifnot(cdmVersion %in% listSupportedVersions())
stopifnot(is.character(cdmDatabaseSchema))
if(missing(outputfolder)) {
outputfolder <- file.path("ddl", cdmVersion, gsub(" ", "_", targetDialect))
}
if(!dir.exists(outputfolder)) dir.create(outputfolder, showWarnings = FALSE, recursive = TRUE)
sql <- createDdl(cdmVersion)
sql <- SqlRender::render(sql = sql, cdmDatabaseSchema = cdmDatabaseSchema, targetDialect = targetDialect)
sql <- SqlRender::translate(sql, targetDialect = targetDialect)
# Post-processing: remove conditional markers and handle dialects
lines <- strsplit(sql, "\n")[[1]]
if (tolower(targetDialect) == "redshift") {
# For Redshift: remove conditional markers but keep the HINT lines
lines <- lines[!grepl("\\{#?if|\\{/if\\}", lines)]
} else {
# For non-Redshift: remove HINT directives and conditional markers
lines <- lines[!grepl("--HINT|\\{#?if|\\{/if\\}", lines)]
}
sql <- paste(lines, collapse = "\n")
filename <- paste("OMOPCDM", gsub(" ", "_", targetDialect), cdmVersion, "ddl.sql", sep = "_")
# Use writeLines instead of SqlRender::writeSql to avoid line wrapping that breaks SQL
writeLines(sql, con = file.path(outputfolder, filename))
invisible(filename)
}
#' @describeIn writeDdl writePrimaryKeys Write the SQL code that creates the primary keys to a file.
#' @return Writes a SQL file with the primary keys for the OMOP CDM based on the specified target dialect and CDM version.
#' @export
#'
writePrimaryKeys <- function(targetDialect, cdmVersion, outputfolder, cdmDatabaseSchema = "@cdmDatabaseSchema") {
# argument checks
stopifnot(targetDialect %in% listSupportedDialects())
stopifnot(cdmVersion %in% listSupportedVersions())
stopifnot(is.character(cdmDatabaseSchema))
if(missing(outputfolder)) {
outputfolder <- file.path("ddl", cdmVersion, gsub(" ", "_", targetDialect))
}
if(!dir.exists(outputfolder)) dir.create(outputfolder, showWarnings = FALSE, recursive = TRUE)
sql <- createPrimaryKeys(cdmVersion)
sql <- SqlRender::render(sql = sql, cdmDatabaseSchema = cdmDatabaseSchema, targetDialect = targetDialect)
sql <- SqlRender::translate(sql, targetDialect = targetDialect)
# Post-processing: remove any conditional markers that may have been added
lines <- strsplit(sql, "\n")[[1]]
lines <- lines[!grepl("\\{#?if|\\{/if\\}", lines)]
sql <- paste(lines, collapse = "\n")
filename <- paste("OMOPCDM", gsub(" ", "_", targetDialect), cdmVersion, "primary", "keys.sql", sep = "_")
# Use writeLines instead of SqlRender::writeSql to avoid line wrapping
writeLines(sql, con = file.path(outputfolder, filename))
invisible(filename)
}
#' @describeIn writeDdl writeForeignKeys Write the SQL code that creates the foreign keys to a file.
#' @return Writes a SQL file with the foreign keys for the OMOP CDM based on the specified target dialect and CDM version.
#' @export
writeForeignKeys <- function(targetDialect, cdmVersion, outputfolder, cdmDatabaseSchema = "@cdmDatabaseSchema") {
# argument checks
stopifnot(targetDialect %in% listSupportedDialects())
stopifnot(cdmVersion %in% listSupportedVersions())
stopifnot(is.character(cdmDatabaseSchema))
if(missing(outputfolder)) {
outputfolder <- file.path("ddl", cdmVersion, gsub(" ", "_", targetDialect))
}
if(!dir.exists(outputfolder)) dir.create(outputfolder, showWarnings = FALSE, recursive = TRUE)
sql <- createForeignKeys(cdmVersion)
sql <- SqlRender::render(sql = sql, cdmDatabaseSchema = cdmDatabaseSchema, targetDialect = targetDialect)
sql <- SqlRender::translate(sql, targetDialect = targetDialect)
# Post-processing: remove any conditional markers that may have been added
lines <- strsplit(sql, "\n")[[1]]
lines <- lines[!grepl("\\{#?if|\\{/if\\}", lines)]
sql <- paste(lines, collapse = "\n")
filename <- paste("OMOPCDM", gsub(" ", "_", targetDialect), cdmVersion, "constraints.sql", sep = "_")
# Use writeLines instead of SqlRender::writeSql to avoid line wrapping
writeLines(sql, con = file.path(outputfolder, filename))
invisible(filename)
}
#' @describeIn writeDdl writeIndex Write the rendered and translated sql that creates recommended indexes to a file.
#' @return Writes a SQL file with the indices for the OMOP CDM based on the specified target dialect and CDM version.
#' @export
writeIndex <- function(targetDialect, cdmVersion, outputfolder, cdmDatabaseSchema = "@cdmDatabaseSchema") {
# argument checks
stopifnot(targetDialect %in% listSupportedDialects())
stopifnot(cdmVersion %in% listSupportedVersions())
stopifnot(is.character(cdmDatabaseSchema))
if(missing(outputfolder)) {
outputfolder <- file.path("ddl", cdmVersion, gsub(" ", "_", targetDialect))
}
if(!dir.exists(outputfolder)) dir.create(outputfolder, showWarnings = FALSE, recursive = TRUE)
sqlFilename <- paste0("OMOP_CDM_indices_v", cdmVersion, ".sql")
sql <- readr::read_file(system.file(file.path("sql", "sql_server", sqlFilename), package = "CommonDataModel"))
sql <- SqlRender::render(sql, targetDialect = targetDialect, cdmDatabaseSchema = cdmDatabaseSchema)
sql <- SqlRender::translate(sql, targetDialect = targetDialect)
filename <- paste("OMOPCDM", gsub(" ", "_", targetDialect), cdmVersion, "indices.sql", sep = "_")
# Use writeLines instead of SqlRender::writeSql to avoid line wrapping
writeLines(sql, con = file.path(outputfolder, filename))
invisible(filename)
}