-
Notifications
You must be signed in to change notification settings - Fork 1
My Status Model
moellep edited this page Nov 5, 2014
·
15 revisions
In this step, we'll add the PropertyModel and its database schema, along with the MyStatusCode enum type.
- First we define the Model.MyStatus as a new file Model/MyStatus.pm. The MyStatus model derives from Model.RealmBase which provides support for automatically updating the user_id and modified_date_time fields.
package NewProject::Model::MyStatus;
use strict;
use Bivio::Base 'Model.RealmBase';
sub execute_load_or_create_for_auth_user {
my($proto, $req) = @_;
# To be called from a Task - load the current model for the Realm/User
# or create one with default values.
$proto->new($req)->load_or_create_for_auth_user;
return;
}
sub internal_initialize {
my($self) = @_;
return $self->merge_initialize_info($self->SUPER::internal_initialize, {
version => 1,
table_name => 'my_status_t',
columns => {
realm_id => ['RealmOwner.realm_id', 'PRIMARY_KEY'],
user_id => ['User.user_id', 'PRIMARY_KEY'],
status_code => ['MyStatusCode', 'NOT_NULL'],
status_comment => ['Text', 'NONE'],
modified_date_time => ['DateTime', 'NOT_NULL'],
},
});
}
sub load_or_create_for_auth_user {
my($self) = @_;
if ($self->unsafe_load({
user_id => $self->req('auth_user_id'),
})) {
return $self;
}
return $self->create({
status_code => b_use('Type.MyStatusCode')->UNKNOWN,
});
}
1;
- Next we add the database schema definition to the
files/npx/ddl/np-tables.sql
CREATE TABLE my_status_t (
realm_id NUMERIC(18) NOT NULL,
user_id NUMERIC(18) NOT NULL,
status_code NUMERIC(2) NOT NULL,
status_comment VARCHAR(500),
modified_date_time DATE NOT NULL,
CONSTRAINT my_status_t1 PRIMARY KEY(realm_id, user_id)
)
/
- And database constraints,
files/npx/ddl/np-constraints.sql
ALTER TABLE my_status_t
ADD CONSTRAINT my_status_t2
FOREIGN KEY (realm_id)
REFERENCES realm_owner_t(realm_id)
/
CREATE INDEX my_status_t3 ON my_status_t (
realm_id
)
/
ALTER TABLE my_status_t
ADD CONSTRAINT my_status_t4
FOREIGN KEY (user_id)
REFERENCES user_t(user_id)
/
CREATE INDEX my_status_t5 ON my_status_t (
user_id
)
/
- Then we create the new enum Type.MyStatusCode, creating the file
Type/MyStatusCode.pm
package NewProject::Type::MyStatusCode;
use strict;
use Bivio::Base 'Type.Enum';
__PACKAGE__->compile([
UNKNOWN => 0,
AWAY => 1,
BUSY => 2,
IDLE => 3,
OFFLINE => 4,
]);
1;
- Now we can recreate the database schema to include our new Property model by running:
$ bivio SQL -force create_test_db
- Finally, create a bunit test which tests the create/update methods on our new PropertyModel. Create a new file
Model/t/MyStatus.bunit
PropertyModel();
req()->set_realm_and_user('site', 'adm');
[
# remove the model if it exists
delete => [
[{
user_id => req('auth_user_id'),
realm_id => req('auth_id'),
}] => not_die(),
],
# create a new model, verify defaults
load_or_create_for_auth_user => [
[] => [{
'Model.MyStatus' => {
status_code => Type_MyStatusCode()->UNKNOWN,
status_comment => undef,
},
}],
],
# update the MyStatus model and verify the change
update => [
[{
status_comment => 'At lunch',
status_code => Type_MyStatusCode()->BUSY,
}] => [{
'Model.MyStatus' => {
status_code => Type_MyStatusCode()->BUSY,
status_comment => 'At lunch',
},
}],
],
# verify load_or_create() returns the same values
load_or_create_for_auth_user => [
[] => [{
'Model.MyStatus' => {
status_code => Type_MyStatusCode()->BUSY,
status_comment => 'At lunch',
},
}],
],
# all changes are rolled back at the end of the bunit
];
- Run the test from the command line:
$ bivio Test unit MyStatus.bunit
MyStatus.bunit: PASSED
Output:
1..3
ok 1
ok 2
ok 3
ok 4
All (4) tests PASSED
All (1) tests PASSED
- Agenda
- Getting Started
- My-Status Example Application
- Model
- View
- Task
- Application Support
- Testing
- Miscellaneous