Manifold Commander

Manifold Universal and Manifold Server editions include Manifold Commander, a console application version of Manifold that provides the full range of Manifold query and scripting capabilities from a command line,  making it easy to automate GIS, DBMS, and ETL tasks.

 

Commander is provided as a manifoldcmd.exe executable file within the Manifold installation hierarchy.  The manifoldcmd.exe executable file launches from a command line such as in a Windows Command Prompt window, or in a .bat batch file, from within Windows Task Manager, or from a Windows PowerShell script and so on.  Commander can run either queries or scripts from within a specified .map file, and Commander also can run scripts from a specified script file stored outside a Manifold project.

 

Using queries or scripts we can use Commander to automate tasks using the full power of Manifold, for example:

 

 

A single Manifold query component can contain many SQL queries to be executed in turn, so SQL can be used for an arbitrarily long and complex sequence of transformations.  Scripts can be written in any of the ten programming languages Manifold supports, for endless variety in programming logic.

Syntax

When launching Commander from a command line, the following syntax applies.

 

manifoldcmd <command> [<options>] [<file>]

 

File names or paths that use spaces should be wrapped with double quote " characters.    The <file> can appear first in the arguments with <commands> and <options> coming later.

Commands and Options

Default values are used for any options not explicitly specified.

 

Commands

 

-export:xxx

Open the .map file in read-only mode and export the component specified to the output file specified by the argument to the -out option.  The component can be in a nested data source.  Supported options:
  

-logfilter:xxx

-logfolder:xxx

-out:xxx

 

The .map file used is always opened in read-only mode, regardless of any other mode specified if the -open:xxx option is included in the command line.

 

Suppose we have a .map project called world.map that contains a map component called Main Map.   The command line:

 

manifoldcmd "c:\world.map" -export:"Main Map" -out:"c:\world_map.gdb"

 

will launch Commander to open the world.map project and to export the Main Map component to an Esri file geodatabase folder called world_map.gdb.  

 

-runquery:xxx

Open the file and run the specified query component.  The component can be in a nested data source.  Supported options:
 

-logfilter:xxx

-logfolder:xxx

-open:xxx

-out:xxx

 

Suppose we have a .map project called County roads.map that contains an SQL query called make buffers, which takes a drawing layer in the project and creates buffers for the objects in that drawing.  The command line:

 

manifoldcmd "County roads.map" -runquery:"make buffers" -out:"buffers.gpkg"

 

will launch Commander to open the County roads.map project and to run the make buffers query within the project, and will write out the result table to a GPKG file called buffers.gpkg.

 

-runqueryfile:xxx

Same as the -runquery command, but the SQL text of the query is taken from the specified file instead of from a query component in the .map project. Supported options:
  

-logfilter:xxx

-logfolder:xxx

-open:xxx

-out:xxx

 

Suppose we have a .map project called County roads.map and we also have a text file called buffers.txt that contains an SQL query.  The query takes a drawing layer in the project and creates buffers for the objects in that drawing.  The command line:

 

manifoldcmd "County roads.map" -runquery:"buffers.txt" -out:"buffers.gpkg"

 

will launch Commander to open the County roads.map project and to open the buffers.txt file, running the SQL in the buffers.txt file as though it was a  query within the project, and will write out the result table to a GPKG file called buffers.gpkg.

-runquerytext:xxx

Same as the -runquery command, but the SQL text of the query is taken directly from the command line as specified by the command.  from the specified file instead of from a query component in the .map project.  Supported options:
  

-logfilter:xxx

-logfolder:xxx

-open:xxx

-out:xxx

 

Suppose we have a .map project called data.map.  The command line:

 

manifoldcmd data.map -runquerytext:"SELECT * FROM blocks WHERE state='CA'" -out:out.jsonl

 

will launch Commander to open the data.map project and will run the SQL with double " quotes as though it was a  query within the project, and will write out the result table to a JSONL file called out.jsonl.

-runscript:xxx

Open the file and run the specified script component.  The component can be in a nested data source.   Supported options:
 

-logfilter:xxx

-logfolder:xxx

-open:xxx

-runscriptfile:xxx

Run the specified script file.  Supported options:
 

-logfilter:xxx

-logfolder:xxx

 

The -runscriptfile command can work in the context of the .map file used as the <file> argument for the manifoldcmd command line.  Commander will open the .map file and then run the script from the specified script file.

 

For example, the fixlayouts.cs C# script published in the user forum adjusts legacy layout text frame vertical alignment to the center setting used for text frames in current Manifold builds.   It can be imported into a project and run, or run as an addin or run using Commander from a command line.  If layouts.map is a project file with the layout to be converted, we can launch the following command line:

 

manifoldcmd layouts.map -open:readwritesave -runscriptfile:fixlayouts.cs

 

A similar use of -runscriptfile appears in the batch file example near the end of this topic.

 

Options

 

-logfilter:min

Skip dates and prefixes when logging to console

-logfilter:minscript

Skip dates and prefixes, skip non-error non-script messages when logging to console, useful to limit output for further processing with command-line tools

-logfilter:none

Log full data to console (default)

-logfolder:xxx

Folder for log files

-open:readonly

Open file in read-only mode (default)

-open:readwrite

Open file in read-write mode

-open:readwritesave

Open file in read-write mode, save file after operation completes, this includes saving all nested data sources

-out:xxx

Output file.  The output file type is determined by the file extension, such as .csv, .json, .map, .sqlite, etc., that is used.

 

Syntax Examples

A .map project called Mexico.map contains a query called MexQuery that from a linked table generates a result table of all provinces in Mexico with a population greater than 3000000.  To run the query and save the result to a CSV file called Mex.csv:

 

manifoldcmd "C:\Projects\Mexico.map" -runquery:MexQuery -out:"C:\Projects\Mex.csv"

 

Save the result to a SQLite file called Mex.sqlite:

 

manifoldcmd "C:\Projects\Mexico.map" -runquery:MexQuery -out:"C:\Projects\Mex.sqlite"

 

Save the result to a Manifold .map file called Mex.map:

 

manifoldcmd "C:\Projects\Mexico.map" -runquery:MexQuery -out:"C:\Projects\Mex.map"

 

Save the result to an Esri file geodatabase within a folder hierarchy C:\Projects\Mex\gdb.gdb\ and create the Mex and gdb.gdb sub-folders:

 

manifoldcmd "C:\Projects\Mexico.map" -runquery:MexQuery -out:"C:\Projects\Mex\gdb"

 

Double-quotes around arguments like the names of files are not necessary if there are no spaces in the argument.   If the output file already exists, the above will overwrite it with the new version.

 

Some users prefer to name the file being used as the first argument, while others prefer to name the file as the last argument.  

Example

This example solves a problem for a business organization that needs to publish a .csv file every day that provides a table of the ten most recent invoices contained in the organization's PostgreSQL database.    Different groups within the organization can connect to that .csv file to get the list of recent invoices.

 

We create a Manifold project saved as an invoices.map project file.  The project contains a data source that is a connection to the organization's PostgreSQL server.   The data source was created as described in the Connect to PostgreSQL topic.

 

 

The illustration above shows the Project pane for the invoices.map project.  It shows an expanded Postgres data source that is the data source for the PostgreSQL database.  Note that it contains a table called public.invoice.   That is a table with all invoices from the organization's order processing software.

 

The project also contains a query called ten_recent, which contains the following SQL:

 

SELECT * FROM [Postgres]::[public.invoice]

   ORDER BY [InvoiceDate] DESC FETCH 10;

 

The query is a tiny query that selects all fields from the public.invoice table inside the PostgreSQL database and fetches the ten most recent invoices by date.

 

Before using Commander with the above project, we close it.    If we want to use Commander on a project at the same time the project is open in an interactive session of Manifold, we must open it read-only in the Manifold interactive session and also use it read-only with Commander.

 

In the Manifold installation folder, we have added an update_csv.bat batch file:

 

 

In this example, the batch file is in the same folder as the manifoldcmd.exe Commander executable file it will launch.  That keeps things simple in terms of the executable being in the PATH used by the command line in the batch file.

 

We can open the batch file in Notepad to see what it contains:

 

 

It contains a single command line:

 

manifoldcmd -runquery:ten_recent -out:"C:\csv\recent.csv" "C:\Projects\invoices.map"

 

The command line launches the Commander executable, manifoldcmd.exe with the -runquery command using the ten_recent query from the invoices.map project.   It uses the -out option to put the result from the query into a CSV file called recent.csv.  

 

The command line uses double " quote characters around the file pathnames even though they are not necessary since there are no spaces in the path names.   It is good to get into the habit of using double quote characters to bracket file names just in case one day you forget to do so and the name includes a space.

 

 

Looking at the C:\csv folder we see it starts out empty.

 

When the batch file is run it creates a new .csv file in the folder.   We can run the batch file by double-clicking it, or it can be run from Windows Task Scheduler if we want to schedule it to run automatically early each morning.

 

 

A new recent.csv file appears in the specified folder.  

 

 

We can open the .csv file in Excel, or in Notepad, or, as shown above, imported as a table into a Manifold session.   It contains the ten most recent invoices from the public.invoice table ordered by the InvoiceDate field.

 

If we run the batch file again, it will overwrite the recent.csv file with the newer version.

Example

Commander can also run scripts that are outside of a .map project, running the script as if it were launched inside of a Manifold session.

 

Suppose we have a C# script stored in a file called c:\scripts\convert.cs that convert a TIFF file, c:\data\example.tif into a PNG file c:\data\converted.png.

 

The convert.cs file contains the following script:

// C#

using M = Manifold;

class Script

{

static Manifold.Context Manifold;

static void Main()

{

 M.Application app = Manifold.Application;

 using (M.Database db = app.CreateDatabaseForFile("c:\\data\\example.tif", true))

 db.ExportFile("example", "c:\\data\\converted.png");

 app.Log("Done");

}

}

 

The command line we can use, either from a command prompt or in a .bat batch file, is:

 

manifoldcmd -runscriptfile:"c:\scripts\convert.cs"

 

Running the above command line will convert the TIF file into a PNG file. Most applications, of course, will use a more elaborate script.  The above is a very simple example showing the basics.

Example

When vertical alignment for text styles in layouts was introduced as a new feature, old .map projects did not have that setting.  Vertical alignment by default was set to being centered in the frame for all new layouts, but old layouts would appear using top alignment for lack of having a vertical alignment property.  To update old layouts to the new default, a C# script called fixlayouts.cs was published which would go into each layout and frame in a project and explicitly set vertical alignment to centered for all frames with text that did not yet have a vertical alignment property.

 

The fixlayouts.cs script can be run by importing it into a project and then running it, or by placing the fixlayouts.cs script in the extras folder of a Manifold installation, where it will appear in the Tools - Add-ins - Extras command as an add-in that can be run.   An even better way to run the fixlayouts.cs script is to use Commander to run it on all .map projects in a folder hierarchy.  

 

That can easily be done by creating and running a batch file that uses standard Windows command line conventions to iterate through an entire folder hierarchy and to apply the Commander command line to each .map file that is found.    For example, we could create a fixlayouts.bat batch file that contains:

 

@echo off

 

setlocal

 

set mfdcmd="c:\manifold-9.0.177.4\manifoldcmd.exe"

set script="c:\data\fixlayouts.cs"

for /R "c:\projects" %%i IN (*.map) do %mfdcmd% %%i ^

 -runscriptfile:%script% -open:readwritesave -logfilter:min

 

endlocal

 

The above batch file assumes that the Manifold installation folder is c:\manifold-9.0.177.4, the script is in the c:\data folder, and that the projects we want to update are located in the c:\projects folder. Change those to the actual folders in use. The /R key makes the batch file search through subfolders of c:\projects to find all .map projects in subfolders.

 

Notes

Universal and Professional - Commander is limited to Universal and Server editions.  When launched on a machine activated with Professional edition, nothing happens.

 

Log files postfix - Commander log files use a -cmd postfix, to distinguish them from log files for other Manifold applications.

 

 

See Also

Queries

 

Scripts

 

SQL Functions