The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

OP::ExtID - Overloaded object class for foreign base64-encoded GUIDs

DESCRIPTION

Extends OP::ID.

SYNOPSIS

  use OP::ExtID;

  my $id = OP::ExtID->new("EO2JXisF3hGSSg+s3t/Aww==");

PUBLIC CLASS METHODS

  • $class->assert([$query], @rules)

    ExtID() assertions are like pointers defining relationships with other classes, or within a class to define parent/child hierarchy.

    Attributes asserted as ExtID() must match an id in the specified class's database table.

    ExtID() may be wrapped in an Array() assertion for handling one-to-many relationships, at a small performance cost.

    If using MySQL, ExtID also enforces database-level foreign key constraints. In addition to enforcing allowed values on the database level, this will incur a CASCADE operation on DELETE and UPDATE events (meaning if a parent is deleted or updated, the corresponding child rows will be deleted or updated as well; always use parent id in a child object, rather than child id in a parent object).

    The following example illustrates self-referencing and externally referencing attributes with ExtID, using the "Folder" and "Document" desktop paradigm. Each saved object becomes a row in a database table.

    Create a folder class for documents and other folders:

      #
      # File: ExampleFolder.pm
      #
    
      use OP;
    
      create "OP::ExampleFolder" => {
        #
        # Folders can go in other folders:
        #
        parentId => OP::ExtID->assert(
          "OP::ExampleFolder",
          subtype(
            optional => 1
          )
        ),
    
        ...
      };

    A document class. Documents refer to their parent folder:

      #
      # File: ExampleTextDocument.pm
      #
    
      use OP;
      use OP::ExampleFolder;
    
      create "OP::ExampleTextDocument" => {
        #
        # This doc's location in the folder hierarchy
        #
        folderId => OP::ExtID->assert("OP::ExampleFolder"),
    
        #
        # Textual content of the document
        #
        content  => OP::Str->assert(
          subtype(
            columnType => "TEXT"
          )
        ),
    
        # ...
      };

    Caller example which populates some test folders and docs:

      #!/bin/env perl
      #
      # File: somecaller.pl
      #
    
      use strict;
      use warnings;
    
      use OP::ExampleFolder;
      use OP::ExampleTextDocument;
    
      sub main {
        #
        # A parent folder named "General"
        #
        my $folder = OP::ExampleFolder->spawn("General");
        $folder->save();
    
        #
        # A child folder named "Specific"
        #
        my $subfolder = OP::ExampleFolder->spawn("Specific");
        $subfolder->setFolderId( $folder->id() );
        $subfolder->save();
    
        #
        # Put a test document "README" in the parent folder:
        #
        my $readme = OP::ExampleTextDocument->spawn("README");
        $readme->setFolderId( $folder->id() );
        $readme->setContent("Lorem Ipsum Foo! Bla bla bla...");
        $readme->save();
    
        #
        # Put a "Test Text Doc" doc in the sub-folder:
        #
        my $doc = OP::ExampleTextDocument->spawn("Test Text Doc");
        $doc->setFolderId( $subfolder->id() );
        $doc->setContent("Lorem Ipsum Foo! Bla bla bla...");
        $doc->save();
      }
    
      main();

    If a string is specified as a second argument to ExtID(), it will be used as a SQL query, which selects a subset of Ids used as allowed values at runtime. If this query is not given, a flat, immutable list of Ids will be plugged in for allowed values at compile time.

      create "OP::Example" => {
        userId => OP::ExtID->assert(
          "OP::Example::User",
          "select id from example_user where foo = 1"
        ),
    
        # ...
      };

SEE ALSO

This file is part of OP.