# Generated by `bundle exec rake schema_artifacts:dump`.
# DO NOT EDIT BY HAND. Any edits will be lost the next time the rake task is run.
---
index_templates: {}
indices:
  artists:
    aliases: {}
    mappings:
      dynamic: strict
      properties:
        id:
          type: keyword
        name:
          type: keyword
        lifetimeSales:
          type: long
        albums:
          properties:
            name:
              type: keyword
            releasedOn:
              type: date
              format: strict_date
          type: nested
        __counts:
          properties:
            albums:
              type: integer
        __sources:
          type: keyword
        __versions:
          type: object
          dynamic: 'false'
        __typename:
          type: constant_keyword
          value: Artist
    settings:
      index.mapping.ignore_malformed: false
      index.mapping.coerce: false
      index.number_of_replicas: 1
      index.number_of_shards: 1
      index.max_result_window: 10000
scripts:
  field_as_day_of_week_f2b5c7d9e8f75bf2457b52412bfb6537:
    context: field
    script:
      lang: painless
      source: |-
        // Check if required params are missing
        if (params.offset_ms == null) {
          throw new IllegalArgumentException("Missing required parameter: offset_ms");
        }
        if (params.time_zone == null) {
          throw new IllegalArgumentException("Missing required parameter: time_zone");
        }

        // Set variables used in the loop
        ZoneId zoneId = ZoneId.of(params.time_zone);
        List results = new ArrayList();

        for (ZonedDateTime timestamp : doc[params.field]) {
          // Convert the timestamp to the specified time zone
          ZonedDateTime zonedTimestamp = timestamp.withZoneSameInstant(zoneId);

          // Adjust the timestamp based on the offset_ms parameter
          ZonedDateTime adjustedTimestamp = zonedTimestamp.plus(params.offset_ms, ChronoUnit.MILLIS);

          // Format and add the result to the list
          results.add(adjustedTimestamp.getDayOfWeek().name());
        }

        return results;
  field_as_time_of_day_ed82aba44fc66bff5635bec4305c1c66:
    context: field
    script:
      lang: painless
      source: |-
        // Check if required params are missing
        if (params.offset_ms == null) {
          throw new IllegalArgumentException("Missing required parameter: offset_ms");
        }
        if (params.time_zone == null) {
          throw new IllegalArgumentException("Missing required parameter: time_zone");
        }
        if (params.interval == null) {
          throw new IllegalArgumentException("Missing required parameter: interval");
        }

        // Set variables used in the loop
        ZoneId zoneId = ZoneId.of(params.time_zone);
        ChronoUnit intervalUnit;
        if (params.interval == "hour") {
          intervalUnit = ChronoUnit.HOURS;
        } else if (params.interval == "minute") {
          intervalUnit = ChronoUnit.MINUTES;
        } else if (params.interval == "second") {
          intervalUnit = ChronoUnit.SECONDS;
        } else {
          throw new IllegalArgumentException("Invalid interval value: " + params.interval);
        }
        DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_TIME;
        List results = new ArrayList();

        for (ZonedDateTime timestamp : doc[params.field]) {
          // Convert the timestamp to the specified time zone
          ZonedDateTime zonedTimestamp = timestamp.withZoneSameInstant(zoneId);

          // Adjust the timestamp based on the offset_ms parameter
          ZonedDateTime adjustedTimestamp = zonedTimestamp.plus(params.offset_ms, ChronoUnit.MILLIS);

          // Truncate the timestamp to the specified interval
          adjustedTimestamp = adjustedTimestamp.truncatedTo(intervalUnit);

          // Format and add the result to the list
          results.add(adjustedTimestamp.format(formatter));
        }

        return results;
  filter_by_time_of_day_ea12d0561b24961789ab68ed38435612:
    context: filter
    script:
      lang: painless
      source: |-
        ZoneId zoneId = ZoneId.of(params.time_zone);

        for (ZonedDateTime timestamp : doc[params.field]) {
          long docValue = timestamp
            .withZoneSameInstant(zoneId)
            .toLocalTime()
            .toNanoOfDay();

          // Perform comparisons based on whichever params are set.
          // ElasticGraph takes care of passing us param values as nano-of-day so that we
          // can directly and efficiently compare against `docValue`.
          if ((params.gte == null || docValue >= params.gte) &&
              (params.gt == null || docValue > params.gt) &&
              (params.lte == null || docValue <= params.lte) &&
              (params.lt == null || docValue < params.lt) &&
              (params.equal_to_any_of == null || params.equal_to_any_of.contains(docValue))) {
            return true;
          }
        }

        // No timestamp values matched the params, so return `false`.
        return false;
  update_index_data_1fdfaf1c9261c96019decc89b515bd9a:
    context: update
    script:
      lang: painless
      source: |-
        Map source = ctx._source;
        String sourceId = params.sourceId;
        String relationship = params.relationship;

        // Numbers in JSON appear to be parsed as doubles, but we want the version stored as a long, so we need to cast it here.
        long eventVersion = (long) params.version;

        if (source.__sources == null) {
          source.__sources = [];
        }

        if (source.__versions == null) {
          source.__versions = [:];
        }

        if (source.__versions[relationship] == null) {
          source.__versions[relationship] = [:];
        }

        Map relationshipVersionsMap = source.__versions.get(relationship);
        List previousSourceIdsForRelationship = relationshipVersionsMap.keySet().stream().filter(id -> id != sourceId).collect(Collectors.toList());

        if (previousSourceIdsForRelationship.size() > 0) {
          String previousIdDescription = previousSourceIdsForRelationship.size() == 1 ? previousSourceIdsForRelationship.get(0) : previousSourceIdsForRelationship.toString();
          throw new IllegalArgumentException(
            "Cannot update document " + params.id + " " +
            "with data from related " + relationship + " " + sourceId + " " +
            "because the related " + relationship + " has apparently changed (was: " + previousSourceIdsForRelationship + "), " +
            "but mutations of relationships used with `sourced_from` are not supported because " +
            "allowing it could break ElasticGraph's out-of-order processing guarantees."
         );
        }

        Number maybeDocVersion = source.__versions.get(params.relationship)?.get(params.sourceId);

        // Our JSON schema requires event versions to be non-negative, so we can safely use Long.MIN_VALUE as a stand-in when the value is null.
        long docVersion = maybeDocVersion == null ? Long.MIN_VALUE : maybeDocVersion.longValue();

        if (docVersion >= eventVersion) {
          throw new IllegalArgumentException("ElasticGraph update was a no-op: [" +
            params.id + "]: version conflict, current version [" +
            docVersion + "] is higher or equal to the one provided [" +
            eventVersion + "]");
        } else {
          source.putAll(params.data);
          Map __counts = params.__counts;

          if (__counts != null) {
            if (source.__counts == null) {
              source.__counts = [:];
            }

            source.__counts.putAll(__counts);
          }

          source.id = params.id;
          source.__versions[relationship][sourceId] = eventVersion;

          // Record the relationship in `__sources` if it's not already there. We maintain it as an append-only set using a sorted list.
          // This ensures deterministic ordering of its elements regardless of event ingestion order, and lets us check membership in O(log N) time.
          //
          // As per https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Collections.html#binarySearch(java.util.List,java.lang.Object):
          //
          // > Returns the index of the search key, if it is contained in the list; otherwise, (-(insertion point) - 1).
          // > The insertion point is defined as the point at which the key would be inserted into the list: the index
          // > of the first element greater than the key, or list.size() if all elements in the list are less than the
          // > specified key. Note that this guarantees that the return value will be >= 0 if and only if the key is found.
          int sourceBinarySearchResult = Collections.binarySearch(source.__sources, relationship);
          if (sourceBinarySearchResult < 0) {
            source.__sources.add(-sourceBinarySearchResult - 1, relationship);
          }
        }
