pggraphql 0.0.13 → 0.0.15

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1435a943bfa68882db3826bb0f70561db6ad90cb
4
- data.tar.gz: 9efca16a8d0c08f171162645661b541248cc70bb
3
+ metadata.gz: 30009a5c466252f930ace1828c0111d0e6f78fd4
4
+ data.tar.gz: 51f4d7fdf7d354cc81797c11abf22c3c54a224ee
5
5
  SHA512:
6
- metadata.gz: 592df918ac04b3f7c4b1201c0c2d7088f5888296a62d968a041a98fd99463a1dac132f466fb1c76ae4e5536595687674aab8082221f91be40fd9a4a88a5bb59f
7
- data.tar.gz: 4bf4ac82696eb398dba7752a92f2605ebfa5d3c17daf3011fcd895e388ba369565803a29e6de06bddac3554555321aff32bd63cb697b03df59085b4559d77ab5
6
+ metadata.gz: 801bdabcbd2cb22177ed107c71a7eb49dbc968f27c10fe25f864d72b0ebb0da580d58daefb86c8921e84263aa9f51f6e9dce684f93417c4015c3b59b0c770d67
7
+ data.tar.gz: 6a8c862a0bee46b0f4248c795ba64c7814054f507f66962bef395d9b95b2835711574f978f8d168b7c86d8fb41b4a731ac897350856d0087988d54f7834718b9
@@ -1,3 +1,3 @@
1
1
  module Pggraphql
2
- VERSION = "0.0.13"
2
+ VERSION = "0.0.15"
3
3
  end
data/lib/pggraphql.rb CHANGED
@@ -42,6 +42,8 @@ module PgGraphQl
42
42
  type = link ? link.type : self.types[e[0].to_s.split("@").first.singularize.to_sym]
43
43
  ids = e[1][:id]
44
44
 
45
+ raise "type not found: #{e[0]}; link_name: #{link_name}" unless type
46
+
45
47
  raise "found :id with without value on type #{type.name.inspect}" if e[1].key?(:id) && ids.nil?
46
48
  raise "found empty :id array on type #{type.name.inspect}" if e[1].key?(:id) && ids.is_a?(Array) && ids.empty?
47
49
 
@@ -69,7 +71,7 @@ module PgGraphQl
69
71
  # column_expr = type.mappings[field_name] || column_name
70
72
 
71
73
  column_expr = if field_def[:expr]
72
- field_def[:expr].call(column_name)
74
+ handle_sql_part(field_def[:expr].call(column_name), params)
73
75
  else
74
76
  column_name
75
77
  end
@@ -97,7 +99,21 @@ module PgGraphQl
97
99
  wheres << ("(" + handle_sql_part(type.filter, params) + ")") if type.filter
98
100
 
99
101
  if link
100
- wheres << ("(" + handle_sql_part(link.fk, params) + ")")
102
+ fk = link.fk.is_a?(Proc) ? link.fk.call(level) : link.fk
103
+
104
+ if link_name.to_s.index("__")
105
+ subtype_type, subtype_link_name = link_name.to_s.split("__")
106
+
107
+ fk = "#{link.type.table}.id = #{subtype_type}.#{subtype_link_name}_id" if fk == :belongs_to
108
+ fk = "#{link.type.table}.#{parent.name}_id = #{subtype_type}.id" if fk == :has_one
109
+ fk = "#{link.type.table}.#{parent.name}_id = #{subtype_type}.id" if fk == :many
110
+ else
111
+ fk = "#{link.type.table}.id = #{parent.table}.#{link.name}_id" if fk == :belongs_to
112
+ fk = "#{link.type.table}.#{parent.name}_id = #{parent.table}.id" if fk == :has_one
113
+ fk = "#{link.type.table}.#{parent.name}_id = #{parent.table}.id" if fk == :many
114
+ end
115
+
116
+ wheres << ("(" + handle_sql_part(fk, params) + ")")
101
117
  wheres << ("(" + handle_sql_part(link.filter, params) + ")") if link.filter
102
118
  end
103
119
 
@@ -106,12 +122,17 @@ module PgGraphQl
106
122
  sql += "x.*"
107
123
  sql += "), '[]'::json)" if is_many
108
124
  sql += ") from (select #{columns} from #{type.table}"
109
-
110
125
 
111
126
  unless type.subtypes.empty?
112
127
  sql += "\n" + type.subtypes.map do |f|
113
128
  subtype = f[1]
114
- "left join #{subtype.table} as #{subtype.name} on (#{handle_sql_part(subtype.fk, params)})"
129
+ fk = subtype.fk.is_a?(Proc) ? subtype.fk.call(level) : subtype.fk
130
+
131
+ fk = "#{subtype.name}.id = #{type.table}.id and #{type.table}.type = '#{subtype.name}'" if fk == :subtype
132
+
133
+ subtype_as = subtype.fk.is_a?(Proc) ? "#{subtype.name}#{level}" : subtype.name
134
+ # subtype_as = (link && parent && link.type == parent.name) ? "#{subtype.name}#{level}" : subtype.name
135
+ "left join #{subtype.table} as #{subtype_as} on (#{handle_sql_part(fk, params)})"
115
136
  end.join("\n")
116
137
  end
117
138
 
@@ -184,14 +205,24 @@ module PgGraphQl
184
205
  def one(name, opts={})
185
206
  create_link(name, false, opts)
186
207
  end
208
+
209
+ def has_one(name, opts={})
210
+ one(name, opts.merge({fk: :has_one}))
211
+ end
212
+
213
+ def belongs_to(name, opts={})
214
+ one(name, opts.merge({fk: :belongs_to}))
215
+ end
216
+
187
217
  def many(name, opts={})
188
- create_link(name, true, opts)
218
+ create_link(name, true, {fk: :many}.merge(opts))
189
219
  end
190
220
  def subtype(name, opts={})
191
221
  subtype = @subtypes[name] = SubType.new(self, name)
192
- opts.each_pair do |key, val|
222
+ {fk: :subtype}.merge(opts).each_pair do |key, val|
193
223
  subtype.send(:"#{key}=", val)
194
224
  end
225
+ yield(subtype) if block_given?
195
226
  subtype
196
227
  end
197
228
  def create_link(name, many, opts)
@@ -205,12 +236,25 @@ module PgGraphQl
205
236
 
206
237
  class SubType
207
238
  attr_accessor :name, :table, :fk
239
+ attr_reader :type
208
240
  def initialize(type, name)
209
241
  @type = type
210
242
  @name = name
211
243
  @table = nil
212
244
  @fk = nil
213
245
  end
246
+ def has_one(name, opts={})
247
+ @type.has_one(:"#{@name}__#{name}", {type: name}.merge(opts))
248
+ end
249
+ def belongs_to(name, opts={})
250
+ @type.belongs_to(:"#{@name}__#{name}", {type: name}.merge(opts))
251
+ end
252
+ def one(name, opts={})
253
+ @type.one(:"#{@name}__#{name}", {type: name}.merge(opts))
254
+ end
255
+ def many(name, opts={})
256
+ @type.many(:"#{@name}__#{name}", {type: name}.merge(opts))
257
+ end
214
258
  end
215
259
 
216
260
  class Link
@@ -353,21 +353,16 @@ module PgGraphQl
353
353
  }
354
354
  }) do |s|
355
355
  s.root :product
356
-
357
356
  s.type :user, fields: [:email] do |t|
358
357
  t.many :orders, fk: "user_id = users.id"
359
358
  end
360
359
 
361
360
  s.type :order
362
-
363
361
  s.type :product, null_pk: :array, fields: [:type, :clickout__destination_url, :download__download_url] do |t|
364
-
365
362
  t.subtype :download, table: :product_downloads, fk: "download.id = products.id and products.type = 'download'"
366
363
  t.subtype :clickout, table: :product_clickouts, fk: "clickout.id = products.id and products.type = 'clickout'"
367
-
368
364
  t.many :download__users, type: :user, fk: "id = download.id"
369
365
  end
370
-
371
366
  end
372
367
 
373
368
  assert_equal token(<<-SQL
@@ -393,6 +388,105 @@ module PgGraphQl
393
388
  SQL
394
389
  ), token(res[:sql])
395
390
  assert_equal [], res[:params]
391
+
392
+ # ------
393
+
394
+ res = to_sql({
395
+ products: {
396
+ type: nil,
397
+ clickout__destination_url: nil,
398
+ download__download_url: nil,
399
+ download__users: {
400
+ orders: {}
401
+ }
402
+ }
403
+ }) do |s|
404
+ s.root :product
405
+ s.type :user, fields: [:email] do |t|
406
+ t.many :orders
407
+ end
408
+
409
+ s.type :order
410
+ s.type :product, null_pk: :array, fields: [:type, :clickout__destination_url, :download__download_url] do |t|
411
+ t.subtype :download, table: :product_downloads
412
+ t.subtype :clickout, table: :product_clickouts
413
+ t.many :download__users, type: :user
414
+ end
415
+ end
416
+
417
+ assert_equal token(<<-SQL
418
+ select 'products'::text as key,
419
+ (select to_json(coalesce(json_agg(x.*), '[]'::json))
420
+ from (select products.id,
421
+ type,
422
+ clickout.destination_url as clickout__destination_url,
423
+ download.download_url as download__download_url,
424
+ (select to_json(coalesce(json_agg(x.*), '[]'::json))
425
+ from (select users.id,
426
+ (select to_json(coalesce(json_agg(x.*), '[]'::json))
427
+ from (select orders.id
428
+ from orders
429
+ where (orders.user_id = users.id)) x) as "orders"
430
+ from users
431
+ where (users.product_id = download.id)) x) as "download__users"
432
+ from products
433
+ left join product_downloads as download on (download.id = products.id
434
+ and products.type = 'download')
435
+ left join product_clickouts as clickout on (clickout.id = products.id
436
+ and products.type = 'clickout')) x) as value
437
+ SQL
438
+ ), token(res[:sql])
439
+ assert_equal [], res[:params]
440
+
441
+ # ------
442
+
443
+ res = to_sql({
444
+ products: {
445
+ type: nil,
446
+ clickout__destination_url: nil,
447
+ download__download_url: nil,
448
+ download__users: {
449
+ orders: {}
450
+ }
451
+ }
452
+ }) do |s|
453
+ s.root :product
454
+ s.type :user, fields: [:email] do |t|
455
+ t.many :orders
456
+ end
457
+
458
+ s.type :order
459
+ s.type :product, null_pk: :array, fields: [:type, :clickout__destination_url, :download__download_url] do |t|
460
+ t.subtype :download, table: :product_downloads do |st|
461
+ st.many :users, type: :user
462
+ end
463
+ t.subtype :clickout, table: :product_clickouts
464
+ end
465
+ end
466
+
467
+ assert_equal token(<<-SQL
468
+ select 'products'::text as key,
469
+ (select to_json(coalesce(json_agg(x.*), '[]'::json))
470
+ from (select products.id,
471
+ type,
472
+ clickout.destination_url as clickout__destination_url,
473
+ download.download_url as download__download_url,
474
+ (select to_json(coalesce(json_agg(x.*), '[]'::json))
475
+ from (select users.id,
476
+ (select to_json(coalesce(json_agg(x.*), '[]'::json))
477
+ from (select orders.id
478
+ from orders
479
+ where (orders.user_id = users.id)) x) as "orders"
480
+ from users
481
+ where (users.product_id = download.id)) x) as "download__users"
482
+ from products
483
+ left join product_downloads as download on (download.id = products.id
484
+ and products.type = 'download')
485
+ left join product_clickouts as clickout on (clickout.id = products.id
486
+ and products.type = 'clickout')) x) as value
487
+ SQL
488
+ ), token(res[:sql])
489
+ assert_equal [], res[:params]
396
490
  end
397
491
 
398
492
  def test_inherit_with_pk
@@ -426,6 +520,105 @@ module PgGraphQl
426
520
  # one
427
521
  #####################
428
522
 
523
+ def test_link_belongs_to
524
+ res = to_sql({user: {id: 1, email: "email", address: {id: "99"}}}) do |s|
525
+ s.root :user
526
+ s.type :user, fields: [:email] do |t|
527
+ t.one :address, fk: :belongs_to
528
+ end
529
+ s.type :address
530
+ end
531
+
532
+ assert_equal token(<<-SQL
533
+ select 'user'::text as key,
534
+ (select to_json(x.*)
535
+ from (select users.id,
536
+ email,
537
+ (select to_json(x.*)
538
+ from (select addresses.id
539
+ from addresses
540
+ where addresses.id = ? and (addresses.id = users.address_id) limit 1) x) as "address"
541
+ from users
542
+ where users.id = ? limit 1) x) as value
543
+ SQL
544
+ ), token(res[:sql])
545
+ assert_equal ["99", 1], res[:params]
546
+ end
547
+
548
+ def test_link_belongs_to___name_different_from_type
549
+ res = to_sql({user: {id: 1, email: "email", other_address: {id: "99"}}}) do |s|
550
+ s.root :user
551
+ s.type :user, fields: [:email] do |t|
552
+ t.one :other_address, type: :address, fk: :belongs_to
553
+ end
554
+ s.type :address
555
+ end
556
+
557
+ assert_equal token(<<-SQL
558
+ select 'user'::text as key,
559
+ (select to_json(x.*)
560
+ from (select users.id,
561
+ email,
562
+ (select to_json(x.*)
563
+ from (select addresses.id
564
+ from addresses
565
+ where addresses.id = ? and (addresses.id = users.other_address_id) limit 1) x) as "other_address"
566
+ from users
567
+ where users.id = ? limit 1) x) as value
568
+ SQL
569
+ ), token(res[:sql])
570
+ assert_equal ["99", 1], res[:params]
571
+ end
572
+
573
+ def test_link_has_one___name_different_from_type
574
+ res = to_sql({user: {id: 1, email: "email", other_address: {id: "99"}}}) do |s|
575
+ s.root :user
576
+ s.type :user, fields: [:email] do |t|
577
+ t.one :other_address, type: :address, fk: :has_one
578
+ end
579
+ s.type :address
580
+ end
581
+
582
+ assert_equal token(<<-SQL
583
+ select 'user'::text as key,
584
+ (select to_json(x.*)
585
+ from (select users.id,
586
+ email,
587
+ (select to_json(x.*)
588
+ from (select addresses.id
589
+ from addresses
590
+ where addresses.id = ? and (addresses.user_id = users.id) limit 1) x) as "other_address"
591
+ from users
592
+ where users.id = ? limit 1) x) as value
593
+ SQL
594
+ ), token(res[:sql])
595
+ assert_equal ["99", 1], res[:params]
596
+ end
597
+
598
+ def test_link_has_one
599
+ res = to_sql({user: {id: 1, email: "email", address: {id: "99"}}}) do |s|
600
+ s.root :user
601
+ s.type :user, fields: [:email] do |t|
602
+ t.one :address, fk: :has_one
603
+ end
604
+ s.type :address
605
+ end
606
+
607
+ assert_equal token(<<-SQL
608
+ select 'user'::text as key,
609
+ (select to_json(x.*)
610
+ from (select users.id,
611
+ email,
612
+ (select to_json(x.*)
613
+ from (select addresses.id
614
+ from addresses
615
+ where addresses.id = ? and (addresses.user_id = users.id) limit 1) x) as "address"
616
+ from users
617
+ where users.id = ? limit 1) x) as value
618
+ SQL
619
+ ), token(res[:sql])
620
+ assert_equal ["99", 1], res[:params]
621
+ end
429
622
 
430
623
  def test_link_one
431
624
  res = to_sql({user: {id: 1, email: "email", address: {id: "99"}}}) do |s|
@@ -677,6 +870,56 @@ module PgGraphQl
677
870
  SQL
678
871
  ), token(res[:sql])
679
872
  assert_equal ["99", 1], res[:params]
873
+
874
+ # ----
875
+
876
+ res = to_sql({user: {id: 1, email: "email", address: {id: "99"}}}) do |s|
877
+ s.root :user
878
+ s.type :user, fields: [:email] do |t|
879
+ t.many :address, fk: :many
880
+ end
881
+ s.type :address
882
+ end
883
+
884
+ assert_equal token(<<-SQL
885
+ select 'user'::text as key,
886
+ (select to_json(x.*)
887
+ from (select users.id,
888
+ email,
889
+ (select to_json(coalesce(json_agg(x.*), '[]'::json))
890
+ from (select addresses.id
891
+ from addresses
892
+ where addresses.id = ? and (addresses.user_id = users.id)) x) as "address"
893
+ from users
894
+ where users.id = ? limit 1) x) as value
895
+ SQL
896
+ ), token(res[:sql])
897
+ assert_equal ["99", 1], res[:params]
898
+
899
+ # ----
900
+
901
+ res = to_sql({user: {id: 1, email: "email", other_addresses: {id: "99"}}}) do |s|
902
+ s.root :user
903
+ s.type :user, fields: [:email] do |t|
904
+ t.many :other_addresses, type: :address, fk: :many
905
+ end
906
+ s.type :address
907
+ end
908
+
909
+ assert_equal token(<<-SQL
910
+ select 'user'::text as key,
911
+ (select to_json(x.*)
912
+ from (select users.id,
913
+ email,
914
+ (select to_json(coalesce(json_agg(x.*), '[]'::json))
915
+ from (select addresses.id
916
+ from addresses
917
+ where addresses.id = ? and (addresses.user_id = users.id)) x) as "other_addresses"
918
+ from users
919
+ where users.id = ? limit 1) x) as value
920
+ SQL
921
+ ), token(res[:sql])
922
+ assert_equal ["99", 1], res[:params]
680
923
  end
681
924
 
682
925
  def test_link_many_nested_pk
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pggraphql
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.13
4
+ version: 0.0.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jan Zimmek
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-18 00:00:00.000000000 Z
11
+ date: 2015-04-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json