bson 4.3.0 → 4.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/Rakefile +16 -9
  5. data/ext/bson/bson_native.c +102 -28
  6. data/lib/bson.rb +1 -1
  7. data/lib/bson/active_support.rb +17 -0
  8. data/lib/bson/array.rb +1 -1
  9. data/lib/bson/binary.rb +1 -1
  10. data/lib/bson/boolean.rb +1 -1
  11. data/lib/bson/code.rb +1 -1
  12. data/lib/bson/code_with_scope.rb +1 -1
  13. data/lib/bson/config.rb +1 -1
  14. data/lib/bson/date.rb +1 -1
  15. data/lib/bson/date_time.rb +1 -1
  16. data/lib/bson/decimal128.rb +1 -1
  17. data/lib/bson/decimal128/builder.rb +1 -1
  18. data/lib/bson/document.rb +42 -4
  19. data/lib/bson/environment.rb +1 -1
  20. data/lib/bson/false_class.rb +1 -1
  21. data/lib/bson/float.rb +1 -1
  22. data/lib/bson/hash.rb +1 -1
  23. data/lib/bson/int32.rb +17 -4
  24. data/lib/bson/int64.rb +17 -4
  25. data/lib/bson/integer.rb +2 -2
  26. data/lib/bson/json.rb +1 -1
  27. data/lib/bson/max_key.rb +1 -1
  28. data/lib/bson/min_key.rb +1 -1
  29. data/lib/bson/nil_class.rb +1 -1
  30. data/lib/bson/object.rb +1 -1
  31. data/lib/bson/object_id.rb +1 -1
  32. data/lib/bson/open_struct.rb +1 -1
  33. data/lib/bson/regexp.rb +1 -1
  34. data/lib/bson/registry.rb +1 -1
  35. data/lib/bson/specialized.rb +1 -1
  36. data/lib/bson/string.rb +1 -1
  37. data/lib/bson/symbol.rb +6 -3
  38. data/lib/bson/time.rb +1 -1
  39. data/lib/bson/time_with_zone.rb +54 -0
  40. data/lib/bson/timestamp.rb +1 -1
  41. data/lib/bson/true_class.rb +1 -1
  42. data/lib/bson/undefined.rb +1 -1
  43. data/lib/bson/version.rb +2 -2
  44. data/spec/bson/array_spec.rb +1 -1
  45. data/spec/bson/binary_spec.rb +1 -1
  46. data/spec/bson/boolean_spec.rb +1 -1
  47. data/spec/bson/byte_buffer_spec.rb +40 -0
  48. data/spec/bson/code_spec.rb +1 -1
  49. data/spec/bson/code_with_scope_spec.rb +1 -1
  50. data/spec/bson/date_spec.rb +1 -1
  51. data/spec/bson/date_time_spec.rb +1 -1
  52. data/spec/bson/decimal128_spec.rb +1 -1
  53. data/spec/bson/document_spec.rb +60 -1
  54. data/spec/bson/false_class_spec.rb +1 -1
  55. data/spec/bson/float_spec.rb +1 -1
  56. data/spec/bson/hash_spec.rb +1 -1
  57. data/spec/bson/int32_spec.rb +139 -3
  58. data/spec/bson/int64_spec.rb +139 -3
  59. data/spec/bson/integer_spec.rb +3 -3
  60. data/spec/bson/json_spec.rb +1 -1
  61. data/spec/bson/max_key_spec.rb +1 -1
  62. data/spec/bson/min_key_spec.rb +1 -1
  63. data/spec/bson/nil_class_spec.rb +1 -1
  64. data/spec/bson/object_id_spec.rb +1 -1
  65. data/spec/bson/object_spec.rb +1 -1
  66. data/spec/bson/open_struct_spec.rb +1 -1
  67. data/spec/bson/regexp_spec.rb +1 -1
  68. data/spec/bson/registry_spec.rb +1 -1
  69. data/spec/bson/string_spec.rb +1 -1
  70. data/spec/bson/symbol_spec.rb +3 -3
  71. data/spec/bson/time_spec.rb +1 -1
  72. data/spec/bson/time_with_zone_spec.rb +68 -0
  73. data/spec/bson/timestamp_spec.rb +1 -1
  74. data/spec/bson/true_class_spec.rb +1 -1
  75. data/spec/bson/undefined_spec.rb +1 -1
  76. data/spec/bson_spec.rb +1 -1
  77. data/spec/spec_helper.rb +15 -1
  78. data/spec/support/shared_examples.rb +1 -1
  79. data/spec/support/spec_config.rb +9 -0
  80. metadata +73 -68
  81. metadata.gz.sig +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: b2cdf98517b40720fa4e2cdfaae83903ac8d1907
4
- data.tar.gz: 821e69506dcde2eca70b737a97a8d0f3f4cce3f3
2
+ SHA256:
3
+ metadata.gz: 84427d100a7c6e64e513b120537d2347cae31bcb08f2d9270d46946f0cecab6f
4
+ data.tar.gz: 9bfb6408d1c44c3ff4cc25de3beaeb37cbd5ff18d271c44af989b37f050760f6
5
5
  SHA512:
6
- metadata.gz: 285a6ba405445c535fc2157c81bee4ce48825716d2048acd3060221371b1cecd6081c5e1c487f67e373292ed97841d6e45b78abdb98cf3f81bf854d10c5f4473
7
- data.tar.gz: 194eed21affeaf868a337ba758034f11496c077f02945a403c923a29de0c1f1e11f8da2a9318ecc5aefd3964b56b4aafd3ea167ee24edde962e580ac08f4f3ce
6
+ metadata.gz: fb891b58d7763ad8a26858941a8067fa601db56cdef379f5a56fb59de1c25851d98cbf4653fb592bba985717d1e06f85681138979e9a061ab91cb1ea186dd4c2
7
+ data.tar.gz: b33f84f1c0b06b0c5c1095bf6fa047d066ba3be9ca2f1cb7860bfab3c8a36066b84be74a61cc539500f0eeb30bba441ec4ba213e24fb004379f47b918d133a14
Binary file
data.tar.gz.sig CHANGED
Binary file
data/Rakefile CHANGED
@@ -20,6 +20,7 @@ $LOAD_PATH.unshift(File.expand_path("../lib", __FILE__))
20
20
  require "rake"
21
21
  require "rake/extensiontask"
22
22
  require "rspec/core/rake_task"
23
+ require 'fileutils'
23
24
 
24
25
  def jruby?
25
26
  defined?(JRUBY_VERSION)
@@ -62,15 +63,9 @@ else
62
63
  end
63
64
 
64
65
  task :clean_all => :clean do
65
- begin
66
- Dir.chdir(Pathname(__FILE__).dirname + "lib") do
67
- `rm bson_native.#{extension}`
68
- `rm bson_native.o`
69
- `rm bson-ruby.jar`
70
- end
71
- rescue Exception => e
72
- puts e.message
73
- end
66
+ FileUtils.rm_f(File.join(File.dirname(__FILE__), 'lib', "bson_native.#{extension}"))
67
+ FileUtils.rm_f(File.join(File.dirname(__FILE__), 'lib', "bson_native.o"))
68
+ FileUtils.rm_f(File.join(File.dirname(__FILE__), 'lib', "bson-ruby.jar"))
74
69
  end
75
70
 
76
71
  task :spec => :compile do
@@ -126,3 +121,15 @@ namespace :benchmark do
126
121
  end
127
122
 
128
123
  task :default => [ :clean_all, :spec ]
124
+
125
+ desc "Generate all documentation"
126
+ task :docs => 'docs:yard'
127
+
128
+ namespace :docs do
129
+ desc "Generate yard documention"
130
+ task :yard do
131
+ out = File.join('yard-docs', BSON::VERSION)
132
+ FileUtils.rm_rf(out)
133
+ system "yardoc -o #{out} --title bson-#{BSON::VERSION}"
134
+ end
135
+ end
@@ -73,12 +73,15 @@ static VALUE rb_bson_byte_buffer_get_hash(VALUE self);
73
73
  static VALUE rb_bson_byte_buffer_get_array(VALUE self);
74
74
  static VALUE rb_bson_byte_buffer_put_byte(VALUE self, VALUE byte);
75
75
  static VALUE rb_bson_byte_buffer_put_bytes(VALUE self, VALUE bytes);
76
+ static VALUE rb_bson_byte_buffer_put_bson_partial_string(VALUE self, const char *str, int32_t length);
76
77
  static VALUE rb_bson_byte_buffer_put_cstring(VALUE self, VALUE string);
77
78
  static VALUE rb_bson_byte_buffer_put_decimal128(VALUE self, VALUE low, VALUE high);
78
79
  static VALUE rb_bson_byte_buffer_put_double(VALUE self, VALUE f);
79
80
  static VALUE rb_bson_byte_buffer_put_int32(VALUE self, VALUE i);
80
81
  static VALUE rb_bson_byte_buffer_put_int64(VALUE self, VALUE i);
82
+ static VALUE rb_bson_byte_buffer_put_bson_string(VALUE self, const char *str, int32_t length);
81
83
  static VALUE rb_bson_byte_buffer_put_string(VALUE self, VALUE string);
84
+ static VALUE rb_bson_byte_buffer_put_symbol(VALUE self, VALUE symbol);
82
85
  static VALUE rb_bson_byte_buffer_put_hash(VALUE self, VALUE hash, VALUE validating_keys);
83
86
  static VALUE rb_bson_byte_buffer_put_array(VALUE self, VALUE array, VALUE validating_keys);
84
87
  static VALUE rb_bson_byte_buffer_read_position(VALUE self);
@@ -118,7 +121,7 @@ static void pvt_put_byte(byte_buffer_t *b, const char byte);
118
121
  static void pvt_put_int32(byte_buffer_t *b, const int32_t i32);
119
122
  static void pvt_put_int64(byte_buffer_t *b, const int64_t i);
120
123
  static void pvt_put_double(byte_buffer_t *b, double f);
121
- static void pvt_put_cstring(byte_buffer_t *b, VALUE string);
124
+ static void pvt_put_cstring(byte_buffer_t *b, const char *str, int32_t length);
122
125
  static void pvt_put_bson_key(byte_buffer_t *b, VALUE string, VALUE validating_keys);
123
126
 
124
127
  /**
@@ -173,6 +176,7 @@ void Init_bson_native()
173
176
  rb_define_method(rb_byte_buffer_class, "put_int32", rb_bson_byte_buffer_put_int32, 1);
174
177
  rb_define_method(rb_byte_buffer_class, "put_int64", rb_bson_byte_buffer_put_int64, 1);
175
178
  rb_define_method(rb_byte_buffer_class, "put_string", rb_bson_byte_buffer_put_string, 1);
179
+ rb_define_method(rb_byte_buffer_class, "put_symbol", rb_bson_byte_buffer_put_symbol, 1);
176
180
  rb_define_method(rb_byte_buffer_class, "read_position", rb_bson_byte_buffer_read_position, 0);
177
181
  rb_define_method(rb_byte_buffer_class, "replace_int32", rb_bson_byte_buffer_replace_int32, 2);
178
182
  rb_define_method(rb_byte_buffer_class, "rewind!", rb_bson_byte_buffer_rewind, 0);
@@ -461,6 +465,7 @@ void pvt_put_array_index(byte_buffer_t *b, int32_t index)
461
465
  {
462
466
  char buffer[16];
463
467
  const char *c_str = NULL;
468
+ size_t length;
464
469
 
465
470
  if (index < 1000) {
466
471
  c_str = index_strings[index];
@@ -468,7 +473,7 @@ void pvt_put_array_index(byte_buffer_t *b, int32_t index)
468
473
  c_str = buffer;
469
474
  snprintf(buffer, sizeof(buffer), "%d", index);
470
475
  }
471
- size_t length = strlen(c_str) + 1;
476
+ length = strlen(c_str) + 1;
472
477
  ENSURE_BSON_WRITE(b, length);
473
478
  memcpy(WRITE_PTR(b), c_str, length);
474
479
  b->write_position += length;
@@ -533,8 +538,9 @@ VALUE rb_bson_byte_buffer_get_byte(VALUE self)
533
538
  }
534
539
 
535
540
  uint8_t pvt_get_type_byte(byte_buffer_t *b){
541
+ int8_t byte;
536
542
  ENSURE_BSON_READ(b, 1);
537
- int8_t byte = *READ_PTR(b);
543
+ byte = *READ_PTR(b);
538
544
  b->read_position += 1;
539
545
  return (uint8_t)byte;
540
546
  }
@@ -759,7 +765,12 @@ VALUE pvt_read_field(byte_buffer_t *b, VALUE rb_buffer, uint8_t type){
759
765
  VALUE rb_bson_byte_buffer_put_byte(VALUE self, VALUE byte)
760
766
  {
761
767
  byte_buffer_t *b;
762
- const char *str = RSTRING_PTR(byte);
768
+ const char *str;
769
+
770
+ if (!RB_TYPE_P(byte, T_STRING))
771
+ rb_raise(rb_eArgError, "Invalid input");
772
+
773
+ str = RSTRING_PTR(byte);
763
774
 
764
775
  TypedData_Get_Struct(self, byte_buffer_t, &rb_byte_buffer_data_type, b);
765
776
  ENSURE_BSON_WRITE(b, 1);
@@ -782,8 +793,14 @@ void pvt_put_byte( byte_buffer_t *b, const char byte)
782
793
  VALUE rb_bson_byte_buffer_put_bytes(VALUE self, VALUE bytes)
783
794
  {
784
795
  byte_buffer_t *b;
785
- const char *str = RSTRING_PTR(bytes);
786
- const size_t length = RSTRING_LEN(bytes);
796
+ const char *str;
797
+ size_t length;
798
+
799
+ if (!RB_TYPE_P(bytes, T_STRING) && !RB_TYPE_P(bytes, RUBY_T_DATA))
800
+ rb_raise(rb_eArgError, "Invalid input");
801
+
802
+ str = RSTRING_PTR(bytes);
803
+ length = RSTRING_LEN(bytes);
787
804
 
788
805
  TypedData_Get_Struct(self, byte_buffer_t, &rb_byte_buffer_data_type, b);
789
806
  ENSURE_BSON_WRITE(b, length);
@@ -793,42 +810,74 @@ VALUE rb_bson_byte_buffer_put_bytes(VALUE self, VALUE bytes)
793
810
  }
794
811
 
795
812
  /**
796
- * Writes a cstring to the byte buffer.
813
+ * Writes a string (which may form part of a BSON object) to the byte buffer.
814
+ * length does not include the null terminator.
797
815
  */
798
- VALUE rb_bson_byte_buffer_put_cstring(VALUE self, VALUE string)
816
+ VALUE rb_bson_byte_buffer_put_bson_partial_string(VALUE self, const char *str, int32_t length)
799
817
  {
800
818
  byte_buffer_t *b;
801
819
  TypedData_Get_Struct(self, byte_buffer_t, &rb_byte_buffer_data_type, b);
802
- pvt_put_cstring(b, string);
820
+ pvt_put_cstring(b, str, length);
803
821
  return self;
804
822
  }
805
823
 
806
- void pvt_put_cstring(byte_buffer_t *b, VALUE string)
824
+ /**
825
+ * length does not include the null terminator.
826
+ */
827
+ void pvt_put_cstring(byte_buffer_t *b, const char *str, int32_t length)
807
828
  {
808
- char *c_str = RSTRING_PTR(string);
809
- size_t length = RSTRING_LEN(string) + 1;
810
-
811
- if (!rb_bson_utf8_validate(c_str, length - 1, false)) {
812
- rb_raise(rb_eArgError, "String %s is not a valid UTF-8 CString.", c_str);
829
+ int bytes_to_write;
830
+ if (!rb_bson_utf8_validate(str, length, false)) {
831
+ rb_raise(rb_eArgError, "String %s is not a valid UTF-8 CString.", str);
813
832
  }
814
- ENSURE_BSON_WRITE(b, length);
815
- memcpy(WRITE_PTR(b), c_str, length);
816
- b->write_position += length;
833
+ bytes_to_write = length + 1;
834
+ ENSURE_BSON_WRITE(b, bytes_to_write);
835
+ memcpy(WRITE_PTR(b), str, bytes_to_write);
836
+ b->write_position += bytes_to_write;
817
837
  }
818
838
 
819
839
  /**
820
840
  * Write a hash key to the byte buffer, validating it if requested
821
841
  */
822
842
  void pvt_put_bson_key(byte_buffer_t *b, VALUE string, VALUE validating_keys){
823
- if(RTEST(validating_keys)){
824
- char *c_str = RSTRING_PTR(string);
825
- size_t length = RSTRING_LEN(string);
826
- if(length > 0 && (c_str[0] == '$' || memchr(c_str, '.', length))){
827
- rb_exc_raise(rb_funcall(rb_bson_illegal_key, rb_intern("new"),1, string));
843
+ char *c_str = RSTRING_PTR(string);
844
+ size_t length = RSTRING_LEN(string);
845
+
846
+ if (RTEST(validating_keys)) {
847
+ if (length > 0 && (c_str[0] == '$' || memchr(c_str, '.', length))) {
848
+ rb_exc_raise(rb_funcall(rb_bson_illegal_key, rb_intern("new"), 1, string));
828
849
  }
829
850
  }
830
851
 
831
- pvt_put_cstring(b, string);
852
+ pvt_put_cstring(b, c_str, length);
853
+ }
854
+
855
+ /**
856
+ * Writes a cstring to the byte buffer.
857
+ * This magically supports both Ruby symbols and strings.
858
+ */
859
+ VALUE rb_bson_byte_buffer_put_cstring(VALUE self, VALUE string)
860
+ {
861
+ int32_t length;
862
+
863
+ if (TYPE(string) == T_SYMBOL) {
864
+ const char *sym = rb_id2name(SYM2ID(string));
865
+ length = strlen(sym);
866
+
867
+ return rb_bson_byte_buffer_put_bson_partial_string(self, sym, length);
868
+ } else if (TYPE(string) == T_STRING) {
869
+ const char *str = RSTRING_PTR(string);
870
+ length = RSTRING_LEN(string);
871
+
872
+ return rb_bson_byte_buffer_put_bson_partial_string(self, str, length);
873
+ } else if (TYPE(string) == T_FIXNUM) {
874
+ const char *str = RSTRING_PTR(rb_fix2str(string, 10));
875
+ length = strlen(str);
876
+
877
+ return rb_bson_byte_buffer_put_bson_partial_string(self, str, length);
878
+ } else {
879
+ rb_raise(rb_eTypeError, "Invalid type for string");
880
+ }
832
881
  }
833
882
 
834
883
  /**
@@ -945,15 +994,18 @@ void pvt_validate_length(byte_buffer_t *b)
945
994
  }
946
995
 
947
996
  /**
948
- * Writes a string to the byte buffer.
997
+ * Write BSON string to byte buffer given a C string.
998
+ * length is inclusive of the NULL terminator in the C string.
949
999
  */
950
- VALUE rb_bson_byte_buffer_put_string(VALUE self, VALUE string)
1000
+ static VALUE rb_bson_byte_buffer_put_bson_string(VALUE self, const char *str, int32_t length)
951
1001
  {
952
1002
  byte_buffer_t *b;
953
1003
  int32_t length_le;
954
1004
 
955
- char *str = RSTRING_PTR(string);
956
- const int32_t length = RSTRING_LEN(string) + 1;
1005
+ if (length <= 0) {
1006
+ rb_raise(rb_eArgError, "The length must include the NULL terminator, and thus be at least 1");
1007
+ }
1008
+
957
1009
  length_le = BSON_UINT32_TO_LE(length);
958
1010
 
959
1011
  if (!rb_bson_utf8_validate(str, length - 1, true)) {
@@ -970,6 +1022,28 @@ VALUE rb_bson_byte_buffer_put_string(VALUE self, VALUE string)
970
1022
  return self;
971
1023
  }
972
1024
 
1025
+ /**
1026
+ * Writes a string to the byte buffer.
1027
+ */
1028
+ VALUE rb_bson_byte_buffer_put_string(VALUE self, VALUE string)
1029
+ {
1030
+ const char *str = RSTRING_PTR(string);
1031
+ const int32_t length = RSTRING_LEN(string) + 1;
1032
+
1033
+ return rb_bson_byte_buffer_put_bson_string(self, str, length);
1034
+ }
1035
+
1036
+ /**
1037
+ * Writes a symbol to the byte buffer.
1038
+ */
1039
+ VALUE rb_bson_byte_buffer_put_symbol(VALUE self, VALUE symbol)
1040
+ {
1041
+ const char *sym = rb_id2name(SYM2ID(symbol));
1042
+ const int32_t length = strlen(sym) + 1;
1043
+
1044
+ return rb_bson_byte_buffer_put_bson_string(self, sym, length);
1045
+ }
1046
+
973
1047
  /**
974
1048
  * Get the read position.
975
1049
  */
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2009-2014 MongoDB Inc.
1
+ # Copyright (C) 2009-2019 MongoDB Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -0,0 +1,17 @@
1
+ # Copyright (C) 2018-2019 MongoDB Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ # Require this file if using BSON with ActiveSupport.
16
+
17
+ require "bson/time_with_zone"
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2009-2014 MongoDB Inc.
1
+ # Copyright (C) 2009-2019 MongoDB Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2009-2014 MongoDB Inc.
1
+ # Copyright (C) 2009-2019 MongoDB Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2009-2014 MongoDB Inc.
1
+ # Copyright (C) 2009-2019 MongoDB Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2009-2014 MongoDB Inc.
1
+ # Copyright (C) 2009-2019 MongoDB Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2009-2014 MongoDB Inc.
1
+ # Copyright (C) 2009-2019 MongoDB Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2016 MongoDB Inc.
1
+ # Copyright (C) 2016-2019 MongoDB Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2009-2014 MongoDB Inc.
1
+ # Copyright (C) 2009-2019 MongoDB Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2009-2014 MongoDB Inc.
1
+ # Copyright (C) 2009-2019 MongoDB Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2016 MongoDB Inc.
1
+ # Copyright (C) 2016-2019 MongoDB Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2016 MongoDB Inc.
1
+ # Copyright (C) 2016-2019 MongoDB Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2009-2014 MongoDB Inc.
1
+ # Copyright (C) 2009-2019 MongoDB Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -35,8 +35,25 @@ module BSON
35
35
  class Document < ::Hash
36
36
 
37
37
  # Get a value from the document for the provided key. Can use string or
38
- # symbol access, but the fastest will be to always provide a key that is of
39
- # the same type as the stored keys.
38
+ # symbol access, with string access being the faster of the two.
39
+ #
40
+ # @example Get an element for the key.
41
+ # document.fetch("field")
42
+ #
43
+ # @example Get an element for the key by symbol.
44
+ # document.fetch(:field)
45
+ #
46
+ # @param [ String, Symbol ] key The key to look up.
47
+ #
48
+ # @return [ Object ] The found value. Raises KeyError if none found.
49
+ #
50
+ # @since 4.4.0
51
+ def fetch(key)
52
+ super(convert_key(key))
53
+ end
54
+
55
+ # Get a value from the document for the provided key. Can use string or
56
+ # symbol access, with string access being the faster of the two.
40
57
  #
41
58
  # @example Get an element for the key.
42
59
  # document["field"]
@@ -44,7 +61,7 @@ module BSON
44
61
  # @example Get an element for the key by symbol.
45
62
  # document[:field]
46
63
  #
47
- # @param [ String, Symbol ] key The key to lookup.
64
+ # @param [ String, Symbol ] key The key to look up.
48
65
  #
49
66
  # @return [ Object ] The found value, or nil if none found.
50
67
  #
@@ -192,6 +209,27 @@ module BSON
192
209
  end
193
210
  end
194
211
 
212
+ if instance_methods.include?(:slice)
213
+ # Slices a document to include only the given keys.
214
+ # Will normalize symbol keys into strings.
215
+ # (this method is backported from ActiveSupport::Hash)
216
+ #
217
+ # @example Get a document/hash with only the `name` and `age` fields present
218
+ # document # => { _id: <ObjectId>, :name => 'John', :age => 30, :location => 'Earth' }
219
+ # document.slice(:name, 'age') # => { name: 'John', age: 30 }
220
+ # document.slice('name') # => { name: 'John' }
221
+ # document.slice(:foo) # => nil
222
+ #
223
+ # @param [ Array<String, Symbol> ] *keys Keys, that will be kept in the resulting document
224
+ #
225
+ # @return [ BSON::Document ] The document with only the selected keys
226
+ #
227
+ # @since 4.3.1
228
+ def slice(*keys)
229
+ super(*keys.map{|key| convert_key(key)})
230
+ end
231
+ end
232
+
195
233
  private
196
234
 
197
235
  def convert_key(key)