pod4 0.7.1 → 0.7.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.hgtags +1 -0
- data/Gemfile +10 -12
- data/lib/pod4/alert.rb +13 -16
- data/lib/pod4/basic_model.rb +15 -19
- data/lib/pod4/errors.rb +3 -4
- data/lib/pod4/interface.rb +25 -32
- data/lib/pod4/metaxing.rb +12 -15
- data/lib/pod4/model.rb +56 -81
- data/lib/pod4/nebulous_interface.rb +59 -74
- data/lib/pod4/null_interface.rb +8 -13
- data/lib/pod4/param.rb +2 -2
- data/lib/pod4/pg_interface.rb +42 -46
- data/lib/pod4/sequel_interface.rb +24 -36
- data/lib/pod4/tds_interface.rb +29 -37
- data/lib/pod4/typecasting.rb +7 -10
- data/lib/pod4/version.rb +1 -1
- data/lib/pod4.rb +8 -9
- data/md/fixme.md +0 -19
- data/pod4.gemspec +1 -1
- data/spec/jruby/pg_interface_spec.rb +16 -0
- data/spec/mri/pg_interface_spec.rb +13 -0
- data/spec/{common → mri}/sequel_interface_spec.rb +14 -1
- data/spec/mri/tds_interface_spec.rb +13 -0
- metadata +6 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9c0490f9b2e4082a0d36fde99281b5ec3b18dc06
|
4
|
+
data.tar.gz: 5338ef5d4695a2b0385a0093e43f4e4658c580c6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 21795d227c37d1a80d6d60a0a74f9c5111818cd80dcc696e2fc77641bbcbba9d1f089ab5ec44302825861d5aff0a6e8a3111e8c218cfd7beba5d07753ca9f7ed
|
7
|
+
data.tar.gz: ec96c28be57e17385efef6725cf83e402399eeacaa55be1f089139a1a8f6b889e547f5da36f77b255c2b770a4796948698f25fbbda4d9a918951b08dcebfb308
|
data/.hgtags
CHANGED
data/Gemfile
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
|
-
|
4
3
|
gemspec
|
5
4
|
|
6
5
|
|
@@ -10,29 +9,28 @@ group :development, :test do
|
|
10
9
|
gem "bundler", "~> 1.11"
|
11
10
|
gem "rake", "~> 10.5"
|
12
11
|
gem "rspec", "~> 3.4"
|
13
|
-
|
12
|
+
gem 'pry'
|
13
|
+
gem "pry-doc"
|
14
14
|
|
15
15
|
# For testing
|
16
|
-
gem "sequel",
|
17
|
-
gem "nebulous_stomp"
|
16
|
+
gem "sequel", "~> 4.35"
|
17
|
+
gem "nebulous_stomp", "~> 2"
|
18
18
|
|
19
|
-
platforms :
|
20
|
-
gem "sqlite3",
|
21
|
-
gem "tiny_tds",
|
22
|
-
gem "pg"
|
19
|
+
platforms :ruby do
|
20
|
+
gem "sqlite3", "~> 1.3"
|
21
|
+
gem "tiny_tds", "~> 1.0"
|
22
|
+
gem "pg"
|
23
23
|
end
|
24
24
|
|
25
25
|
platforms :jruby do
|
26
26
|
gem "jruby-lint"
|
27
|
-
gem "
|
27
|
+
gem "pg_jruby"
|
28
28
|
end
|
29
29
|
|
30
30
|
|
31
31
|
# Development tools
|
32
|
-
platforms :
|
32
|
+
platforms :ruby do
|
33
33
|
gem "rdoc"
|
34
|
-
gem "pry"
|
35
|
-
gem "pry-doc"
|
36
34
|
gem "ripper-tags"
|
37
35
|
end
|
38
36
|
|
data/lib/pod4/alert.rb
CHANGED
@@ -2,10 +2,10 @@ module Pod4
|
|
2
2
|
|
3
3
|
|
4
4
|
##
|
5
|
-
# An Alert is an error, warning or note which might be raised in validation
|
6
|
-
#
|
7
|
-
#
|
8
|
-
# message on the page.
|
5
|
+
# An Alert is an error, warning or note which might be raised in validation in the model.
|
6
|
+
#
|
7
|
+
# They are, however, designed to follow all the way through the controller to the view; you
|
8
|
+
# should use them whenever you want to display a message on the page.
|
9
9
|
#
|
10
10
|
class Alert
|
11
11
|
|
@@ -26,18 +26,17 @@ module Pod4
|
|
26
26
|
|
27
27
|
|
28
28
|
##
|
29
|
-
# A new alert must have a type (error warning info or success); there
|
30
|
-
#
|
31
|
-
#
|
29
|
+
# A new alert must have a type (error warning info or success); there should be a message to
|
30
|
+
# display, obviously. Note that you can pass an exception in place of a message, in which case
|
31
|
+
# @exception will be set.
|
32
32
|
#
|
33
|
-
# You may optionally specify the name of the field to be highlighted.
|
34
|
-
#
|
35
|
-
#
|
36
|
-
#
|
33
|
+
# You may optionally specify the name of the field to be highlighted. Models will give
|
34
|
+
# validation alerts a field that corresponds to the model attribute; but this is not enforced
|
35
|
+
# here, and your controller will have to sort things out if the model is expecting different
|
36
|
+
# field names.
|
37
37
|
#
|
38
38
|
def initialize(type, field=nil, message)
|
39
|
-
raise ArgumentError, "unknown alert type"
|
40
|
-
unless ALERTTYPES.include? type.to_s.to_sym
|
39
|
+
raise ArgumentError, "unknown alert type" unless ALERTTYPES.include? type.to_s.to_sym
|
41
40
|
|
42
41
|
@type = type.to_s.to_sym
|
43
42
|
@field = field ? field.to_sym : nil
|
@@ -58,8 +57,7 @@ module Pod4
|
|
58
57
|
|
59
58
|
|
60
59
|
##
|
61
|
-
# An array of Alert is automatically sorted into descending order of
|
62
|
-
# seriousness
|
60
|
+
# An array of Alert is automatically sorted into descending order of seriousness
|
63
61
|
#
|
64
62
|
def <=>(other)
|
65
63
|
ALERTTYPES.index(self.type) <=> ALERTTYPES.index(other.type)
|
@@ -79,7 +77,6 @@ module Pod4
|
|
79
77
|
self
|
80
78
|
end
|
81
79
|
|
82
|
-
|
83
80
|
end
|
84
81
|
##
|
85
82
|
|
data/lib/pod4/basic_model.rb
CHANGED
@@ -9,11 +9,11 @@ module Pod4
|
|
9
9
|
|
10
10
|
|
11
11
|
##
|
12
|
-
# The ultimate parent of all models. It has an interface, an id, a status,
|
13
|
-
#
|
12
|
+
# The ultimate parent of all models. It has an interface, an id, a status, and alerts. That's
|
13
|
+
# pretty much it.
|
14
14
|
#
|
15
|
-
# This is useful to the user for weirder models -- for example, where the
|
16
|
-
#
|
15
|
+
# This is useful to the user for weirder models -- for example, where the datasource records and
|
16
|
+
# the model instances don't map one-to-one.
|
17
17
|
#
|
18
18
|
# See Pod4::Model for documentation about Models.
|
19
19
|
#
|
@@ -34,8 +34,7 @@ module Pod4
|
|
34
34
|
class << self
|
35
35
|
|
36
36
|
##
|
37
|
-
# You MUST call this in your model definition to give it an instance of an
|
38
|
-
# interface.
|
37
|
+
# You MUST call this in your model definition to give it an instance of an interface.
|
39
38
|
#
|
40
39
|
def set_interface(interface)
|
41
40
|
define_class_method(:interface) {interface}
|
@@ -61,8 +60,7 @@ module Pod4
|
|
61
60
|
|
62
61
|
|
63
62
|
##
|
64
|
-
# Syntactic sugar; same as self.class.interface, which returns the
|
65
|
-
# interface instance.
|
63
|
+
# Syntactic sugar; same as self.class.interface, which returns the interface instance.
|
66
64
|
#
|
67
65
|
def interface; self.class.interface; end
|
68
66
|
|
@@ -70,8 +68,7 @@ module Pod4
|
|
70
68
|
##
|
71
69
|
# Return the list of alerts.
|
72
70
|
#
|
73
|
-
# We don't use attr_reader for this because it won't protect an array from
|
74
|
-
# external changes.
|
71
|
+
# We don't use attr_reader for this because it won't protect an array from external changes.
|
75
72
|
#
|
76
73
|
def alerts; @alerts.dup; end
|
77
74
|
|
@@ -79,10 +76,9 @@ module Pod4
|
|
79
76
|
##
|
80
77
|
# Clear down the alerts.
|
81
78
|
#
|
82
|
-
# Note that set model_status to :okay. Theoretically it might need to be
|
83
|
-
#
|
84
|
-
#
|
85
|
-
# can solve.
|
79
|
+
# Note that set model_status to :okay. Theoretically it might need to be :empty or :deleted,
|
80
|
+
# but if you are calling clear_alerts before a call to `read` or after a call to `delete`, then
|
81
|
+
# you have more problems than I can solve.
|
86
82
|
#
|
87
83
|
def clear_alerts
|
88
84
|
@alerts = []
|
@@ -91,12 +87,12 @@ module Pod4
|
|
91
87
|
|
92
88
|
|
93
89
|
##
|
94
|
-
# Raise a SwingShift exception for the model if any alerts are status
|
95
|
-
#
|
90
|
+
# Raise a SwingShift exception for the model if any alerts are status :error; otherwise do
|
91
|
+
# nothing.
|
92
|
+
#
|
93
|
+
# Note the alias of or_die for this method, which means that if you have kept to the idiom of
|
94
|
+
# CRUD methods returning self, then you can steal a lick from Perl and say:
|
96
95
|
#
|
97
|
-
# Note the alias of or_die for this method, which means that if you have
|
98
|
-
# kept to the idiom of CRUD methods returning self, then you can steal a
|
99
|
-
# lick from Perl and say:
|
100
96
|
# MyModel.new(14).read.or_die
|
101
97
|
#
|
102
98
|
def raise_exceptions
|
data/lib/pod4/errors.rb
CHANGED
@@ -16,8 +16,7 @@ module Pod4
|
|
16
16
|
##
|
17
17
|
# Base error class for Swingshift
|
18
18
|
#
|
19
|
-
# Also used for any configuration errors where ArgumentError is not
|
20
|
-
# appropriate.
|
19
|
+
# Also used for any configuration errors where ArgumentError is not appropriate.
|
21
20
|
#
|
22
21
|
class Pod4Error < StandardError
|
23
22
|
|
@@ -45,8 +44,8 @@ module Pod4
|
|
45
44
|
##
|
46
45
|
# Raised if a Pod4 method runs into problems
|
47
46
|
#
|
48
|
-
# Note, invalid parameters get a Ruby ArgumentError. This is for, eg, an
|
49
|
-
#
|
47
|
+
# Note, invalid parameters get a Ruby ArgumentError. This is for, eg, an interface finding that
|
48
|
+
# the ID it was given to read does not exist.
|
50
49
|
#
|
51
50
|
class CantContinue < Pod4Error
|
52
51
|
|
data/lib/pod4/interface.rb
CHANGED
@@ -8,25 +8,22 @@ module Pod4
|
|
8
8
|
##
|
9
9
|
# Abstract class, The parent of all interfaces.
|
10
10
|
#
|
11
|
-
# An interface encapsulates whatever method we are using up connect to the
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
11
|
+
# An interface encapsulates whatever method we are using up connect to the data. Its state is
|
12
|
+
# therefore that of the connection, not the DB table or whatever entity that the data source uses
|
13
|
+
# to group data. It raises only SwingShift errors (wrapping the error it gets inside a SwingShift
|
14
|
+
# error).
|
15
15
|
#
|
16
|
-
# We would expect a child of Interface for each data access type
|
17
|
-
#
|
18
|
-
# the signatures of the methods below.
|
16
|
+
# We would expect a child of Interface for each data access type (sequelInterface,
|
17
|
+
# NebulousInterface, etc). These children *will not change* the signatures of the methods below.
|
19
18
|
#
|
20
|
-
# The methods below are the required ones. Interfaces will likely implement
|
21
|
-
#
|
19
|
+
# The methods below are the required ones. Interfaces will likely implement other,
|
20
|
+
# interface-specific, ways of accessing data.
|
22
21
|
#
|
23
|
-
# In Normal use, the interface classes will in turn be subclassed as inner
|
24
|
-
#
|
25
|
-
# entity that they are drawing data from.
|
22
|
+
# In Normal use, the interface classes will in turn be subclassed as inner classes within each
|
23
|
+
# model, in order to customise them for the specific entity that they are drawing data from.
|
26
24
|
#
|
27
|
-
# Note that your Interface subclass probably returns an Octothorpe rather
|
28
|
-
#
|
29
|
-
# were the latter in most cases.)
|
25
|
+
# Note that your Interface subclass probably returns an Octothorpe rather than a Hash, q.v..
|
26
|
+
# (But you should be able to treat the former as if it were the latter in most cases.)
|
30
27
|
#
|
31
28
|
class Interface
|
32
29
|
extend Metaxing
|
@@ -43,9 +40,9 @@ module Pod4
|
|
43
40
|
|
44
41
|
|
45
42
|
##
|
46
|
-
# Individual implementations are likely to have very different initialize
|
47
|
-
#
|
48
|
-
#
|
43
|
+
# Individual implementations are likely to have very different initialize methods, which will
|
44
|
+
# accept whatever SwingShift object is needed to contact the data store, eg. the Sequel DB
|
45
|
+
# object.
|
49
46
|
#
|
50
47
|
def initialize
|
51
48
|
raise NotImplemented, "Interface needs to define an 'initialize' method"
|
@@ -53,11 +50,10 @@ module Pod4
|
|
53
50
|
|
54
51
|
|
55
52
|
##
|
56
|
-
# List accepts a parameter as selection criteria, and returns an array of
|
57
|
-
#
|
58
|
-
#
|
59
|
-
#
|
60
|
-
# should follow the same format as the return value for read(). )
|
53
|
+
# List accepts a parameter as selection criteria, and returns an array of Octothorpes. Exactly
|
54
|
+
# what the selection criteria look like will vary from interface to interface. So will the
|
55
|
+
# contents of the return OT, although it must include the ID field. (Ideally each element of
|
56
|
+
# the return array should follow the same format as the return value for read(). )
|
61
57
|
#
|
62
58
|
# Note that list should ALWAYS return an array; never nil.
|
63
59
|
#
|
@@ -67,9 +63,8 @@ module Pod4
|
|
67
63
|
|
68
64
|
|
69
65
|
##
|
70
|
-
# Create accepts a record parameter (Hash or OT, but again, the format of
|
71
|
-
#
|
72
|
-
# return the ID for the new record.
|
66
|
+
# Create accepts a record parameter (Hash or OT, but again, the format of this will vary)
|
67
|
+
# representing a record, and creates the record. Should return the ID for the new record.
|
73
68
|
#
|
74
69
|
def create(record)
|
75
70
|
raise NotImplemented, "Interface needs to define 'create' method"
|
@@ -77,9 +72,8 @@ module Pod4
|
|
77
72
|
|
78
73
|
|
79
74
|
##
|
80
|
-
# Read accepts an ID, and returns an Octothorpe representing the unique
|
81
|
-
#
|
82
|
-
# an empty Octothorpe.
|
75
|
+
# Read accepts an ID, and returns an Octothorpe representing the unique record for that ID. If
|
76
|
+
# there is no record matching the ID then it returns an empty Octothorpe.
|
83
77
|
#
|
84
78
|
def read(id)
|
85
79
|
raise NotImplemented, "Interface needs to define 'read' method"
|
@@ -87,9 +81,8 @@ module Pod4
|
|
87
81
|
|
88
82
|
|
89
83
|
##
|
90
|
-
# Update accepts an ID and a record parameter. It updates the record on the
|
91
|
-
#
|
92
|
-
# self.
|
84
|
+
# Update accepts an ID and a record parameter. It updates the record on the data source that
|
85
|
+
# matches the ID using the record parameter. It returns self.
|
93
86
|
#
|
94
87
|
def update(id, record)
|
95
88
|
raise NotImplemented, "Interface needs to define 'update' method"
|
data/lib/pod4/metaxing.rb
CHANGED
@@ -37,24 +37,21 @@ module Pod4
|
|
37
37
|
# puts Foo.bar # -> 23
|
38
38
|
# puts MyFoo.bar # -> 42
|
39
39
|
#
|
40
|
-
# This example gives us something different from a class attribute @@bar --
|
41
|
-
#
|
42
|
-
#
|
43
|
-
# MyFoo at all. This is a value that has inheritance.
|
40
|
+
# This example gives us something different from a class attribute @@bar -- the value of which
|
41
|
+
# would be shared between Foo and MyFoo. And different again from an attribute @bar on class
|
42
|
+
# Foo, which wouldn't turn up in MyFoo at all. This is a value that has inheritance.
|
44
43
|
#
|
45
|
-
# And this example shows pretty much the only metaprogramming trick you
|
46
|
-
#
|
44
|
+
# And this example shows pretty much the only metaprogramming trick you will find me pulling.
|
45
|
+
# It's enough to do a hell of a lot.
|
47
46
|
#
|
48
|
-
# Note that you need to be very careful what parameters you pass in order
|
49
|
-
#
|
50
|
-
#
|
51
|
-
# use local variables or dups.
|
47
|
+
# Note that you need to be very careful what parameters you pass in order to preserve this
|
48
|
+
# inheritance: if you pass a reference to something on Foo, you will be sharing it with MyFoo,
|
49
|
+
# not just inheriting it. Best to use local variables or dups.
|
52
50
|
#
|
53
|
-
# ...Well, actually, you aren't getting a method on the class -- these are
|
54
|
-
#
|
55
|
-
#
|
56
|
-
#
|
57
|
-
# comes to defining class methods.
|
51
|
+
# ...Well, actually, you aren't getting a method on the class -- these are defined in the
|
52
|
+
# class' immediate ancestor, eg, Object. You're getting a method on the eigenclass, which Ruby
|
53
|
+
# inserts between the class' ancestor and the class. For all of me I can't see a practical
|
54
|
+
# difference when it comes to defining class methods.
|
58
55
|
#
|
59
56
|
def define_class_method(method, *args, &blk)
|
60
57
|
metaclass.send(:define_method, method, *args, &blk)
|
data/lib/pod4/model.rb
CHANGED
@@ -16,19 +16,19 @@ module Pod4
|
|
16
16
|
#
|
17
17
|
# Note that we distinguish between 'models' and 'interfaces':
|
18
18
|
#
|
19
|
-
# The model represents the data to your application, in the format that makes
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
19
|
+
# The model represents the data to your application, in the format that makes most sense to your
|
20
|
+
# application: that might be the same format that it is stored in on the database, or it might
|
21
|
+
# not. The model doesn't care about where the data comes from. Models are all subclasses of
|
22
|
+
# Pod4::Model.
|
23
23
|
#
|
24
|
-
# An interface encapsulates the connection to whatever is providing the data
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
24
|
+
# An interface encapsulates the connection to whatever is providing the data.# it might be a
|
25
|
+
# wrapper for calls to the Sequel ORM, for example. Or it could be a making a series of calls to
|
26
|
+
# a set of Nebulous verbs. It only cares about dealing with the data source, and it is only
|
27
|
+
# called by the model.
|
28
28
|
#
|
29
|
-
# An interface is a seperate class, which is defined for each model. There
|
30
|
-
#
|
31
|
-
#
|
29
|
+
# An interface is a seperate class, which is defined for each model. There are parent classes for
|
30
|
+
# most of the data sources you will need, but failing that, you can always create one from the
|
31
|
+
# ultimate parent, Pod4::Interface.
|
32
32
|
#
|
33
33
|
# Simple Example
|
34
34
|
# ---------------
|
@@ -46,10 +46,9 @@ module Pod4
|
|
46
46
|
# attr_columns :one, :two, :three
|
47
47
|
# end
|
48
48
|
#
|
49
|
-
# In this example we have a model that relies on the Sequel ORM to talk to a
|
50
|
-
# table
|
51
|
-
#
|
52
|
-
# validation or error control.
|
49
|
+
# In this example we have a model that relies on the Sequel ORM to talk to a table 'example'. The
|
50
|
+
# table has a primary key field 'id' and columns which correspond to our three attributes one,
|
51
|
+
# two and three. There is no validation or error control.
|
53
52
|
#
|
54
53
|
# Here is an example of this model in use:
|
55
54
|
#
|
@@ -66,9 +65,8 @@ module Pod4
|
|
66
65
|
# Overriding Column Representation
|
67
66
|
# --------------------------------
|
68
67
|
#
|
69
|
-
# If you want to represent information differently on the model than it is
|
70
|
-
#
|
71
|
-
# know about and override:
|
68
|
+
# If you want to represent information differently on the model than it is stored on the data
|
69
|
+
# source, there are four methods you potentially need to know about and override:
|
72
70
|
#
|
73
71
|
# * set -- used by you to set model column values
|
74
72
|
# * to_ot -- used by you to get model column values
|
@@ -82,10 +80,9 @@ module Pod4
|
|
82
80
|
class << self
|
83
81
|
|
84
82
|
##
|
85
|
-
# You should call this in your model definition to define model 'columns'
|
86
|
-
#
|
87
|
-
#
|
88
|
-
# `map_to_interface` will try to help you with.
|
83
|
+
# You should call this in your model definition to define model 'columns' -- it gives you
|
84
|
+
# exactly the functionality of `attr_accessor` but also registers the attribute as one that
|
85
|
+
# `to_ot`, `map_to_model` and `map_to_interface` will try to help you with.
|
89
86
|
#
|
90
87
|
def attr_columns(*cols)
|
91
88
|
c = columns.dup
|
@@ -106,15 +103,15 @@ module Pod4
|
|
106
103
|
##
|
107
104
|
# Call this to return an array of record information.
|
108
105
|
#
|
109
|
-
# What you actually get depends on the interface, but it must include a
|
110
|
-
#
|
106
|
+
# What you actually get depends on the interface, but it must include a recognisable record
|
107
|
+
# ID in each array element.
|
111
108
|
#
|
112
|
-
# For the purposes of Model we assume that we can make an instance out of
|
113
|
-
#
|
114
|
-
#
|
109
|
+
# For the purposes of Model we assume that we can make an instance out of each array element,
|
110
|
+
# and we return an array of instances of the model.# Override this method if that is not true
|
111
|
+
# for your Interface.
|
115
112
|
#
|
116
|
-
# Note that list should ALWAYS return an array, and array elements should
|
117
|
-
#
|
113
|
+
# Note that list should ALWAYS return an array, and array elements should always respond to
|
114
|
+
# :id -- otherwise we raise a Pod4Error.
|
118
115
|
#
|
119
116
|
def list(params=nil)
|
120
117
|
fail_no_id_fld unless interface.id_fld
|
@@ -123,7 +120,6 @@ module Pod4
|
|
123
120
|
key = ot[interface.id_fld]; fail_no_id unless key
|
124
121
|
|
125
122
|
rec = self.new(key)
|
126
|
-
|
127
123
|
rec.map_to_model(ot) # seperately, in case model forgot to return self
|
128
124
|
rec
|
129
125
|
end
|
@@ -132,18 +128,14 @@ module Pod4
|
|
132
128
|
|
133
129
|
|
134
130
|
def test_for_octo(param)
|
135
|
-
raise( ArgumentError,
|
136
|
-
'Parameter must be a Hash or Octothorpe',
|
137
|
-
caller ) \
|
131
|
+
raise( ArgumentError, 'Parameter must be a Hash or Octothorpe', caller ) \
|
138
132
|
unless param.kind_of?(Hash) || param.kind_of?(Octothorpe)
|
139
133
|
|
140
134
|
end
|
141
135
|
|
142
136
|
|
143
137
|
def test_for_invalid_status(action, status)
|
144
|
-
raise( Pod4Error,
|
145
|
-
"Invalid model status for an action of #{action}",
|
146
|
-
caller ) \
|
138
|
+
raise( Pod4Error, "Invalid model status for an action of #{action}", caller ) \
|
147
139
|
if [:empty, :deleted].include? status
|
148
140
|
|
149
141
|
end
|
@@ -151,18 +143,12 @@ module Pod4
|
|
151
143
|
|
152
144
|
|
153
145
|
def fail_no_id_fld
|
154
|
-
raise POd4Error,
|
155
|
-
"No ID field defined in interface",
|
156
|
-
caller
|
157
|
-
|
146
|
+
raise POd4Error, "No ID field defined in interface", caller
|
158
147
|
end
|
159
148
|
|
160
149
|
|
161
150
|
def fail_no_id
|
162
|
-
raise Pod4Error,
|
163
|
-
"ID field missing from record",
|
164
|
-
caller
|
165
|
-
|
151
|
+
raise Pod4Error, "ID field missing from record", caller
|
166
152
|
end
|
167
153
|
|
168
154
|
end
|
@@ -170,21 +156,20 @@ module Pod4
|
|
170
156
|
|
171
157
|
|
172
158
|
##
|
173
|
-
# Syntactic sugar; pretty much the same as self.class.columns, which
|
174
|
-
#
|
159
|
+
# Syntactic sugar; pretty much the same as self.class.columns, which returns the `attr_columns`
|
160
|
+
# array.
|
175
161
|
#
|
176
162
|
def columns; self.class.columns.dup; end
|
177
163
|
|
178
164
|
|
179
165
|
##
|
180
166
|
# Call this to write a new record to the data source.
|
181
|
-
#
|
182
|
-
# that's okay.
|
167
|
+
#
|
168
|
+
# Note: create needs to set @id. But interface.create should return it, so that's okay.
|
183
169
|
#
|
184
170
|
def create
|
185
171
|
validate
|
186
|
-
@model_id = interface.create(map_to_interface)
|
187
|
-
unless @model_status == :error
|
172
|
+
@model_id = interface.create(map_to_interface) unless @model_status == :error
|
188
173
|
|
189
174
|
@model_status = :okay if @model_status == :empty
|
190
175
|
self
|
@@ -215,8 +200,7 @@ module Pod4
|
|
215
200
|
Model.test_for_invalid_status(:update, @model_status)
|
216
201
|
|
217
202
|
clear_alerts; validate
|
218
|
-
interface.update(@model_id, map_to_interface)
|
219
|
-
unless @model_status == :error
|
203
|
+
interface.update(@model_id, map_to_interface) unless @model_status == :error
|
220
204
|
|
221
205
|
self
|
222
206
|
end
|
@@ -241,13 +225,11 @@ module Pod4
|
|
241
225
|
#
|
242
226
|
# Override this to add validation - calling `add_alert` for each problem.
|
243
227
|
#
|
244
|
-
# Note that you can only validate what is actually stored on the model. If
|
245
|
-
#
|
246
|
-
# to override that routine.
|
228
|
+
# Note that you can only validate what is actually stored on the model. If you want to check
|
229
|
+
# the data being passed to the model in `set`, you need to override that routine.
|
247
230
|
#
|
248
|
-
# Also, you don't have any way of telling whether you are currently
|
249
|
-
#
|
250
|
-
# `update` respectively.
|
231
|
+
# Also, you don't have any way of telling whether you are currently creating a new record or
|
232
|
+
# updating an old one: override `create` and `update` respectively.
|
251
233
|
#
|
252
234
|
def validate
|
253
235
|
# Holding pattern. All models should use super, in principal
|
@@ -257,13 +239,11 @@ module Pod4
|
|
257
239
|
##
|
258
240
|
# Set instance values on the model from a Hash or Octothorpe.
|
259
241
|
#
|
260
|
-
# This is what your code calls when it wants to update the model. Override
|
261
|
-
#
|
262
|
-
# control data types, etc.
|
242
|
+
# This is what your code calls when it wants to update the model. Override it if you need it to
|
243
|
+
# set anything not in attr_columns, or to control data types, etc.
|
263
244
|
#
|
264
|
-
# You might want to put validation here, too, if what you are validating is
|
265
|
-
#
|
266
|
-
# from here just fine.
|
245
|
+
# You might want to put validation here, too, if what you are validating is something that
|
246
|
+
# isn't actually stored on the model. You can call add_alert from here just fine.
|
267
247
|
#
|
268
248
|
# See also: `to_ot`, `map_to_model`, `map_to_interface`
|
269
249
|
#
|
@@ -276,8 +256,7 @@ module Pod4
|
|
276
256
|
##
|
277
257
|
# Return an Octothorpe of all the attr_columns attributes.
|
278
258
|
#
|
279
|
-
# Override if you want to return any extra data. (You will need to create a
|
280
|
-
# new Octothorpe.)
|
259
|
+
# Override if you want to return any extra data. (You will need to create a new Octothorpe.)
|
281
260
|
#
|
282
261
|
# See also: `set`, `map_to_model', 'map_to_interface'
|
283
262
|
#
|
@@ -289,13 +268,11 @@ module Pod4
|
|
289
268
|
##
|
290
269
|
# Used by the interface to set the column values on the model.
|
291
270
|
#
|
292
|
-
# Don't use this to set model attributes from your code; use `set`,
|
293
|
-
# instead.
|
271
|
+
# Don't use this to set model attributes from your code; use `set`, instead.
|
294
272
|
#
|
295
|
-
# By default this does exactly the same as `set`. Override it if you want
|
296
|
-
#
|
297
|
-
#
|
298
|
-
# the data back.
|
273
|
+
# By default this does exactly the same as `set`. Override it if you want the model to
|
274
|
+
# represent data differently than the data source does -- but then you will have to override
|
275
|
+
# `map_to_interface`, too, to convert the data back.
|
299
276
|
#
|
300
277
|
# See also: `to_ot`, `map_to_model'
|
301
278
|
#
|
@@ -309,16 +286,15 @@ module Pod4
|
|
309
286
|
##
|
310
287
|
# used by the model to get an OT of column values for the interface.
|
311
288
|
#
|
312
|
-
# Don't use this to get model values in your code; use `to_ot`, instead
|
313
|
-
#
|
314
|
-
# the data source.
|
289
|
+
# Don't use this to get model values in your code; use `to_ot`, instead.# This is called by
|
290
|
+
# model.create and model.update when it needs to write to the data source.
|
315
291
|
#
|
316
|
-
# By default this behaves exactly the same as to_ot. Override it if you
|
317
|
-
#
|
318
|
-
#
|
292
|
+
# By default this behaves exactly the same as to_ot. Override it if you want the model to
|
293
|
+
# represent data differently than the data source -- in which case you also need to override
|
294
|
+
# `map_to_model`.
|
319
295
|
#
|
320
|
-
# Bear in mind that any attribute could be nil, and likely will be when
|
321
|
-
#
|
296
|
+
# Bear in mind that any attribute could be nil, and likely will be when `map_to_interface` is
|
297
|
+
# called from the create method.
|
322
298
|
#
|
323
299
|
# See also: `to_ot`, `set`.
|
324
300
|
#
|
@@ -351,7 +327,6 @@ module Pod4
|
|
351
327
|
end
|
352
328
|
end
|
353
329
|
|
354
|
-
|
355
330
|
end
|
356
331
|
##
|
357
332
|
|