Comment Commands

Dodeca comments are stored per tenant, addressed by a set of key/value pairs (their "intersection"). These commands find, update, delete, copy, and clean up comments using a shared key-specification syntax for matching an intersection.

Find Comments

Find and list comments in the current tenant:

dshell/SAMPLE:>find-comments

The listing includes each matching comment’s ID, key/value address, author, text, and last-updated date.

Narrow the results with --include-key-spec, a comma-separated list of Key=Value pairs the comment’s address must satisfy:

dshell/SAMPLE:>find-comments --include-key-spec "Market=New York"

Omit the value to match any value for a key, or omit the key to match any key with a given value:

dshell/SAMPLE:>find-comments --include-key-spec "Market="
dshell/SAMPLE:>find-comments --include-key-spec "=West"

Combine multiple pairs to require all of them:

dshell/SAMPLE:>find-comments --include-key-spec "Market=West,Measures=Sales"

Add --partial-address to match comments whose address only partially satisfies the key spec, and --after/--before to further restrict by last-updated date.

Update Comments

Add, update, or remove keys on the address of matching comments. --include-key-spec selects which comments to update (same syntax as find-comments), --update-key-spec gives the keys to add or update, and --remove-key-spec gives a comma-separated list of keys to remove from the address:

dshell/SAMPLE:>update-comments --include-key-spec "Time=Feb" --update-key-spec "Year=FY2021"
dshell/SAMPLE:>update-comments --include-key-spec "Time=Feb" --remove-key-spec Scenario,Year

--partial-address behaves the same as it does for find-comments.

Delete Comments

Delete comments matching a key spec (same --include-key-spec/--partial-address/--after/--before filters as find-comments, plus --comment-id to target a single comment by ID). The matching comments are only deleted if --confirm is also given; otherwise the command reports how many comments matched and does not delete anything:

dshell/SAMPLE:>delete-comments --include-key-spec "Time=Feb"
dshell/SAMPLE:>delete-comments --include-key-spec "Time=Feb" --confirm

Copy Comments

copy-comments copies matching comments, optionally changing their address or author, and optionally into a different tenant. --include-key-spec and --exclude-key-spec select which comments to copy (comments must match the include spec and must not match the exclude spec); --author further restricts to comments created by a given author.

Copy comments and add a new key to their address:

dshell/SAMPLE:>copy-comments --include-key-spec "Scenario=Variance" --add-key-spec Time=Mar

Copy comments and remove one or more keys from their address (comma-separated):

dshell/SAMPLE:>copy-comments --include-key-spec "Scenario=Variance" --remove-key-spec Scenario,Market

Combine include and exclude specs, and set a new author on the copies:

dshell/SAMPLE:>copy-comments --include-key-spec "Time=Jan,Market=West Seattle" --exclude-key-spec "Time=Feb" --add-key-spec Year=FY2021 --new-author "Tim Tow"

Quote a key spec whenever a value contains a space or the spec has multiple comma-separated pairs. Use --tenant to copy the matching comments into a different tenant instead of the current one:

dshell/SAMPLE:>copy-comments --include-key-spec "Scenario=Variance" --tenant OTHERTENANT

Copying within the same tenant requires either a --remove-key-spec/--add-key-spec change or a different --tenant; a same-tenant copy with no address change is refused to avoid creating exact duplicates.

Zap Gremlins

Scan every comment in the current tenant for invalid Unicode characters and clean them up:

dshell/SAMPLE:>zap-gremlins

Add --dry-run to only report how many comments would be affected without saving changes, and --fetch-size (default 1000) to control the JDBC fetch size used while scanning.

Import Comments

There is no comment-specific export command. To move comments between repositories or tenants, use export-tenant to produce a full tenant export file (comments included among other tenant content), then use import-comments to import only the comments from that file into the current tenant:

dshell/SAMPLE:>import-comments --file tenant-export.xml

import-comments is equivalent to import-tenant with only comments enabled. See Tenants for export-tenant/import-tenant.

Updating Comment Addresses

This workflow shows how to update existing comment addresses in a Dodeca repository. Because comment updates can affect many rows, the example first exports a tenant and imports it into an in-memory repository so the changes can be tested before they are applied to the target repository.

Connect to an existing Dodeca repository:

dshell/:>connect local-dodeca-server

Validate the connection by listing the detected tenants:

dshell/:>list-tenants
+---------------------------+
|Tenant                     |
+---------------------------+
|SAMPLE                     |
|STARTER_KIT                |
|___DODECA_SERVER_LICENSE___|
+---------------------------+

Switch to the SAMPLE tenant:

dshell/:>use SAMPLE
dshell/SAMPLE:>

Export the tenant. The default export-tenant command includes comments:

dshell/SAMPLE:>export-tenant

This creates SAMPLE.zip in the current directory. Create a new in-memory Dodeca repository to test the comment modifications:

dshell/SAMPLE:>inmem

A new repository, including all Dodeca tables, is created in memory. It is lost when Dodeca Shell exits. This provides a simple place to test changes. Verify that the in-memory repository has no tenants:

dshell/SAMPLE:>list-tenants

The result should be empty:

dshell/:>list-tenants
+------+
|Tenant|
+------+

dshell/:>

Set the active tenant to SAMPLE. Use --force because the tenant does not exist yet in the in-memory repository:

dshell/SAMPLE:>use SAMPLE --force

Import the tenant export created earlier:

dshell/SAMPLE:>import-tenant SAMPLE.zip

Use find-comments to inspect the comments in the repository. For repositories with many comments, this command can generate a large amount of output:

dshell/SAMPLE:>find-comments
+------+-------------------+-----------------------------------------------+-------------------+
|Author|Keys               |Comment                                        |Created            |
+------+-------------------+-----------------------------------------------+-------------------+
|system|Entity: Entity1    |This is a comment for Scenario2/Period4/Entity1|2021-02-04T20:02:14|
|      |Period: Period4    |                                               |                   |
|      |Scenario: Scenario2|                                               |                   |
|system|Entity: Entity2    |This is a comment for Scenario2/Period4/Entity2|2021-02-04T20:02:14|
|      |Period: Period4    |                                               |                   |
|      |Scenario: Scenario2|                                               |                   |
|system|Entity: Entity0    |This is a comment for Scenario9/Period3/Entity0|2021-02-04T20:02:14|
|      |Period: Period3    |                                               |                   |
|      |Scenario: Scenario9|                                               |                   |

... omitted for brevity ...

|system|Entity: Entity1    |This is a comment for Scenario2/Period1/Entity1|2021-02-04T20:02:14|
|      |Period: Period1    |                                               |                   |
|      |Scenario: Scenario2|                                               |                   |
+------+-------------------+-----------------------------------------------+-------------------+

Use find-comments to look for comments at a particular intersection:

dshell/SAMPLE:>find-comments --include-key-spec "Scenario=Scenario2"
+------+----+-------+-------+
|Author|Keys|Comment|Created|
+------+----+-------+-------+

Comments: 0

No comments are found because no comment has an address that consists only of Scenario=Scenario2. To search by a partial address, add --partial-address:

dshell/SAMPLE:>find-comments --include-key-spec "Scenario=Scenario2" --partial-address
+------+-------------------+-----------------------------------------------+-------------------+
|Author|Keys               |Comment                                        |Created            |
+------+-------------------+-----------------------------------------------+-------------------+
|system|Entity: Entity1    |This is a comment for Scenario2/Period4/Entity1|2021-02-04T20:02:14|
|      |Period: Period4    |                                               |                   |
|      |Scenario: Scenario2|                                               |                   |
|system|Entity: Entity2    |This is a comment for Scenario2/Period4/Entity2|2021-02-04T20:02:14|
|      |Period: Period4    |                                               |                   |
|      |Scenario: Scenario2|                                               |                   |

... omitted for brevity ...

|system|Entity: Entity1    |This is a comment for Scenario2/Period1/Entity1|2021-02-04T20:02:14|
|      |Period: Period1    |                                               |                   |
|      |Scenario: Scenario2|                                               |                   |
+------+-------------------+-----------------------------------------------+-------------------+

Comments: 15

After the test data is loaded and the target comments are identified, use update-comments. This command updates all comments whose address includes Scenario=Scenario2, changing the Scenario value to Budget:

dshell/SAMPLE:>update-comments --include-key-spec "Scenario=Scenario2" --partial-address --update-key-spec "Scenario=Budget"

After the update, searching for the original partial address should return no comments:

dshell/SAMPLE:>find-comments --include-key-spec "Scenario=Scenario2" --partial-address
+------+----+-------+-------+
|Author|Keys|Comment|Created|
+------+----+-------+-------+

Comments: 0

Searching for the updated partial address should return the 15 updated comments:

dshell/SAMPLE:>find-comments --include-key-spec "Scenario=Budget" --partial-address
+------+----------------+-----------------------------------------------+-------------------+
|Author|Keys            |Comment                                        |Created            |
+------+----------------+-----------------------------------------------+-------------------+
|system|Entity: Entity1 |This is a comment for Scenario2/Period4/Entity1|2021-02-04T20:02:14|
|      |Period: Period4 |                                               |                   |
|      |Scenario: Budget|                                               |                   |
|system|Entity: Entity2 |This is a comment for Scenario2/Period4/Entity2|2021-02-04T20:02:14|
|      |Period: Period4 |                                               |                   |
|      |Scenario: Budget|                                               |                   |

... omitted for brevity ...

|system|Entity: Entity1 |This is a comment for Scenario2/Period1/Entity1|2021-02-04T20:02:14|
|      |Period: Period1 |                                               |                   |
|      |Scenario: Budget|                                               |                   |
+------+----------------+-----------------------------------------------+-------------------+

Comments: 15

The include key specification is optional. If it is omitted, every comment in the repository is affected:

dshell/SAMPLE:>update-comments --update-key-spec "Foo=Bar"
dshell/SAMPLE:>find-comments
+------+-------------------+-----------------------------------------------+-------------------+
|Author|Keys               |Comment                                        |Created            |
+------+-------------------+-----------------------------------------------+-------------------+
|system|Entity: Entity1    |This is a comment for Scenario2/Period4/Entity1|2021-02-04T20:02:14|
|      |Foo: Bar           |                                               |                   |
|      |Period: Period4    |                                               |                   |
|      |Scenario: Scenario2|                                               |                   |
|system|Entity: Entity2    |This is a comment for Scenario2/Period4/Entity2|2021-02-04T20:02:14|
|      |Foo: Bar           |                                               |                   |
|      |Period: Period4    |                                               |                   |
|      |Scenario: Scenario2|

...

Use --remove-key-spec to remove keys from comment addresses. This variation removes the Foo key that was added to every comment in the previous example:

dshell/SAMPLE:>update-comments --remove-key-spec "Foo"
dshell/SAMPLE:>find-comments
+------+-------------------+-----------------------------------------------+-------------------+
|Author|Keys               |Comment                                        |Created            |
+------+-------------------+-----------------------------------------------+-------------------+
|system|Entity: Entity1    |This is a comment for Scenario2/Period4/Entity1|2021-02-04T20:02:14|
|      |Period: Period4    |                                               |                   |
|      |Scenario: Scenario2|                                               |                   |
|system|Entity: Entity2    |This is a comment for Scenario2/Period4/Entity2|2021-02-04T20:02:14|
|      |Period: Period4    |                                               |                   |
|      |Scenario: Scenario2|                                               |                   |
|system|Entity: Entity0    |This is a comment for Scenario9/Period3/Entity0|2021-02-04T20:02:14|
|      |Period: Period3    |                                               |                   |
|      |Scenario: Scenario9|                                               |                   |

...

Run this command carefully because address changes can create comment intersection collisions. For example, removing a key can cause a comment to have the same address as an existing comment.

After testing the commands, either run the same commands while connected to the repository that should be modified, or export the updated comments and import them into the target repository and tenant.

To export only comments from the in-memory tenant, use export-tenant --exclude-artifacts:

dshell/SAMPLE:>export-tenant --exclude-artifacts

This is the same export-tenant command used earlier, but it excludes artifacts from the export.

After connecting to the repository where the comments should be updated, select the target tenant. This example imports to a new tenant named SAMPLE2:

dshell/SAMPLE2:>use SAMPLE2 --force

Import the comments:

dshell/SAMPLE2:>import-tenant SAMPLE.zip

Validate the updated comment addresses:

dshell/SAMPLE2:>find-comments
+------+-------------------+-----------------------------------------------+-------------------+
|Author|Keys               |Comment                                        |Created            |
+------+-------------------+-----------------------------------------------+-------------------+
|system|Entity: Entity1    |This is a comment for Scenario2/Period4/Entity1|2021-02-04T20:02:14|
|      |Period: Period4    |                                               |                   |
|      |Scenario: Budget   |                                               |                   |
|system|Entity: Entity2    |This is a comment for Scenario2/Period4/Entity2|2021-02-04T20:02:14|
|      |Period: Period4    |                                               |                   |
|      |Scenario: Budget   |                                               |                   |
|system|Entity: Entity0    |This is a comment for Scenario9/Period3/Entity0|2021-02-04T20:02:14|
|      |Period: Period3    |                                               |                   |
|      |Scenario: Scenario9|                                               |                   |

...