text: """To implement the RFC 6902 logic for patches, there are some various complex methods needed.
  For clarity, they are in this separate file as helper methods."""
  
  from copy import deepcopy
  from jsonpatch import JsonPatch
  
  from app import db
  from apps.releases.models import ReleasesCategoriesMapping, ReleasesFormatsMapping
  from apps.releases.add_cfps import add_categories, add_formats, add_people, add_songs
  from apps.people.models import ReleasesPeopleMapping
  from apps.songs.models import ReleasesSongsMapping
  
  
  def patch_item(release, patchdata, **kwargs):
      """Sequentially runs the patches defined in the JSON."""
      result = None
      # Map the values to DB column names
      mapped_patchdata = []
      for p in patchdata:
          # Replace eg. /title with /Title
          p = patch_mapping(p)
          mapped_patchdata.append(p)
  
      # Prevent a KeyError for the mapping models by using a separate list for Releases table
      separate_values = ["/Categories", "/Formats", "/People", "/Songs"]
      release_patches = mapped_patchdata
      for separate in separate_values:
          release_patches = [rp for rp in release_patches if separate not in rp.values()]
  
      data = release.asdict(exclude_pk=True, **kwargs)
      patch = JsonPatch(release_patches)
      data = patch.apply(data)
      release.fromdict(data)
  
      # If the patches contain Category patches, run them.
      if [cat for cat in mapped_patchdata if "/Categories" in cat.values()]:
          result = patch_categories(mapped_patchdata, release.ReleaseID)
  
      # If the patches contain Format patches, run them.
      if [fmt for fmt in mapped_patchdata if "/Formats" in fmt.values()]:
          result = patch_formats(mapped_patchdata, release.ReleaseID)
  
      # If the patches contain People patches, run them.
      if [pe for pe in mapped_patchdata if "/People" in pe.values()]:
          result = patch_people(mapped_patchdata, release.ReleaseID)
  
      # If the patches contain Song patches, run them.
      if [s for s in mapped_patchdata if "/Songs" in s.values()]:
          result = patch_songs(mapped_patchdata, release.ReleaseID)
  
      # We only return from non-Release patches. It is None if no test ops were in the patches.
      # TODO: How/Should we handle the multiple results from each mapping type?
      # But generally "op": "test" is only used once - it doesn't really make sense to use it many
      # times in one JSON anyway.
      return result
  
  
  def patch_mapping(patch):
      """This is used to map a patch "path" or "from" to a custom value."""
      mapping = {
          "/title": "/Title",
          "/releaseCode": "/ReleaseCode",
          "/releaseDate": "/Date",
          "/artist": "/Artist",
          "/credits": "/Credits",
          "/categories": "/Categories",
          "/formats": "/Formats",
          "/people": "/People",
          "/songs": "/Songs",
      }
  
      mutable = deepcopy(patch)
      for prop in patch:
          if prop == "path" or prop == "from":
              mutable[prop] = mapping.get(patch[prop], None)
      return mutable
  
  
  def patch_categories(patches, release_id):
      """Apply patches to ReleasesCategoriesMapping table. Since there are multiple rows, we need
      some special processing for it, which the regular JsonPatch cannot handle."""
      # Filter out unrelated patches
      cat_patches = [p for p in patches if "/Categories" in p.values()]
  
      for patch in cat_patches:
          if patch["op"] == "add":
              # Generally it is a list of values, eg.
              # {"op": "add", "path": "/Categories", "value": [1, 2, "New"]}
              # Where 1 and 2 are references to existing ones, and "New" is a new category to add
              # also, non-array values are possible:
              # {"op": "add", "path": "/Categories", "value": "Another"}
              add_categories(release_id, patch["value"])
          elif patch["op"] == "copy":
              # This has no meaningful operation in Release Categories, so not implemented.
              continue
          elif patch["op"] == "move":
              # This has no meaningful operation in Release Categories, so not implemented.
              continue
          elif patch["op"] == "remove":
              # NB "remove" is for deleting an entire resource.
              # To remove specific ID(s), use "replace".
              ReleasesCategoriesMapping.query.filter_by(ReleaseID=release_id).delete()
              db.session.commit()
          elif patch["op"] == "replace":
              # This is really a delete + insert operation in the Release Categories case
              ReleasesCategoriesMapping.query.filter_by(ReleaseID=release_id).delete()
              db.session.commit()
              add_categories(release_id, patch["value"])
  
  
  def patch_formats(patches, release_id):
      """Apply patches to ReleasesFormatsMapping table. Since there are multiple rows, we need
      some special processing for it, which the regular JsonPatch cannot handle."""
      # Filter out unrelated patches
      fmt_patches = [p for p in patches if "/Formats" in p.values()]
  
      for patch in fmt_patches:
          if patch["op"] == "add":
              # Generally it is a list of values, eg.
              # {"op": "add", "path": "/Formats", "value": [1, 2, "New"]}
              # Where 1 and 2 are references to existing ones, and "New" is a new format to add
              # also, non-array values are possible:
              # {"op": "add", "path": "/Formats", "value": "Another"}
              add_formats(release_id, patch["value"])
          elif patch["op"] == "copy":
              # This has no meaningful operation in Release Formats, so not implemented.
              continue
          elif patch["op"] == "move":
              # This has no meaningful operation in Release Formats, so not implemented.
              continue
          elif patch["op"] == "remove":
              # NB "remove" is for deleting an entire resource.
              # To remove specific ID(s), use "replace".
              ReleasesFormatsMapping.query.filter_by(ReleaseID=release_id).delete()
              db.session.commit()
          elif patch["op"] == "replace":
              # This is really a delete + insert operation in the Release Formats case
              ReleasesFormatsMapping.query.filter_by(ReleaseID=release_id).delete()
              db.session.commit()
              add_formats(release_id, patch["value"])
  
  
  def patch_people(patches, release_id):
      """Apply patches to ReleasesPeopleMapping table. Since there are multiple rows, we need
      some special processing for it, which the regular JsonPatch cannot handle."""
      # Filter out unrelated patches
      people_patches = [p for p in patches if "/People" in p.values()]
  
      for patch in people_patches:
          if patch["op"] == "add":
              # Generally it is a list of values, eg.
              # {"op": "add", "path": "/People", "value": [{1: "Guitar", {"New": "Drums"}]}
              # Where 1 is a reference to an existing person, and "New" is a new person to add
              # also, non-array values are possible:
              # {"op": "add", "path": "/People", "value": {"New": "Bass"}}
              add_people(release_id, patch["value"])
          elif patch["op"] == "copy":
              # This has no meaningful operation in Release People, so not implemented.
              continue
          elif patch["op"] == "move":
              # This has no meaningful operation in Release People, so not implemented.
              continue
          elif patch["op"] == "remove":
              # NB "remove" is for deleting an entire resource.
              # To remove specific ID(s), use "replace".
              ReleasesPeopleMapping.query.filter_by(ReleaseID=release_id).delete()
              db.session.commit()
          elif patch["op"] == "replace":
              # This is really a delete + insert operation in the Release People case
              ReleasesPeopleMapping.query.filter_by(ReleaseID=release_id).delete()
              db.session.commit()
              add_people(release_id, patch["value"])
  
  
  def patch_songs(patches, release_id):
      """Apply patches to ReleasesSongsMapping table. Since there are multiple rows, we need
      some special processing for it, which the regular JsonPatch cannot handle."""
      # Filter out unrelated patches
      song_patches = [p for p in patches if "/Songs" in p.values()]
  
      for patch in song_patches:
          if patch["op"] == "add":
              # Generally it is a list of values, eg.
              # {"op": "add", "path": "/Songs", "value": [{1: 123, {"New Song": 223}]}
              # Where 1 is a reference to an existing song, and "New" is a new song to add
              # also, non-array values are possible:
              # {"op": "add", "path": "/Songs", "value": {"New": 555}}
              add_songs(release_id, patch["value"])
          elif patch["op"] == "copy":
              # This has no meaningful operation in Release Songs, so not implemented.
              continue
          elif patch["op"] == "move":
              # This has no meaningful operation in Release Songs, so not implemented.
              continue
          elif patch["op"] == "remove":
              # NB "remove" is for deleting an entire resource.
              # To remove specific ID(s), use "replace".
              ReleasesSongsMapping.query.filter_by(ReleaseID=release_id).delete()
              db.session.commit()
          elif patch["op"] == "replace":
              # This is really a delete + insert operation in the Release People case
              ReleasesSongsMapping.query.filter_by(ReleaseID=release_id).delete()
              db.session.commit()
              add_songs(release_id, patch["value"])
  