Repository: thrift Updated Branches: refs/heads/master 228b328f7 -> 86da51d2a
THRIFT-3339 Support for database/sql Client: Go Patch: Adam Beberg <[email protected]> Contributed by Sentient Technologies - http://www.sentient.ai/ This closes #623 Project: http://git-wip-us.apache.org/repos/asf/thrift/repo Commit: http://git-wip-us.apache.org/repos/asf/thrift/commit/86da51d2 Tree: http://git-wip-us.apache.org/repos/asf/thrift/tree/86da51d2 Diff: http://git-wip-us.apache.org/repos/asf/thrift/diff/86da51d2 Branch: refs/heads/master Commit: 86da51d2aedb499f198c47c451929da687dea3f9 Parents: 228b328 Author: Jens Geyer <[email protected]> Authored: Wed Oct 14 14:20:37 2015 +0200 Committer: Jens Geyer <[email protected]> Committed: Wed Oct 14 14:34:03 2015 +0200 ---------------------------------------------------------------------- compiler/cpp/src/generate/t_go_generator.cc | 54 ++++++++++++++++++------ 1 file changed, 40 insertions(+), 14 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/thrift/blob/86da51d2/compiler/cpp/src/generate/t_go_generator.cc ---------------------------------------------------------------------- diff --git a/compiler/cpp/src/generate/t_go_generator.cc b/compiler/cpp/src/generate/t_go_generator.cc index f04bc48..3e6cdbd 100644 --- a/compiler/cpp/src/generate/t_go_generator.cc +++ b/compiler/cpp/src/generate/t_go_generator.cc @@ -247,9 +247,9 @@ public: std::string go_autogen_comment(); std::string go_package(); - std::string go_imports_begin(); + std::string go_imports_begin(bool ttypes); std::string go_imports_end(); - std::string render_includes(); + std::string render_includes(bool ttypes); std::string render_import_protection(); std::string render_fastbinary_includes(); std::string declare_argument(t_field* tfield); @@ -756,18 +756,19 @@ void t_go_generator::init_generator() { } // Print header - f_types_ << go_autogen_comment() << go_package() << render_includes() + f_types_ << go_autogen_comment() << go_package() << render_includes(true) << render_import_protection(); - f_consts_ << go_autogen_comment() << go_package() << render_includes(); + f_consts_ << go_autogen_comment() << go_package() << render_includes(false); f_const_values_ << endl << "func init() {" << endl; } /** - * Renders all the imports necessary for including another Thrift program + * Renders all the imports necessary for including another Thrift program. + * If ttypes include the additional imports for ttypes.go. */ -string t_go_generator::render_includes() { +string t_go_generator::render_includes(bool ttypes) { const vector<t_program*>& includes = program_->get_includes(); string result = ""; string unused_prot = ""; @@ -791,7 +792,7 @@ string t_go_generator::render_includes() { result += "\n"; } - return go_imports_begin() + result + go_imports_end() + unused_prot; + return go_imports_begin(ttypes) + result + go_imports_end() + unused_prot; } string t_go_generator::render_import_protection() { @@ -823,12 +824,21 @@ string t_go_generator::go_package() { } /** - * Render the beginning of the import statement + * Render the beginning of the import statement. + * If ttypes include the additional imports for ttypes.go. */ -string t_go_generator::go_imports_begin() { +string t_go_generator::go_imports_begin(bool ttypes) { + string extra; + // If writing ttypes.go, and there are enums, need extra imports. + if (ttypes && get_program()->get_enums().size() > 0) { + extra = + "\t\"database/sql/driver\"\n" + "\t\"errors\"\n"; + } return string( "import (\n" "\t\"bytes\"\n" + + extra + "\t\"fmt\"\n" "\t\"" + gen_thrift_import_ + "\"\n"); } @@ -955,6 +965,21 @@ void t_go_generator::generate_enum(t_enum* tenum) { f_types_ << "if (err != nil) {" << endl << "return err" << endl << "}" << endl; f_types_ << "*p = q" << endl; f_types_ << "return nil" << endl; + f_types_ << "}" << endl << endl; + + // Generate Scan for sql.Scanner interface + f_types_ << "func (p *" << tenum_name << ") Scan(value interface{}) error {" <<endl; + f_types_ << "v, ok := value.(int64)" <<endl; + f_types_ << "if !ok {" <<endl; + f_types_ << "return errors.New(\"Scan value is not int64\")" <<endl; + f_types_ << "}" <<endl; + f_types_ << "*p = " << tenum_name << "(v)" << endl; + f_types_ << "return nil" << endl; + f_types_ << "}" << endl << endl; + + // Generate Value for driver.Valuer interface + f_types_ << "func (p " << tenum_name << ") Value() (driver.Value, error) {" <<endl; + f_types_ << "return int64(p), nil" << endl; f_types_ << "}" << endl; } @@ -1219,19 +1244,20 @@ void t_go_generator::generate_go_struct_definition(ofstream& out, t_type* fieldType = (*m_iter)->get_type(); string goType = type_to_go_type_with_opt(fieldType, is_pointer_field(*m_iter)); - string gotag; + string gotag = "db:\"" + escape_string((*m_iter)->get_name()) + "\" "; if ((*m_iter)->get_req() == t_field::T_OPTIONAL) { - gotag = "json:\"" + escape_string((*m_iter)->get_name()) + ",omitempty\""; + gotag += "json:\"" + escape_string((*m_iter)->get_name()) + ",omitempty\""; } else { - gotag = "json:\"" + escape_string((*m_iter)->get_name()) + "\""; + gotag += "json:\"" + escape_string((*m_iter)->get_name()) + "\""; } + + // Check for user override of db and json tags using "go.tag" std::map<string, string>::iterator it = (*m_iter)->annotations_.find("go.tag"); if (it != (*m_iter)->annotations_.end()) { gotag = it->second; } indent(out) << publicize((*m_iter)->get_name()) << " " << goType << " `thrift:\"" << escape_string((*m_iter)->get_name()) << "," << sorted_keys_pos; - if ((*m_iter)->get_req() == t_field::T_REQUIRED) { out << ",required"; } @@ -1653,7 +1679,7 @@ void t_go_generator::generate_service(t_service* tservice) { f_service_name = package_dir_ + "/" + filename + ".go"; } f_service_.open(f_service_name.c_str()); - f_service_ << go_autogen_comment() << go_package() << render_includes(); + f_service_ << go_autogen_comment() << go_package() << render_includes(false); generate_service_interface(tservice); generate_service_client(tservice);
