Data.pm 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. package Trog::Data;
  2. use 5.040;
  3. use re '/aasx';
  4. use warnings FATAL => 'all';
  5. use Module::Runtime();
  6. use Path::Tiny();
  7. use Trog::Log qw{:all};
  8. #It's just a factory
  9. =head1 Trog::Data
  10. This is a data model factory.
  11. =head2 Trog::Data->new(Trog::Config) = $handle
  12. Returns a new Trog::Data::* class appropriate to what is configured in the Trog::Config object passed.
  13. Memoized: every call after the first returns the first handle, whatever it is passed.
  14. =cut
  15. sub new ( $, $config ) {
  16. state $datamodule;
  17. return $datamodule if $datamodule;
  18. my $module = "Trog::Data::" . model($config);
  19. Module::Runtime::require_module($module);
  20. $datamodule = $module->new($config);
  21. return $datamodule;
  22. }
  23. =head2 model(Trog::Config) = STRING
  24. The data model to serve from: general.data_model, except on a site which never
  25. moved its posts across with bin/migrate.pl.
  26. SQLite is the shipped default, so a FlatFile site which never saved a
  27. data_model of its own, or which saved the default back, is configured for a
  28. database that does not exist. While data/posts.sqlite is missing and data/files
  29. holds posts, this answers FlatFile and warns, so the site keeps serving the
  30. posts it has. Once the migration has written the database, the configuration
  31. applies as written.
  32. =cut
  33. # FlatFile's datastore, named here because loading that model creates its tag
  34. # index, and this has to look before choosing. Trog::Data::FlatFile has its own.
  35. our $flatfile_store = 'data/files';
  36. sub model ($config) {
  37. my $model = $config->param('general.data_model');
  38. return $model unless $model eq 'SQLite';
  39. # Which that model only creates on first use.
  40. require Trog::Data::SQLite;
  41. no warnings 'once';
  42. my $sqlite_db = $Trog::Data::SQLite::dbname;
  43. return $model if -e $sqlite_db;
  44. my $posts = eval {
  45. scalar grep { -f } Path::Tiny::path($flatfile_store)->children; ## no critic (ProhibitFiletest_f) -- counting names, nothing is opened
  46. } or return $model;
  47. WARN("general.data_model is SQLite, but $sqlite_db does not exist and $flatfile_store holds $posts post(s). Serving them from FlatFile. Run bin/migrate.pl to move them across.");
  48. return 'FlatFile';
  49. }
  50. 1;