pg_conn 0.38.2 → 0.40.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 27da5832145c359fa1472604184f836add4fabceb458dee4b609c05b6eec5196
4
- data.tar.gz: 109029c0961d83cb35710d2f716a31412eb1fcf68d55b05b1d1d6dc26af6b8d3
3
+ metadata.gz: f946804765203fcdb2c40e704831e488e2a47c1975ce371217faa528c533141c
4
+ data.tar.gz: fa08dce1b7e10162aaa5e2cd20e0ada630f95a794462528a73969c6bd5ad484c
5
5
  SHA512:
6
- metadata.gz: f787e6859f348afd97657c15f6fce1c75ab8e1dc0eeb04ef703879b6b50c493246eb71ec1690b8eb3f2c3f98fefd0b204d7ddde5e6e5d9fe76de5f46c21ff964
7
- data.tar.gz: 15968312f5b7f5b0835ebd694484deb6ac84c4dd51c57b99d710b72b08d51d154c040f61acef2751037a7f1d0967f3d7ccdcf271d29ce5cbd4432055e61dc003
6
+ metadata.gz: 41262613001be5709f861d125af4287a82968ce60878dca3c885a34033d0ef78786b76a774738123fbd97ffdaaad5821cf480899cc56772f3691757c831de8a7
7
+ data.tar.gz: de131f33563c6ec6e52c03d4537dd3ab730506534e84a0aae1aefaefc763a05fd45376713a4ee2d91177967c2def949c566bf137376f6c61496f0e7f691ad97f
data/TODO CHANGED
@@ -96,7 +96,6 @@ TODO
96
96
  o Proper implementation of call of functions and procedures: Functions should
97
97
  be called through #value, #tuple etc. and procedures through #call.
98
98
  Proceduer output parameters needs handling too
99
- o Implement search_path
100
99
  o Create an abstract PgConnBase and have PgStmts (writes statements to array)
101
100
  and PgConn (sends statements to server) classes derived from it
102
101
  o fix silent
@@ -119,6 +118,7 @@ TODO
119
118
  + Quote methods (value, identier, ... -> Postgres string)
120
119
  + Have a 'with' method that combines multiple brachet-methods:
121
120
  conn.with(schema: public, transation: true) { ... }
121
+ + Implement search_path
122
122
 
123
123
 
124
124
  REFACTOR
@@ -152,7 +152,7 @@ module PgConn
152
152
  end
153
153
  end
154
154
 
155
- # Set current serial value for the table
155
+ # Set current serial value for the table. The sequence is marked unused if value is nil
156
156
  def set_serial(schema, table, value)
157
157
  uid = "#{schema}.#{table}"
158
158
  seq = sequence(schema, table) or raise ArgumentError, "Table #{uid} does not have a sequence"
@@ -1,3 +1,3 @@
1
1
  module PgConn
2
- VERSION = "0.38.2"
2
+ VERSION = "0.40.0"
3
3
  end
data/lib/pg_conn.rb CHANGED
@@ -465,6 +465,18 @@ module PgConn
465
465
  quote_record_impl(data, schema_name, type, array: true, **opts)
466
466
  end
467
467
 
468
+ # Return current search path. Note that a search path is part of
469
+ # the transaction
470
+ def search_path
471
+ self.value("show search_path").split(/,\s*/) - %w("$user" pg_temp)
472
+ end
473
+
474
+ # Set search path. It accepts a schema or an array of schema names
475
+ def search_path=(schemas)
476
+ schema_array = Array(schemas).flatten - %w("$user" pg_temp) + %w(pg_temp)
477
+ self.exec "set search_path to #{schema_array.join(', ')}"
478
+ end
479
+
468
480
  # :call-seq:
469
481
  # exist?(query)
470
482
  # exist?(table, id)
@@ -739,6 +751,14 @@ module PgConn
739
751
  h
740
752
  end
741
753
 
754
+ # TODO
755
+ # structset
756
+ # recordset
757
+ # structmap
758
+ # recormap
759
+ # multistruct
760
+ # multirecord
761
+
742
762
  # Return the value of calling the given postgres function. It dynamically
743
763
  # detects the structure of the result and return a value or an array of
744
764
  # values if the result contained only one column (like #value or #values),
@@ -780,9 +800,9 @@ module PgConn
780
800
 
781
801
  # :call-seq:
782
802
  # insert(table, record|records)
783
- # insert(table, fields, record|records|tuples)
803
+ # insert(table, fields, record|records|tuples|values)
784
804
  # insert(schema, table, record|records)
785
- # insert(schema, table, fields, record|records|tuples)
805
+ # insert(schema, table, fields, record|records|tuples|values)
786
806
  #
787
807
  # Insert record(s) in table and return id(s)
788
808
  #
@@ -821,7 +841,8 @@ module PgConn
821
841
  fields ||= data.first.keys
822
842
  tuples = data.map { |record| fields.map { |field| record[field] } }
823
843
  else
824
- raise ArgumentError
844
+ fields.size == 1 or raise ArgumentError, "Illegal number of fields, expected exactly one"
845
+ tuples = data.map { |e| [e] }
825
846
  end
826
847
  elsif data.is_a?(Hash)
827
848
  method = upsert ? :value? : :value # The pg_conn method when only one record is inserted
@@ -884,17 +905,47 @@ module PgConn
884
905
  exec %(delete from #{table} where #{constraint})
885
906
  end
886
907
 
887
- # Execute block with global options and resets afterwards. Currently only
888
- # :silent, :notice and :warning is supported. Very useful in RSpec tests
908
+ # Execute block with the given set of global or local options and reset
909
+ # them afterwards
889
910
  #
890
- # TODO: :error, :fail, :symbol, :schema, :search_path
911
+ # The global options :silent, :notice and :warning are supported, they're
912
+ # very useful in RSpec tests
913
+ #
914
+ # Local options are :search_path that runs the block with the given
915
+ # schemas, :username that runs the block as the given user, and :commit
916
+ # that runs the block in a transaction if true or false; true commits the
917
+ # transaction and false rolls it back. It is not run in a transaction if
918
+ # :commit is nil
891
919
  #
892
920
  def with(**options, &block)
921
+ search_path = options.delete(:search_path)
922
+ username = options.delete(:username)
923
+ commit = options.delete(:commit)
924
+
925
+ saved_options = @options.dup
926
+ saved_search_path = self.search_path if search_path
927
+
893
928
  begin
894
- saved_options = @options.dup
895
929
  set_options(options)
896
- yield
930
+ self.search_path = search_path if search_path
931
+
932
+ inner = lambda {
933
+ if !commit.nil?
934
+ self.transaction(commit: commit) {
935
+ block.yield
936
+ }
937
+ else
938
+ block.yield
939
+ end
940
+ }
941
+
942
+ if username
943
+ self.su(username, &inner)
944
+ else
945
+ inner.call
946
+ end
897
947
  ensure
948
+ self.search_path = saved_search_path if search_path
898
949
  set_options(saved_options)
899
950
  end
900
951
  end
@@ -966,16 +1017,23 @@ module PgConn
966
1017
  # Switch user to the given user and execute the statement before swithcing
967
1018
  # back to the original user
968
1019
  #
969
- # FIXME: The out-commented transaction block makes postspec fail for some reason
1020
+ # FIXME:
1021
+ # The out-commented transaction block makes postspec fail for some
1022
+ # reason. Note that user-switches lives within transactions
1023
+ #
970
1024
  # TODO: Rename 'sudo' because it acts just like it.
1025
+ #
971
1026
  def su(username, &block)
972
1027
  raise Error, "Missing block in call to PgConn::Connection#su" if !block_given?
973
1028
  realuser = self.value "select current_user"
974
1029
  result = nil
975
1030
  # transaction(commit: false) {
1031
+ begin
976
1032
  execute "set session authorization #{username}"
977
1033
  result = yield
1034
+ ensure
978
1035
  execute "set session authorization #{realuser}"
1036
+ end
979
1037
  # }
980
1038
  result
981
1039
  end
@@ -1078,7 +1136,7 @@ module PgConn
1078
1136
  # that the transaction timestamp is set to the start of the first
1079
1137
  # transaction even if transactions are nested
1080
1138
  #
1081
- # FIXME: There is some strange problem in rspec where an #insert handles
1139
+ # FIXME: There is some strange problem in rspec where #insert handles
1082
1140
  # an exception correctly while #exec, #execute, and #transaction does not
1083
1141
  def transaction(commit: true, &block)
1084
1142
  if block_given?
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pg_conn
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.38.2
4
+ version: 0.40.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Claus Rasmussen