lafcadio 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. data/lib/lafcadio.rb +32 -0
  2. data/lib/lafcadio.rb~ +32 -0
  3. data/lib/lafcadio/TestSuite.rb +16 -0
  4. data/lib/lafcadio/dateTime.rb +2 -0
  5. data/lib/lafcadio/dateTime/Month.rb +93 -0
  6. data/lib/lafcadio/domain.rb +119 -0
  7. data/lib/lafcadio/domain.rb~ +119 -0
  8. data/lib/lafcadio/domain/DomainObject.rb +375 -0
  9. data/lib/lafcadio/domain/DomainObject.rb~ +371 -0
  10. data/lib/lafcadio/domain/MapObject.rb +22 -0
  11. data/lib/lafcadio/domain/ObjectType.rb +80 -0
  12. data/lib/lafcadio/includer.rb +18 -0
  13. data/lib/lafcadio/mock.rb +2 -0
  14. data/lib/lafcadio/mock/MockDbBridge.rb +78 -0
  15. data/lib/lafcadio/mock/MockDbBridge.rb~ +74 -0
  16. data/lib/lafcadio/mock/MockObjectStore.rb +20 -0
  17. data/lib/lafcadio/objectField.rb +14 -0
  18. data/lib/lafcadio/objectField/AutoIncrementField.rb +25 -0
  19. data/lib/lafcadio/objectField/BooleanField.rb +83 -0
  20. data/lib/lafcadio/objectField/DateField.rb +33 -0
  21. data/lib/lafcadio/objectField/DateTimeField.rb +25 -0
  22. data/lib/lafcadio/objectField/DecimalField.rb +41 -0
  23. data/lib/lafcadio/objectField/EmailField.rb +28 -0
  24. data/lib/lafcadio/objectField/EnumField.rb +62 -0
  25. data/lib/lafcadio/objectField/FieldValueError.rb +4 -0
  26. data/lib/lafcadio/objectField/IntegerField.rb +15 -0
  27. data/lib/lafcadio/objectField/LinkField.rb +92 -0
  28. data/lib/lafcadio/objectField/LinkField.rb~ +86 -0
  29. data/lib/lafcadio/objectField/MoneyField.rb +13 -0
  30. data/lib/lafcadio/objectField/MonthField.rb +16 -0
  31. data/lib/lafcadio/objectField/ObjectField.rb +142 -0
  32. data/lib/lafcadio/objectField/PasswordField.rb +29 -0
  33. data/lib/lafcadio/objectField/StateField.rb +13 -0
  34. data/lib/lafcadio/objectField/SubsetLinkField.rb +25 -0
  35. data/lib/lafcadio/objectField/TextField.rb +23 -0
  36. data/lib/lafcadio/objectField/TextListField.rb +21 -0
  37. data/lib/lafcadio/objectField/TimeStampField.rb +15 -0
  38. data/lib/lafcadio/objectStore.rb +100 -0
  39. data/lib/lafcadio/objectStore/Cache.rb +81 -0
  40. data/lib/lafcadio/objectStore/Committer.rb +65 -0
  41. data/lib/lafcadio/objectStore/CouldntMatchObjectTypeError.rb +4 -0
  42. data/lib/lafcadio/objectStore/DbBridge.rb +140 -0
  43. data/lib/lafcadio/objectStore/DbBridge.rb~ +140 -0
  44. data/lib/lafcadio/objectStore/DomainComparable.rb +25 -0
  45. data/lib/lafcadio/objectStore/DomainObjectInitError.rb +9 -0
  46. data/lib/lafcadio/objectStore/DomainObjectNotFoundError.rb +4 -0
  47. data/lib/lafcadio/objectStore/DomainObjectProxy.rb +62 -0
  48. data/lib/lafcadio/objectStore/DomainObjectSqlMaker.rb +74 -0
  49. data/lib/lafcadio/objectStore/ObjectStore.rb +207 -0
  50. data/lib/lafcadio/objectStore/ObjectStore.rb~ +207 -0
  51. data/lib/lafcadio/objectStore/SqlValueConverter.rb +30 -0
  52. data/lib/lafcadio/objectStore/SqlValueConverter.rb~ +30 -0
  53. data/lib/lafcadio/query.rb +203 -0
  54. data/lib/lafcadio/query/Compare.rb +55 -0
  55. data/lib/lafcadio/query/CompoundCondition.rb +39 -0
  56. data/lib/lafcadio/query/Condition.rb +66 -0
  57. data/lib/lafcadio/query/Condition.rb~ +66 -0
  58. data/lib/lafcadio/query/Equals.rb +45 -0
  59. data/lib/lafcadio/query/In.rb +20 -0
  60. data/lib/lafcadio/query/Like.rb +48 -0
  61. data/lib/lafcadio/query/Link.rb +20 -0
  62. data/lib/lafcadio/query/Max.rb +32 -0
  63. data/lib/lafcadio/query/Max.rb~ +25 -0
  64. data/lib/lafcadio/query/Not.rb +21 -0
  65. data/lib/lafcadio/query/Query.rb +92 -0
  66. data/lib/lafcadio/schema.rb +2 -0
  67. data/lib/lafcadio/schema/CreateTableStatement.rb +61 -0
  68. data/lib/lafcadio/schema/CreateTableStatement.rb~ +59 -0
  69. data/lib/lafcadio/test.rb +2 -0
  70. data/lib/lafcadio/test/LafcadioTestCase.rb +17 -0
  71. data/lib/lafcadio/test/testconfig.dat +13 -0
  72. data/lib/lafcadio/util.rb +180 -0
  73. data/lib/lafcadio/util/Context.rb +61 -0
  74. data/lib/lafcadio/util/ContextualService.rb +33 -0
  75. data/lib/lafcadio/util/English.rb +117 -0
  76. data/lib/lafcadio/util/HashOfArrays.rb +48 -0
  77. data/lib/lafcadio/util/LafcadioConfig.rb +25 -0
  78. data/lib/lafcadio/util/QueueHash.rb +67 -0
  79. data/lib/lafcadio/util/UsStates.rb +29 -0
  80. data/lib/lafcadio/xml.rb +2 -0
  81. metadata +135 -0
@@ -0,0 +1,18 @@
1
+ class Includer # :nodoc:
2
+ def Includer.include( subdir )
3
+ dir = nil
4
+ $:.each { |includeDir|
5
+ attemptedDir = includeDir + '/lafcadio/' + subdir
6
+ begin
7
+ dir = Dir.open( attemptedDir )
8
+ rescue Errno::ENOENT
9
+ # wrong include directory, try again
10
+ end
11
+ }
12
+ if dir
13
+ dir.entries.each { |entry|
14
+ require "lafcadio/#{ subdir }/#{ $1 }" if entry =~ /(.*)\.rb/
15
+ }
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,2 @@
1
+ require 'lafcadio/includer'
2
+ Includer.include( 'mock' )
@@ -0,0 +1,78 @@
1
+ module Lafcadio
2
+ class MockDbBridge #:nodoc:
3
+ attr_reader :lastPkIdInserted, :retrievalsByType, :query_count
4
+
5
+ def initialize
6
+ @objects = {}
7
+ @retrievalsByType = Hash.new 0
8
+ @query_count = Hash.new( 0 )
9
+ end
10
+
11
+ def addObject(dbObject)
12
+ commit dbObject
13
+ end
14
+
15
+ def commit(dbObject)
16
+ objectsByObjectType = @objects[dbObject.objectType]
17
+ unless objectsByObjectType
18
+ objectsByObjectType = {}
19
+ @objects[dbObject.objectType] = objectsByObjectType
20
+ end
21
+ if dbObject.delete
22
+ objectsByObjectType.delete dbObject.pkId
23
+ else
24
+ object_pkId = dbObject.pkId
25
+ unless object_pkId
26
+ maxpkId = 0
27
+ objectsByObjectType.keys.each { |pkId|
28
+ maxpkId = pkId if pkId > maxpkId
29
+ }
30
+ @lastPkIdInserted = maxpkId + 1
31
+ object_pkId = @lastPkIdInserted
32
+ end
33
+ objectsByObjectType[object_pkId] = dbObject
34
+ end
35
+ end
36
+
37
+ def collection(objectType, objects); objects; end
38
+
39
+ def _getAll(objectType)
40
+ @retrievalsByType[objectType] = @retrievalsByType[objectType] + 1
41
+ @objects[objectType] ? @objects[objectType].values : []
42
+ end
43
+
44
+ def getCollectionByQuery(query)
45
+ @query_count[query] += 1
46
+ objectType = query.objectType
47
+ condition = query.condition
48
+ objects = []
49
+ _getAll( objectType ).each { |dbObj|
50
+ if condition
51
+ objects << dbObj if condition.objectMeets(dbObj)
52
+ else
53
+ objects << dbObj
54
+ end
55
+ }
56
+ coll = collection( objectType, objects )
57
+ if (range = query.limit)
58
+ coll = coll[0..(range.last - range.first)]
59
+ end
60
+ if ( order_by = query.orderBy )
61
+ coll = coll.sort_by { |dobj| dobj.send( order_by ) }
62
+ coll.reverse! if query.orderByOrder == Query::DESC
63
+ end
64
+ coll
65
+ end
66
+
67
+ def group_query( query )
68
+ if query.class == Query::Max
69
+ if ( query.field_name == query.objectType.sqlPrimaryKeyName ||
70
+ query.field_name == 'rate' )
71
+ query.collect( @objects[query.objectType].values )
72
+ else
73
+ raise "Can't handle query with sql '#{ query.toSql }'"
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,74 @@
1
+ module Lafcadio
2
+ class MockDbBridge #:nodoc:
3
+ attr_reader :lastPkIdInserted, :retrievalsByType, :query_count
4
+
5
+ def initialize
6
+ @objects = {}
7
+ @retrievalsByType = Hash.new 0
8
+ @query_count = Hash.new( 0 )
9
+ end
10
+
11
+ def addObject(dbObject)
12
+ commit dbObject
13
+ end
14
+
15
+ def commit(dbObject)
16
+ objectsByObjectType = @objects[dbObject.objectType]
17
+ unless objectsByObjectType
18
+ objectsByObjectType = {}
19
+ @objects[dbObject.objectType] = objectsByObjectType
20
+ end
21
+ if dbObject.delete
22
+ objectsByObjectType.delete dbObject.pkId
23
+ else
24
+ object_pkId = dbObject.pkId
25
+ unless object_pkId
26
+ maxpkId = 0
27
+ objectsByObjectType.keys.each { |pkId|
28
+ maxpkId = pkId if pkId > maxpkId
29
+ }
30
+ @lastPkIdInserted = maxpkId + 1
31
+ object_pkId = @lastPkIdInserted
32
+ end
33
+ objectsByObjectType[object_pkId] = dbObject
34
+ end
35
+ end
36
+
37
+ def collection(objectType, objects); objects; end
38
+
39
+ def _getAll(objectType)
40
+ @retrievalsByType[objectType] = @retrievalsByType[objectType] + 1
41
+ @objects[objectType] ? @objects[objectType].values : []
42
+ end
43
+
44
+ def getCollectionByQuery(query)
45
+ @query_count[query] += 1
46
+ objectType = query.objectType
47
+ condition = query.condition
48
+ objects = []
49
+ _getAll( objectType ).each { |dbObj|
50
+ if condition
51
+ objects << dbObj if condition.objectMeets(dbObj)
52
+ else
53
+ objects << dbObj
54
+ end
55
+ }
56
+ coll = collection( objectType, objects )
57
+ if (range = query.limit)
58
+ coll = coll[0..(range.last - range.first)]
59
+ end
60
+ coll
61
+ end
62
+
63
+ def group_query( query )
64
+ if query.class == Query::Max
65
+ if ( query.field_name == query.objectType.sqlPrimaryKeyName ||
66
+ query.field_name == 'rate' )
67
+ query.collect( @objects[query.objectType].values )
68
+ else
69
+ raise "Can't handle query with sql '#{ query.toSql }'"
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,20 @@
1
+ require 'lafcadio/objectStore/ObjectStore'
2
+ require 'lafcadio/mock/MockDbBridge'
3
+
4
+ module Lafcadio
5
+ # Externally, the MockObjectStore looks and acts exactly like the ObjectStore,
6
+ # but stores all its data in memory. This makes it very useful for unit
7
+ # testing, and in fact LafcadioTestCase#setup creates a new instance of
8
+ # MockObjectStore for each test case.
9
+ class MockObjectStore < ObjectStore
10
+ public_class_method :new
11
+
12
+ def initialize(context) # :nodoc:
13
+ super(context, MockDbBridge.new)
14
+ end
15
+
16
+ def addObject(dbObject) # :nodoc:
17
+ commit dbObject
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,14 @@
1
+ require 'lafcadio/includer'
2
+ Includer.include( 'objectField' )
3
+
4
+ module Lafcadio
5
+ # BlobField stores a string value and expects to store its value in a BLOB
6
+ # field in the database.
7
+ class BlobField < ObjectField
8
+ attr_accessor :size
9
+
10
+ def bind_write?; true; end #:nodoc:
11
+
12
+ def valueForSQL(value); "?"; end #:nodoc:
13
+ end
14
+ end
@@ -0,0 +1,25 @@
1
+ require 'lafcadio/objectField/IntegerField'
2
+
3
+ module Lafcadio
4
+ class AutoIncrementField < IntegerField # :nodoc:
5
+ attr_reader :objectType
6
+
7
+ def initialize(objectType, name, englishName = nil)
8
+ super(objectType, name, englishName)
9
+ @objectType = objectType
10
+ end
11
+
12
+ def HTMLWidgetValueStr(value)
13
+ if value != nil
14
+ super value
15
+ else
16
+ highestValue = 0
17
+ ObjectStore.getObjectStore.getAll(objectType).each { |obj|
18
+ aValue = obj.send(name).to_i
19
+ highestValue = aValue if aValue > highestValue
20
+ }
21
+ (highestValue + 1).to_s
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,83 @@
1
+ require 'lafcadio/objectField/ObjectField'
2
+
3
+ module Lafcadio
4
+ # BooleanField represents a boolean value. By default, it assumes that the
5
+ # table field represents True and False with the integers 1 and 0. There are
6
+ # two different ways to change this default.
7
+ #
8
+ # First, BooleanField includes a few enumerated defaults. Currently there are
9
+ # only
10
+ # * BooleanField::ENUMS_ONE_ZERO (the default, uses integers 1 and 0)
11
+ # * BooleanField::ENUMS_CAPITAL_YES_NO (uses characters 'Y' and 'N')
12
+ # In the XML class definition, this field would look like
13
+ # <field name="field_name" class="BooleanField"
14
+ # enumType="ENUMS_CAPITAL_YES_NO"/>
15
+ # If you're defining a field in Ruby, simply set BooleanField#enumType to one
16
+ # of the values.
17
+ #
18
+ # For more fine-grained specification you can pass specific values in. Use
19
+ # this format for the XML class definition:
20
+ # <field name="field_name" class="BooleanField">
21
+ # <enums>
22
+ # <enum key="true">yin</enum>
23
+ # <enum key="false">tang</enum>
24
+ # </enums>
25
+ # </field>
26
+ # If you're defining the field in Ruby, set BooleanField#enums to a hash.
27
+ # myBooleanField.enums = { true => 'yin', false => 'yang' }
28
+ #
29
+ # +enums+ takes precedence over +enumType+.
30
+ class BooleanField < ObjectField
31
+ ENUMS_ONE_ZERO = 0
32
+ ENUMS_CAPITAL_YES_NO = 1
33
+
34
+ attr_accessor :enumType, :enums
35
+
36
+ def initialize(objectType, name, englishName = nil)
37
+ super(objectType, name, englishName)
38
+ @enumType = ENUMS_ONE_ZERO
39
+ @enums = nil
40
+ end
41
+
42
+ def getEnums( value = nil ) # :nodoc:
43
+ if @enums
44
+ @enums
45
+ elsif @enumType == ENUMS_ONE_ZERO
46
+ if value.class == String
47
+ { true => '1', false => '0' }
48
+ else
49
+ { true => 1, false => 0 }
50
+ end
51
+ elsif @enumType == ENUMS_CAPITAL_YES_NO
52
+ { true => 'Y', false => 'N' }
53
+ else
54
+ raise MissingError
55
+ end
56
+ end
57
+
58
+ def trueEnum( value = nil ) # :nodoc:
59
+ getEnums( value )[true]
60
+ end
61
+
62
+ def falseEnum # :nodoc:
63
+ getEnums[false]
64
+ end
65
+
66
+ def textEnumType # :nodoc:
67
+ @enums ? @enums[true].class == String : @enumType == ENUMS_CAPITAL_YES_NO
68
+ end
69
+
70
+ def valueForSQL(value) # :nodoc:
71
+ if value
72
+ vfs = trueEnum
73
+ else
74
+ vfs = falseEnum
75
+ end
76
+ textEnumType ? "'#{vfs}'" : vfs
77
+ end
78
+
79
+ def valueFromSQL(value, lookupLink = true) # :nodoc:
80
+ value == trueEnum( value )
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,33 @@
1
+ require 'lafcadio/objectField/ObjectField'
2
+ require 'date'
3
+
4
+ module Lafcadio
5
+ # DateField represents a Date.
6
+ class DateField < ObjectField
7
+ RANGE_NEAR_FUTURE = 0
8
+ RANGE_PAST = 1
9
+
10
+ def DateField.valueType # :nodoc:
11
+ Date
12
+ end
13
+
14
+ attr_accessor :range
15
+
16
+ def initialize(objectType, name = "date", englishName = nil)
17
+ super(objectType, name, englishName)
18
+ @range = RANGE_NEAR_FUTURE
19
+ end
20
+
21
+ def valueForSQL(value) # :nodoc:
22
+ value ? "'#{value.to_s}'" : 'null'
23
+ end
24
+
25
+ def valueFromSQL(dbiDate, lookupLink = true) # :nodoc:
26
+ begin
27
+ dbiDate ? dbiDate.to_date : nil
28
+ rescue ArgumentError
29
+ nil
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,25 @@
1
+ require 'lafcadio/util'
2
+ require 'lafcadio/objectField/ObjectField'
3
+
4
+ module Lafcadio
5
+ # DateTimeField represents a DateTime.
6
+ class DateTimeField < ObjectField
7
+ def valueFromSQL(dbi_value, lookupLink = true) # :nodoc:
8
+ dbi_value ? dbi_value.to_time : nil
9
+ end
10
+
11
+ def valueForSQL(value) # :nodoc:
12
+ if value
13
+ year = value.year
14
+ month = value.mon.to_s.pad( 2, "0" )
15
+ day = value.day.to_s.pad( 2, "0" )
16
+ hour = value.hour.to_s.pad( 2, "0" )
17
+ minute = value.min.to_s.pad( 2, "0" )
18
+ second = value.sec.to_s.pad( 2, "0" )
19
+ "'#{year}-#{month}-#{day} #{hour}:#{minute}:#{second}'"
20
+ else
21
+ "null"
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,41 @@
1
+ require 'lafcadio/objectField/ObjectField'
2
+
3
+ module Lafcadio
4
+ # DecimalField represents a decimal value.
5
+ class DecimalField < ObjectField
6
+ attr_reader :precision
7
+
8
+ def DecimalField.valueType #:nodoc:
9
+ Numeric
10
+ end
11
+
12
+ def DecimalField.instantiationParameters( fieldElt ) #:nodoc:
13
+ parameters = super( fieldElt )
14
+ parameters['precision'] = fieldElt.attributes['precision'].to_i
15
+ parameters
16
+ end
17
+
18
+ def self.instantiateWithParameters( domainClass, parameters ) #:nodoc:
19
+ self.new( domainClass, parameters['name'], parameters['precision'],
20
+ parameters['englishName'] )
21
+ end
22
+
23
+ # [objectType] The domain class that this field belongs to.
24
+ # [name] The name of this field.
25
+ # [precision] The expected field precision. (Deprecated)
26
+ # [englishName] The English name of this field. (Deprecated)
27
+ def initialize(objectType, name, precision, englishName = nil)
28
+ super(objectType, name, englishName)
29
+ @precision = precision
30
+ end
31
+
32
+ def valueFromSQL(string, lookupLink = true) #:nodoc:
33
+ string != nil ? string.to_f : nil
34
+ end
35
+
36
+ def processBeforeVerify(value) #:nodoc:
37
+ value = super value
38
+ value != nil && value != '' ? value.to_f : nil
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,28 @@
1
+ require 'lafcadio/objectField/TextField'
2
+ require 'lafcadio/objectField/FieldValueError'
3
+
4
+ module Lafcadio
5
+ # EmailField takes a text value that is expected to be formatted as a single
6
+ # valid email address.
7
+ class EmailField < TextField
8
+ # Is +address+ a valid email address?
9
+ def EmailField.validAddress(address)
10
+ address =~ /^[^ @]+@[^ \.]+\.[^ ,]+$/
11
+ end
12
+
13
+ def initialize(objectType, name = "email", englishName = nil)
14
+ super(objectType, name, englishName)
15
+ end
16
+
17
+ def nullErrorMsg #:nodoc:
18
+ "Please enter an email address."
19
+ end
20
+
21
+ def verify(value, pkId) #:nodoc:
22
+ super(value, pkId)
23
+ if !EmailField.validAddress(value)
24
+ raise FieldValueError, "Please enter a valid email address.", caller
25
+ end
26
+ end
27
+ end
28
+ end