marklogic-community / roxy

Deployment tool for MarkLogic applications. Also provides optional unit test and XQuery MVC structure
Other
87 stars 66 forks source link

Support for temporal #847

Open grtjn opened 6 years ago

grtjn commented 6 years ago

Involves creating indexes (metadata fields?), temporal axis, and collection.

grtjn commented 6 years ago

Bit long, but this worked in app_specific:

  alias_method :original_bootstrap, :bootstrap

  def bootstrap
    original_bootstrap

    logger.info ""
    logger.info "Bootstrapping hidden metadata fields:"
    r = execute_query(
      %Q{
        xquery version "1.0-ml";

        import module namespace admin = "http://marklogic.com/xdmp/admin"
          at "/MarkLogic/admin.xqy";

        let $metadata-fields := (
          (: Temporal fields :)
          "validStart:dateTime",
          "validEnd:dateTime",
          "systemStart:dateTime",
          "systemEnd:dateTime",
          "temporalProtectLevel:string",
          "temporalProtectExTime:dateTime",
          "temporalArchivePaths:string"
        )
        let $config := admin:get-configuration()
        let $dbid := xdmp:database()
        let $fieldspecs :=
          for $field in $metadata-fields
          let $name := substring-before($field, ":")
          return
            admin:database-metadata-field($name)
        let $config := admin:database-add-field($config, $dbid, $fieldspecs)
        let $rangespecs :=
          for $field in $metadata-fields
          let $name := substring-before($field, ":")
          let $type := substring-after($field, ":")
          return
            admin:database-range-field-index($type,
              $name, "http://marklogic.com/collation/codepoint", fn:true() )
        let $config :=
          admin:database-add-range-field-index($config, $dbid, $rangespecs)
        let $_ :=
          admin:save-configuration($config)
        return $metadata-fields
      },
      { :app_name => @properties["ml.app-name"] }
    )
    r.body = parse_body r.body
    logger.info r.body
    logger.info ""

    logger.info "Bootstrapping temporal axes:"
    r = execute_query(
      %Q{
        xquery version "1.0-ml";
        declare namespace html = "http://www.w3.org/1999/xhtml";
        import module namespace temporal = "http://marklogic.com/xdmp/temporal" at "/MarkLogic/temporal.xqy";

        for $coll in ('uni-temporal', 'bi-temporal')
        return
          if (temporal:collections() = $coll) then
            temporal:collection-set-options($coll, "updates-admin-override")
          else ();

        xquery version "1.0-ml";

        for $coll in ('uni-temporal', 'bi-temporal')
        return
          xdmp:collection-delete($coll);

        xquery version "1.0-ml";
        declare namespace html = "http://www.w3.org/1999/xhtml";
        import module namespace temporal = "http://marklogic.com/xdmp/temporal" at "/MarkLogic/temporal.xqy";

        for $coll in ('uni-temporal', 'bi-temporal')
        return
          if (temporal:collections() = $coll) then
            temporal:collection-set-options($coll, "updates-safe")
          else ();

        xquery version "1.0-ml";
        import module namespace temporal = "http://marklogic.com/xdmp/temporal" 
             at "/MarkLogic/temporal.xqy";

        for $coll in ('uni-temporal', 'bi-temporal')
        return
          if (temporal:collections() = $coll) then
            temporal:collection-remove($coll)
          else ();

        xquery version "1.0-ml"; 
        import module namespace temporal = "http://marklogic.com/xdmp/temporal" 
            at "/MarkLogic/temporal.xqy";

        for $axis in ('valid', 'system')
        return
          if (temporal:axes() = $axis) then
            temporal:axis-remove($axis)
          else ();

        xquery version "1.0-ml"; 
        import module namespace temporal = "http://marklogic.com/xdmp/temporal" 
            at "/MarkLogic/temporal.xqy";

        temporal:axis-create(
            "valid",
            cts:field-reference("validStart", "type=dateTime"),
            cts:field-reference("validEnd", "type=dateTime")),
        temporal:axis-create(
            "system",
            cts:field-reference("systemStart", "type=dateTime"),
            cts:field-reference("systemEnd", "type=dateTime"))
      },
      { :app_name => @properties["ml.app-name"] }
    )
    r.body = parse_body r.body
    logger.info r.body
    logger.info ""

    logger.info "Bootstrapping temporal collections:"
    r = execute_query(
      %Q{
        xquery version "1.0-ml";
        import module namespace temporal = "http://marklogic.com/xdmp/temporal" 
             at "/MarkLogic/temporal.xqy";

        temporal:collection-create("bi-temporal", "system", "valid"),
        temporal:collection-create("uni-temporal", "system")
      },
      { :app_name => @properties["ml.app-name"] }
    )
    r.body = parse_body r.body
    logger.info r.body
    logger.info ""
  end
grtjn commented 6 years ago

Nothing needed for wipe if I recall correctly..

grtjn commented 6 years ago

834 covers the metadata fields part

rlouapre commented 6 years ago

Any plan to integrate it in Roxy?

grtjn commented 6 years ago

You asking for it is a good argument to do so.. :)

Pondering about how that should look like in terms of configs. Probably something that looks a little like how management rest api expects it I guess. Or close to SEC xml perhaps?