UR::DataSource(3pm)

πŸ“¦
version 0.470 Β· 2 versions
, in debian bookworm, ubuntu jammy, ubuntu noble

πŸ’– UR::DataSource(3pm) πŸ’–

okay bestie, welcome to the UR::DataSource(3pm) page πŸ’… this is the one about how your objects find their data. let's go πŸ¦‹


πŸŽ€ NAME πŸŽ€

UR::DataSource β€” manage the the relationship between objects and a specific storage system ✨


🌸 SYNOPSIS 🌸

  package MyApp::DataSource::DB;

  class MyApp::DataSource::DB {
      is => ['UR::DataSource::Oracle','UR::Singleton'],
  };
  sub server { 'main_db_server' }
  sub login  { 'db_user' }
  sub auth   { 'db_passwd' }
  sub owner  { 'db_owner' }
  1;

πŸ’– DESCRIPTION πŸ’–

so, a data source instance is basically a logical source of data for your app β€” like, "here's where the stuff lives" 🫢 most of the time it's gonna be some kind of relational database, but like… not always, no cap. UR::DataSource itself is an abstract base class, meaning other data sources inherit from it and do the actual work.

in normal everyday use, your data sources will probably inherit from an abstract data source class like UR::DataSource::Oracle or UR::DataSource::File, plus UR::Singleton. why is that iconic? because it makes linking classes to this data source so easy β€” the class name is the same as its ID, and the module autoloader will just instantiate it automatically for you. main character behaviour, honestly. πŸ‘‘


πŸ¦‹ INHERITANCE πŸ¦‹

UR::Object


πŸ‘‘ Methods πŸ‘‘

ngl, user applications will seldom interact with data sources directly. it's giving backstage crew. but here's everything anyway πŸ’œ

autogenerate_new_object_id_for_class_name_and_rule

  my $id = $datasource->autogenerate_new_object_id_for_class_name_and_rule($class,$boolexpr);

UR::Object::Type calls this when your app calls create() on a class to make a new instance but doesn't specify a value for the ID property. the default implementation just throws an exception with die πŸ’€ β€” but UR::DataSource::RDBMS is built different: it can query a sequence in the database to generate unique IDs. so if you're a dev implementing a new data source, you need to override this method and give it a sensible implementation. periodt.

next_dummy_autogenerated_id

  my $int = $datasource->next_dummy_autogenerated_id()

when you're testing, it's often preferable to avoid using the database's sequence for ID autogeneration but still make ID values that are unique. UR::DataSource::RDBMS calls this method if the use_dummy_autogenerated_ids flag (see below πŸ‘‡) is true. the IDs it generates are unique during the life of the process. and also β€” objects with dummy-generated IDs will never be saved to a real data source during UR::Context::commit(). fake IDs stay fake, periodt πŸ™ˆ

use_dummy_autogenerated_ids

  $bool = $datasource->use_dummy_autogenerated_ids();
  $datasource->use_dummy_autogenerated_ids($bool);

get or set the flag that controls how object IDs are autogenerated. data source child classes should peek at the value of this flag inside their implementation of autogenerate_new_object_id_for_class_name_and_rule. if it's true, they should call next_dummy_autogenerated_id and return that value instead of trying to generate an ID on their own. this flag is also tied to the UR_USE_DUMMY_AUTOGENERATED_IDS environment variable πŸŽ€

resolve_data_sources_for_rule

  $possibly_other_data_source = $data_source->resolve_data_sources_for_rule($boolexpr);

when UR::Context is figuring out which data source to use to process a get() request, it looks at the class metadata for its data source, and then calls resolve_data_sources_for_rule to give that data source a chance to defer to another data source. it's like "not me, ask her" πŸ’…

create_iterator_closure_for_rule_template_and_values

  $subref = $datasource->create_iterator_closure_for_rule_template_and_values(
                             $boolexpr_tmpl,
                             @values
                         );

a front-end for the more widely used create_iterator_closure_for_rule ✨

create_iterator_closure_for_rule

  $subref = $datasource->create_iterator_closure_for_rule($boolexpr);

this is the main entry point UR::Context uses to get data from its underlying data sources. there is no default implementation β€” every subclass implementing a specific data source type must supply its own code, no shortcuts.

the method must accept a UR::BoolExpr $boolexpr (a rule), and return a subref. each time the subref is called it must return one arrayref of data satisfying the rule, and undef when there is no more data to return. lowkey elegant. 🌈

_sync_database

  $bool = $datasource->_sync_database(changed_objects => $listref);

called by UR::Context commit(). $listref will contain all the changed objects that should be saved to that data source. the default implementation prints a warning message and returns true without saving anything β€” yes, it just vibes and does nothing 😭

UR::DataSource::RDBMS has a functioning _sync_database() capable of generating SQL to update, insert and delete rows from the database's tables.

the data source should return true if all the changes were successfully made, false if there were problems.

commit

  $bool = $datasource->commit()

called by UR::Context commit(). after all data sources return true from _sync_database(), commit must make those changes permanent. for RDBMS-type data sources, this commits the transaction πŸ”₯

return true if the commit is successful, false otherwise.

rollback

  $bool = $datasource->rollback()

called by commit in UR::Context if any data sources has problems during _sync_database or commit. it is also called by rollback in UR::Context. data sources should reverse any changes applied during a prior _sync_database that has not been made permanent by commit. undo era πŸ’€

get_default_handle

  $scalar = $datasource->get_default_handle();

should return the "handle" associated with any underlying logical data. for an RDBMS data source, this is the DBI database handle. for a file-based data source, this is the <IO::File> file handle. 🫢

create_from_inline_class_data

  $datasource = $data_source_class_name->create_from_inline_class_data(
                                              $class_data_hashref,
                                              $datasource_data_hashref
                                          );

called by the class initializer when a class definition contains an in-line data source definition. see "Inline Data Sources" in UR::Object::Type::Initializer.

_ignore_table

  $bool = $datasource->_ignore_table($table_name);

used to indicate whether the ur update classes command should create a class for the named table or not. if _ignore_table() returns true, then it will not create a class. leave that table alone bestie βœ‹


πŸ’œ Internal API Methods πŸ’œ

_get_class_data_for_loading

_generate_class_data_for_loading

  $hashref = $datasource->_resolve_query_plan($class_meta);

these two methods are called by UR::Context as part of the object loading process. _generate_class_data_for_loading collects information about a class and its metadata β€” stuff like property names, subclassing information and tables connected to the class β€” and stores that data inside the class's metadata object.

_get_class_data_for_loading is the main entry point; it calls _generate_class_data_for_loading if the data has not been generated and cached yet, and caches the data in the class metadata object. 🧚

_resolve_query_plan

_generate_template_data_for_loading

  $hashref = $datasource->_resolve_query_plan($boolexpr_tmpl);

these two methods are called by UR::Context as part of the object loading process. _generate_template_data_for_loading collects information from the UR::BoolExpr::Template $boolexpr_tmpl (rule template) and returns a hashref used later by the data source. that hashref includes hints about what classes will be involved in loading the resulting data, how those classes are joined together and how columns in the underlying query against the data source will map to properties of the class.

_resolve_query_plan is the main entry point; it calls _generate_template_data_for_loading if the data has not been generated and cached yet, and caches the data in the rule template object. ✨

_generate_loading_templates_arrayref

  my $listref = $datasource->_generate_loading_templates_arrayref($listref);

called by _generate_template_data_for_loading(). the input is a listref of listrefs about properties involved in a query. the second-level data is sets of quads:

  1. The class object for this property
  2. The property metadata object
  3. The database table name the data will come from
  4. The "object number", starting with 0. This is used in inheritance or delegation where a table join will be required.

it returns a listref of hashrefs, one hashref for every class involved in the request; usually just 1, but can be more than one if inheritance or delegation is involved. the data includes information about the class's properties, ID properties, and which columns of the result set the values will be found. 🌸


🌈 MetaDB 🌈

every Namespace created through ur define namespace will have a data source called the MetaDB. for example, the MyApp namespace's MetaDB is called MyApp::DataSource::Meta. the MetaDB is used to store information about the schemas of other data sources in the database. UR itself has a MetaDB with information about the MetaDB's schema, called UR::DataSource::Meta. it's giving meta-meta. it's giving mirrors in mirrors πŸͺž


⭐ SEE ALSO ⭐

  • UR::DataSource::RDBMS β€” The base class for relational database Data Sources, such as UR::DataSource::Oracle, UR::DataSoure::Pg, UR::DataSource::MySQL and UR::DataSource::SQLite
  • UR::DataSource::File, β€” The base class for comma/tab delimited files
  • UR::DataSource::FileMux β€” The base class for file multiplexor data sources.
  • UR::Context, UR::DataSource::Meta

and that's the whole page bestie, you ate that πŸ’… go forth and source your data responsibly 🫢

this icon of a doc is perl v5.32.1, dated 2022-01-17, and it lives in the User Contributed Perl Documentation corner of the world, filed under UR::DataSource(3pm) πŸŽ€ bye pookie 🌸

πŸ“¦ where this page comes from