NAME
OP - Compact prototyping of InnoDB-backed object classes
VERSION
This documentation is for version 0.310_001 of OP.
STATUS
The usual pre-1.0 warnings apply. Consider this alpha code. It does what we currently ask of it, and maybe a little more, but it is a work in progress.
SYNOPSIS
use strict;
use warnings;
use OP;
create "YourApp::YourClass" => { };
See PROTOTYPE COMPONENTS in OP::Class for detailed examples.
A cheat sheet, ex/cheat.html
, is included with this distribution.
DESCRIPTION
OP is a Perl 5 framework for prototyping InnoDB-backed object classes.
This document covers the high-level concepts implemented in OP.
FRAMEWORK ASSUMPTIONS
When using OP, as with any framework, a number of things "just happen" by design. Trying to go against the flow of any of these base assumptions is not recommended.
Configuration
See CONFIGURATION AND ENVIRONMENT in this document.
Classes Make Tables
The core function of OP is to derive database tables from the assertions contained in object classes. OP creates the tables that it needs.
If, rather, you need to derive object classes from a database schema, you may want to take a look at Class::DBI and other similar packages on the CPAN, which specialize in doing just that.
OP::ForeignTable may be used to work with external datasources as if they were OP classes, but this functionality is quite limited.
Default Base Attributes
Database-backed OP objects always have "id", "name", "ctime", and "mtime".
id
=> OP::IDid
is the primary key at the database table level. The gets used in database table indexes, and should generally not be altered once assigned.Base64-encoded Globally Unique IDs are used by default, though it is possible to assert any scalar OP object class for the
id
column. See OP::ID, OP::Serial.name
=> OP::Namename
is a secondary human-readable key.The assertions for the name attribute may be changed to suit a class's requirements, and the name value for any object may be freely changed.
For more information on named objects, see OP::Name.
ctime
=> OP::DateTimectime
is the Unix timestamp representing the object's creation time. OP sets this when saving an object for the first time.For more information on timestamps, see OP::DateTime.
mtime
=> OP::DateTimemtime
is the Unix timestamp representing the object's last modified time. OP updates this each time an object is saved.
undef
Requires Assertion
Undefined values in objects translate to NULL in the database, and OP does not permit this to happen by default.
Instance variables may not be undef, (and the corresponding table column may not be NULL), unless the instance variable was explicitly asserted as optional in the class prototype. To do so, provide "optional" as an assertion argument, as in the following example:
create "YourApp::Example" => {
### Do not permit NULL:
someMandatoryDate => OP::DateTime->assert,
### Permit NULL:
someOptionalDate => OP::DateTime->assert(
subtype(
optional => true,
)
),
# ...
};
Namespace Matters
OP's core packages live under the OP:: namespace. Your classes should live in their own top-level namespace, e.g. "YourApp::". This will translate (in lower case) to the name of the app's database. The database name may be overridden by implementing class method databaseName
.
Namespace elements beyond the top-level translate to lower case table names. In cases of nested namespaces, Perl's "::" delineator is swapped out for an underscore (_). The table name may be overriden by implementing class method tableName
.
create "YourApp::Example::Foo" => {
# overrides default value of "yourapp"
databaseName => sub {
my $class = shift;
return "some_legacy_db";
},
# overrides default value of "example_foo"
tableName => sub {
my $class = shift;
return "some_legacy_table";
},
# ...
};
OBJECT TYPES
OP object types are used when asserting attributes within a class, and are also suitable for instantiation or subclassing in a self-standing manner.
The usage of these types is not mandatory outside the context of creating a new class-- OP always returns attributes from the database in object form, but these object types are not a replacement for Perl's native data types in general usage, unless the developer wishes them to be.
These modes of usage are shown below, and covered in greater detail in specific object class docs.
DECLARING AS SUBCLASS
By default, a superclass of OP::Node is used for new classes. This may be overridden using __BASE__:
use OP;
create "YourApp::Example" => {
__BASE__ => "OP::Hash",
# ...
};
ASSERTING AS ATTRIBUTES
When defining the allowed instance variables for a class, the assert()
method is used:
#
# File: Example.pm
#
use OP;
create "YourApp::Example" => {
someString => OP::Str->assert,
someInt => OP::Int->assert,
};
INSTANTIATING AS OBJECTS
When instantiating, the class method new()
is used, typically with a prototype object for its argument.
#
# File: somecaller.pl
#
use strict;
use warnings;
use YourApp::Example;
my $example = YourApp::Example->new(
name => "Hello",
someString => "foo",
someInt => 12345,
);
$example->save("Saving my first object");
$example->print;
IN METHODS
Constructors and setter methods accept both native Perl 5 data types and their OP object class equivalents. The setters will automatically handle any necessary conversion, or throw an exception if the received arg doesn't quack like a duck.
To wit, native types are OK for constructors:
my $example = YourApp::Example->new(
someString => "foo",
someInt => 123,
);
#
# someStr became a string object:
#
say $example->someString->class;
# "OP::Str"
say $example->someString->size;
# "3"
say $example->someString;
# "foo"
#
# someInt became an integer object:
#
say $example->someInt->class;
# "OP::Int"
say $example->someInt->sqrt;
# 11.0905365064094
say $example->someInt;
# 123
Native types are OK for setters:
$example->setSomeInt(456);
say $example->someInt->class;
# "OP::Int"
ABSTRACT CLASSES & MIX-INS
OP::Class - Abstract "Class" class
OP::Class::Dumper - Introspection mix-in
OP::Object - Abstract object class
OP::Persistence - Storage and retrieval mix-in
OP::Persistence::Generic - Base for vendor-specific DBI modules
OP::Persistence::MySQL - MySQL/InnoDB-specific runtime overrides
OP::Persistence::SQLite - SQLite-specific runtime overrides
OP::Node - Abstract stored object class
OP::Type - Instance variable typing
OP::Scalar - Base class for scalar values
OP::Subtype - Instance variable subtyping
OBJECT TYPES
The basic types listed here may be instantiated as objects, or asserted as inline attributes.
OP::Array - List
OP::Bool - Overloaded boolean
OP::DateTime - Overloaded time object
OP::Domain - Overloaded domain name
OP::Double - Overloaded double-precision number
OP::EmailAddr - Overloaded email address
OP::ExtID - Overloaded foreign key
OP::Float - Overloaded floating point number
OP::Hash - Hashtable
OP::ID - Overloaded GUID primary key
OP::Int - Overloaded integer
OP::IPv4Addr - Overloaded IPv4 address
OP::Name - Unique secondary key
OP::Num - Overloaded number
OP::Rule - Regex reference (qr/ /)
OP::Serial - Auto-incrementing primary key
OP::Str - Overloaded unicode string
OP::TimeSpan - Overloaded time range object
OP::URI - Overloaded URI
CONSTANTS & ENUMERATIONS
OP::Constants - "dot rc" values as constants
OP::Enum - C-style enumerated types as constants
HELPER MODULES
OP::Utility - System functions required globally by OP
OP::Exceptions - Errors thrown by OP
TOYS & TOOLS
bin/opconf
- Generate an .oprc on the local machinebin/oped
- Edit OP objects using VIM and YAMLbin/opid
- Dump OP objects to STDOUT in various formatsbin/opsh
- Interactive and persistent Perl 5 shell
EXPERIMENTAL
Experimental classes are subject to radical upheaval, questionable documentation, and unexplained disappearances. They represent proof of concept in their respective areas, and may move out of experimental status at some point.
INFOMATICS
The infomatics classes are an attempt to replicate certain functionality of RRD using SQL and Perl.
OP::Log - OP::RRNode class factory
OP::RRNode - Round Robin Database Table
OP::Series - Cooked OP::RRNode Series Data
OP::SeriesChart - Image-based Series Visualizer
FOREIGN DB ACCESS
Foreign DB access classes are similar in function to Class::DBI, in that they are used to derive object classes from existing schemas. This is an inversion of how OP normally functions, since OP was designed to derive schemas from classes.
OP::ForeignRow - Non-OP Database Access
OP::ForeignTable - ForeignRow class factory
BULK TABLE WRITER
The Bulk writer provides an alternate method for saving objects, utilizing MySQL's LOAD FILE syntax.
OP::Persistence::Bulk - Deferred fast bulk table writes
CONFIGURATION AND ENVIRONMENT
OP_HOME + .oprc
OP needs to be able to find a valid .oprc file in order to bootstrap itself. This lives under $ENV{OP_HOME}, which defaults to the current user's home directory.
To generate a first-time config for the local machine, copy the .oprc (included with this distribution) to the proper location, or run bin/opconf
(also included with this distribution) as the user who will be running OP. This is a post-install step which is not currently handled by make install
.
See OP::Constants for information regarding customizing and extending the local rc file.
OP + mod_perl
OP-based classes used in a mod_perl app should be preloaded by a startup script. OP_HOME must be set in the script's BEGIN block.
For example, in a file startup.pl
:
use strict;
use warnings;
BEGIN {
$ENV{OP_HOME} = '/home/user/op'; # Directory with the .oprc
}
use MyApp::Component;
use MyApp::OtherComponent;
1;
And in your httpd.conf
:
PerlRequire /path/to/your/startup.pl
SEE ALSO
OP::Class, ex/cheat.html
OP is on GitHub: http://github.com/aayars/op
AUTHOR
Alex Ayars <pause@nodekit.org>
COPYRIGHT
File: OP.pm
Copyright (c) 2009 TiVo Inc.
All rights reserved. This program and the accompanying materials
are made available under the terms of the Common Public License v1.0
which accompanies this distribution, and is available at
http://opensource.org/licenses/cpl1.0.txt