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.