# file      : build/root.build
# license   : not copyrighted - public domain

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')

# The identifier of the database to compile and run the examples 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' examples manifest values.
#
config [string] config.odb_examples.database

database = [string] ($defined(config.odb_examples.database) \
                     ? $config.odb_examples.database        \
                     : '')

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

switch $database
{
  case 'mysql'
    mysql = true

  case 'sqlite'
    sqlite = true

  case 'pgsql'
    pgsql = true

  case 'oracle'
    oracle = true

  case 'mssql'
    mssql = true

  case ''
    assert ($skeleton) \
      'database must be configured via config.odb_examples.database variable'

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

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

# If true, then build the boost/ example.
#
config [bool] config.odb_examples.boost ?= false

boost = $config.odb_examples.boost

# If defined, then, depending on the value, build the qt/ example against Qt6
# (6).
#
config [uint64] config.odb_examples.qt

qt = $defined(config.odb_examples.qt)

if $qt
{
  qt_ver = $config.odb_examples.qt

  assert ($qt_ver == 6) \
    'config.odb_examples.qt value must be 6'
}

# Database connections.
#

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

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

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

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

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

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

# 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_examples.pgsql.user ?= 'odb_test'

# The database name. Note that it WILL BE MODIFIED by the examples.
#
config [string] config.odb_examples.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_examples.pgsql.host

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

# Oracle
#
# The database user.
#
config [string] config.odb_examples.oracle.user ?= 'odb_test'

# The database password.
#
config [string] config.odb_examples.oracle.passwd

# The database host.
#
config [string] config.odb_examples.oracle.host

# The database port.
#
config [uint64] config.odb_examples.oracle.port

# The service name. Note that the database associated with this user on this
# service WILL BE MODIFIED by the examples.
#
config [string] config.odb_examples.oracle.service

# Microsoft SQL Server
#
# The database user.
#
config [string] config.odb_examples.mssql.user ?= 'odb_test'

# The database password.
#
config [string] config.odb_examples.mssql.passwd

# The database name. Note that it WILL BE MODIFIED by the examples.
#
config [string] config.odb_examples.mssql.database ?= 'odb_test'

# The database host.
#
config [string] config.odb_examples.mssql.host

# The database port.
#
config [uint64] config.odb_examples.mssql.port

# The SQL Server instance address.
#
# Note: mutually exclusive with config.odb_examples.mssql.{host,port}.
#
config [string] config.odb_examples.mssql.server

assert (!$defined(config.odb_examples.mssql.server) || \
        !$defined(config.odb_examples.mssql.host))     \
  'variables config.odb_examples.mssql.server and config.odb_examples.mssql.host cannot be specified both'

assert (!$defined(config.odb_examples.mssql.server) || \
        !$defined(config.odb_examples.mssql.port))     \
  'variables config.odb_examples.mssql.server and config.odb_examples.mssql.port cannot be specified both'

# The SQL Server ODBC Driver.
#
config [string, null] config.odb_examples.mssql.driver

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 using.
  #
  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.
  #
  elif $pgsql
  {
    import! pgsql_client = psql%exe{psql}
    testscript{*}: pgsql_client = $pgsql_client
  }
  #
  # Import the sqlplus client for creating the database schemas, etc.
  #
  # Note: expected to be system-installed.
  #
  elif $oracle
  {
    import! oracle_client = sqlplus%exe{sqlplus}
    testscript{*}: oracle_client = $oracle_client
  }
  #
  # Import the sqlcmd client for creating the database schemas, etc.
  #
  # Note: expected to be system-installed.
  #
  elif $mssql
  {
    import! mssql_client = sqlcmd%exe{sqlcmd}
    testscript{*}: mssql_client = $mssql_client
  }

  # 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}
