Call-numbers migration

Context

The new feature was implemented to make it possible to browse call-numbers by their types. It was implemented by using references to call-number types and changing logic for calculating shelving order that is used for call-number sorting.

Instructions

Step 1

Release info:

Required: from Orchid to Poppy/CSP1/CSP2/CSP3

Not required: from Poppy to CSP1/CSP2/CSP3, from CSP1 to CSP2/CSP3, from CSP2 to CSP3

Run time:

Before upgrade

Precondition:

Run script: 

Precondition script
SELECT
    ct1.id AS actual_id,
    expected.expected_id AS expected_id,
    ct1.jsonb->>'name' AS common_name
FROM
    <tenant>_mod_inventory_storage.call_number_type ct1
JOIN
    (VALUES
        ('95467209-6d7b-468b-94df-0f5d7ad2747d', 'Library of Congress classification'),
        ('6caca63e-5651-4db6-9247-3205156e9699', 'Other scheme'),
        ('03dd64d0-5626-4ecd-8ece-4531e0069f35', 'Dewey Decimal classification'),
        ('054d460d-d6b9-4469-9e37-7a78a2266655', 'National Library of Medicine classification'),
        ('fc388041-6cd0-4806-8a74-ebe3b9ab4c6e', 'Superintendent of Documents classification')
    ) AS expected (expected_id, common_name)
ON
    ct1.jsonb->>'name' = expected.common_name
    AND ct1.id::text <> expected.expected_id;

If there are NO results then skip this step

Action:

Run script:

One script action
-- Drop foreign key on holdings_record table
ALTER TABLE <tenant>_mod_inventory_storage.holdings_record
DROP CONSTRAINT IF EXISTS callnumbertypeid_call_number_type_fkey;

-- Create a temporary table to store the mapping
CREATE TEMPORARY TABLE mapping_temp AS
SELECT
    ct1.id AS actual_id,
    expected.expected_id AS expected_id,
    ct1.jsonb->>'name' AS common_name
FROM
    <tenant>_mod_inventory_storage.call_number_type ct1
JOIN
    (VALUES
        ('95467209-6d7b-468b-94df-0f5d7ad2747d', 'Library of Congress classification'),
        ('6caca63e-5651-4db6-9247-3205156e9699', 'Other scheme'),
        ('03dd64d0-5626-4ecd-8ece-4531e0069f35', 'Dewey Decimal classification'),
        ('054d460d-d6b9-4469-9e37-7a78a2266655', 'National Library of Medicine classification'),
        ('fc388041-6cd0-4806-8a74-ebe3b9ab4c6e', 'Superintendent of Documents classification')
    ) AS expected (expected_id, common_name)
ON
    ct1.jsonb->>'name' = expected.common_name
    AND ct1.id::text <> expected.expected_id;

-- Update call-number type references in the holdings_record table
UPDATE <tenant>_mod_inventory_storage.holdings_record AS hr
SET jsonb = jsonb_set(hr.jsonb, '{callNumberTypeId}', to_jsonb(updated.expected_id))
FROM (
    SELECT actual_id, expected_id
    FROM mapping_temp
) AS updated
WHERE
    hr.callnumbertypeid = updated.actual_id;

-- Update call-number type references (itemLevelCallNumberTypeId) in the item table
UPDATE <tenant>_mod_inventory_storage.item AS it
SET jsonb = jsonb_set(it.jsonb, '{itemLevelCallNumberTypeId}', to_jsonb(updated.expected_id))
FROM (
    SELECT actual_id, expected_id
    FROM mapping_temp
) AS updated
WHERE
    it.jsonb->>'itemLevelCallNumberTypeId' = updated.actual_id::text;

-- Update call-number type references (effectiveCallNumberComponents,typeId) in the item table
UPDATE <tenant>_mod_inventory_storage.item AS it
SET jsonb = jsonb_set(it.jsonb, '{effectiveCallNumberComponents,typeId}', to_jsonb(updated.expected_id))
FROM (
    SELECT actual_id, expected_id
    FROM mapping_temp
) AS updated
WHERE
    it.jsonb->'effectiveCallNumberComponents'->>'typeId' = updated.actual_id::text;

-- Update call_number_type table with expected ids
UPDATE <tenant>_mod_inventory_storage.call_number_type AS ct1
SET
    id = updated.expected_id::uuid
FROM (
    SELECT actual_id, expected_id
    FROM mapping_temp
) AS updated
WHERE
    ct1.id = updated.actual_id;

-- Recreate foreign key on holdings_record table
ALTER TABLE IF EXISTS <tenant>_mod_inventory_storage.holdings_record
    ADD CONSTRAINT callnumbertypeid_call_number_type_fkey FOREIGN KEY (callnumbertypeid)
    REFERENCES <tenant>_mod_inventory_storage.call_number_type (id) MATCH SIMPLE
    ON UPDATE NO ACTION
    ON DELETE NO ACTION;

-- Drop the temporary mapping table
DROP TABLE IF EXISTS mapping_temp;

The script could be split into several steps:

  1. Drop foreign key on holdings_record table: 

    Disable FK
    ALTER TABLE <tenant>_mod_inventory_storage.holdings_record 
    DROP CONSTRAINT callnumbertypeid_call_number_type_fkey;
  2. Update call-number type references in the holdings_record table: 

    Update holdings
    UPDATE <tenant>_mod_inventory_storage.holdings_record AS hr
    SET jsonb = jsonb_set(hr.jsonb, '{callNumberTypeId}', to_jsonb(updated.expected_id))
    FROM (
        SELECT
            ct1.id AS actual_id,
            expected.expected_id AS expected_id,
            ct1.jsonb->>'name' AS common_name
        FROM
            <tenant>_mod_inventory_storage.call_number_type ct1
        JOIN
            (VALUES
                ('95467209-6d7b-468b-94df-0f5d7ad2747d', 'Library of Congress classification'),
                ('6caca63e-5651-4db6-9247-3205156e9699','Other scheme'),
                ('03dd64d0-5626-4ecd-8ece-4531e0069f35', 'Dewey Decimal classification'),
                ('054d460d-d6b9-4469-9e37-7a78a2266655', 'National Library of Medicine classification'),
                ('fc388041-6cd0-4806-8a74-ebe3b9ab4c6e', 'Superintendent of Documents classification')
            ) AS expected (expected_id, common_name)
        ON
            ct1.jsonb->>'name' = expected.common_name
            AND ct1.id::text <> expected.expected_id
    ) AS updated
    WHERE
        hr.callnumbertypeid = updated.actual_id;
  3. Update call-number type references (itemLevelCallNumberTypeId) in the item table: 

    Item's itemLevelCallNumberTypeId update
    UPDATE <tenant>_mod_inventory_storage.item AS it
    SET jsonb = jsonb_set(it.jsonb, '{itemLevelCallNumberTypeId}', to_jsonb(updated.expected_id))
    FROM (
        SELECT
            ct1.id AS actual_id,
            expected.expected_id AS expected_id,
            ct1.jsonb->>'name' AS common_name
        FROM
            <tenant>_mod_inventory_storage.call_number_type ct1
        JOIN
            (VALUES
                ('95467209-6d7b-468b-94df-0f5d7ad2747d', 'Library of Congress classification'),
                ('6caca63e-5651-4db6-9247-3205156e9699','Other scheme'),
                ('03dd64d0-5626-4ecd-8ece-4531e0069f35', 'Dewey Decimal classification'),
                ('054d460d-d6b9-4469-9e37-7a78a2266655', 'National Library of Medicine classification'),
                ('fc388041-6cd0-4806-8a74-ebe3b9ab4c6e', 'Superintendent of Documents classification')
            ) AS expected (expected_id, common_name)
        ON
            ct1.jsonb->>'name' = expected.common_name
            AND ct1.id::text <> expected.expected_id
    ) AS updated
    WHERE
        it.jsonb->>'itemLevelCallNumberTypeId' = updated.actual_id::text;
    
    
  4. Update call-number type references (effectiveCallNumberComponents,typeId) in the item table: 

    Item's effectiveCallNumberComponents update
    UPDATE <tenant>_mod_inventory_storage.item AS it
    SET jsonb = jsonb_set(it.jsonb, '{effectiveCallNumberComponents,typeId}', to_jsonb(updated.expected_id))
    FROM (
        SELECT
            ct1.id AS actual_id,
            expected.expected_id AS expected_id,
            ct1.jsonb->>'name' AS common_name
        FROM         
    		<tenant>_mod_inventory_storage.call_number_type ct1
        JOIN
            (VALUES
                ('95467209-6d7b-468b-94df-0f5d7ad2747d', 'Library of Congress classification'),
                ('6caca63e-5651-4db6-9247-3205156e9699','Other scheme'),
                ('03dd64d0-5626-4ecd-8ece-4531e0069f35', 'Dewey Decimal classification'),
                ('054d460d-d6b9-4469-9e37-7a78a2266655', 'National Library of Medicine classification'),
                ('fc388041-6cd0-4806-8a74-ebe3b9ab4c6e', 'Superintendent of Documents classification')
            ) AS expected (expected_id, common_name)
        ON
            ct1.jsonb->>'name' = expected.common_name
            AND ct1.id::text <> expected.expected_id
    ) AS updated
    WHERE
        it.jsonb->'effectiveCallNumberComponents'->>'typeId' = updated.actual_id::text;
    
    
  5. Update call_number_type table with expected ids: 

    Call-number type update
    UPDATE <tenant>_mod_inventory_storage.call_number_type AS ct1
    SET
        id = updated.expected_id
    FROM (
        SELECT
            ct1.id AS actual_id,
            expected.expected_id::uuid AS expected_id,
            ct1.jsonb->>'name' AS common_name
        FROM         
    		<tenant>_mod_inventory_storage.call_number_type ct1
        JOIN
            (VALUES
                ('95467209-6d7b-468b-94df-0f5d7ad2747d', 'Library of Congress classification'),
                ('6caca63e-5651-4db6-9247-3205156e9699','Other scheme'),
                ('03dd64d0-5626-4ecd-8ece-4531e0069f35', 'Dewey Decimal classification'),
                ('054d460d-d6b9-4469-9e37-7a78a2266655', 'National Library of Medicine classification'),
                ('fc388041-6cd0-4806-8a74-ebe3b9ab4c6e', 'Superintendent of Documents classification')
            ) AS expected (expected_id, common_name)
        ON
            ct1.jsonb->>'name' = expected.common_name
            AND ct1.id::text <> expected.expected_id
    ) AS updated
    WHERE
        ct1.id = updated.actual_id;
    
    
  6. Recreate foreign key on holdings_record table:

    Recreate FK
    ALTER TABLE IF EXISTS <tenant>_mod_inventory_storage.holdings_record
        ADD CONSTRAINT callnumbertypeid_call_number_type_fkey FOREIGN KEY (callnumbertypeid)
        REFERENCES <tenant>_mod_inventory_storage.call_number_type (id) MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE NO ACTION;

Action timing:

Tested on database with 7.8M rows in holdings_record table and 9M rows in item table.

Step NExecution time

1

1s
21h 10m
320m
41h 30m
51s
62s
Total3h

Step 2 Precondition

Run time:

After upgrade, before reindex

Release info:

Requires upgrade to Poppy CSP3 before running scripts

Action:

Run script:

Update sql functions
-- Change search path for the script
SET search_path = <tenant>_mod_inventory_storage;

CREATE OR REPLACE FUNCTION dewey_call_number(call_number text)
  RETURNS text AS $$
  DECLARE
    matches text[];
    class_digits text;
    class_decimal text;
    cutter text;
    other text;
  BEGIN
    matches = regexp_match(call_number, '^(\d+)(\.\d+)? *\.?(?:([A-Z]\d{1,3}(?:[A-Z]+)?) *(.*)|(.*))$');
    IF matches IS NULL THEN
      RETURN numerically_sortable(trim2null(call_number));
    END IF;
    class_digits = matches[1];
    class_decimal = matches[2];
    cutter = matches[3];
    other = numerically_sortable(trim2null(concat(trim2null(matches[4]), trim2null(matches[5]))));
    RETURN concat_ws(' ', concat(sortable_number(class_digits), class_decimal),
                          cutter,
                          other
                    );
  END;
$$ LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE STRICT;

CREATE OR REPLACE FUNCTION lc_nlm_call_number(call_number text)
  RETURNS text AS $$
  DECLARE
    matches text[];
    classification text;
    classLetters text;
    classDigits text;
    classDecimal text;
    everythingElse text;
    classSuffix text;
    cutter text;
  BEGIN
    call_number = upper(call_number);
    matches = regexp_match(call_number, '^(([A-Z]+) *(?:(\d+)(\.\d+)?)?)(.*)$');
    IF matches IS NULL THEN
      RETURN trim(cutter_shelf_key(trim2null(call_number)));
    END IF;
    classification = trim(matches[1]);
    classLetters = trim(matches[2]);
    classDigits = trim(matches[3]);
    classDecimal = trim(matches[4]);
    everythingElse = matches[5];
    IF classDigits IS NULL THEN
      RETURN NULL;
    END IF;
    IF length(everythingElse) > 0 THEN
      -- combining greedy and non-greedy:
      -- https://www.postgresql.org/docs/current/functions-matching.html#POSIX-MATCHING-RULES
      matches = regexp_match(everythingElse, '(?:(.*?)(\.?[A-Z]\d+|^\.[A-Z]| \.[A-Z])(.*)){1,1}');
      IF matches IS NULL THEN
        classSuffix = trim2null(everythingElse);
      ELSE
        classSuffix = trim2null(matches[1]);
        cutter = trim(matches[2] || matches[3]);
      END IF;
    END IF;
    classSuffix = numerically_sortable(classSuffix);
    IF substr(classSuffix, 1, 1) BETWEEN 'A' AND 'Z' THEN
      classSuffix = '_' || classSuffix;
    END IF;
    cutter = cutter_shelf_key(cutter);
    return trim(concat_ws(' ', classLetters,
                               concat(length(classDigits), classDigits, classDecimal),
                               trim2null(classSuffix),
                               trim(cutter)
                         ));
  END;
$$ LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE STRICT;

CREATE OR REPLACE FUNCTION su_doc_call_number(call_number text)
  RETURNS text AS $$
  DECLARE
    matches text[];
  BEGIN
    matches = regexp_match(upper(call_number),
        '^([A-Z]+)\s*(\d+)(\.(?:[A-Z]+\d*|\d+))(/(?:[A-Z]+(?:\d+(?:-\d+)?)?|\d+(?:-\d+)?))?:?(.*)$');
    IF matches IS NULL THEN
      RETURN su_doc_part(trim2null(upper(call_number)));
    END IF;
    RETURN concat_ws(' ', matches[1], su_doc_part(matches[2]), su_doc_part(matches[3]), su_doc_part(matches[4]), su_doc_part(matches[5]));
  END;
$$ LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE STRICT;

CREATE OR REPLACE FUNCTION sortable_number(n text)
  RETURNS text AS $$
  DECLARE int_part text;
  BEGIN
    n = regexp_replace(n, '^0+', '');
    int_part = split_part(n, '.', 1);
    RETURN concat(length(int_part), n);
  END;
$$ LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE STRICT;

CREATE OR REPLACE FUNCTION cutter_shelf_key(s text)
  RETURNS text AS $$
  DECLARE
    chunk text;
    matches text[];
    cutter text;
    suffix text;
    result text;
  BEGIN
    FOREACH chunk IN ARRAY regexp_split_to_array(s, '(?=\.?[A-Z][0-9])') LOOP
      matches = regexp_match(chunk, '([A-Z][0-9]+)(.*)');
      IF matches IS NULL THEN
        -- before the first cutter
        IF result IS NULL THEN
            result = trim2null(numerically_sortable(chunk));
        ELSE
            result = concat_ws(' ', result, trim2null(numerically_sortable(chunk)));
        END IF;
      ELSE
        cutter = matches[1];
        suffix = trim2null(numerically_sortable(matches[2]));
        result = concat_ws(' ', result, cutter, suffix);
      END IF;
    END LOOP;
    RETURN result;
  END;
$$ LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE STRICT;

Step 2 (Option 1)

Release info:

Requires upgrade to Poppy CSP3 before running scripts

Run time:

After upgrade, before reindex

Precondition:

No preconditions

Action:

Run script:

Recalculate shelving order
-- Change search path for the script
SET search_path = <tenant>_mod_inventory_storage;

-- Recalculate effective values and shelving order in items
UPDATE item
SET jsonb = set_item_effective_values(item_data.holdings, item_data.item)
FROM (
    select item.id, hr.jsonb as holdings, item.jsonb as item from holdings_record hr
    join item on item.holdingsRecordId = hr.id
    where item.jsonb->'effectiveCallNumberComponents'->'callNumber' IS NOT NULL
    and item.jsonb->'effectiveCallNumberComponents'->'callNumber' != 'null'
) AS item_data
WHERE item.id = item_data.id;

Action timing:

Tested on database with 9M rows in item table.

Execution time: TBD


Step 2 (Option 2)

Release info:

Requires upgrade to Poppy CSP3 before running scripts

Run time:

After upgrade, before reindex

Precondition:

No preconditions

Action:

  1. Disable triggers

    ALTER TABLE {tenant}_mod_inventory_storage.item DISABLE TRIGGER audit_item;
    
    ALTER TABLE {tenant}_mod_inventory_storage.item DISABLE  TRIGGER check_statistical_code_references_on_insert;
    
    ALTER TABLE {tenant}_mod_inventory_storage.item DISABLE  TRIGGER check_statistical_code_references_on_update;
    
    ALTER TABLE {tenant}_mod_inventory_storage.item DISABLE  TRIGGER set_id_in_jsonb;
    
    ALTER TABLE {tenant}_mod_inventory_storage.item DISABLE  TRIGGER set_item_md_json_trigger;
    
    ALTER TABLE {tenant}_mod_inventory_storage.item DISABLE  TRIGGER set_item_md_trigger;
    
    ALTER TABLE {tenant}_mod_inventory_storage.item DISABLE  TRIGGER set_item_ol_version_trigger;
    
    ALTER TABLE {tenant}_mod_inventory_storage.item DISABLE  TRIGGER update_item_references;
    
    ALTER TABLE {tenant}_mod_inventory_storage.item DISABLE  TRIGGER update_item_status_date;
    
    ALTER TABLE {tenant}_mod_inventory_storage.item DISABLE  TRIGGER updatecompleteupdateddate_item_delete;
    
    ALTER TABLE {tenant}_mod_inventory_storage.item DISABLE  TRIGGER updatecompleteupdateddate_item_insert_update;
  2. Create uuid_range table

    create table public.uuid_range
    (
        id             serial primary key,
        partition      uuid,
        subrange_start uuid,
        subrange_end   uuid,
        completed      boolean default false
    );-- If table exists and filled then do:
    UPDATE public.uuid_range SET completed=false;
    -- If table was just created then fill it:
    
    DO
    $$
        DECLARE
            partition_start UUID;
            subrange_start  UUID;
            subrange_end    UUID;
        BEGIN
            FOR i IN 0..15
                LOOP
                    partition_start := (rpad(to_hex(i), 8, '0') || '-0000-0000-0000-000000000000')::UUID;
                    subrange_start := partition_start;
    
                    FOR j IN 1..4096
                        LOOP
                            IF i < 15 OR (i = 15 AND j < 4096) THEN
                                if (j < 4096) then
                                    subrange_end := (to_hex(i)::text || rpad(lpad(to_hex(j), 3, '0'), 7, '0') ||
                                                     '-0000-0000-0000-000000000000')::UUID;
                                else
                                    subrange_end := (rpad(to_hex(i + 1), 8, '0') || '-0000-0000-0000-000000000000')::UUID;
                                end if;
                            ELSE
                                subrange_end := 'ffffffff-ffff-ffff-ffff-ffffffffffff'::UUID; -- upper bound for last subrange in last partition
                            END IF;
    
                            INSERT INTO public.uuid_range (partition, subrange_start, subrange_end)
                            VALUES (partition_start, subrange_start, subrange_end);
    
                            subrange_start := subrange_end;
                        END LOOP;
                END LOOP;
        END;
    $$
    LANGUAGE plpgsql; 
  3. Update step should be executed for each partition created from step #2. Update script can be executed concurrently.

    set search_path = "{tenant}_mod_inventory_storage", "public";
    
    do
    $$
        declare
            partition_to_process uuid := '{partition}'::uuid;
            range_rec           public.uuid_range%rowtype;
        begin
            for range_rec in select ur.*
                             from public.uuid_range ur
                             where ur.partition = partition_to_process
                               and ur.completed = false
                loop
                    --             start transaction;
                    UPDATE item i SET jsonb = set_item_effective_values(item_data.holdings, item_data.item)
    				FROM (
    					select item.id, hr.jsonb as holdings, item.jsonb as item from holdings_record hr
    					join item on item.holdingsRecordId = hr.id
                    	where item.id between range_rec.subrange_start and range_rec.subrange_end
                    	and item.jsonb->'effectiveCallNumberComponents'->'callNumber' IS NOT NULL
    					and item.jsonb->'effectiveCallNumberComponents'->'callNumber' != 'null'
    				) AS item_data
    				WHERE i.id = item_data.id;
     
                    update uuid_range
                    set completed = true
                    where id = range_rec.id;
                    --
                    raise notice 'subrange id: % completed', range_rec.id;
                    commit;
                end loop;
        end
    $$;
  4. Monitor how many sub-partitions in partitions are left to be processed

    select partition, count(partition)
    from public.uuid_range
    where completed = false
    group by partition
    order by partition;  
  5. Enable triggers

    ALTER TABLE {tenant}_mod_inventory_storage.item ENABLE TRIGGER audit_item;
    
    ALTER TABLE {tenant}_mod_inventory_storage.item ENABLE TRIGGER check_statistical_code_references_on_insert;
    
    ALTER TABLE {tenant}_mod_inventory_storage.item ENABLE TRIGGER check_statistical_code_references_on_update;
    
    ALTER TABLE {tenant}_mod_inventory_storage.item ENABLE TRIGGER set_id_in_jsonb;
    
    ALTER TABLE {tenant}_mod_inventory_storage.item ENABLE TRIGGER set_item_md_json_trigger;
    
    ALTER TABLE {tenant}_mod_inventory_storage.item ENABLE TRIGGER set_item_md_trigger;
    
    ALTER TABLE {tenant}_mod_inventory_storage.item ENABLE TRIGGER set_item_ol_version_trigger;
    
    ALTER TABLE {tenant}_mod_inventory_storage.item ENABLE TRIGGER update_item_references;
    
    ALTER TABLE {tenant}_mod_inventory_storage.item ENABLE TRIGGER update_item_status_date;
    
    ALTER TABLE {tenant}_mod_inventory_storage.item ENABLE TRIGGER updatecompleteupdateddate_item_delete;
    
    ALTER TABLE {tenant}_mod_inventory_storage.item ENABLE TRIGGER updatecompleteupdateddate_item_insert_update;

Step 2 (Option 3). Requires Poppy CSP #3. Unstable on big amounts of data

Run time:

After upgrade, before reindex

Precondition:

No preconditions

Action

Run script:

-- Change search path for the script
SET search_path = <tenant>_mod_inventory_storage;

-- Recalculate effective values for items with no call number type specified. No shelving order recalculation
UPDATE item
SET jsonb = set_item_effective_values_no_shelv_recalc(item_data.holdings, item_data.item)
FROM (
    select item.id, hr.jsonb as holdings, item.jsonb as item from holdings_record hr
    join item on item.holdingsRecordId = hr.id
    where trim2null(hr.jsonb->>'callNumberTypeId') IS NOT NULL
    and trim2null(item.jsonb->'effectiveCallNumberComponents'->>'typeId') IS NULL
) AS item_data
WHERE item.id = item_data.id;

Step 3. Requires Poppy CSP #3. Unstable on big amounts of data

  1. Run async item shelving order migration via api. Anytime, may be during runtime. Values surrounded by "<>" to be replaced

    curl --location --request POST '<okapi-url>/inventory-storage/migrations/jobs' \
    --header 'X-Okapi-Tenant: <tenant>' \
    --header 'X-Okapi-Token: <token>' \
    --header 'Content-Type: application/json' \
    --data '{
      "migrations": ["itemShelvingOrderMigration"],
      "affectedEntities": ["ITEM"]
    }'
  2. Monitor execution until response body parameter "jobStatus" is "Completed". <jobId> is returned from previous request as "id" parameter in response body

    curl --location --request GET '<okapi-url>/inventory-storage/migrations/jobs/<jobId>' \
    --header 'X-Okapi-Tenant: <tenant>' \
    --header 'X-Okapi-Token: <token>' \
    --header 'Content-Type: application/json'
  3. Once migration is completed - reindex instances


Viacheslav Kolesnyk
April 16, 2024

It was added here to provide faster fix for clients and avoid waiting for CSP. Not planned for Quesnelia as those functions are absent in repository branches other than Poppy. And these scripts are meant to be run for Poppy upgrade.

Wayne Schneider
April 16, 2024

These functions are used only for the migration?

I just installed the CSP in a test environment and these functions were not defined in this way, so it is clearly not part of the CSP itself.

Viacheslav Kolesnyk
April 16, 2024

Yes.

Initial versions of functions are a part of module liquibase scripts for Poppy. Could be found here https://github.com/folio-org/mod-inventory-storage/blob/release/v27.0/src/main/resources/templates/db_scripts/instance-hr-item/write.sql and are used here https://github.com/folio-org/mod-inventory-storage/blob/release/v27.0/src/main/resources/templates/db_scripts/schema.json .

Functions provided here are intended to replace some of functions defined in module liquibase scripts.

Wayne Schneider
April 16, 2024

I’m sorry to be dense here. Are the updated versions of the functions not used a runtime, but only during a migration? If they are used at runtime, if they are not included as part of tenant initialization how would a new Poppy or Quesnelia tenant get the updated version?

Viacheslav Kolesnyk
April 17, 2024

Yes, those functions are not used at runtime. They are used only during Poppy manual migration described on this page.