Description
David Gustafsson
2018-04-10 09:17:23 UTC
Created attachment 73916 [details] [review] Bug 20551: Add option for including deleted records in export_records.pl Add option "--include_deleted" to include deleted biblios in export_records.pl as marc records with record status (in leader) set to "d". How to test: 1) Run tests in t/db_dependent/Exporter/Record.t 2) All tests should pass 3) Delete a biblio record in Koha 4) Run the export script as: `export_records.pl --date=<date-just-before-deletion> --include_deleted` 5) Open the generated koha.mrc, and verify that contains the recently deleted record, and that the record header has record status "d". 6) Perform the same check with: `export_records.pl --date=<date-just-before-deletion> --include_deleted --format=xml` Sponsored-by: Gothenburg University Library Created attachment 73923 [details] [review] Bug 20551: Add option for including deleted records in export_records.pl Add option "--include_deleted" to include deleted biblios in export_records.pl as marc records with record status (in leader) set to "d" and "--deleted_only" to export only deleted biblios. How to test: 1) Run tests in t/db_dependent/Exporter/Record.t 2) All tests should pass 3) Delete a biblio record in Koha 4) Run the export script as: `export_records.pl --date=<date-just-before-deletion> --include_deleted` 5) Open the generated koha.mrc, and verify that contains the recently deleted record, and that the record header has record status "d". 6) Perform the same check with: `export_records.pl --date=<date-just-before-deletion> --include_deleted --format=xml` 7) Run: `export_records.pl --date=<date-just-before-deletion> --deleted_only --format=xml` and verify that only the deleted biblio was included in the export. Sponsored-by: Gothenburg University Library As some might need it, also added an '--deleted_only' option, to export only the deleted biblios. Created attachment 75113 [details] [review] Bug 20551: Add option for including deleted records in export_records.pl Add option "--include_deleted" to include deleted biblios in export_records.pl as marc records with record status (in leader) set to "d" and "--deleted_only" to export only deleted biblios. How to test: 1) Run tests in t/db_dependent/Exporter/Record.t 2) All tests should pass 3) Delete a biblio record in Koha 4) Run the export script as: `export_records.pl --date=<date-just-before-deletion> --include_deleted` 5) Open the generated koha.mrc, and verify that contains the recently deleted record, and that the record header has record status "d". 6) Perform the same check with: `export_records.pl --date=<date-just-before-deletion> --include_deleted --format=xml` 7) Run: `export_records.pl --date=<date-just-before-deletion> --deleted_only --format=xml` and verify that only the deleted biblio was included in the export. Sponsored-by: Gothenburg University Library Rebased against Koha master. Created attachment 82843 [details] [review] Bug 20551: Add option for including deleted records in export_records.pl Add option "--include_deleted" to include deleted biblios in export_records.pl as marc records with record status (in leader) set to "d" and "--deleted_only" to export only deleted biblios. How to test: 1) Run tests in t/db_dependent/Exporter/Record.t 2) All tests should pass 3) Delete a biblio record in Koha 4) Run the export script as: `export_records.pl --date=<date-just-before-deletion> --include_deleted` 5) Open the generated koha.mrc, and verify that contains the recently deleted record, and that the record header has record status "d". 6) Perform the same check with: `export_records.pl --date=<date-just-before-deletion> --include_deleted --format=xml` 7) Run: `export_records.pl --date=<date-just-before-deletion> --deleted_only --format=xml` and verify that only the deleted biblio was included in the export. Sponsored-by: Gothenburg University Library Rebase against master (untested, will test later and verify that still works). The functionality of this works as described in the test plan. However, the QA tools raise this warning: FAIL Koha/Exporter/Record.pm FAIL critic # Subroutines::ProhibitExplicitReturnUndef: Got 1 violation(s). And t/db_dependent/Exporter/Record.t returns this error: t/db_dependent/Exporter/Record.t .. 1/6 # No tests run! # Failed test 'No tests run for subtest "export xml"' # at t/db_dependent/Exporter/Record.t line 187. # No tests run! # Failed test 'No tests run for subtest "export iso2709"' # at t/db_dependent/Exporter/Record.t line 219. # Looks like you failed 2 tests of 6. t/db_dependent/Exporter/Record.t .. Dubious, test returned 2 (wstat 512, 0x200) Failed 2/6 subtests Test Summary Report ------------------- t/db_dependent/Exporter/Record.t (Wstat: 512 Tests: 6 Failed: 2) Failed tests: 2-3 Non-zero exit status: 2 Files=1, Tests=6, 3 wallclock secs ( 0.02 usr 0.01 sys + 1.41 cusr 0.69 csys = 2.13 CPU) Result: FAIL Created attachment 82914 [details] [review] Bug 20551: Add option for including deleted records in export_records.pl Add option "--include_deleted" to include deleted biblios in export_records.pl as marc records with record status (in leader) set to "d" and "--deleted_only" to export only deleted biblios. How to test: 1) Run tests in t/db_dependent/Exporter/Record.t 2) All tests should pass 3) Delete a biblio record in Koha 4) Run the export script as: `export_records.pl --date=<date-just-before-deletion> --include_deleted` 5) Open the generated koha.mrc, and verify that contains the recently deleted record, and that the record header has record status "d". 6) Perform the same check with: `export_records.pl --date=<date-just-before-deletion> --include_deleted --format=xml` 7) Run: `export_records.pl --date=<date-just-before-deletion> --deleted_only --format=xml` and verify that only the deleted biblio was included in the export. Sponsored-by: Gothenburg University Library Found the culprit (next in map that accidentally got there in rebase, where should just return empty list), now tests should pass. Forgot to fix the perl critic issue, will do. Created attachment 82918 [details] [review] Bug 20551: Add option for including deleted records in export_records.pl Add option "--include_deleted" to include deleted biblios in export_records.pl as marc records with record status (in leader) set to "d" and "--deleted_only" to export only deleted biblios. How to test: 1) Run tests in t/db_dependent/Exporter/Record.t 2) All tests should pass 3) Delete a biblio record in Koha 4) Run the export script as: `export_records.pl --date=<date-just-before-deletion> --include_deleted` 5) Open the generated koha.mrc, and verify that contains the recently deleted record, and that the record header has record status "d". 6) Perform the same check with: `export_records.pl --date=<date-just-before-deletion> --include_deleted --format=xml` 7) Run: `export_records.pl --date=<date-just-before-deletion> --deleted_only --format=xml` and verify that only the deleted biblio was included in the export. Sponsored-by: Gothenburg University Library Patch didn't apply for me. I got: CONFLICT (content): Merge conflict in misc/export_records.pl Failed to merge in the changes. Patch failed at 0001 Bug 20551: Add option for including deleted records in export_records.pl Same for me, marking "Patch doesn't apply". Frnak, you can set that status too if you run into this the next time! Created attachment 90184 [details] [review] Bug 20551: Add option for including deleted records in export_records.pl Add option "--include_deleted" to include deleted biblios in export_records.pl as marc records with record status (in leader) set to "d" and "--deleted_only" to export only deleted biblios. How to test: 1) Run tests in t/db_dependent/Exporter/Record.t 2) All tests should pass 3) Delete a biblio record in Koha 4) Run the export script as: `export_records.pl --date=<date-just-before-deletion> --include_deleted` 5) Open the generated koha.mrc, and verify that contains the recently deleted record, and that the record header has record status "d". 6) Perform the same check with: `export_records.pl --date=<date-just-before-deletion> --include_deleted --format=xml` 7) Run: `export_records.pl --date=<date-just-before-deletion> --deleted_only --format=xml` and verify that only the deleted biblio was included in the export. Sponsored-by: Gothenburg University Library Rebased against master. Created attachment 90190 [details] [review] Bug 20551: Fix option name in pod Created attachment 90220 [details] [review] Bug 20551: Rename "marcflavour" field to "schema" Test during hackfest 2019 error: sha1 information is lacking or useless (Koha/Exporter/Record.pm). error: could not build fake ancestor Patch failed at 0001 Bug 20551: Rename "marcflavour" field to "schema" Created attachment 93619 [details] [review] Bug 20551: Add option for including deleted records in export_records.pl Add option "--include_deleted" to include deleted biblios in export_records.pl as marc records with record status (in leader) set to "d" and "--deleted_only" to export only deleted biblios. How to test: 1) Run tests in t/db_dependent/Exporter/Record.t 2) All tests should pass 3) Delete a biblio record in Koha 4) Run the export script as: `export_records.pl --date=<date-just-before-deletion> --include_deleted` 5) Open the generated koha.mrc, and verify that contains the recently deleted record, and that the record header has record status "d". 6) Perform the same check with: `export_records.pl --date=<date-just-before-deletion> --include_deleted --format=xml` 7) Run: `export_records.pl --date=<date-just-before-deletion> --deleted_only --format=xml` and verify that only the deleted biblio was included in the export. Sponsored-by: Gothenburg University Library Created attachment 93620 [details] [review] Bug 20551: Fix option name in pod Created attachment 93621 [details] [review] Bug 20551: Rename "marcflavour" field to "schema" Should now be rebased against master. (In reply to David Gustafsson from comment #23) > Should now be rebased against master. The patch itself applies and works fine for me. However, the test doesn't pass: t/db_dependent/Exporter/Record.t .. 1/6 # Failed test 'Deleted record has the correct leader value' # at t/db_dependent/Exporter/Record.t line 186. # got: '00134dam a22000617a 4500' # expected: '00136dam a22000617a 4500' # Looks like you failed 1 test of 4. # Failed test 'export xml' # at t/db_dependent/Exporter/Record.t line 187. # Failed test 'Deleted record has the correct leader value' # at t/db_dependent/Exporter/Record.t line 218. # got: '00134dam a22000617a 4500' # expected: '00136dam a22000617a 4500' # Looks like you failed 1 test of 4. # Failed test 'export iso2709' # at t/db_dependent/Exporter/Record.t line 219. t/db_dependent/Exporter/Record.t .. 5/6 # Looks like you failed 2 tests of 6. t/db_dependent/Exporter/Record.t .. Dubious, test returned 2 (wstat 512, 0x200) Failed 2/6 subtests Test Summary Report ------------------- t/db_dependent/Exporter/Record.t (Wstat: 512 Tests: 6 Failed: 2) Failed tests: 2-3 Non-zero exit status: 2 Files=1, Tests=6, 4 wallclock secs ( 0.02 usr 0.00 sys + 2.94 cusr 0.28 csys = 3.24 CPU) Result: FAIL The test failed because I ran the test on an empty database. I will now sign off the patch. 1. Doesn't it make sense to have this for authority records as well? 2. Why is --date mandatory? 3. POD does not tell that --deleted_only and --include_deleted is only available for bibs 4. --id_list_file does not work with --deleted_only 5. Items are not exported, I guess that's expected but maybe we should have it noted somewhere? *** Bug 17693 has been marked as a duplicate of this bug. *** (In reply to Jonathan Druart from comment #26) > 1. Doesn't it make sense to have this for authority records as well? The authority records are stored in auth_header table. But deleted records is not kept anywhere else. As I can see, this would require to keep deleted authority records in an another table like deletedauth_header. Hi Frank, you are right, we do not keep the deleted authorities, so that takes care of 1. I think some of the other questions could still be answered/improved: (In reply to Jonathan Druart from comment #26) > 1. Doesn't it make sense to have this for authority records as well? Because we don't keep them ;) > 2. Why is --date mandatory? Not sure about this one, can you explain? > 3. POD does not tell that --deleted_only and --include_deleted is only > available for bibs Easy fix to documentation I think and it could help people who are not aware of database structure. > 4. --id_list_file does not work with --deleted_only Cannot tell about this one, but sounds worth looking into. > 5. Items are not exported, I guess that's expected but maybe we should have > it noted somewhere? Maybe also a note in the docs? (In reply to Jonathan Druart from comment #26) > 1. Doesn't it make sense to have this for authority records as well? > > 2. Why is --date mandatory? > > 3. POD does not tell that --deleted_only and --include_deleted is only > available for bibs > > 4. --id_list_file does not work with --deleted_only > > 5. Items are not exported, I guess that's expected but maybe we should have > it noted somewhere? 2) I think I just assumed it was required since included in the SQL-query, also before the patch. Did not realize that "SELECT * FROM biblio_metadata WHERE timestamp > ''" is equivalent with "SELECT * FROM biblio_metadata" if every timestamp entry has a value. So with that in mind an empty timestamp is ok, though the code is a real eyesore :) 3) I think it's already pretty clear since will produce an error message is --included_deleted or --deleted_only is used in conjunction with record_type other than 'bibs'. But I clarified this in the usage documentation for said options. 4) Did not work since have to add special case for @deleted_record_ids, fixed this. 5). There actually is a "deleteditems" table so I guess it would be possible to include these, even though it's hard to imagine why you would want to do this. Since the default is to include items perhaps it would be best to leave this as is and never include items for deleted biblios, or you will get more data than you probably want by default. It would also increase code complexity, probably with little benefit. If someone requests this it can be fixed later perhaps. Will point it out in the documentation that items are not included. Created attachment 105403 [details] [review] Bug 20551: Improve documentation and make compatible with more options Created attachment 116408 [details] [review] Bug 20551: Add option for including deleted records in export_records.pl Add option "--include_deleted" to include deleted biblios in export_records.pl as marc records with record status (in leader) set to "d" and "--deleted_only" to export only deleted biblios. How to test: 1) Run tests in t/db_dependent/Exporter/Record.t 2) All tests should pass 3) Delete a biblio record in Koha 4) Run the export script as: `export_records.pl --date=<date-just-before-deletion> --include_deleted` 5) Open the generated koha.mrc, and verify that contains the recently deleted record, and that the record header has record status "d". 6) Perform the same check with: `export_records.pl --date=<date-just-before-deletion> --include_deleted --format=xml` 7) Run: `export_records.pl --date=<date-just-before-deletion> --deleted_only --format=xml` and verify that only the deleted biblio was included in the export. Sponsored-by: Gothenburg University Library Great job! Signed-off-by: Frank Hansen <frank.hansen@ub.lu.se> Created attachment 116409 [details] [review] Bug 20551: Fix option name in pod Signed-off-by: Frank Hansen <frank.hansen@ub.lu.se> Created attachment 116410 [details] [review] Bug 20551: Rename "marcflavour" field to "schema" Signed-off-by: Frank Hansen <frank.hansen@ub.lu.se> Created attachment 116411 [details] [review] Bug 20551: Improve documentation and make compatible with more options Signed-off-by: Frank Hansen <frank.hansen@ub.lu.se>
>
> 5). There actually is a "deleteditems" table so I guess it would be possible
> to include these, even though it's hard to imagine why you would want to do
> this. Since the default is to include items perhaps it would be best to
> leave this as is and never include items for deleted biblios, or you will
> get more data than you probably want by default. It would also increase code
> complexity, probably with little benefit. If someone requests this it can be
> fixed later perhaps. Will point it out in the documentation that items are
> not included.
I think introducing the export of deleted records and deleted items separately would be a good idea. Let's start with this well defined feature and think about the deleted items some more.
While records have a flag to say "deleted", we don't have the same for items. So we could start exporting deleted items that belonged to deleted records, but what about other deleted items on existing records? How to "mark" them as deleted?
I am sorry, but tests are failing :( kohadev-koha@kohadevbox:/home/vagrant/kohaclone$ prove t/db_dependent/Exporter/Record.t t/db_dependent/Exporter/Record.t .. 1/6 Use of uninitialized value in concatenation (.) or string at /usr/share/perl5/MARC/File/XML.pm line 397, <$fh> chunk 7. # Failed test 'Deleted record has the correct leader value' # at t/db_dependent/Exporter/Record.t line 179. # got: '00134dam a22000617a 4500' # expected: '00136dam a22000617a 4500' # Looks like you failed 1 test of 4. # Failed test 'export xml' # at t/db_dependent/Exporter/Record.t line 180. # Failed test 'Deleted record has the correct leader value' # at t/db_dependent/Exporter/Record.t line 211. # got: '00134dam a22000617a 4500' # expected: '00136dam a22000617a 4500' # Looks like you failed 1 test of 4. # Failed test 'export iso2709' # at t/db_dependent/Exporter/Record.t line 212. # Looks like you failed 2 tests of 6. t/db_dependent/Exporter/Record.t .. Dubious, test returned 2 (wstat 512, 0x200) Failed 2/6 subtests Created attachment 123099 [details] [review] Bug 20551: fix tests Created attachment 123101 [details] [review] Bug 20551: Add missing subroutine import Created attachment 123102 [details] [review] Bug 20551: Fix tests (In reply to Katrin Fischer from comment #36) > > > > 5). There actually is a "deleteditems" table so I guess it would be possible > > to include these, even though it's hard to imagine why you would want to do > > this. Since the default is to include items perhaps it would be best to > > leave this as is and never include items for deleted biblios, or you will > > get more data than you probably want by default. It would also increase code > > complexity, probably with little benefit. If someone requests this it can be > > fixed later perhaps. Will point it out in the documentation that items are > > not included. > > I think introducing the export of deleted records and deleted items > separately would be a good idea. Let's start with this well defined feature > and think about the deleted items some more. > > While records have a flag to say "deleted", we don't have the same for > items. So we could start exporting deleted items that belonged to deleted > records, but what about other deleted items on existing records? How to > "mark" them as deleted? Now the tests are fixed. Regarding export of deleted items from a first glance I can see how you would expect this just as matter of symmetry with the regular export, but both conceptually and for lots of other reasons it makes no sense at all. 1. Exporting deleted records is probably never done to save the record information somewhere else, but to use data in records to match a record somewhere else to remove. I cannot imagine a case where this data would be found on an item-level. 2. It would require us to refactor C4::Biblio::EmbedItemsInMarcBiblio just for this specific case (which is an edge case that in practice will probably never be utilized), further increasing the burden of code maintenance and risk of introducing new bugs. If I'm incorrect and this feature is requested by many users it's always possible to implement later, but I would be very surprised if this turns out to be the case. Created attachment 125211 [details] [review] Bug 20551: Add option for including deleted records in export_records.pl Add option "--include_deleted" to include deleted biblios in export_records.pl as marc records with record status (in leader) set to "d" and "--deleted_only" to export only deleted biblios. How to test: 1) Run tests in t/db_dependent/Exporter/Record.t 2) All tests should pass 3) Delete a biblio record in Koha 4) Run the export script as: `export_records.pl --date=<date-just-before-deletion> --include_deleted` 5) Open the generated koha.mrc, and verify that contains the recently deleted record, and that the record header has record status "d". 6) Perform the same check with: `export_records.pl --date=<date-just-before-deletion> --include_deleted --format=xml` 7) Run: `export_records.pl --date=<date-just-before-deletion> --deleted_only --format=xml` and verify that only the deleted biblio was included in the export. Sponsored-by: Gothenburg University Library Signed-off-by: Frank Hansen <frank.hansen@ub.lu.se> Created attachment 125212 [details] [review] Bug 20551: Fix option name in pod Signed-off-by: Frank Hansen <frank.hansen@ub.lu.se> Created attachment 125213 [details] [review] Bug 20551: Rename "marcflavour" field to "schema" Signed-off-by: Frank Hansen <frank.hansen@ub.lu.se> Created attachment 125214 [details] [review] Bug 20551: Improve documentation and make compatible with more options Signed-off-by: Frank Hansen <frank.hansen@ub.lu.se> Created attachment 125215 [details] [review] Bug 20551: Add missing subroutine import Created attachment 125216 [details] [review] Bug 20551: Fix tests Rebase against master. Created attachment 128895 [details] [review] Bug 20551: Add option for including deleted records in export_records.pl Add option "--include_deleted" to include deleted biblios in export_records.pl as marc records with record status (in leader) set to "d" and "--deleted_only" to export only deleted biblios. How to test: 1) Run tests in t/db_dependent/Exporter/Record.t 2) All tests should pass 3) Delete a biblio record in Koha 4) Run the export script as: `export_records.pl --date=<date-just-before-deletion> --include_deleted` 5) Open the generated koha.mrc, and verify that contains the recently deleted record, and that the record header has record status "d". 6) Perform the same check with: `export_records.pl --date=<date-just-before-deletion> --include_deleted --format=xml` 7) Run: `export_records.pl --date=<date-just-before-deletion> --deleted_only --format=xml` and verify that only the deleted biblio was included in the export. Sponsored-by: Gothenburg University Library Signed-off-by: Frank Hansen <frank.hansen@ub.lu.se> Created attachment 128896 [details] [review] Bug 20551: Fix option name in pod Signed-off-by: Frank Hansen <frank.hansen@ub.lu.se> Created attachment 128897 [details] [review] Bug 20551: Rename "marcflavour" field to "schema" Signed-off-by: Frank Hansen <frank.hansen@ub.lu.se> Created attachment 128898 [details] [review] Bug 20551: Improve documentation and make compatible with more options Signed-off-by: Frank Hansen <frank.hansen@ub.lu.se> Created attachment 128899 [details] [review] Bug 20551: Add missing subroutine import Created attachment 128900 [details] [review] Bug 20551: Fix tests Signed-off-by: Frank Hansen <frank.hansen@ub.lu.se> Works fine for me. Signing off Will this enhancement be available from the staff interface? i.e., Tools > Export data (.../cgi-bin/koha/tools/export.pl) (In reply to Cab Vinton from comment #55) > Will this enhancement be available from the staff interface? i.e., Tools > > Export data (.../cgi-bin/koha/tools/export.pl) From looking at the patch set this will only appear in the command line script. But as this has been waiting a while now, I suggest we file a separate report for making this available on GUI side. What do you think? + my $marc_flavour = C4::Context->preference('marcflavour'); + my $biblio_metadata = $resultset->find({ + 'biblionumber' => $biblionumber, + 'format' => 'marcxml', + 'marcflavour' => $marc_flavour + }); + my $marc_xml = $biblio_metadata->metadata; + $marc_xml = StripNonXmlChars($marc_xml); + + my $record = eval { + MARC::Record::new_from_xml($marc_xml, 'UTF-8', $marc_flavour) + }; + if (!$record) { You test $record, but you should have tested $biblio_metadata too ? Otherwise you already crash on ->metadata.. + return unless (@{$record_ids} || @{$deleted_record_ids} && $format ne 'csv'); Parentheses here would be more helpful inside. The outer ones are not needed. But in order to read easier, you could do A || ( B && C ) sub export binmode $fh, ':encoding(UTF-8)' unless $format eq 'csv'; } else { binmode STDOUT, ':encoding(UTF-8)' unless $format eq 'csv'; What happens if we choose csv? Are we not doing UTF-8 ? Later we do: print marc2csv( $record_ids, $csv_profile_id, $itemnumbers ); (In reply to Marcel de Rooy from comment #58) > + return unless (@{$record_ids} || @{$deleted_record_ids} && $format ne > 'csv'); > > Parentheses here would be more helpful inside. The outer ones are not needed. > But in order to read easier, you could do A || ( B && C ) And functionally: why not deleted records in csv ? + my ($record_type) = @_; + my $validator = $encoding_validator->('Record'); + $validator = $encoding_validator->('Deleted record'); Deleted flag ? - my $record = _get_record_for_export( { %$params, record_id => $record_id } ); + for my $record (@records, @deleted_records) { + print MARC::File::XML::record($record); Noting that get_record_for_export does a lot more and we seem to loose that now? Ok, not all my questions have the same importance and I realize that this dev is already too long in the pipeline, but I like to have feedback now. Changing status to reflect that (In reply to Katrin Fischer from comment #56) > From looking at the patch set this will only appear in the command line > script. But as this has been waiting a while now, I suggest we file a > separate report for making this available on GUI side. What do you think? I missed this earlier, but Yes, a separate report for the GUI side makes sense. I would wait until this one is fully signed off, but others are welcome to proceed if they wish. Not sure how prevalent this is, but I believe quite a few union catalogs still ask contributing members to regularly send updates w/ lists of records added & deleted. So this feature would come in handy for all the folks who don't have access to the command line. (In reply to Marcel de Rooy from comment #57) > + my $marc_flavour = C4::Context->preference('marcflavour'); > + my $biblio_metadata = $resultset->find({ > + 'biblionumber' => $biblionumber, > + 'format' => 'marcxml', > + 'marcflavour' => $marc_flavour > + }); > + my $marc_xml = $biblio_metadata->metadata; > + $marc_xml = StripNonXmlChars($marc_xml); > + > + my $record = eval { > + MARC::Record::new_from_xml($marc_xml, 'UTF-8', $marc_flavour) > + }; > + if (!$record) { > > You test $record, but you should have tested $biblio_metadata too ? > Otherwise you already crash on ->metadata.. Hi, thanks for the feedback. There is no definite right or wrong, but personally try to avoid defensive programming where things are very unlikely to fail. Ids should be valid since have been previously fetched from database, in case of the XML-decoding it's highly unlikely to go wrong, but I can imagine cases where it could. (In reply to Marcel de Rooy from comment #57) > + my $marc_flavour = C4::Context->preference('marcflavour'); > + my $biblio_metadata = $resultset->find({ > + 'biblionumber' => $biblionumber, > + 'format' => 'marcxml', > + 'marcflavour' => $marc_flavour > + }); > + my $marc_xml = $biblio_metadata->metadata; > + $marc_xml = StripNonXmlChars($marc_xml); > + > + my $record = eval { > + MARC::Record::new_from_xml($marc_xml, 'UTF-8', $marc_flavour) > + }; > + if (!$record) { > > You test $record, but you should have tested $biblio_metadata too ? > Otherwise you already crash on ->metadata.. Hi, thanks for the feedback. There is no definite right or wrong, but personally try to avoid defensive programming where things are very unlikely to fail. Ids should be valid since have been previously fetched from database, in case of the XML-decoding it's highly unlikely to go wrong, but I can imagine cases where it could.(In reply to Marcel de Rooy from comment #58) > + return unless (@{$record_ids} || @{$deleted_record_ids} && $format ne > 'csv'); > > Parentheses here would be more helpful inside. The outer ones are not needed. > But in order to read easier, you could do A || ( B && C ) Yes,they could be removed. Personally I think it's more confusing, or at least a bit unsightly, to use parenthesis for anything else than changing operator precedence. At least with "||" and "&&" where there really should be no confusion. (In reply to Marcel de Rooy from comment #59) > sub export > > binmode $fh, ':encoding(UTF-8)' unless $format eq 'csv'; > } else { > binmode STDOUT, ':encoding(UTF-8)' unless $format eq 'csv'; > > What happens if we choose csv? Are we not doing UTF-8 ? > Later we do: > > print marc2csv( $record_ids, $csv_profile_id, $itemnumbers ); I had a look at this and don't think this block is part of the patch. (In reply to Marcel de Rooy from comment #59) > sub export > > binmode $fh, ':encoding(UTF-8)' unless $format eq 'csv'; > } else { > binmode STDOUT, ':encoding(UTF-8)' unless $format eq 'csv'; > > What happens if we choose csv? Are we not doing UTF-8 ? > Later we do: > > print marc2csv( $record_ids, $csv_profile_id, $itemnumbers ); marc2csv uses GetMarcBiblio to load biblios that does not support loading deleted biblios which resides in another table. marc2csv would have to be carefully reviewed and refactored to ensure it can handle deleted biblios, this would increase the scope of this patch and I just did not think it was worth the effort. A separate issues could perhaps be created in case there is an interest implementing support for this. Sorry, the last comment was meant to be a response to:
> And functionally: why not deleted records in csv ?
(In reply to Marcel de Rooy from comment #61) > + my ($record_type) = @_; > > + my $validator = $encoding_validator->('Record'); > > + $validator = $encoding_validator->('Deleted record'); > > Deleted flag ? I don't think I understand. The string is correct, but looking at the code I wonder why creating a closure instead of just providing the argument further down, I should probably change this. (In reply to Marcel de Rooy from comment #62) > - my $record = _get_record_for_export( { %$params, record_id => > $record_id } ); > > + for my $record (@records, @deleted_records) { > + print MARC::File::XML::record($record); > > Noting that get_record_for_export does a lot more and we seem to loose that > now? Yes, right now I can't think of any reason why deleted records should not be a new record type in _get_record_for_export and processed in the same way as the others (authorities and biblios). I will look into this. (_get_record_for_export is still called to fetch the other records though, so no functionality has been removed there, but reading what it does don't se how most of the same operations should not work also on deleted biblios) Created attachment 132936 [details] [review] Bug 20551: Fetch deleted biblios through _get_record_export Created attachment 132937 [details] [review] Bug 20551: Refactor unmotivated partially applied validator function Thanks again for the feedback, I think at least the most important issues should now be fixed. Must have forgotten to change status, setting to Needs Signoff. (In reply to David Gustafsson from comment #76) > Must have forgotten to change status, setting to Needs Signoff. Hi David, The patches do not apply anymore but I'd be happy to signoff if you rebase it on current main :) Best, Arthur Created attachment 176623 [details] [review] Bug 20551: Add option for including deleted records in export_records.pl Add option "--include_deleted" to include deleted biblios in export_records.pl as marc records with record status (in leader) set to "d" and "--deleted_only" to export only deleted biblios. How to test: 1) Run tests in t/db_dependent/Exporter/Record.t 2) All tests should pass 3) Delete a biblio record in Koha 4) Run the export script as: `export_records.pl --date=<date-just-before-deletion> --include_deleted` 5) Open the generated koha.mrc, and verify that contains the recently deleted record, and that the record header has record status "d". 6) Perform the same check with: `export_records.pl --date=<date-just-before-deletion> --include_deleted --format=xml` 7) Run: `export_records.pl --date=<date-just-before-deletion> --deleted_only --format=xml` and verify that only the deleted biblio was included in the export. Sponsored-by: Gothenburg University Library Signed-off-by: Frank Hansen <frank.hansen@ub.lu.se> Created attachment 176624 [details] [review] Bug 20551: Fix option name in pod Signed-off-by: Frank Hansen <frank.hansen@ub.lu.se> Created attachment 176625 [details] [review] Bug 20551: Rename "marcflavour" field to "schema" Signed-off-by: Frank Hansen <frank.hansen@ub.lu.se> Created attachment 176626 [details] [review] Bug 20551: Improve documentation and make compatible with more options Signed-off-by: Frank Hansen <frank.hansen@ub.lu.se> Created attachment 176627 [details] [review] Bug 20551: Add missing subroutine import Created attachment 176628 [details] [review] Bug 20551: Fix tests Signed-off-by: Frank Hansen <frank.hansen@ub.lu.se> Works fine for me. Signing off Created attachment 176629 [details] [review] Bug 20551: Fetch deleted biblios through _get_record_export Created attachment 176630 [details] [review] Bug 20551: Refactor unmotivated partially applied validator function Created attachment 176631 [details] [review] Bug 20551: (QA follow-up) perltidy and test fixes Just made a rebase a small patch to make the QA scripts happy. Arthur Created attachment 177536 [details] [review] Bug 20551: Move some code that might be reused into functions Ohhhh there is an issue when biblio.biblionumber is on control field like 001 : my ($id_tag, $id_subfield) = GetMarcFromKohaField('biblio.biblionumber', ''); my $record_id = $record->subfield($id_tag, $id_subfield); Fails with : Control fields (generally, just tags below 010) do not have subfields, use data() at /usr/share/perl5/MARC/Record.pm line 240. Maybe when record can not be encoded we should not try to read its content Created attachment 178343 [details] [review] Bug 20551: Add option for including deleted records in export_records.pl Add option "--include_deleted" to include deleted biblios in export_records.pl as marc records with record status (in leader) set to "d" and "--deleted_only" to export only deleted biblios. How to test: 1) Run tests in t/db_dependent/Exporter/Record.t 2) All tests should pass 3) Delete a biblio record in Koha 4) Run the export script as: `export_records.pl --date=<date-just-before-deletion> --include_deleted` 5) Open the generated koha.mrc, and verify that contains the recently deleted record, and that the record header has record status "d". 6) Perform the same check with: `export_records.pl --date=<date-just-before-deletion> --include_deleted --format=xml` 7) Run: `export_records.pl --date=<date-just-before-deletion> --deleted_only --format=xml` and verify that only the deleted biblio was included in the export. Sponsored-by: Gothenburg University Library Signed-off-by: Frank Hansen <frank.hansen@ub.lu.se> Created attachment 178344 [details] [review] Bug 20551: Fix option name in pod Signed-off-by: Frank Hansen <frank.hansen@ub.lu.se> Created attachment 178345 [details] [review] Bug 20551: Rename "marcflavour" field to "schema" Signed-off-by: Frank Hansen <frank.hansen@ub.lu.se> Created attachment 178346 [details] [review] Bug 20551: Improve documentation and make compatible with more options Signed-off-by: Frank Hansen <frank.hansen@ub.lu.se> Created attachment 178347 [details] [review] Bug 20551: Add missing subroutine import Created attachment 178348 [details] [review] Bug 20551: Fix tests Signed-off-by: Frank Hansen <frank.hansen@ub.lu.se> Works fine for me. Signing off Created attachment 178349 [details] [review] Bug 20551: Fetch deleted biblios through _get_record_export Created attachment 178350 [details] [review] Bug 20551: Refactor unmotivated partially applied validator function Created attachment 178351 [details] [review] Bug 20551: (QA follow-up) perltidy and test fixes Created attachment 178352 [details] [review] Bug 20551: Move some code that might be reused into functions Created attachment 178353 [details] [review] Bug 20551: (QA follow-up) don't read record content if there is an error during decoding just made a rebase using autorebase script + small patch in reply to fridolin's comment Created attachment 178378 [details] [review] Bug 20551: Get biblionumber safly in validator function Created attachment 178379 [details] [review] Bug 20551: Get biblionumber safely in validator function (In reply to Arthur Suzuki from comment #102) > just made a rebase using autorebase script + small patch in reply to > fridolin's comment Thanks for the rebase. As it's useful to still get the biblionumber and not that hard to fix I restored including it in the error message, but now done so will not crash if not stored in a subfield. I think for performance, this call should be outside validator : my ( $id_tag, $id_code ) = GetMarcFromKohaField( 'biblio.biblionumber', '' ); Because validator is called in the loop. We have some use of export more that 1 million records :) Arg I've been using this feature on an a big export and DB server crashed. I see the output file is not filled little by little. I think it comes from this change : + @records = map { + my $record = _get_record_for_export( { %{$params}, record_id => $_ } ); + $record ? $record : (); + } @{$record_ids}; For a huge export the @records object will take too much RAM. Without this path the records are build one by one. Please make some tests to confirm. Created attachment 178575 [details] [review] Bug 20551: Use iterator for retrieving records to save memory Created attachment 178617 [details] [review] Bug 20551: Use iterator for retrieving records to save memory (In reply to Fridolin Somers from comment #107) > Arg I've been using this feature on an a big export and DB server crashed. > I see the output file is not filled little by little. > > I think it comes from this change : > > + @records = map { > + my $record = _get_record_for_export( { %{$params}, record_id => > $_ } ); > + $record ? $record : (); > + } @{$record_ids}; > > For a huge export the @records object will take too much RAM. > > Without this path the records are build one by one. > > Please make some tests to confirm. Good catch, didn't think about that aspect, I fixed this by using an iterator instead. I don't think we need to think about the performance cost of running GetMarcFromKohaField multiple times as it's only called for records with encoding errors, which should be a very small proportion of the total records. Created attachment 178618 [details] [review] Bug 20551: Use iterator for retrieving records to save memory Created attachment 178619 [details] [review] Bug 20551: Use iterator for retrieving records to save memory Hello, In some condition the code could fail : in the sub _get_deleted_biblio_for_export : ---- # Creating schema is expensive, allow caller to # pass it so don't have to recreate for each call my $resultset = $params->{resultset} || Koha::Database->new()->schema()->resultset('DeletedbiblioMetadata'); my $marc_flavour = C4::Context->preference('marcflavour'); my $biblio_metadata = $resultset->find( { 'biblionumber' => $biblionumber, 'format' => 'marcxml', 'schema' => $marc_flavour } ); my $marc_xml = $biblio_metadata->metadata; $marc_xml = StripNonXmlChars($marc_xml); ---- It seems that an empty result set could lead to querying an empty $biblio_metadata object, resulting in a crash. Probably should warn about "no deleted records" and early return in case of empty resultset? Also I had some errors in the record_iterator sub. Fixed by explicitely using $deleted_record_id instead of $_ : my $records_iterator = sub { if (my $record_id = pop(@record_ids)) { return _get_record_for_export( { %{$params}, record_id => $record_id } ); } elsif (my $deleted_record_id = pop(@deleted_record_ids)) { return _get_record_for_export( { %{$params}, record_type => 'deleted_bibs', - record_id => $_, + record_id => $deleted_record_id, resultset => $deleted_resultset } ); } return; }; I guess the previous error was due to no biblionumber being passed to the _get_record_for_export sub. Created attachment 178679 [details] [review] Bug 20551: Use iterator for retrieving records to save memory Created attachment 178680 [details] [review] Bug 20551: Cache resultset instead of passing to sub Created attachment 178681 [details] [review] Bug 20551: Warn and return if deleted biblio not found Created attachment 178682 [details] [review] Bug 20551: Use timetstamp of deletedbiblio_metadata instead of deletedbibio (In reply to Arthur Suzuki from comment #114) > Also I had some errors in the record_iterator sub. > Fixed by explicitely using $deleted_record_id instead of $_ : > > my $records_iterator = sub { > if (my $record_id = pop(@record_ids)) { > return _get_record_for_export( { %{$params}, record_id => > $record_id } ); > } > elsif (my $deleted_record_id = pop(@deleted_record_ids)) { > return _get_record_for_export( > { > %{$params}, > record_type => 'deleted_bibs', > - record_id => $_, > + record_id => $deleted_record_id, > resultset => $deleted_resultset > } > ); > } > return; > }; > > I guess the previous error was due to no biblionumber being passed to the > _get_record_for_export sub. I don't think that could occur as the deleted biblionumber is always retrieved from the database before and thus always exists. But I agree it should be added to be consistent with (In reply to Arthur Suzuki from comment #113) > Hello, > In some condition the code could fail : > in the sub _get_deleted_biblio_for_export : > ---- > # Creating schema is expensive, allow caller to > > # pass it so don't have to recreate for each call > > my $resultset = $params->{resultset} || > Koha::Database->new()->schema()->resultset('DeletedbiblioMetadata'); > my $marc_flavour = C4::Context->preference('marcflavour'); > my $biblio_metadata = $resultset->find( > { > 'biblionumber' => $biblionumber, > 'format' => 'marcxml', > 'schema' => $marc_flavour > } > ); > my $marc_xml = $biblio_metadata->metadata; > $marc_xml = StripNonXmlChars($marc_xml); > ---- > > It seems that an empty result set could lead to querying an empty > $biblio_metadata object, resulting in a crash. > Probably should warn about "no deleted records" and early return in case of > empty resultset? I don't think that could occur as the deleted biblionumber is always retrieved from the database before and thus always exists. But I agree it should be added to be consistent with _get_biblio_for_export and future proofing the code. You are right it was triggered by me forgetting to replace $_ with $deleted_record_id in the previous patch. I have fixed this now. Also changed the table deleted biblios is selected from in export_records.pl from deletedbiblio to deletedbiblio_metadata as biblio_metadata is used for non deleted biblios. The deleted biblios resultset is now also cached instead of passed as an argument. Tried to apply patches to current master but got the tests failing : ''' kohadev-koha@kohadevbox:koha(main)$ prove t/db_dependent/Exporter/Record.t t/db_dependent/Exporter/Record.t .. 1/7 # Failed test 'Export XML: 3 records should have been exported' # at t/db_dependent/Exporter/Record.t line 200. # got: '1' # expected: '3' # Looks like you planned 4 tests but ran 2. # Looks like you failed 1 test of 2 run. # Failed test 'export xml' # at t/db_dependent/Exporter/Record.t line 211. Can't call method "subfield" on an undefined value at t/db_dependent/Exporter/Record.t line 202, <$fh> line 3. # Looks like your test exited with 11 just after 3. t/db_dependent/Exporter/Record.t .. Dubious, test returned 11 (wstat 2816, 0xb00) Failed 5/7 subtests Test Summary Report ------------------- t/db_dependent/Exporter/Record.t (Wstat: 2816 (exited 11) Tests: 3 Failed: 1) Failed test: 2 Non-zero exit status: 11 Parse errors: Bad plan. You planned 7 tests but ran 3. Files=1, Tests=3, 4 wallclock secs ( 0.03 usr 0.01 sys + 3.58 cusr 0.33 csys = 3.95 CPU) Result: FAIL ''' Created attachment 179748 [details] [review] Bug 20551: Return 0 instead of undef from _get_record_for_export not to break iterator loop (In reply to Arthur Suzuki from comment #120) > Tried to apply patches to current master but got the tests failing : > ''' > kohadev-koha@kohadevbox:koha(main)$ prove t/db_dependent/Exporter/Record.t > t/db_dependent/Exporter/Record.t .. 1/7 > # Failed test 'Export XML: 3 records should have been exported' > # at t/db_dependent/Exporter/Record.t line 200. > # got: '1' > # expected: '3' > # Looks like you planned 4 tests but ran 2. > # Looks like you failed 1 test of 2 run. > > # Failed test 'export xml' > # at t/db_dependent/Exporter/Record.t line 211. > Can't call method "subfield" on an undefined value at > t/db_dependent/Exporter/Record.t line 202, <$fh> line 3. > # Looks like your test exited with 11 just after 3. > t/db_dependent/Exporter/Record.t .. Dubious, test returned 11 (wstat 2816, > 0xb00) > Failed 5/7 subtests > > Test Summary Report > ------------------- > t/db_dependent/Exporter/Record.t (Wstat: 2816 (exited 11) Tests: 3 Failed: 1) > Failed test: 2 > Non-zero exit status: 11 > Parse errors: Bad plan. You planned 7 tests but ran 3. > Files=1, Tests=3, 4 wallclock secs ( 0.03 usr 0.01 sys + 3.58 cusr 0.33 > csys = 3.95 CPU) > Result: FAIL > ''' Thanks for spotting this! The issue should now be fixed. Created attachment 179749 [details] [review] Bug 20551: Return 0 instead of undef from _get_deleted_record_for_export Created attachment 180648 [details] [review] Bug 20551: Add option for including deleted records in export_records.pl Add option "--include_deleted" to include deleted biblios in export_records.pl as marc records with record status (in leader) set to "d" and "--deleted_only" to export only deleted biblios. How to test: 1) Run tests in t/db_dependent/Exporter/Record.t 2) All tests should pass 3) Delete a biblio record in Koha 4) Run the export script as: `export_records.pl --date=<date-just-before-deletion> --include_deleted` 5) Open the generated koha.mrc, and verify that contains the recently deleted record, and that the record header has record status "d". 6) Perform the same check with: `export_records.pl --date=<date-just-before-deletion> --include_deleted --format=xml` 7) Run: `export_records.pl --date=<date-just-before-deletion> --deleted_only --format=xml` and verify that only the deleted biblio was included in the export. Sponsored-by: Gothenburg University Library Signed-off-by: Frank Hansen <frank.hansen@ub.lu.se> Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com> Created attachment 180649 [details] [review] Bug 20551: Fix option name in pod Signed-off-by: Frank Hansen <frank.hansen@ub.lu.se> Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com> Created attachment 180650 [details] [review] Bug 20551: Rename "marcflavour" field to "schema" Signed-off-by: Frank Hansen <frank.hansen@ub.lu.se> Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com> Created attachment 180651 [details] [review] Bug 20551: Improve documentation and make compatible with more options Signed-off-by: Frank Hansen <frank.hansen@ub.lu.se> Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com> Created attachment 180652 [details] [review] Bug 20551: Add missing subroutine import Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com> Created attachment 180653 [details] [review] Bug 20551: Fix tests Signed-off-by: Frank Hansen <frank.hansen@ub.lu.se> Works fine for me. Signing off Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com> Created attachment 180654 [details] [review] Bug 20551: Fetch deleted biblios through _get_record_export Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com> Created attachment 180655 [details] [review] Bug 20551: Refactor unmotivated partially applied validator function Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com> Created attachment 180656 [details] [review] Bug 20551: (QA follow-up) perltidy and test fixes Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com> Created attachment 180657 [details] [review] Bug 20551: Move some code that might be reused into functions Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com> Created attachment 180658 [details] [review] Bug 20551: (QA follow-up) don't read record content if there is an error during decoding Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com> Created attachment 180659 [details] [review] Bug 20551: Get biblionumber safely in validator function Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com> Created attachment 180660 [details] [review] Bug 20551: Use iterator for retrieving records to save memory Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com> Created attachment 180661 [details] [review] Bug 20551: Cache resultset instead of passing to sub Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com> Created attachment 180662 [details] [review] Bug 20551: Warn and return if deleted biblio not found Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com> Created attachment 180663 [details] [review] Bug 20551: Use timetstamp of deletedbiblio_metadata instead of deletedbibio Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com> Created attachment 180664 [details] [review] Bug 20551: Return 0 instead of undef from _get_record_for_export not to break iterator loop Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com> Created attachment 180665 [details] [review] Bug 20551: Return 0 instead of undef from _get_deleted_record_for_export Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com> |