pggraphql 0.0.13 → 0.0.15

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 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