datoki 2.0.1 → 3.1.0
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.
- checksums.yaml +4 -4
- data/README.md +6 -1
- data/VERSION +1 -1
- data/lib/datoki.rb +182 -141
- data/specs/0010-Datoki.db.rb +20 -4
- data/specs/0010-Numeric.rb +47 -2
- data/specs/0010-Numeric_db.rb +1 -1
- data/specs/0010-varchar.rb +29 -15
- data/specs/0010-varchar_db.rb +1 -1
- data/specs/0011-string_ish.rb +60 -0
- data/specs/0012-pseudo.rb +34 -0
- data/specs/0020-clean!.rb +19 -0
- data/specs/0020-clean.rb +8 -12
- data/specs/0030-matching.rb +93 -0
- data/specs/0031-set_to.rb +32 -0
- metadata +6 -3
- data/specs/0010-Datoki.db.new.rb +0 -31
- data/specs/0020-on.rb +0 -64
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 43a52b61961fb85e568c481ec205a0367f13a50b
|
4
|
+
data.tar.gz: 9b9064f20a24ebe7b141ea54f9e201ce447fa1d7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 389d463817cdad3695f0355216e3e6eba492ed092c63ffe18a7c391351f9a66305121b7242d4076c74fdb5cd64ff68195e980caba5298fc3149771c9a8e3a591
|
7
|
+
data.tar.gz: b23b19e80b655b8020bd5f57ef71772093c5b351c7a47026dbe08490e5074223e29653ae532afb649c895a9c5efa85ae55d9f3ec3b5cd0520c7b5ffe09ba49a4
|
data/README.md
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
|
2
2
|
# Datoki
|
3
3
|
|
4
|
-
A Ruby gem
|
4
|
+
A Ruby gem that is part abstraction layer, part validator...
|
5
|
+
for managing data in PostgreSQL.
|
5
6
|
|
6
7
|
## Installation
|
7
8
|
|
@@ -39,3 +40,7 @@ A Ruby gem for managing validation and records using PostgreSQL.
|
|
39
40
|
end # === class
|
40
41
|
```
|
41
42
|
|
43
|
+
## NOTE:
|
44
|
+
|
45
|
+
1) Raises an error if a mismatch between field definition and schema.
|
46
|
+
Example: `:allow_null != field[:allow][:null]`
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
3.1.0
|
data/lib/datoki.rb
CHANGED
@@ -11,7 +11,7 @@ module Datoki
|
|
11
11
|
Schema_Conflict = Class.new RuntimeError
|
12
12
|
|
13
13
|
Actions = [:all, :create, :read, :update, :update_or_create, :trash, :delete]
|
14
|
-
Char_Types = [:varchar, :text]
|
14
|
+
Char_Types = [:varchar, :text, :string_ish]
|
15
15
|
Numeric_Types = [:smallint, :integer, :bigint, :decimal, :numeric]
|
16
16
|
Types = Char_Types + Numeric_Types + [:datetime]
|
17
17
|
|
@@ -51,7 +51,6 @@ module Datoki
|
|
51
51
|
attr_reader :ons, :fields, :fields_as_required
|
52
52
|
|
53
53
|
def initialize_def_field
|
54
|
-
@on_doc = []
|
55
54
|
@ons = {}
|
56
55
|
@fields = {} # Ex: {:name=>{}, :age=>{}}
|
57
56
|
@fields_as_required = {} # Ex: {:name!=>:name}
|
@@ -59,8 +58,6 @@ module Datoki
|
|
59
58
|
@schema = {}
|
60
59
|
@schema_match = false
|
61
60
|
@table_name = nil
|
62
|
-
name = self.to_s.downcase.to_sym
|
63
|
-
table(name) if Datoki.db.tables.include?(name)
|
64
61
|
end
|
65
62
|
|
66
63
|
def schema_match?
|
@@ -68,6 +65,7 @@ module Datoki
|
|
68
65
|
end
|
69
66
|
|
70
67
|
def table name
|
68
|
+
fail ArgumentError, "Table name must be a Symbol: #{name.inspect}" unless name.is_a?(Symbol)
|
71
69
|
if !@schema.empty? || @table_name
|
72
70
|
fail "Schema/table already defined: #{@table_name.inspect}"
|
73
71
|
end
|
@@ -75,10 +73,11 @@ module Datoki
|
|
75
73
|
db_schema = Datoki.db.schema(name)
|
76
74
|
|
77
75
|
if !db_schema
|
78
|
-
fail "Schema not found for: #{name.inspect}"
|
76
|
+
fail ArgumentError, "Schema not found for: #{name.inspect}"
|
79
77
|
end
|
80
78
|
|
81
79
|
@table_name = name
|
80
|
+
self.const_set(:TABLE, DB[@table_name])
|
82
81
|
|
83
82
|
db_schema.each { |pair|
|
84
83
|
@schema[pair.first] = pair.last
|
@@ -130,15 +129,25 @@ module Datoki
|
|
130
129
|
end
|
131
130
|
end
|
132
131
|
|
133
|
-
def
|
134
|
-
|
132
|
+
def pseudo
|
133
|
+
fields[@current_field][:pseudo] = true
|
135
134
|
end
|
136
135
|
|
137
136
|
def allow sym
|
138
137
|
fields[@current_field][:allow][sym] = true;
|
139
138
|
end
|
140
139
|
|
140
|
+
def field? *args
|
141
|
+
inspect_field?(:type, field[:name], *args)
|
142
|
+
end
|
143
|
+
|
141
144
|
def field *args
|
145
|
+
# === Setup a default table if none specified:
|
146
|
+
if !@table_name
|
147
|
+
t_name = self.to_s.downcase.to_sym
|
148
|
+
table(name) if Datoki.db.tables.include?(t_name)
|
149
|
+
end
|
150
|
+
|
142
151
|
return fields[@current_field] if args.empty?
|
143
152
|
return fields[args.first] unless block_given?
|
144
153
|
|
@@ -214,11 +223,9 @@ module Datoki
|
|
214
223
|
name = @current_field
|
215
224
|
db_schema = schema[@current_field]
|
216
225
|
|
217
|
-
if db_schema && !field
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
return true if field[:schema_match]
|
226
|
+
return true if db_schema && !field
|
227
|
+
return true if field[:schema_has_been_matched]
|
228
|
+
return true if field[:pseudo]
|
222
229
|
|
223
230
|
if db_schema[:allow_null] != field[:allow][:null]
|
224
231
|
fail Schema_Conflict, "#{name}: :allow_null: #{db_schema[:allow_null].inspect} != #{field[:allow][:null].inspect}"
|
@@ -245,10 +252,12 @@ module Datoki
|
|
245
252
|
end
|
246
253
|
|
247
254
|
# === match :type
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
255
|
+
if field[:type] != :string_ish
|
256
|
+
db_type = Datoki.db_type_to_ruby db_schema[:db_type], db_schema[:type]
|
257
|
+
type = field[:type]
|
258
|
+
if db_type != type
|
259
|
+
fail Schema_Conflict, "#{name}: :type: #{db_type.inspect} != #{type.inspect}"
|
260
|
+
end
|
252
261
|
end
|
253
262
|
|
254
263
|
# === match :max_length
|
@@ -270,14 +279,7 @@ module Datoki
|
|
270
279
|
fail Schema_Conflict, "#{name}: :allow_null: #{db_schema[:allow_null].inspect} != #{field[:allow][:null].inspect}"
|
271
280
|
end
|
272
281
|
|
273
|
-
field[:
|
274
|
-
end
|
275
|
-
|
276
|
-
attr_reader :on_doc
|
277
|
-
def on *args
|
278
|
-
return(field_on *args) if !block_given?
|
279
|
-
@on_doc << [args, Proc.new]
|
280
|
-
self
|
282
|
+
field[:schema_has_been_matched] = true
|
281
283
|
end
|
282
284
|
|
283
285
|
def field_on action, meth_name_sym
|
@@ -373,6 +375,14 @@ module Datoki
|
|
373
375
|
when [Fixnum, Fixnum]
|
374
376
|
field[:min], field[:max] = args
|
375
377
|
|
378
|
+
when [Proc], [Regexp]
|
379
|
+
matches *args
|
380
|
+
|
381
|
+
when [Fixnum, Fixnum, Proc], [Fixnum, Fixnum, Regexp]
|
382
|
+
field[:min] = args.shift
|
383
|
+
field[:max] = args.shift
|
384
|
+
matches *args
|
385
|
+
|
376
386
|
else
|
377
387
|
fail "Unknown args: #{args.inspect}"
|
378
388
|
|
@@ -380,6 +390,15 @@ module Datoki
|
|
380
390
|
|
381
391
|
end # === def
|
382
392
|
|
393
|
+
[:mis_match, :small, :big].each { |name|
|
394
|
+
eval <<-EOF
|
395
|
+
def #{name} msg
|
396
|
+
field[:error_msgs] ||= {}
|
397
|
+
field[:error_msgs][:#{name}] = msg
|
398
|
+
end
|
399
|
+
EOF
|
400
|
+
}
|
401
|
+
|
383
402
|
def enable *props
|
384
403
|
props.each { |prop|
|
385
404
|
case prop
|
@@ -404,9 +423,9 @@ module Datoki
|
|
404
423
|
}
|
405
424
|
end
|
406
425
|
|
407
|
-
def set_to
|
426
|
+
def set_to v = :blok
|
408
427
|
field[:cleaners][:set_to] ||= []
|
409
|
-
field[:cleaners][:set_to].
|
428
|
+
field[:cleaners][:set_to] << (v == :blok ? Proc.new : v)
|
410
429
|
end
|
411
430
|
|
412
431
|
def equal_to *args
|
@@ -432,17 +451,10 @@ module Datoki
|
|
432
451
|
EOF
|
433
452
|
}
|
434
453
|
|
435
|
-
def
|
454
|
+
def matches v = :blok
|
436
455
|
fail "Not allowed for #{field[:type].inspect}" unless field?(:chars)
|
437
456
|
field[:cleaners][:match] ||= []
|
438
|
-
field[:cleaners][:match] <<
|
439
|
-
end
|
440
|
-
|
441
|
-
def not_match *args
|
442
|
-
fail "Not allowed for #{field[:type].inspect}" unless field?(:chars)
|
443
|
-
field[:cleaners][:not_match] ||= []
|
444
|
-
field[:cleaners][:not_match] << args
|
445
|
-
self
|
457
|
+
field[:cleaners][:match] << (v == :blok ? Proc.new : v)
|
446
458
|
end
|
447
459
|
|
448
460
|
def create raw
|
@@ -454,13 +466,14 @@ module Datoki
|
|
454
466
|
|
455
467
|
# ================= Instance Methods ===============
|
456
468
|
|
457
|
-
attr_reader :error
|
469
|
+
attr_reader :error, :data
|
458
470
|
def initialize unknown = nil
|
459
471
|
@data = nil
|
460
472
|
@field_name = nil
|
461
473
|
@clean = nil
|
462
474
|
@error = nil
|
463
475
|
@skips = {}
|
476
|
+
@db_ops = {} # Ex: :db_insert=>true, :db_update=>true
|
464
477
|
|
465
478
|
if unknown
|
466
479
|
if unknown.keys.all? { |f| self.class.fields.has_key?(f) }
|
@@ -472,56 +485,62 @@ module Datoki
|
|
472
485
|
end
|
473
486
|
|
474
487
|
if @raw
|
475
|
-
self.class.on_doc.each { |raw_arr|
|
476
|
-
|
477
|
-
conds = raw_arr.first
|
478
|
-
func = raw_arr.last
|
479
|
-
instance_eval(&func) if conds.all? { |cond|
|
480
|
-
case cond
|
481
|
-
when Symbol
|
482
|
-
send(cond)
|
483
|
-
when Proc
|
484
|
-
cond.arity == 1 ? cond.call(@raw) : instance_eval(&cond)
|
485
|
-
when TrueClass, FalseClass
|
486
|
-
cond
|
487
|
-
else
|
488
|
-
fail ArgumentError, "Unknown: #{cond.inspect}"
|
489
|
-
end
|
490
|
-
}
|
491
488
|
|
492
|
-
|
489
|
+
schema = self.class.schema
|
490
|
+
|
491
|
+
case
|
492
|
+
when create? && respond_to?(:create)
|
493
|
+
create
|
494
|
+
when update? && respond_to?(:update)
|
495
|
+
update
|
496
|
+
when delete? && respond_to?(:delete)
|
497
|
+
delete
|
498
|
+
end
|
493
499
|
|
494
|
-
if
|
495
|
-
@
|
496
|
-
|
500
|
+
if @clean
|
501
|
+
@clean.each { |k, v|
|
502
|
+
# === Delete nil value if schema has a default value:
|
503
|
+
@clean.delete(k) if @clean[k].nil? && schema[k] && schema[k][:default]
|
497
504
|
}
|
498
505
|
end
|
499
506
|
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
+
fail "No clean values found." if (!@clean || @clean.empty?)
|
508
|
+
|
509
|
+
if !@skips[:db] && !self.class.schema.empty?
|
510
|
+
|
511
|
+
final = db_clean
|
512
|
+
begin
|
513
|
+
case
|
514
|
+
|
515
|
+
when create?
|
516
|
+
db_insert
|
517
|
+
|
518
|
+
when update?
|
519
|
+
|
520
|
+
DB[self.class.table].
|
521
|
+
where(primary_key[:name] => final.delete(primary_key[:name])).
|
522
|
+
update(final)
|
523
|
+
|
524
|
+
when delete?
|
525
|
+
DB[self.class.table].
|
526
|
+
where(primary_key[:name] => final.delete(primary_key[:name])).
|
527
|
+
delete
|
528
|
+
|
507
529
|
end
|
508
530
|
|
509
|
-
|
510
|
-
@clean.delete(k) if @clean[k].nil? && has_default
|
511
|
-
}
|
512
|
-
end
|
531
|
+
rescue Sequel::UniqueConstraintViolation => e
|
513
532
|
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
end unless @skips[:db]
|
522
|
-
end # === if @raw
|
533
|
+
self.class.fields.each { |f|
|
534
|
+
if e.message["'\"#{f}_"]
|
535
|
+
field_name f
|
536
|
+
fail! :unique, "{{English name}} already taken: #{final[f]}"
|
537
|
+
end
|
538
|
+
}
|
539
|
+
raise e
|
523
540
|
|
524
|
-
|
541
|
+
end # === begin/rescue
|
542
|
+
end # === if !@skips[:db]
|
543
|
+
end # === if @raw
|
525
544
|
end
|
526
545
|
|
527
546
|
def skip name
|
@@ -532,6 +551,22 @@ module Datoki
|
|
532
551
|
@error && !@error.empty?
|
533
552
|
end
|
534
553
|
|
554
|
+
def db_clean
|
555
|
+
@clean.select { |k, v|
|
556
|
+
!self.class.fields[k][:pseudo]
|
557
|
+
}
|
558
|
+
end
|
559
|
+
|
560
|
+
def clean! *args
|
561
|
+
args.each { |name|
|
562
|
+
if @raw[name].nil? && (!@clean || @clean[name].nil?)
|
563
|
+
fail ArgumentError, "#{name.inspect} is not set."
|
564
|
+
else
|
565
|
+
clean name
|
566
|
+
end
|
567
|
+
}
|
568
|
+
end
|
569
|
+
|
535
570
|
def clean *args
|
536
571
|
@clean ||= {}
|
537
572
|
|
@@ -546,10 +581,8 @@ module Datoki
|
|
546
581
|
|
547
582
|
name = args.first
|
548
583
|
|
549
|
-
if (real_name = self.class.fields_as_required[name])
|
550
|
-
|
551
|
-
else
|
552
|
-
name = real_name || name
|
584
|
+
if (real_name = self.class.fields_as_required[name])
|
585
|
+
return(clean! real_name)
|
553
586
|
end
|
554
587
|
|
555
588
|
@clean[name] = @raw[name] if !clean.has_key?(name) && @raw.has_key?(name)
|
@@ -572,14 +605,14 @@ module Datoki
|
|
572
605
|
if field?(:numeric) && clean[name].is_a?(String)
|
573
606
|
clean_val = Integer(clean[name]) rescue String
|
574
607
|
if clean_val == String
|
575
|
-
fail! "
|
608
|
+
fail! :wrong_type, "{{English name}} must be numeric."
|
576
609
|
else
|
577
610
|
clean[name] = clean_val
|
578
611
|
end
|
579
612
|
end
|
580
613
|
|
581
614
|
if field?(:text) && clean[name].is_a?(String) && clean[name].empty? && field[:min].to_i > 0
|
582
|
-
fail! "
|
615
|
+
fail! :required, "{{English name}} is required."
|
583
616
|
end
|
584
617
|
# ================================
|
585
618
|
|
@@ -593,25 +626,30 @@ module Datoki
|
|
593
626
|
when [NilClass, Fixnum]
|
594
627
|
case
|
595
628
|
when clean[name].is_a?(String) && clean[name].size > field[:max]
|
596
|
-
fail! "
|
629
|
+
fail! :big, "{{English name}} can't be longer than {{max}} characters."
|
597
630
|
when clean[name].is_a?(Numeric) && clean[name] > field[:max]
|
598
|
-
fail! "
|
631
|
+
fail! :big, "{{English name}} can't be higher than {{max}}."
|
599
632
|
end
|
600
633
|
|
601
634
|
when [Fixnum, NilClass]
|
602
635
|
case
|
603
636
|
when clean[name].is_a?(String) && clean[name].size < field[:min]
|
604
|
-
fail! "
|
637
|
+
fail! :short, "{{English name}} can't be shorter than {{min}} characters."
|
605
638
|
when clean[name].is_a?(Numeric) && clean[name] < field[:min]
|
606
|
-
fail! "
|
639
|
+
fail! :short, "{{English name}} can't be less than {{min}."
|
607
640
|
end
|
608
641
|
|
609
642
|
when [Fixnum, Fixnum]
|
610
643
|
case
|
611
|
-
when
|
612
|
-
fail! "
|
613
|
-
when
|
614
|
-
fail! "
|
644
|
+
when field?(:chars) && clean[name].size > field[:max]
|
645
|
+
fail! :big, "{{English name}} must be between {{min}} and {{max}} characters."
|
646
|
+
when field?(:chars) && clean[name].size < field[:min]
|
647
|
+
fail! :small, "{{English name}} must be between {{min}} and {{max}} characters."
|
648
|
+
|
649
|
+
when field?(:numeric) && clean[name] > field[:max]
|
650
|
+
fail! :big, "{{English name}} must be between {{min}} and {{max}}."
|
651
|
+
when field?(:numeric) && clean[name] < field[:min]
|
652
|
+
fail! :small, "{{English name}} must be between {{min}} and {{max}}."
|
615
653
|
end
|
616
654
|
|
617
655
|
else
|
@@ -637,7 +675,7 @@ module Datoki
|
|
637
675
|
# === Is value in options? =======
|
638
676
|
if field[:options]
|
639
677
|
if !field[:options].include?(clean[name])
|
640
|
-
fail! "
|
678
|
+
fail! :mis_match, "{{English name}} can only be: #{field[:options].map(&:inspect).join ', '}"
|
641
679
|
end
|
642
680
|
end
|
643
681
|
# ================================
|
@@ -650,53 +688,55 @@ module Datoki
|
|
650
688
|
when :type
|
651
689
|
case
|
652
690
|
when field?(:numeric) && !clean[name].is_a?(Integer)
|
653
|
-
fail! "
|
691
|
+
fail! :wrong_type, "{{English name}} needs to be an integer."
|
654
692
|
when field?(:chars) && !clean[name].is_a?(String)
|
655
|
-
fail! "
|
693
|
+
fail! :wrong_type, "{{English name}} needs to be a String."
|
656
694
|
end
|
657
695
|
|
658
696
|
when :exact_size
|
659
697
|
if clean[name].size != field[:exact_size]
|
660
698
|
case
|
661
699
|
when field?(:chars) || clean[name].is_a?(String)
|
662
|
-
fail! "
|
700
|
+
fail! :mis_match, "{{English name}} needs to be {{exact_size}} in length."
|
663
701
|
else
|
664
|
-
fail! "
|
702
|
+
fail! :mis_match, "{{English name}} can only be {{exact_size}} in size."
|
665
703
|
end
|
666
704
|
end
|
667
705
|
|
668
706
|
when :set_to
|
669
707
|
args.each { |meth|
|
670
|
-
clean[name] = send(meth)
|
708
|
+
clean[name] = (meth.is_a?(Symbol) ? send(meth) : meth.call(self, clean[name]))
|
671
709
|
}
|
672
710
|
|
673
711
|
when :equal_to
|
674
712
|
args.each { |pair|
|
675
713
|
meth, msg, other = pair
|
676
714
|
target = send(meth)
|
677
|
-
fail!(msg || "
|
715
|
+
fail!(msg || "{{English name}} must be equal to: #{target.inspect}") unless clean[name] == target
|
678
716
|
}
|
679
717
|
|
680
718
|
when :included_in
|
681
719
|
arr, msg, other = args
|
682
|
-
fail!(msg || "
|
720
|
+
fail!(msg || "{{English name}} must be one of these: #{arr.join ', '}") unless arr.include?(clean[name])
|
683
721
|
|
684
722
|
when :upcase
|
685
723
|
clean[name] = clean[name].upcase
|
686
724
|
|
687
725
|
when :match
|
688
|
-
args.each { |
|
689
|
-
regex
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
726
|
+
args.each { |regex|
|
727
|
+
case regex
|
728
|
+
when Regexp
|
729
|
+
if clean[name] !~ regex
|
730
|
+
fail!(:mis_match, "{{English name}} is invalid.")
|
731
|
+
end
|
732
|
+
|
733
|
+
when Proc
|
734
|
+
if !regex.call(self, clean[name])
|
735
|
+
fail!(:mis_match, "{{English name}} is invalid.")
|
736
|
+
end
|
694
737
|
|
695
|
-
|
696
|
-
|
697
|
-
regex, msg, other = pair
|
698
|
-
if clean[name] =~ regex
|
699
|
-
fail!(msg || "!English_name must not match #{regex.inspect}")
|
738
|
+
else
|
739
|
+
fail ArgumentError, "Unknown matcher: #{regex.inspect}"
|
700
740
|
end
|
701
741
|
}
|
702
742
|
|
@@ -706,34 +746,31 @@ module Datoki
|
|
706
746
|
} # === field[:cleaners].each
|
707
747
|
end # === def clean
|
708
748
|
|
709
|
-
def
|
710
|
-
|
749
|
+
def error_msg type
|
750
|
+
field[:error_msgs] && field[:error_msgs][type]
|
711
751
|
end
|
712
752
|
|
713
|
-
def
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
fail ArgumentError, "Unknown value: #{cond.inspect}"
|
723
|
-
end
|
724
|
-
}
|
725
|
-
end
|
753
|
+
def fail! *args
|
754
|
+
case args.size
|
755
|
+
when 1
|
756
|
+
msg = args.shift
|
757
|
+
when 2
|
758
|
+
msg = error_msg(args.shift) || args.shift
|
759
|
+
else
|
760
|
+
fail ArgumentError, "Unknown args: #{args.inspect}"
|
761
|
+
end
|
726
762
|
|
727
|
-
|
728
|
-
err_msg = msg.gsub(/!([a-z\_\-]+)/i) { |raw|
|
763
|
+
err_msg = msg.gsub(/\{\{([a-z\_\-\ ]+)\}\}/i) { |raw|
|
729
764
|
name = $1
|
730
765
|
case name
|
731
|
-
when "
|
766
|
+
when "English name"
|
732
767
|
self.class.fields[field_name][:english_name].capitalize.gsub('_', ' ')
|
733
|
-
when "
|
768
|
+
when "ENGLISH NAME"
|
734
769
|
self.class.fields[field_name][:english_name].upcase.gsub('_', ' ')
|
735
770
|
when "max", "min", "exact_size"
|
736
771
|
self.class.fields[field_name][name.downcase.to_sym]
|
772
|
+
when "val"
|
773
|
+
clean[field_name]
|
737
774
|
else
|
738
775
|
fail "Unknown value: #{name}"
|
739
776
|
end
|
@@ -771,24 +808,16 @@ module Datoki
|
|
771
808
|
self.class.inspect_field? :type, field_name, *args
|
772
809
|
end
|
773
810
|
|
774
|
-
def create new_data
|
775
|
-
@new_data = new_data
|
776
|
-
run :create
|
777
|
-
self
|
778
|
-
end
|
779
|
-
|
780
|
-
def update new_data
|
781
|
-
@new_data = new_data
|
782
|
-
run :update
|
783
|
-
self
|
784
|
-
end
|
785
|
-
|
786
811
|
def primary_key
|
787
812
|
arr = self.class.fields.detect { |k, v| v[:primary_key] }
|
788
813
|
fail "Primary key not found." unless arr
|
789
814
|
arr.last
|
790
815
|
end
|
791
816
|
|
817
|
+
def new?
|
818
|
+
!@data
|
819
|
+
end
|
820
|
+
|
792
821
|
def create?
|
793
822
|
(@raw.has_key?(:create) && @raw[:create]) ||
|
794
823
|
@raw.has_key?(primary_key[:name]) && !@raw[primary_key[:name]]
|
@@ -806,6 +835,18 @@ module Datoki
|
|
806
835
|
!!(@raw.has_key?(:delete) && !@raw[:delete])
|
807
836
|
end
|
808
837
|
|
838
|
+
def TABLE
|
839
|
+
self.class::TABLE
|
840
|
+
end
|
841
|
+
|
842
|
+
def db_insert
|
843
|
+
k = :db_insert
|
844
|
+
final = db_clean
|
845
|
+
fail "Already inserted." if @db_ops[k]
|
846
|
+
@data = (@data || {}).merge(TABLE().returning.insert(final).first)
|
847
|
+
@db_ops[k] = true
|
848
|
+
end
|
849
|
+
|
809
850
|
end # === module Datoki ===
|
810
851
|
|
811
852
|
|
data/specs/0010-Datoki.db.rb
CHANGED
@@ -14,13 +14,29 @@ describe "Datoki.db" do
|
|
14
14
|
|
15
15
|
@klass = Class.new {
|
16
16
|
include Datoki
|
17
|
-
table
|
17
|
+
table :datoki_test
|
18
18
|
field(:id) { integer; primary_key }
|
19
19
|
field(:title) { varchar 1, 123 }
|
20
20
|
field(:body) { text nil, 1, 123 }
|
21
|
+
|
22
|
+
def create
|
23
|
+
clean :title, :body
|
24
|
+
end
|
21
25
|
}
|
22
26
|
}
|
23
27
|
|
28
|
+
it "allows an undefined field that exists in the db schema" do
|
29
|
+
Class.new {
|
30
|
+
include Datoki
|
31
|
+
table :datoki_test
|
32
|
+
field(:id) { primary_key }
|
33
|
+
field(:title) { varchar 1, 123 }
|
34
|
+
def create
|
35
|
+
clean :title
|
36
|
+
end
|
37
|
+
}.create(:title=>'title').data.should == {:id=>1, :title=>'title', :body=>'hello'}
|
38
|
+
end
|
39
|
+
|
24
40
|
it 'raises Schema_Conflict if a field is found that allows null, but not specifed to do so' do
|
25
41
|
should.raise(Datoki::Schema_Conflict) {
|
26
42
|
Class.new {
|
@@ -30,13 +46,13 @@ describe "Datoki.db" do
|
|
30
46
|
field(:title) { varchar 1, 123 }
|
31
47
|
field(:body) { text 1, 123 }
|
32
48
|
}
|
33
|
-
}.message.should.match
|
49
|
+
}.message.should.match /body: :allow_null: true != false/
|
34
50
|
end
|
35
51
|
|
36
52
|
it "requires field if value = null and :allow_null = false" do
|
37
|
-
should.raise(
|
53
|
+
should.raise(Sequel::NotNullConstraintViolation) {
|
38
54
|
@klass.create :title=>nil, :body=>"hiya"
|
39
|
-
}.message.should.match
|
55
|
+
}.message.should.match /null value in column "title" violates not-null constraint/
|
40
56
|
end
|
41
57
|
|
42
58
|
it "requires a value if: :text field, value = (empty string), min = 1, allow null" do
|
data/specs/0010-Numeric.rb
CHANGED
@@ -7,6 +7,9 @@ describe Numeric do
|
|
7
7
|
include Datoki
|
8
8
|
field(:id) { primary_key }
|
9
9
|
field(:age) { smallint 1, 150 }
|
10
|
+
def create
|
11
|
+
clean :age
|
12
|
+
end
|
10
13
|
}
|
11
14
|
end
|
12
15
|
}
|
@@ -31,8 +34,11 @@ describe Numeric do
|
|
31
34
|
include Datoki
|
32
35
|
field(:id) { primary_key }
|
33
36
|
field(:age) { smallint nil, 1, 99 }
|
37
|
+
def create
|
38
|
+
clean :age
|
39
|
+
end
|
34
40
|
}.create(:age=>nil).
|
35
|
-
clean
|
41
|
+
clean.should == {:age=>nil}
|
36
42
|
end
|
37
43
|
|
38
44
|
it "allows nil in an array" do
|
@@ -40,8 +46,11 @@ describe Numeric do
|
|
40
46
|
include Datoki
|
41
47
|
field(:id) { primary_key }
|
42
48
|
field(:age) { smallint [nil, 1,2,3,4] }
|
49
|
+
def create
|
50
|
+
clean :age
|
51
|
+
end
|
43
52
|
}.create(:age=>nil).
|
44
|
-
clean
|
53
|
+
clean.should == {:age=>nil}
|
45
54
|
end
|
46
55
|
|
47
56
|
it "allows to specify an Array of possible values" do
|
@@ -49,6 +58,9 @@ describe Numeric do
|
|
49
58
|
include Datoki
|
50
59
|
field(:id) { primary_key }
|
51
60
|
field(:age) { smallint [1,2,3,4] }
|
61
|
+
def create
|
62
|
+
clean :age
|
63
|
+
end
|
52
64
|
}.create(:age=>2).
|
53
65
|
clean[:age].should == 2
|
54
66
|
end
|
@@ -59,8 +71,41 @@ describe Numeric do
|
|
59
71
|
include Datoki
|
60
72
|
field(:id) { primary_key }
|
61
73
|
field(:num) { smallint [1,2,3,4] }
|
74
|
+
def create
|
75
|
+
clean :num
|
76
|
+
end
|
62
77
|
}.create :num=>0
|
63
78
|
}.error[:msg].should.match /Num can only be: 1, 2, 3, 4/
|
64
79
|
end
|
65
80
|
|
81
|
+
it "uses :big error msg" do
|
82
|
+
catch(:invalid) {
|
83
|
+
Class.new {
|
84
|
+
include Datoki
|
85
|
+
field(:squirrels) {
|
86
|
+
smallint 10, 10
|
87
|
+
big '{{val}} is too big.'
|
88
|
+
}
|
89
|
+
def create
|
90
|
+
clean :squirrels
|
91
|
+
end
|
92
|
+
}.create :squirrels=>50
|
93
|
+
}.error[:msg].should == "50 is too big."
|
94
|
+
end # === it uses :big error msg
|
95
|
+
|
96
|
+
it "uses :small error msg" do
|
97
|
+
catch(:invalid) {
|
98
|
+
Class.new {
|
99
|
+
include Datoki
|
100
|
+
field(:squirrels) {
|
101
|
+
smallint 10, 10
|
102
|
+
small '{{val}} is too small.'
|
103
|
+
}
|
104
|
+
def create
|
105
|
+
clean :squirrels
|
106
|
+
end
|
107
|
+
}.create :squirrels=>5
|
108
|
+
}.error[:msg].should == "5 is too small."
|
109
|
+
end # === it uses :small error msg
|
110
|
+
|
66
111
|
end # === describe Numeric
|
data/specs/0010-Numeric_db.rb
CHANGED
data/specs/0010-varchar.rb
CHANGED
@@ -1,20 +1,14 @@
|
|
1
1
|
|
2
2
|
describe :varchar do # ================================================
|
3
3
|
|
4
|
-
it "requires field by default during :create" do
|
5
|
-
should.raise(ArgumentError) {
|
6
|
-
Class.new {
|
7
|
-
include Datoki
|
8
|
-
field(:title) { varchar }
|
9
|
-
}.create({})
|
10
|
-
}.message.should.match /:title is not set/
|
11
|
-
end
|
12
|
-
|
13
4
|
it "raises RuntimeError if allow :null and :min = 0" do
|
14
5
|
should.raise(RuntimeError) {
|
15
6
|
Class.new {
|
16
7
|
include Datoki
|
17
8
|
field(:name) { varchar nil, 0, 50 }
|
9
|
+
def create
|
10
|
+
clean :name
|
11
|
+
end
|
18
12
|
}
|
19
13
|
}.message.should.match /varchar can't be both: allow :null && :min = 0/
|
20
14
|
end
|
@@ -24,6 +18,9 @@ describe :varchar do # ================================================
|
|
24
18
|
Class.new {
|
25
19
|
include Datoki
|
26
20
|
field(:title) { varchar 3, 255 }
|
21
|
+
def create
|
22
|
+
clean :title
|
23
|
+
end
|
27
24
|
}.create :title => '1'
|
28
25
|
}.error[:msg].should.match /Title must be between 3 and 255 characters/i
|
29
26
|
end
|
@@ -33,6 +30,9 @@ describe :varchar do # ================================================
|
|
33
30
|
Class.new {
|
34
31
|
include Datoki
|
35
32
|
field(:title) { varchar 0, 5 }
|
33
|
+
def create
|
34
|
+
clean :title
|
35
|
+
end
|
36
36
|
}.create :title => '123456'
|
37
37
|
}.error[:msg].should.match /Title must be between 0 and 5 characters/
|
38
38
|
end
|
@@ -42,8 +42,11 @@ describe :varchar do # ================================================
|
|
42
42
|
Class.new {
|
43
43
|
include Datoki
|
44
44
|
field :title do
|
45
|
-
varchar
|
46
|
-
|
45
|
+
varchar /\A[a-zA-Z0-9]+\z/i
|
46
|
+
mis_match "Title must be only: alphanumeric"
|
47
|
+
end
|
48
|
+
def create
|
49
|
+
clean :title
|
47
50
|
end
|
48
51
|
}.create :title => '$! title'
|
49
52
|
}.error[:msg].should.match /Title must be only: alphanumeric/
|
@@ -52,10 +55,12 @@ describe :varchar do # ================================================
|
|
52
55
|
it "allows varchar to be nil" do
|
53
56
|
r = Class.new {
|
54
57
|
include Datoki
|
55
|
-
field(:title) {
|
56
|
-
|
57
|
-
|
58
|
-
|
58
|
+
field(:title) { varchar nil, 1, 123 }
|
59
|
+
field(:body) { varchar nil, 1, 123 }
|
60
|
+
def create
|
61
|
+
clean :title, :body
|
62
|
+
end
|
63
|
+
}.create({:body=>'yo'})
|
59
64
|
r.clean.has_key?(:title).should == false
|
60
65
|
end
|
61
66
|
|
@@ -69,6 +74,9 @@ describe :varchar do # ================================================
|
|
69
74
|
'Custom title'
|
70
75
|
end
|
71
76
|
}
|
77
|
+
def create
|
78
|
+
clean :title
|
79
|
+
end
|
72
80
|
}.
|
73
81
|
create(:title => 'My Title').
|
74
82
|
clean[:title].should.match /Custom title/
|
@@ -78,6 +86,9 @@ describe :varchar do # ================================================
|
|
78
86
|
Class.new {
|
79
87
|
include Datoki
|
80
88
|
field(:title) { varchar }
|
89
|
+
def create
|
90
|
+
clean :title
|
91
|
+
end
|
81
92
|
}.
|
82
93
|
create(:title => ' my title ').
|
83
94
|
clean[:title].should == 'my title'
|
@@ -90,6 +101,9 @@ describe :varchar do # ================================================
|
|
90
101
|
varchar
|
91
102
|
disable :strip
|
92
103
|
}
|
104
|
+
def create
|
105
|
+
clean :title
|
106
|
+
end
|
93
107
|
}.
|
94
108
|
create(:title => ' my title ').
|
95
109
|
clean[:title].should == ' my title '
|
data/specs/0010-varchar_db.rb
CHANGED
@@ -0,0 +1,60 @@
|
|
1
|
+
|
2
|
+
describe :string do
|
3
|
+
|
4
|
+
before {
|
5
|
+
CACHE[:datoki_string] ||= begin
|
6
|
+
reset_db <<-EOF
|
7
|
+
CREATE TABLE "datoki_test" (
|
8
|
+
id serial NOT NULL PRIMARY KEY,
|
9
|
+
ip inet NOT NULL
|
10
|
+
);
|
11
|
+
EOF
|
12
|
+
end
|
13
|
+
}
|
14
|
+
|
15
|
+
it "treats special PG types as a string" do
|
16
|
+
Class.new {
|
17
|
+
include Datoki
|
18
|
+
table :datoki_test
|
19
|
+
field(:ip) {
|
20
|
+
string_ish 5, 50, /\A[0-9\:\.]+\Z/
|
21
|
+
mis_match "Invalid format for ip: !val"
|
22
|
+
}
|
23
|
+
def create
|
24
|
+
clean :ip
|
25
|
+
end
|
26
|
+
}.create(:ip=>'127.0.0.2')
|
27
|
+
DB[:datoki_test].all.should == [{:id=>1, :ip=>'127.0.0.2'}]
|
28
|
+
end # === it treats special PG types as a string
|
29
|
+
|
30
|
+
it "uses :big error msg" do
|
31
|
+
catch(:invalid) {
|
32
|
+
Class.new {
|
33
|
+
include Datoki
|
34
|
+
field(:note) {
|
35
|
+
string_ish 1,5
|
36
|
+
big '{{English name}} can\'t be bigger than {{max}}.'
|
37
|
+
}
|
38
|
+
def create
|
39
|
+
clean :note
|
40
|
+
end
|
41
|
+
}.create :note=>"1234567"
|
42
|
+
}.error[:msg].should == "Note can\'t be bigger than 5."
|
43
|
+
end # === it uses :big error msg
|
44
|
+
|
45
|
+
it "uses :small error msg" do
|
46
|
+
catch(:invalid) {
|
47
|
+
Class.new {
|
48
|
+
include Datoki
|
49
|
+
field(:note) {
|
50
|
+
string_ish 2,5
|
51
|
+
small '{{English name}} can\'t be smaller than {{min}}.'
|
52
|
+
}
|
53
|
+
def create
|
54
|
+
clean :note
|
55
|
+
end
|
56
|
+
}.create :note=>"1"
|
57
|
+
}.error[:msg].should == "Note can\'t be smaller than 2."
|
58
|
+
end # === it uses :small error msg
|
59
|
+
|
60
|
+
end # === describe :string
|
@@ -0,0 +1,34 @@
|
|
1
|
+
|
2
|
+
describe :pseudo do
|
3
|
+
|
4
|
+
before {
|
5
|
+
CACHE[:datoki_pseudo] ||= begin
|
6
|
+
reset_db <<-EOF
|
7
|
+
CREATE TABLE "datoki_test" (
|
8
|
+
id serial NOT NULL PRIMARY KEY,
|
9
|
+
title varchar(15) NOT NULL,
|
10
|
+
body text NOT NULL
|
11
|
+
);
|
12
|
+
EOF
|
13
|
+
end
|
14
|
+
}
|
15
|
+
|
16
|
+
it "does not save values to database" do
|
17
|
+
Class.new {
|
18
|
+
include Datoki
|
19
|
+
table :datoki_test
|
20
|
+
field(:title) { varchar 5, 15 }
|
21
|
+
field(:body) { text 5, 15 }
|
22
|
+
field(:password) {
|
23
|
+
string_ish 5, 10, /\A[a-z0-9\ ]+\Z/
|
24
|
+
pseudo
|
25
|
+
}
|
26
|
+
def create
|
27
|
+
clean :title, :body, :password
|
28
|
+
end
|
29
|
+
}.create(:title=>'Yo yo yo', :body=>'The body',:password=>'11111111')
|
30
|
+
|
31
|
+
DB[:datoki_test].all.should == [{:id=>1,:title=>'Yo yo yo', :body=>'The body'}]
|
32
|
+
end # === it does not save values to database
|
33
|
+
|
34
|
+
end # === describe :pseudo
|
@@ -0,0 +1,19 @@
|
|
1
|
+
|
2
|
+
describe :clean! do
|
3
|
+
|
4
|
+
it "fails w/ArgumentError if field is undefined" do
|
5
|
+
c = Class.new {
|
6
|
+
include Datoki
|
7
|
+
|
8
|
+
field(:name) { varchar }
|
9
|
+
def create
|
10
|
+
clean! :name, :nick
|
11
|
+
end
|
12
|
+
}
|
13
|
+
|
14
|
+
should.raise(ArgumentError) {
|
15
|
+
c.create(:nick=>'Bob')
|
16
|
+
}.message.should.match /:name is not set/
|
17
|
+
end # === it fails w/ArgumentError if underfined
|
18
|
+
|
19
|
+
end # === describe :clean!
|
data/specs/0020-clean.rb
CHANGED
@@ -6,7 +6,10 @@ describe :clean do
|
|
6
6
|
include Datoki
|
7
7
|
|
8
8
|
field(:nick_name) { varchar 1,50 }
|
9
|
-
|
9
|
+
def create
|
10
|
+
clean :nick_name
|
11
|
+
skip :db
|
12
|
+
end
|
10
13
|
|
11
14
|
def happy?
|
12
15
|
true
|
@@ -24,12 +27,9 @@ describe :clean do
|
|
24
27
|
field(:nick_name) { varchar 3, 255 }
|
25
28
|
field(:age) { smallint; allow :null }
|
26
29
|
|
27
|
-
|
30
|
+
def create
|
28
31
|
clean :nick_name, :age
|
29
|
-
|
30
|
-
|
31
|
-
def happy?
|
32
|
-
true
|
32
|
+
skip :db
|
33
33
|
end
|
34
34
|
}
|
35
35
|
c.create(:nick_name=>'Wiley').
|
@@ -41,17 +41,13 @@ describe :clean do
|
|
41
41
|
include Datoki
|
42
42
|
|
43
43
|
field(:name) { varchar }
|
44
|
-
|
44
|
+
def create
|
45
45
|
clean :name!
|
46
46
|
end
|
47
|
-
|
48
|
-
def happy?
|
49
|
-
true
|
50
|
-
end
|
51
47
|
}
|
52
48
|
|
53
49
|
should.raise(ArgumentError) {
|
54
|
-
c.
|
50
|
+
c.create(:nick=>'Bob')
|
55
51
|
}.message.should.match /:name is not set/
|
56
52
|
end # === it fails w/ArgumentError if underfined
|
57
53
|
|
@@ -0,0 +1,93 @@
|
|
1
|
+
|
2
|
+
describe :matching do
|
3
|
+
|
4
|
+
before {
|
5
|
+
CACHE[:datoki_matching] ||= begin
|
6
|
+
reset_db <<-EOF
|
7
|
+
CREATE TABLE "datoki_test" (
|
8
|
+
id serial NOT NULL PRIMARY KEY,
|
9
|
+
title varchar(15) NOT NULL,
|
10
|
+
body text NOT NULL,
|
11
|
+
age smallint NOT NULL
|
12
|
+
);
|
13
|
+
EOF
|
14
|
+
end
|
15
|
+
}
|
16
|
+
|
17
|
+
it "uses error message from :mis_match" do
|
18
|
+
catch(:invalid) {
|
19
|
+
Class.new {
|
20
|
+
include Datoki
|
21
|
+
table :datoki_test
|
22
|
+
field(:title) { varchar 5, 15, lambda { |r, val| false }; mis_match "Title is bad." }
|
23
|
+
field(:body) { text 5, 10 }
|
24
|
+
field(:age) { smallint }
|
25
|
+
def create
|
26
|
+
clean :title, :body, :age
|
27
|
+
end
|
28
|
+
}.create(:title=>'title', :body=>'body', :age=>50)
|
29
|
+
}.error[:msg].should.match /Title is bad/
|
30
|
+
end # === it uses error message from :mis_match
|
31
|
+
|
32
|
+
it "inserts data into db if match w/Regexp matcher" do
|
33
|
+
Class.new {
|
34
|
+
include Datoki
|
35
|
+
table :datoki_test
|
36
|
+
field(:title) { varchar 5, 15, /title 4/ }
|
37
|
+
field(:body) { text 5, 10 }
|
38
|
+
field(:age) { smallint }
|
39
|
+
def create
|
40
|
+
clean :title, :body, :age
|
41
|
+
end
|
42
|
+
}.create(:title=>'title 4', :body=>'body 4', :age=>50)
|
43
|
+
|
44
|
+
DB[:datoki_test].all.last.should == {:id=>1, :title=>'title 4', :body=>'body 4', :age=>50}
|
45
|
+
end # === it inserts data into db if matcher returns true
|
46
|
+
|
47
|
+
it "inserts data into db if lambda matcher returns true" do
|
48
|
+
Class.new {
|
49
|
+
include Datoki
|
50
|
+
table :datoki_test
|
51
|
+
field(:title) { varchar 5, 15, lambda { |r, val| true } }
|
52
|
+
field(:body) { text 5, 10 }
|
53
|
+
field(:age) { smallint }
|
54
|
+
def create
|
55
|
+
clean :title, :body, :age
|
56
|
+
end
|
57
|
+
}.create(:title=>'title 5', :body=>'body 5', :age=>50)
|
58
|
+
|
59
|
+
DB[:datoki_test].all.last.should == {:id=>2, :title=>'title 5', :body=>'body 5', :age=>50}
|
60
|
+
end # === it inserts data into db if matcher returns true
|
61
|
+
|
62
|
+
it "throws :invalid if mis-match w/Regexp matcher" do
|
63
|
+
catch(:invalid) {
|
64
|
+
Class.new {
|
65
|
+
include Datoki
|
66
|
+
table :datoki_test
|
67
|
+
field(:title) { varchar 5, 15, /\Agood\Z/; mis_match "Title is really bad." }
|
68
|
+
field(:body) { text 5, 10 }
|
69
|
+
field(:age) { smallint }
|
70
|
+
def create
|
71
|
+
clean :title, :body, :age
|
72
|
+
end
|
73
|
+
}.create(:title=>'baddd', :body=>'body', :age=>50)
|
74
|
+
}.error[:msg].should.match /Title is really bad/
|
75
|
+
end # === it accepts a Regexp as a matcher
|
76
|
+
|
77
|
+
it "throws :invalid if lambda matcher returns false" do
|
78
|
+
r = catch(:invalid) {
|
79
|
+
Class.new {
|
80
|
+
include Datoki
|
81
|
+
table :datoki_test
|
82
|
+
field(:title) { varchar 5, 15, lambda { |r, v| false } }
|
83
|
+
field(:body) { text 5, 10 }
|
84
|
+
field(:age) { smallint }
|
85
|
+
def create
|
86
|
+
clean :title, :body, :age
|
87
|
+
end
|
88
|
+
}.create(:title=>'title', :body=>'body', :age=>50)
|
89
|
+
}
|
90
|
+
r.error[:msg].should.match /Title is invalid/
|
91
|
+
end # === it throws :invalid if matcher returns false
|
92
|
+
|
93
|
+
end # === describe :matching
|
@@ -0,0 +1,32 @@
|
|
1
|
+
|
2
|
+
describe :set_to do
|
3
|
+
|
4
|
+
it "sets val to block" do
|
5
|
+
Class.new {
|
6
|
+
include Datoki
|
7
|
+
field(:age) {
|
8
|
+
smallint
|
9
|
+
set_to { |raw, val| val + 50 }
|
10
|
+
}
|
11
|
+
def create
|
12
|
+
clean :age
|
13
|
+
end
|
14
|
+
}.create(:age=>20).
|
15
|
+
clean.should == {:age=>70}
|
16
|
+
end # === it sets val to lambda
|
17
|
+
|
18
|
+
it "sets val to lambda" do
|
19
|
+
Class.new {
|
20
|
+
include Datoki
|
21
|
+
field(:age) {
|
22
|
+
smallint
|
23
|
+
set_to(lambda { |raw, val| val + 10 })
|
24
|
+
}
|
25
|
+
def create
|
26
|
+
clean :age
|
27
|
+
end
|
28
|
+
}.create(:age=>20).
|
29
|
+
clean.should == {:age=>30}
|
30
|
+
end # === it sets val to lambda
|
31
|
+
|
32
|
+
end # === describe :set_to
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: datoki
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- da99
|
@@ -108,7 +108,6 @@ files:
|
|
108
108
|
- VERSION
|
109
109
|
- datoki.gemspec
|
110
110
|
- lib/datoki.rb
|
111
|
-
- specs/0010-Datoki.db.new.rb
|
112
111
|
- specs/0010-Datoki.db.rb
|
113
112
|
- specs/0010-Numeric.rb
|
114
113
|
- specs/0010-Numeric_db.rb
|
@@ -118,8 +117,12 @@ files:
|
|
118
117
|
- specs/0010-schema_conflict.rb
|
119
118
|
- specs/0010-varchar.rb
|
120
119
|
- specs/0010-varchar_db.rb
|
120
|
+
- specs/0011-string_ish.rb
|
121
|
+
- specs/0012-pseudo.rb
|
122
|
+
- specs/0020-clean!.rb
|
121
123
|
- specs/0020-clean.rb
|
122
|
-
- specs/
|
124
|
+
- specs/0030-matching.rb
|
125
|
+
- specs/0031-set_to.rb
|
123
126
|
- specs/lib/helpers.rb
|
124
127
|
homepage: https://github.com/da99/datoki
|
125
128
|
licenses:
|
data/specs/0010-Datoki.db.new.rb
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
|
2
|
-
describe 'Datoki.db :new' do
|
3
|
-
|
4
|
-
before {
|
5
|
-
CACHE[:datoki_db_new] ||= begin
|
6
|
-
reset_db <<-EOF
|
7
|
-
CREATE TABLE "datoki_test" (
|
8
|
-
id serial NOT NULL PRIMARY KEY,
|
9
|
-
parent_id smallint NOT NULL,
|
10
|
-
title varchar(123) NOT NULL,
|
11
|
-
body text
|
12
|
-
);
|
13
|
-
EOF
|
14
|
-
end
|
15
|
-
}
|
16
|
-
|
17
|
-
it "raises Schema_Conflict if field has not been defined, but exists in the db schema" do
|
18
|
-
should.raise(Datoki::Schema_Conflict) {
|
19
|
-
Class.new {
|
20
|
-
include Datoki
|
21
|
-
table :datoki_test
|
22
|
-
field(:id) { primary_key }
|
23
|
-
field(:parent_id) { smallint }
|
24
|
-
field(:body) { text nil, 1, 222 }
|
25
|
-
}.new
|
26
|
-
}.message.should.match /:title has not been defined/
|
27
|
-
end
|
28
|
-
|
29
|
-
end # === describe Datoki.db :new
|
30
|
-
|
31
|
-
|
data/specs/0020-on.rb
DELETED
@@ -1,64 +0,0 @@
|
|
1
|
-
|
2
|
-
describe :on do
|
3
|
-
|
4
|
-
it "executes proc if condition is true" do
|
5
|
-
c = Class.new {
|
6
|
-
include Datoki
|
7
|
-
|
8
|
-
on :happy? do
|
9
|
-
@result = :happy
|
10
|
-
end
|
11
|
-
|
12
|
-
on :sad? do
|
13
|
-
@result= :happy
|
14
|
-
end
|
15
|
-
|
16
|
-
attr_reader :result
|
17
|
-
|
18
|
-
def happy?
|
19
|
-
@raw[:state] == :happy
|
20
|
-
end
|
21
|
-
|
22
|
-
def sad?
|
23
|
-
@raw[:state] == :sad
|
24
|
-
end
|
25
|
-
}
|
26
|
-
|
27
|
-
c.create(:state => :happy).
|
28
|
-
result.should == :happy
|
29
|
-
end # === it executes proc if condition is true
|
30
|
-
|
31
|
-
it "executes nested :on if condition matches" do
|
32
|
-
c = Class.new {
|
33
|
-
include Datoki
|
34
|
-
|
35
|
-
RESULT = []
|
36
|
-
|
37
|
-
attr_reader :result
|
38
|
-
|
39
|
-
on :true? do
|
40
|
-
on :filled? do
|
41
|
-
@result ||= []
|
42
|
-
@result << :found
|
43
|
-
end
|
44
|
-
on :false? do
|
45
|
-
fail
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
def false?
|
50
|
-
false
|
51
|
-
end
|
52
|
-
|
53
|
-
def filled?
|
54
|
-
true
|
55
|
-
end
|
56
|
-
|
57
|
-
def true?
|
58
|
-
true
|
59
|
-
end
|
60
|
-
}
|
61
|
-
c.create({}).result.should == [:found]
|
62
|
-
end # === it executes nested :on if condition matches
|
63
|
-
|
64
|
-
end # === describe :on
|