rb: raise if an object is serialized without required fields [THRIFT-143]
authorKevin Clark <kclark@apache.org>
Tue, 11 Nov 2008 05:46:04 +0000 (05:46 +0000)
committerKevin Clark <kclark@apache.org>
Tue, 11 Nov 2008 05:46:04 +0000 (05:46 +0000)
git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@712945 13f79535-47bb-0310-9956-ffa450edef68

compiler/cpp/src/generate/t_rb_generator.cc
lib/rb/benchmark/gen-rb/BenchmarkService.rb
lib/rb/lib/thrift/struct.rb
lib/rb/spec/gen-rb/NonblockingService.rb
lib/rb/spec/gen-rb/ThriftSpec_types.rb

index c6122ce..f878ad7 100644 (file)
@@ -62,8 +62,7 @@ class t_rb_generator : public t_oop_generator {
    */
 
   void generate_rb_struct(std::ofstream& out, t_struct* tstruct, bool is_exception);
-  void generate_rb_struct_reader(std::ofstream& out, t_struct* tstruct);
-  void generate_rb_struct_writer(std::ofstream& out, t_struct* tstruct);
+  void generate_rb_struct_required_validator(std::ofstream& out, t_struct* tstruct);
   void generate_rb_function_helpers(t_function* tfunction);
   void generate_rb_simple_constructor(std::ofstream& out, t_struct* tstruct);
   void generate_rb_simple_exception_constructor(std::ofstream& out, t_struct* tstruct);
@@ -463,7 +462,8 @@ void t_rb_generator::generate_rb_struct(std::ofstream& out, t_struct* tstruct, b
   generate_field_constants(out, tstruct);
   generate_accessors(out, tstruct);
   generate_field_defns(out, tstruct);
-
+  generate_rb_struct_required_validator(out, tstruct);
+  
   indent_down();
   indent(out) << "end" << endl << endl;
 }
@@ -1027,4 +1027,30 @@ void t_rb_generator::generate_rdoc(std::ofstream& out, t_doc* tdoc) {
   }
 }
 
+void t_rb_generator::generate_rb_struct_required_validator(std::ofstream& out, 
+                                                           t_struct* tstruct) {
+  indent(out) << "def validate" << endl;
+  indent_up();
+  
+  const vector<t_field*>& fields = tstruct->get_members();
+  vector<t_field*>::const_iterator f_iter;
+
+  for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
+    t_field* field = (*f_iter);
+    if (field->get_req() == t_field::T_REQUIRED) {
+      indent(out) << "raise Thrift::ProtocolException.new(Thrift::ProtocolException::UNKNOWN, 'Required field " << field->get_name() << " is unset!')";
+      if (field->get_type()->is_bool()) {
+        out << " if @" << field->get_name() << ".nil?";
+      } else {
+        out << " unless @" << field->get_name();
+      }
+      out << endl;
+    }
+  }  
+  
+  indent_down();
+  indent(out) << "end" << endl << endl;
+  
+}
+
 THRIFT_REGISTER_GENERATOR(rb, "Ruby", "");
index 7d39882..2c3ae4f 100644 (file)
@@ -52,6 +52,9 @@ require File.dirname(__FILE__) + '/Benchmark_types'
           FIELDS = {
             N => {:type => Thrift::Types::BYTE, :name => 'n'}
           }
+          def validate
+          end
+
         end
 
         class Fibonacci_result
@@ -62,6 +65,9 @@ require File.dirname(__FILE__) + '/Benchmark_types'
           FIELDS = {
             SUCCESS => {:type => Thrift::Types::I32, :name => 'success'}
           }
+          def validate
+          end
+
         end
 
       end
index c530b33..a51f209 100644 (file)
@@ -82,6 +82,7 @@ module Thrift
     end
 
     def read(iprot)
+      validate
       # TODO(kevinclark): Make sure transport is C readable
       if iprot.respond_to?(:decode_binary)
         iprot.decode_binary(self, iprot.trans)
@@ -98,6 +99,7 @@ module Thrift
     end
 
     def write(oprot)
+      validate
       if oprot.respond_to?(:encode_binary)
         # TODO(kevinclark): Clean this so I don't have to access the transport.
         oprot.trans.write oprot.encode_binary(self)
index ee5fae1..a886805 100644 (file)
@@ -121,6 +121,9 @@ require File.dirname(__FILE__) + '/ThriftSpec_types'
           FIELDS = {
             ENGLISH => {:type => Thrift::Types::BOOL, :name => 'english'}
           }
+          def validate
+          end
+
         end
 
         class Greeting_result
@@ -131,6 +134,9 @@ require File.dirname(__FILE__) + '/ThriftSpec_types'
           FIELDS = {
             SUCCESS => {:type => Thrift::Types::STRUCT, :name => 'success', :class => Hello}
           }
+          def validate
+          end
+
         end
 
         class Block_args
@@ -139,6 +145,9 @@ require File.dirname(__FILE__) + '/ThriftSpec_types'
           FIELDS = {
 
           }
+          def validate
+          end
+
         end
 
         class Block_result
@@ -149,6 +158,9 @@ require File.dirname(__FILE__) + '/ThriftSpec_types'
           FIELDS = {
             SUCCESS => {:type => Thrift::Types::BOOL, :name => 'success'}
           }
+          def validate
+          end
+
         end
 
         class Unblock_args
@@ -159,6 +171,9 @@ require File.dirname(__FILE__) + '/ThriftSpec_types'
           FIELDS = {
             N => {:type => Thrift::Types::I32, :name => 'n'}
           }
+          def validate
+          end
+
         end
 
         class Unblock_result
@@ -167,6 +182,9 @@ require File.dirname(__FILE__) + '/ThriftSpec_types'
           FIELDS = {
 
           }
+          def validate
+          end
+
         end
 
         class Shutdown_args
@@ -175,6 +193,9 @@ require File.dirname(__FILE__) + '/ThriftSpec_types'
           FIELDS = {
 
           }
+          def validate
+          end
+
         end
 
         class Shutdown_result
@@ -183,6 +204,9 @@ require File.dirname(__FILE__) + '/ThriftSpec_types'
           FIELDS = {
 
           }
+          def validate
+          end
+
         end
 
         class Sleep_args
@@ -193,6 +217,9 @@ require File.dirname(__FILE__) + '/ThriftSpec_types'
           FIELDS = {
             SECONDS => {:type => Thrift::Types::DOUBLE, :name => 'seconds'}
           }
+          def validate
+          end
+
         end
 
         class Sleep_result
@@ -201,6 +228,9 @@ require File.dirname(__FILE__) + '/ThriftSpec_types'
           FIELDS = {
 
           }
+          def validate
+          end
+
         end
 
       end
index 0251524..6e5fed4 100644 (file)
@@ -15,6 +15,9 @@ module SpecNamespace
       FIELDS = {
         GREETING => {:type => Thrift::Types::STRING, :name => 'greeting', :default => 'hello world'}
       }
+      def validate
+      end
+
     end
 
     class Foo
@@ -47,6 +50,9 @@ module SpecNamespace
         ]), :element => {:type => Thrift::Types::I16}},
         OPT_STRING => {:type => Thrift::Types::STRING, :name => 'opt_string', :optional => true}
       }
+      def validate
+      end
+
     end
 
     class BoolStruct
@@ -57,6 +63,9 @@ module SpecNamespace
       FIELDS = {
         YESNO => {:type => Thrift::Types::BOOL, :name => 'yesno', :default => true}
       }
+      def validate
+      end
+
     end
 
     class SimpleList