DBBUILD

DBBUILD adds one or more subsystems to a database, working from an AbaPerls SQL directory structure in SourceSafe or on disk. When building from disk, the structure is typically created by a previous invocation of DBBUILD with -noexec -get, as part of the two-step operation for installation at a customer site. You can also use DBBUILD to rebuilda subsystem already present in the database, by means of the -rebuild switch.

To get an overview of the process where DBBUILD fits in, see the page Life-cycle of a database.

Contents:
    Command-Line Syntax
    Current Directory when Building
    How DBBUILD Builds the Database
    Loading BCP Files
    Output from DBBUILD
    Help Tables

Command-Line Syntax

dbbuild {-database db [-Server server] [-User user] [-Password pwd] [-save file]}
        | -noexec
        [-config config-file | -VSS SS-path] [-subsystem subsys]
        [-label version] [-get | -use_disk]
        [-rebuild] [-log file] [-bcp [directory]] [-[no]insert] [-force]
        [-sptwice] [-tablesfirst]
        [-charset CP] [-[no]crypt] [-environment DEV | TEST | PROD]
        [-Macro &macro=value [...]] -site site-id] [-[no]subscriber]
        [-undef &macro [...]]

Thus, you must specify either of -database and -noexec, but you cannot specify both.

Database switches
-database Name of the database to build. Prior to invoking DBBUILD, you must have created the database with CREATE DATABASE. The database may be completely empty, save objects created by SQL Server, or it may contain one or more subsystems since previous builds.
-Server The server where the database resides. If you do not specify -Server, the local server is the default. The environment variable ABAPERLS_CTIMEOUT determines how log to wait for a connection. The default is 5 seconds.
   Note that if you specify the server instance by port number, you must enclose the server specifcation in quotes, for instance -S "127.0.0.1,2093".
-User
-Password
Which login and password to use with SQL authentication. If you leave out both username and password, AbaPerls will use Windows authentication. If you specify -password only, AbaPerls will login as sa. It's illegal to specify a user without a password. If you have a blank password, you need to change this before you can use AbaPerls.
   No matter if you use SQL authentication or Windows authentication, the login you use must map to a database user with dbo as the default schema, or AbaPerls will not let you proceed. Obviously, the user needs permission to perform all actions implied by AbaPerls and the files you load.
-save Use this option to save the generated SQL code to file in case you wish to review it. If you do not provide a file extension, DBBUILD adds .SQL. By default DBBUILD does not save any file.
   Do not use the saved SQL code to build another database, but always build your databases directly with DBBUILD. Two executions of DBBUILD typically generates different SQL code depending configuration options, whether other subsystems are present in the database, the version of SQL Server etc.
-noexec Specifies that DBBUILD is to get the files and run them through Preppis to get all required include files and compile C# and VB files, but not proceed with further steps in the AbaPerls file-loading process. You typically use -noexec together with -get to create kits for installation at customer sites.
   When you specify -noexec, you cannot specify -database, -Server, -Password or -save.
SourceSafe options
-config Instructs DBBUILD to build the database from the config-file you have specified. DBBUILD tacks on /SQL on the project specifications in the config-file and emits a warning for the projects in the config-file that do not have any SQL project.
   If there is no subsystem in the database, DBBUILD will use the configuration options in the config-file both on database level and on subsystem level. If there already is a subsystem in the database, DBBUILD will obey the options saved in the database for the database level, and ignore the database-level options in the config-file. DBBUILD will apply the configuration options in the config-file for the subsystem(s) that it adds.
   If the config-file includes a subsystem which is already present in the database, DBBUILD skips this subsystem, unless you specify -rebuild.
-VSS An SS-path for a singular SourceSafe project to build from. When you specify -VSS, you should normally specify the subsystem name with -subsystem, else the subsystem will be named NAMELESS. If there are other subsystems present in the database, specifying -subsystem with -VSS is mandatory.
-subsystem If you specify -subsystem together with -config, DBBUILD will only build the specified subsystem.
   Together with -VSS, -subsystem specifies the name of the subsystem you build. If you specify -VSS without -subsystem, DBBUILD will name the subsystem NAMELESS. You can only use this name in a database where there are no other subsystems.
-label Which version in SourceSafe that DBBUILD is to read from. For a config-file, this is a version, specified by version number, date or label, of the config-file, which in its turn determines which version of the projects to use, as described on the config-file page.
   For a singular project that you specify with -VSS, -label is a version number, date or label of that project. If the subsystem ABAPERLS is installed in the database, you must specify a label on the form LetterMajor.Middle.Minor.
-get With -get, DBBUILD creates, in the current directory, a directory for each subsystem it builds. In each subsystem directory, DBBUILD gets the files and places them in an AbaPerls SQL directory structure
   You typically use -get together with -noexec to create kits for installation at customer sites.
   You cannot use -get together with -use_disk. If you specify -get, you must also specify -config or -VSS.
-use_disk There are two uses for -use_disk. When you specify -VSS or -config, you can use -use_disk to instruct DBBUILD to apply all steps in the AbaPerls file-lookup order, and thus let local files override what is in SourceSafe. With -nouse_disk (the default with -VSS or -config), DBBUILD only looks in SourceSafe. -use_disk is handy when you want to test the effects of some changes that you do not want to check in, for instance removal of one or more columns in a table.
   When you specify neither of -VSS or -config, this implies -use_disk. You typically use this to build from a disk structure created with -get. In this case there is a file SUBSYSTEMS.LIS that DBBUILD uses to determine which files to load, as described on the page installation at a customer site.
Miscellaneous
-rebuild Reloads most of the objects in one more existing subsystem in a database. See below under How DBBUILD Builds the Database for the exact details on which objects that are reloaded.
   When you specify -rebuild, DBBUILD takes all configuration options from the config-file and replaces those already present in the database. The options in the database are discarded.
   If specify -rebuild together -subsystem to rebuild a single subsystem DBBUILD still uses the database-wide settings and only discards the settings for the specified subsystem. Settings for other subsystems and database-wide settings untouched.
   Note: with -rebuild, DBBUILD does not check the config-file against the database, and neither does it check whether the versions of the subsystem are correct, so you need to be careful when you use -rebuild. (This is not a feature, but a bug, and will eventually be corrected.)
-bcp Instructs DBBUILD to load BCP files from the specified directory. If you specify -bcp without any directory, DBBUILD will read the BCP files from the current directory. See further below under Loading BCP files about the format of the BCP files etc.
   For the subsystem ABAPERLS, DBBUILD ignores -bcp, but always loads the INSERT-files for ABAPERLS.
   You cannot specify -bcp with -noexec.
-[no]insert Whether DBBUILD should load INSERT-files or not. If you do not specify -insert, the default depends on the -bcp option. If you specify neither -insert, nor -bcp, DBBUILD will load INSERT-files, and you need to specify -noinsert if you for some reason do not want to load INSERT-files. If you specify -bcp but not -insert, DBBUILD will not load INSERT-files. Thus, if you want to load both BCP files and INSERT-files, you must specify -insert. (The INSERT-files are loaded after the BCP files, see below.)
   For the subsystem ABAPERLS, DBBUILD ignores the setting of -insert, and always loads the INSERT-files for this subsystem.
-log Name of log file for the build. If you do not specify -log, DBBUILD writes the log for the build to db.LOG. See below about the contents of the log file.
-force Specifies that if there is a conflict between the configuration options in the config-file, or those saved in the database, and the configuration options on the command-line, the command-line takes precedence. If you do not specify -force, and there is a conflict, DBBUILD will abort with an error message, and no file will be loaded.
   Only use -force when you really need to override the configuration saved in the database.
-sptwice Specifies that DBBUILD should run through the stored procedures in the SP directory twice. This is good on SQL 2005 and later, if you want complete dependency information in the database that you can review with sp_depends. (On earlier versions of SQL Server, -sptwice does not help, as dependency information are erased with ALTER PROCEDURE.)
-tablesfirst Instructs DBBUILD to use a build order, where all table and view definitions are loaded before any functions or stored procedures. This is useful if you find that you in practice refers to tables in higher subsystems in lower subsystems. (Something you probably should avoid.) For the exact details, see the section How DBBUILD builds the database below.
   You  cannot specify -tablesfirst with -noexec.
Configuration options
-Adefaults
-Anulls
-Apadding
-Aquoted
-charset -crypt
-environment

-Macro
-quoterepl
-site
-subscriber
-undef
These switches are configuration options. The setting of a configuration option is primarily taken from the config-file or the database according to the prededence rules for configuration options. If the config-file/database defines a setting for an option and you specify a different setting on the command-line, you must use -force to override.

Current Directory when Building

When you build from SourceSafe and specify -use_disk, your current directory must be one from which DBBUILD can find the files you want to load from disk, rather than from SourceSafe. One approach is to put all files you want load from outside SourceSafe in one directory and run DBBUILD from there. But beware that files that are in subdirectories with regards to the special directories in the AbaPerls SQL directory structure, must also be in subdirectories to the current directory. See the examples for the AbaPerls file-lookup order.

You could also have the files in the working directories that mirror the AbaPerls SQL directory structure in SourceSafe. In this case, while you could run DBBUILD from any directory in the structure, I recommend using the top directory or SCRIPTS. If you want to override files from different subsystems, you can create one directory for each subsystem (with the same name as the subsystem), and each such directory have an AbaPerls SQL directory structure where you place the files you want to override.

When you build from disk without using SourceSafe, your current directory should have on directory for each subsystem, and in each subsystem directory there should be an SQL directory under which there is an AbaPerls SQL directory structure. Be careful so that the path to the current directory does not include any of the directory names from the AbaPerls SQL directory structure, because in such case DBBUILD will assume that you are inside the structure – not above the top of another. If you are toying out an entirely new database, you may have not defined any subsystems, but you still need to use -subsystem to give the name of the directory above the SQL directory. Or call this directory NAMELESS which is the default for -subsystem.

When you build from SourceSafe without specifying -use_disk, the current directory can be whatever you like.

How DBBUILD Builds the Database

The first thing DBBUILD does, is to check whether there are any tables in the database (not counting the system tables of SQL Server). If DBBUILD finds no tables, DBBUILD removes all types, rules and defaults (created with CREATE DEFAULT) from the database, assuming that these are inherited from the model database. (And assuming that no one in his sane mind puts user tables in model.)

DBBUILD then determines which subsystems to build:

For each subsystem, DBBUILD determines which files to load in one of these ways:

Having determined the list of files to load, DBBUILD then proceeds to loads the files in this order: (Note that when we say "directory" this could also refer to a project in SourceSafe. And recall that all subdirectories are included.)

  1. A START row is written to the table abainstallhistory, or if does not exist in abainstallinfo (created if needed).
  2. DBBUILD loads the .SQL files in the MESSAGE directory.
  3. DBBUILD loads synonym files in the MESSAGE directory.
  4. DBBUILD loads the .ASSEM files in the ASSEMBLIES directory.
  5. DBBUILD loads the .XMLSC files in the TYPE directory.
  6. DBBUILD loads the .TYP files in the TYPE directory.
  7. DBBUILD loads the .TBLTYP files in the TYPE directory.
  8. DBBUILD loads the files TBL/*.TBL, including files that is in a sub-directory of TBL.)
  9. If there is any VIEW directory, DBBUILD runs the *.VIEW files there.
  10. DBBUILD loads the files in FUNCTIONS.
  11. DBBUILD loads the files in SP.
  12. If you specified -sptwice, DBBUILD loads the files in SP once more.
  13. DBBUILD loads triggers on tables in TBL/*.TRI.
  14. DBBUILD loads triggers on views in VIEW/*.VTRI.
  15. If you specified -bcp, DBBUILD loads BCP files as detailed under loading BCP files, below. (Not for ABAPERLS).
  16. If you specified -insert (which is the default unless you specified -bcp) or the subsystem is ABAPERLS, DBBUILD loads TBL/*.INS.
  17. DBBUILD loads indexes and statistics on tables in TBL/*.IX.
  18. DBBUILD loads indexes and statistics on views in VIEW/*.VIX.
  19. DBBUILD loads TBL/*.FKEY
  20. DBBUILD loads MESSAGE/*.POSTSQL.
  21. DBBUILD saves configuration options on database level.
  22. DBBUILD saves configuration options for the subsystem.
  23. DBBUILD writes a STOP row to abainstallhistory or abainstallinfo.

Within each group, the load order follows the sort order defined by the Windows regional settings on system level. (That is, if you as a user have Swedish regional settings, but the default setting on the machine is US-English, then DBBUILD will sort according to US-English. It's Perl that works this way, and AbaPerls can't but comply.) There are however a few deviations:

With the switch -rebuild you can rebuild a database, without affecting the data in the tables. In this case DBBUILD performs only steps 1, 3, 4, 9-14 and 16-23 above. That is, types and tables are not rebuilt, while synonyms, assemblies, views, functions, procedures, triggers, indexes, INSERT-files, and foreign keys are reloaded. Note that even if you specify -bcp with -rebuild, no BCP files will ever be loaded.

When you specify the switch -tablesfirst, DBBUILD traverses the subsystem in two rounds, and in the first round DBBUILD performs steps 1-9 and 21-23 only, and in the second round, DBBUILD performs steps 1, 8-21 only. (For the ABAPERLS subsystem, all steps are performed in the first round.)

Note: the build order makes some assumption how things refer to each other that are not always true. The most typical case is user-defined functions that may refer to tables and views, but tables and views may also refer to user-defined functions. With the build order of DBBUILD the creation of a table of a view fails if there is a reference to a user-defined function. A workaround is to include a $REQUIRE directive in the file that defines the table or view to have the function created before the table/view. (While off-topic for this manual, a word of caution for scalar user-defined functions: they almost always turn a query from being truly set-based to be iterative like a cursor. Thus, while you can use a scalar UDF in a constraint, it may have serious performance impacts.)

Loading BCP Files

If you specify a directory as argument to -bcp, DBBUILD reads BCP files from the current directory. That is, DBBUILD does not read the BCP files from the subsystem directories, but assumes that all files are in the same place. This is advantageous when you want to rebuild a database from scripts, for instance because you want to change the collation (sort order), or the database is corrupted. You can bulk out all data into one place, and do not need to sort the files per subsystem.

Note that AbaPerls system tables are never loaded through BCP, but will be repopulated with the objects and subsystems that are included in the build.

The files should be named table.BCP, that is the same name as the table, and with the file extension .BCP. DBBUILD attempts to load non-empty files named *.BCP that fits with the tables in the current subsystem. Empty BCP-files are merely noted in the build log.

DBBUILD determines the format of  the BCP files in this way:

  1. If there is a tbl.FMT, DBUILD will use this file as a format file. (Typically this file would have been generated by DOBCP).
  2. If DBBUILD can find the strings @!@ on the first line or the string <-> on the second line, DBBUILD will assume these command-line switches for BCP: -c -t@!@ -r"\n<->\n". (This is the character format used by DOBCP.)
  3. If neither applies, DBBUILD assumes native format.

Note that DBBUILD is not able to detect if the BCP file was generated with the -unicode option with DOBCP, but you must always use format files in this case.

Overall the use of format files is recommended. For instance, if you move data from one collation to another and use native format, you need to use format files to describe the BCP files correctly. (Note that sql_variant columns will retain their collation, since for them the collation is part of the data.)

DBBUILD runs BCP with a batch size of 1000, and uses the -E switch if required to maintain IDENTITY values.

DBBUILD runs BCP with the option -h "CHECK_CONSTRAINTS", meaning that all constraints for the table are checked when the data is loaded. Typically foreign keys will not be present when BCP runs, as DBBUILD loads them later. On the other hand, CHECK constraints are present if they appear in the .TBL file (which is the normal thing). If DBBUILD would load the files without the constraint checks, SQL Server would mark the constraints as "not trusted", and the optimizer would not ignore the constraints when building query plans, which in some cases can lead to less effecient plans.

There is one exception to this: if there are types with the name ending in _upduser, DBBUILD assumes that for each such type there is a rule bound to it that requires the value to be equal to SYSTEM_USER or similar. DBBUILD unbinds these rules prior to bulk-loading, assuming that then name of the rules is the type name with _rule tacked on to it. When DBBUILD has finished bulk-loading the subsystem, it rebinds the rules. If you use some other mechanish, for instance a constraint to enforce the value of an auditing column, I'm afraid that it's not going to work with DBBUILD.

Output from DBBUILD

DBBUILD produces two forms of output: it prints to the command-line window, and it produces a log file.

The output to the command-line window only serves the purpose of giving progress information. There is no need to monitor the output.

On the other hand, it is essential that you check the log file, because if a file produces errors when DBBUILD loads it, the errors are written to the log only. The log file includes a full list of files that DBBUILD has loaded.

First in the log file, you find a header which reports the user that run the script, when he did it and with which command-line options. For each subsystem, there is a header with the configuration options that DBBUILD used for that subsystem. DBBUILD reports only the configuration options that were set explicitly, by command-line switches, or settings read from the database.

For a database with a reasonable number of tables, the log becomes huge and tedious to read directly. To this end there is the command LISTERRS that extracts the interesting messages from the log as well as the header information.

Note: There is one category of messages that are only printed to the command-line window: warnings and errors from Perl itself. Such messages should not occur, and are likely to be indications of bugs in AbaPerls (or Perl). A Perl error is usually fatal and terminates DBBUILD.

Help Table

Even if you opt to not install the subsystem ABAPERLS in your database, DBBUILD one help tables: abainstallinfo. Older versions of DBBUILD also created ababuildaid in tempdb, but this has been dropped.

Abainstallinfo gives an installation history for the database, akin to the one in abainstallhistory, and is also maintained by the update scripts generated by DBUPDGEN. If you later opt to add the ABAPERLS subsystem to your database, abainstallinfo will be converted to abainstallhistory.