summaryrefslogtreecommitdiff
path: root/odb-tests/build/root.build
blob: 41f0556df8e390d8543bee4a1ca72ecda6572a91 (plain)
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
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
# file      : build/root.build
# license   : GNU GPL v2; see accompanying LICENSE file

cxx.std = latest

using cxx

hxx{*}: extension = hxx
ixx{*}: extension = ixx
txx{*}: extension = txx
cxx{*}: extension = cxx

define sql: file
sql{*}: extension = sql

define xml: file
xml{*}: extension = xml

skeleton = ($build.mode == 'skeleton')

# @@ TMP: remove once no longer used by libodb-<db>.
#
config [bool] config.odb_tests.develop ?= false

# List of the identifiers of the databases to compile and run the tests
# against. The valid identifiers are mysql, sqlite, pgsql, oracle, and mssql.
#
# Note: can be specified by the user but is also conditionally reflected by
#       the libodb-* libraries' tests manifest values.
#
config [string_set] config.odb_tests.database

databases = [strings] ($defined(config.odb_tests.database) \
                       ? $config.odb_tests.database        \
                       : )

assert ($skeleton || $size($databases) > 0) \
  'at least one database must be configured via config.odb_tests.database variable'

mysql  = false
sqlite = false
pgsql  = false
oracle = false
mssql  = false

for db: $databases
{
  switch $db
  {
    case 'mysql'
      mysql = true

    case 'sqlite'
      sqlite = true

    case 'pgsql'
      pgsql = true

    case 'oracle'
      oracle = true

    case 'mssql'
      mssql = true

    default
      fail "invalid database '$db' specified in config.odb_tests.database value"
  }
}

# If true, then build and run the test drivers in the dynamic multi-database
# mode.
#
# Note: do not assign the default value so that if it's not specified by the
# user, then it won't be saved into config.build. Failed that, if we need to
# reconfigure a single-database configuration into multi (or vise-versa), then
# we will have to (remember to) override the saved multi_database value
# explicitly.
#
config [bool, config.report.variable=multi] config.odb_tests.multi_database

multi = ($defined(config.odb_tests.multi_database) \
         ? $config.odb_tests.multi_database        \
         : $size($databases) > 1)

assert ($skeleton || $multi || $size($databases) == 1) \
  'only one database can be configured if config.odb_tests.multi_database value is false'

# If true, then this package is enabled as an external test for libodb library
# (see libodb's manifest for details).
#
# Note that this variable is not used in this package itself.
#
config [bool] config.odb_tests.libodb_test ?= false

# Database connections.
#

# PostgreSQL
#
# The database user. Note that the named user must be allowed to connect to
# the database server without specifying credentials.
#
config [string] config.odb_tests.pgsql.user ?= 'odb_test'

# The database name. Note that it WILL BE MODIFIED by the tests.
#
config [string] config.odb_tests.pgsql.database ?= 'odb_test'

# The database host or directory of Unix-domain socket. Leaving this variable
# undefined results in using Unix-domain sockets. Machines without Unix-domain
# sockets will connect to localhost.
#
config [string] config.odb_tests.pgsql.host

# The database port or the socket file name extension for Unix-domain
# connections.
#
# For example, specifying:
#
#   config.odb_tests.pgsql.host=/var/run/postgresql
#   config.odb_tests.pgsql.port=5433
#
# Will result in the /var/run/postgresql/.s.PGSQL.5433 socket being used.
#
config [string] config.odb_tests.pgsql.port

# If true, then assume that libodb-pgsql supports the bulk operations.
#
# Note: config.odb_tests.pgsql.bulk_default is reflected from manifest.
#
config [bool] config.odb_tests.pgsql.bulk_default ?= false
config [bool] config.odb_tests.pgsql.bulk ?= ($cxx.target.class != 'windows' && \
                                              $config.odb_tests.pgsql.bulk_default)
pgsql_bulk = $config.odb_tests.pgsql.bulk

# MySQL
#
# The database user.
#
config [string] config.odb_tests.mysql.user ?= 'odb_test'

# The database password.
#
config [string] config.odb_tests.mysql.passwd

# The database name. Note that it WILL BE MODIFIED by the tests.
#
config [string] config.odb_tests.mysql.database ?= 'odb_test'

# The database host.
#
config [string] config.odb_tests.mysql.host

# The database port.
#
config [uint64] config.odb_tests.mysql.port

# The database socket path.
#
config [path] config.odb_tests.mysql.socket

if! $skeleton
{
  if ($cxx.target.system == 'win32-msvc')
    cxx.poptions += -D_CRT_SECURE_NO_WARNINGS -D_SCL_SECURE_NO_WARNINGS

  switch $cxx.class
  {
    case 'gcc'
    {
      cxx.coptions += -Wno-unknown-pragmas
    }
    case 'msvc'
    {
      cxx.coptions += /wd4068 /wd4251 /wd4275 /wd4800
    }
  }

  # Import odb that we are testing.
  #
  import! [metadata] odb = odb%exe{odb}

  # Import the mysql client for creating the database schemas, etc.
  #
  if $mysql
  {
    import! mysql_client = mysql-client%exe{mysql}
    testscript{*}: mysql_client = $mysql_client
  }

  # Import the psql client for creating the database schemas, etc.
  #
  if $pgsql
  {
    import! pgsql_client = psql%exe{psql}
    testscript{*}: pgsql_client = $pgsql_client
  }

  # Notes:
  #
  # - The second prerequisite ($<[1]) is expected to be a metadata library
  #   target which we will use to extract the poptions variable value for
  #   specifying the contained options on the ODB compiler command line.
  #
  # - The additional options for the ODB compiler command line must be
  #   specified via the odb_options variable.
  #
  # - If the pre/post-migration SQL files are being generated, then the
  #   version numbers the object model is being migrated through must be
  #   specified via the schema_versions variable in the NNN form (001 002,
  #   etc; see the implementation for details).
  #
  # Also note that we need ((-.+)?) instead of just (-.+)? because we use this
  # capture as a back-reference in the pattern.
  #
  [rule_name=odb_compile]                                     \
  <hxx{~'/(.+)-odb((-.+)?)/'}                                 \
   ixx{~'/\1-odb\2/'}                                         \
   cxx{~'/\1-odb\2/'}>: hxx{~'/\1/'} libue{~'/.+-meta/'} $odb
  {{
    pops = $cxx.lib_poptions($<[1])
    depdb hash $pops

    hp = $path($>[0])
    bn = $base($leaf($hp))
    db = $regex.replace($bn, '.+-odb(-(.+))?', '\2')

    if ($db == '') # *-odb.?xx target group?
      db = ($multi ? 'common' : $databases[0])
    end

    # If the external SQL schema file will be generated, then add it as a
    # dynamic target group member.
    #
    # @@ BUILD2 Probably we should add support for --generate-dep ODB compiler
    # option. Then presumably this will be take care of automatically.
    #
    # We assume that the '--generate-schema' and '--schema-format' strings
    # will never appear as standalone option values.
    #
    if ($db != 'common' && $regex.find_match($odb_options, '--generate-schema'))
      schema_format = ($db == 'sqlite' ? 'embedded' : 'sql')

      for o: $odb_options
        if ($o == '--schema-format')
          schema_format = [null] # Indicate that the schema format comes next.
        elif ($schema_format == [null])
          schema_format = $o
        end
      end
    else
      schema_format = ''
    end

    ts = ($schema_format == 'sql'                                               \
          ? "$directory($hp)/$regex.replace($bn, '(.+)-odb(-.+)?', '\1\2').sql" \
          : '')

    # If the object model change log and/or migration SQL files will be
    # generated, then add them as a dynamic target group member.
    #
    changelog = ''
    init_changelog = false
    suppress_migration = false

    for o: $odb_options
      if ($o == '--changelog')
        changelog = [null] # Indicate that the changelog path comes next.
      elif ($changelog == [null])
        changelog = $o
      elif ($o == '--init-changelog')
        init_changelog = true
      elif ($o == '--suppress-migration')
        suppress_migration = true
      end
    end

    if ($changelog != '')
      if ($init_changelog)
        ts = ($ts == '' ? "$changelog" : "$ts$\n$changelog")
      end

      if ($schema_format == 'sql' && !$suppress_migration)
        n = $base($leaf($path($<[0])))

        # Note that it's not easy to deduce the object model migration files
        # list. Thus, we expect the version numbers the object model is being
        # migrated through to be explicitly specified via the schema_versions
        # variable.
        #
        for v: $schema_versions
          ns = "$out_base/$n-$v-pre.sql$\n$out_base/$n-$v-post.sql"
          ts = ($ts == '' ? "$ns" : "$ts$\n$ns")
        end
      end
    end

    depdb dyndep --dyn-target --target-what 'generated schema' --format lines \
    -- echo "$ts"

    $odb --std c++11                            \
         ($multi ? --multi-database dynamic : ) \
         --database $db                         \
         --output-dir $out_base                 \
         $odb_options                           \
         "-I$src_base"                          \
         $pops                                  \
         $path($<[0])
  }}

  # Every exe{} in this project is by default a test.
  #
  exe{*}: test = true

  # Specify the test target for cross-testing.
  #
  test.target = $cxx.target
}

# The helper targets which can be used as prerequisites of test drivers
# which require either a specific database client or multiple clients for
# all the enabled databases.
#
alias{mysql-client}: $mysql_client:
{
  include = $mysql
  clean = false
}

alias{pgsql-client}: $pgsql_client:
{
  include = $pgsql
  clean = false
}

alias{database-client}: alias{mysql-client pgsql-client}