diff --git a/code/reindexer/src/org/aspen_discovery/reindexer/GroupedWorkIndexer.java b/code/reindexer/src/org/aspen_discovery/reindexer/GroupedWorkIndexer.java index c945befbc29..1e1363bdaab 100644 --- a/code/reindexer/src/org/aspen_discovery/reindexer/GroupedWorkIndexer.java +++ b/code/reindexer/src/org/aspen_discovery/reindexer/GroupedWorkIndexer.java @@ -373,7 +373,7 @@ public GroupedWorkIndexer(String serverName, Connection dbConn, Ini configIni, b getV2SeriesStmt = dbConn.prepareStatement("SELECT * from series where seriesPermanentId = ?", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); checkIfSeriesMemberExistsStmt = dbConn.prepareStatement("SELECT * from series_member where seriesId = ? AND groupedWorkPermanentId = ?", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); - getSeriesMemberStmt = dbConn.prepareStatement("SELECT sm.id as seriesMemberId, sm.seriesId, s.seriesPermanentId, s.version, s.groupedWorkSeriesTitle, s.author, s.seriesLanguage, s.isIndexed, sm.volume, sm.priorityScore, sm.deleted, sm.userAdded FROM series_member AS sm LEFT JOIN series AS s ON sm.seriesId = s.id WHERE groupedWorkPermanentId = ?", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); + getSeriesMemberStmt = dbConn.prepareStatement("SELECT sm.id as seriesMemberId, sm.seriesId, s.seriesPermanentId, s.version, s.groupedWorkSeriesTitle, s.author, s.seriesLanguage, s.isIndexed, sm.volume, sm.priorityScore, sm.deleted, sm.userAdded, sm.groupedWorkPermanentId, sm.userDefinedVolume FROM series_member AS sm LEFT JOIN series AS s ON sm.seriesId = s.id WHERE groupedWorkPermanentId = ?", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); addSeriesStmt = dbConn.prepareStatement("INSERT INTO series (displayName, audience, created, dateUpdated, author, groupedWorkSeriesTitle, version) VALUES (?, ?, ?, ?, ?, ?, 1)", PreparedStatement.RETURN_GENERATED_KEYS); addSeriesV2Stmt = dbConn.prepareStatement("INSERT INTO series (displayName, audience, created, dateUpdated, author, groupedWorkSeriesTitle, seriesPermanentId, seriesLanguage, version) VALUES (?, ?, ?, ?, ?, ?, ?, ?, 2)", PreparedStatement.RETURN_GENERATED_KEYS); addSeriesMemberStmt = dbConn.prepareStatement("INSERT INTO series_member (seriesId, isPlaceholder, groupedWorkPermanentId, volume, pubDate, displayName, author, description, weight, priorityScore) VALUES (?, 0, ?, ?, ?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE id = LAST_INSERT_ID(id)", PreparedStatement.RETURN_GENERATED_KEYS); @@ -1596,7 +1596,7 @@ private void updateSeriesDataForWork(AbstractGroupedWorkSolr groupedWork) { key = seriesMember.getSeriesPermanentId(); } if (seriesMembersInDb.containsKey(key)) { - seriesMembersInDb.get(key).addVolume(seriesMemberRS.getString("volume"), seriesMemberRS.getBoolean("deleted"), seriesMemberRS.getBoolean("userAdded")); + seriesMembersInDb.get(key).addVolume(seriesMemberRS.getString("volume"), seriesMemberRS.getBoolean("deleted"), seriesMemberRS.getBoolean("userAdded"), seriesMemberRS.getBoolean("userDefinedVolume")); }else{ seriesMembersInDb.put(key, seriesMember); } @@ -1907,10 +1907,14 @@ private void addMemberToSeries(long seriesId, SeriesInfo seriesInfo, AbstractGro private void updateSeriesMembers(long seriesId, SeriesInfo seriesInfo, SeriesMember seriesMember, AbstractGroupedWorkSolr groupedWork, long timeNow) { for (String volume : seriesInfo.getVolumes()) { Set existingVolumes = seriesMember.getVolumes(); - if (!existingVolumes.contains(volume)) { + boolean isSameWorkWithUserDefinedVolume = seriesMember.getMemberGroupedWorkPermanentId().equals(groupedWork.id) && seriesMember.hasUserDefinedVolume(); + if (!existingVolumes.contains(volume) && !isSameWorkWithUserDefinedVolume) { addSeriesMemberWithVolume(seriesId, seriesInfo, volume, groupedWork, timeNow, 0); }else{ seriesMember.setVolumeFoundInIndex(volume); + if (existingVolumes.contains(volume)){ //if volume info matches, remove user-defined volume tag + seriesMember.setUserDefinedVolume(false); + } //Update priority score as needed if (!Objects.equals(seriesInfo.getPriorityScore(), seriesMember.getPriorityScore())) { try { @@ -1936,7 +1940,7 @@ private void updateSeriesMembers(long seriesId, SeriesInfo seriesInfo, SeriesMem //Delete any series members that no longer exist (with the volume) boolean valuesWereDeleted = false; for (SeriesMemberVolume volume : seriesMember.getSeriesVolumes()) { - if (!volume.isFoundInIndex() && !volume.isUserAdded()) { + if (!volume.isFoundInIndex() && !volume.isUserAdded() && !volume.isUserDefinedVolume()) { deleteSeriesMember(seriesMember.getSeriesId(), groupedWork.getId(), volume.getVolume()); valuesWereDeleted = true; } diff --git a/code/reindexer/src/org/aspen_discovery/reindexer/SeriesMember.java b/code/reindexer/src/org/aspen_discovery/reindexer/SeriesMember.java index 2fe29eef9c8..eb16e687f61 100644 --- a/code/reindexer/src/org/aspen_discovery/reindexer/SeriesMember.java +++ b/code/reindexer/src/org/aspen_discovery/reindexer/SeriesMember.java @@ -15,6 +15,7 @@ public class SeriesMember { private final String seriesPermanentId; private final String groupedWorkSeriesTitle; private String author; + private String groupedWorkPermanentId; @SuppressWarnings("FieldCanBeLocal") private final String seriesLanguage; //A list of volumes found in the database with a flag for if it was found in the current index @@ -24,6 +25,7 @@ public class SeriesMember { private int version; private boolean foundInCurrentIndex = false; private boolean deleted; + private boolean userDefinedVolume; /** * Constructor for use when loading series that are already linked to a Grouped Work via a Series Member @@ -32,13 +34,15 @@ public SeriesMember(ResultSet seriesMemberRS) throws SQLException { this.seriesId = seriesMemberRS.getLong("seriesId"); this.seriesPermanentId = seriesMemberRS.getString("seriesPermanentId"); this.groupedWorkSeriesTitle = seriesMemberRS.getString("groupedWorkSeriesTitle"); + this.groupedWorkPermanentId = seriesMemberRS.getString("groupedWorkPermanentId"); this.author = seriesMemberRS.getString("author"); this.seriesLanguage = seriesMemberRS.getString("seriesLanguage"); - this.volumes.put(seriesMemberRS.getString("volume"), new SeriesMemberVolume(seriesMemberRS.getString("volume"), seriesMemberRS.getBoolean("deleted"), seriesMemberRS.getBoolean("userAdded"))); + this.volumes.put(seriesMemberRS.getString("volume"), new SeriesMemberVolume(seriesMemberRS.getString("volume"), seriesMemberRS.getBoolean("deleted"), seriesMemberRS.getBoolean("userAdded"), seriesMemberRS.getBoolean("userDefinedVolume"))); this.priorityScore = seriesMemberRS.getInt("priorityScore"); this.isIndexed = seriesMemberRS.getBoolean("isIndexed"); this.version = seriesMemberRS.getInt("version"); this.deleted = seriesMemberRS.getBoolean("deleted"); + this.userDefinedVolume = seriesMemberRS.getBoolean("userDefinedVolume"); } /** @@ -85,6 +89,14 @@ public String getSeriesPermanentId() { return seriesPermanentId; } + public String getMemberGroupedWorkPermanentId() { + return groupedWorkPermanentId; + } + + public boolean hasUserDefinedVolume() { + return userDefinedVolume; + } + private String normalizedSeriesName; public String getNormalizedSeriesName() { if (normalizedSeriesName == null) { @@ -135,6 +147,10 @@ public void setVolumeFoundInIndex(String volumeId) { } } + public void setUserDefinedVolume(boolean userDefinedVolume) { + this.userDefinedVolume = userDefinedVolume; + } + public boolean isIndexed() { return isIndexed; } @@ -151,8 +167,8 @@ public void setVersion(int version) { this.version = version; } - public void addVolume(String volume, boolean deleted, boolean userAdded) { - this.volumes.put(volume, new SeriesMemberVolume(volume, deleted, userAdded)); + public void addVolume(String volume, boolean deleted, boolean userAdded, boolean userDefinedVolume) { + this.volumes.put(volume, new SeriesMemberVolume(volume, deleted, userAdded, userDefinedVolume)); } public boolean isDeleted() { diff --git a/code/reindexer/src/org/aspen_discovery/reindexer/SeriesMemberVolume.java b/code/reindexer/src/org/aspen_discovery/reindexer/SeriesMemberVolume.java index 81e4b5c26fa..ff93cc661f6 100644 --- a/code/reindexer/src/org/aspen_discovery/reindexer/SeriesMemberVolume.java +++ b/code/reindexer/src/org/aspen_discovery/reindexer/SeriesMemberVolume.java @@ -5,15 +5,17 @@ public class SeriesMemberVolume { private boolean deleted; private boolean userAdded; private boolean foundInIndex; + private boolean userDefinedVolume; public SeriesMemberVolume() { } - public SeriesMemberVolume(String volume, boolean deleted, boolean userAdded) { + public SeriesMemberVolume(String volume, boolean deleted, boolean userAdded, boolean userDefinedVolume) { this.volume = volume; this.deleted = deleted; this.userAdded = userAdded; + this.userDefinedVolume = userDefinedVolume; } public String getVolume() { @@ -36,6 +38,10 @@ public boolean isUserAdded() { return userAdded; } + public boolean isUserDefinedVolume() { + return userDefinedVolume; + } + public void setUserAdded(boolean userAdded) { this.userAdded = userAdded; } diff --git a/code/web/release_notes/26.10.00/DIS-2941.yaml b/code/web/release_notes/26.10.00/DIS-2941.yaml new file mode 100644 index 00000000000..9c5ddf51422 --- /dev/null +++ b/code/web/release_notes/26.10.00/DIS-2941.yaml @@ -0,0 +1,12 @@ +Jira: DIS-2941 +Type: Bug +Developer: Kodi Lein (KL) +ContributingOrg: Grove For Libraries +Sponsor: HMCPL +GroveRelease: 26.10.00 +CommunityRelease: 26.11.00 +Component: Series +Description: + - Fix issue where edited volume information for V2 series gets overwritten during indexing. +NewSettings: +NewPermissions: \ No newline at end of file diff --git a/code/web/sys/DBMaintenance/version_updates/26.10.00.php b/code/web/sys/DBMaintenance/version_updates/26.10.00.php index 7a4b8b806bd..78e50cc49e3 100644 --- a/code/web/sys/DBMaintenance/version_updates/26.10.00.php +++ b/code/web/sys/DBMaintenance/version_updates/26.10.00.php @@ -41,6 +41,15 @@ function getUpdates26_10_00(): array { //add_oauth2_user_consents_table //kodi + 'series_member_user_defined_volume' => [ + 'title' => 'User Defined Volumes for Series Members (V2 Series)', + 'description' => 'Add column for storing if a series member has a user-defined volume value.', + 'continueOnError' => false, + 'sql' => [ + "ALTER TABLE series_member ADD COLUMN userDefinedVolume TINYINT(1) NOT NULL DEFAULT 0", + ], + ], + //series_member_user_defined_volume //yanjun diff --git a/code/web/sys/Series/SeriesMember.php b/code/web/sys/Series/SeriesMember.php index a37b24c8a9a..be400da4783 100644 --- a/code/web/sys/Series/SeriesMember.php +++ b/code/web/sys/Series/SeriesMember.php @@ -15,6 +15,7 @@ class SeriesMember extends DataObject { public $weight; public $cover; public $userAdded; + public $userDefinedVolume; public $excluded; public $deleted; /** @noinspection PhpUnused */ @@ -105,6 +106,12 @@ static function getObjectStructure(string $context = ''): array { 'label' => 'User Added', 'readOnly' => true, ], + 'userDefinedVolume' => [ + 'property' => 'userDefinedVolume', + 'type' => 'hidden', + 'label' => 'User Defined Volume', + 'readOnly' => true, + ], 'excluded' => [ 'property' => 'excluded', 'type' => 'checkbox', @@ -120,6 +127,9 @@ static function getObjectStructure(string $context = ''): array { public function update(string $context = '') : int|bool { if ($this->groupedWorkPermanentId) { + if (in_array('volume', $this->_changedFields, true)) { + $this->userDefinedVolume = true; + } $this->isPlaceholder = false; } else { $this->isPlaceholder = true; @@ -142,6 +152,7 @@ public function getNumericColumnNames(): array { 'pubDate', 'isPlaceholder', 'userAdded', + 'userDefinedVolume', 'excluded' ]; }