datoki 2.0.1 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|