<?xml version="1.0" encoding="UTF-8"?>
<changelog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.liquigraph.org/schema/1.0/liquigraph.xsd">
    <changeset id="DIS-566_repair_bad_metadata:1" author="asingh" run-on-change="true">
        <query>
            <![CDATA[
                CALL apoc.periodic.iterate(
                    "
                        WITH
                            'mysql_artrelations' AS url_alias,
                            '
                                SELECT
                                    ta.id AS id,
                                    ta.track_id AS track_id,
                                    ta.type AS type,
                                    ta.name AS name,
                                    artist_info.vendor_id AS vendor_id,
                                    coalesce(releases.subaccount_id, 0) AS subaccount_id
                                FROM track_artist ta
                                JOIN track ON ta.track_id = track.id
                                JOIN releases ON track.release_id = releases.release_id
                                JOIN artist_info ON releases.artist_id = artist_info.artist_id
                                WHERE ta.id IN (92501912, 93054483, 92517925)
                                ORDER BY ta.id
                            ' AS sql
                        CALL apoc.load.jdbc(url_alias, sql)
                        YIELD row
                        RETURN row
                    ",
                    "
                        // A future version of APOC has batchMode = 'BATCH_SINGLE' for this, but we have to collect and reunwind instead.
                        WITH collect(row) AS rows
                        UNWIND range(0, size(rows) - 1) AS rowNumber
                        WITH rowNumber, size(rows) AS totalRows, rows[rowNumber] AS row
                        // This is the insert script from here: https://github.com/theorchard/lambda-kinesis-to-neo4j/blob/31dbf87fdb3509d0a96d519043271e2d3d11e2d9/lambda/kinesis-to-neo4j/logic/art_relations/queries.py#L618-L656
                        MERGE (ta:TrackArtist {id: toInteger(row.id)})
                            SET ta.trackId = toInteger(row.track_id),
                                ta.name = row.name,
                                ta.type = row.type,
                                ta.updated_at = datetime()
                        // NOTE: modified to add toInteger
                        MERGE (t:Track:Orchard {id: toInteger(row.track_id)})
                        MERGE (t)-[:HAS_SOURCE_ARTIST]->(ta)
                        // NOTE: This increments the id by totalRows
                        MERGE (i:IncrementId {nodeName: 'LabelParticipant'})
                            ON CREATE SET i.id = 1
                            ON MATCH SET i.id = i.id + 1
                        MERGE (
                            lp:LabelParticipant:Orchard {
                                normalizedName: toLower(trim(apoc.text.regreplace(row.name, '[ ]+', ''))),
                                // NOTE: These don't come back as numbers for whatever reason,
                                vendorId: toInteger(row.vendor_id),
                                subaccountId: toInteger(row.subaccount_id)
                            }
                        )
                            ON CREATE SET
                                // i.id will be the id of the increment node after all the increments have finished, so we need to remove totalRows and add the current row id back in.
                                lp.id = i.id - totalRows + rowNumber + 1,
                                lp.uuid = apoc.create.uuid(),
                                lp.createdAt = datetime(),
                                lp.modifiedAt = datetime(),
                                lp.name = trim(apoc.text.regreplace(row.name, '[ ]{2,}', ' '))
                            ON MATCH SET
                                lp.modifiedAt = datetime(),
                                lp.name = trim(apoc.text.regreplace(row.name, '[ ]{2,}', ' '))
                        MERGE (lp)-[participation:PARTICIPATED_IN {participated_as: row.type}]->(t)
                            SET participation.updatedAt = datetime()
                        MERGE (lp)-[cf:CREATED_FROM]->(ta)
                            ON CREATE SET cf.created_at = datetime()
                        MERGE (v:Vendor:Label:Orchard {id: lp.vendorId})
                        MERGE (v)-[:HAS_LABEL_PARTICIPANT]->(lp)
                        FOREACH (hasSubAccount IN
                                        CASE WHEN not (lp.subaccountId = 0) THEN [1] ELSE [] END |
                            MERGE (sa:SubAccount:Subaccount:Label {id: lp.subaccountId})
                            MERGE (sa)-[:HAS_LABEL_PARTICIPANT]->(lp)
                        )
                        // Remove old relationship
                        WITH ta, lp
                        OPTIONAL MATCH (ta)<-[rel:CREATED_FROM]-(other)
                        WHERE other <> lp
                        DELETE rel
                    ",
                    {
                        batchSize: 10000,
                        iterateList: true,
                        // Parallel: false is prone to deadlocking
                        // See https://github.com/neo4j-contrib/neo4j-apoc-procedures/issues/1768
                        parallel: true,
                        // This parameter has an OBOE - setting it to 1 causes two threads to run
                        // See https://github.com/neo4j-contrib/neo4j-apoc-procedures/issues/1782
                        concurrency: 1,
                        retries: 1
                    }
                )
                YIELD failedOperations, errorMessages
                // For some reason calling apoc.util.validate directly doesn't actually fail the batch inside of apoc.periodic.iterate, but this does
                CALL apoc.do.when(
                    failedOperations > 0,
                    'CALL apoc.util.validate(true, "At least one sub-operation failed: %s", [reduce(all_errors = "", error IN keys(errorMessages) | all_errors + ", " + error)]) RETURN 0',
                    '',
                    { errorMessages: errorMessages }
                )
                YIELD value AS _
                RETURN 0
            ]]>
        </query>
    </changeset>
</changelog>
