
00001 using System; 00002 using System.Collections.Generic; 00003 using System.Linq; 00004 using System.Text; 00005 00006 namespace RoutineAnalyzer 00007 { 00008 class CppSetRoutineParam : RoutineParamBase 00009 { 00010 #region Static Methods 00011 00019 public static string GetCppGetOperation(ParameterTypes type) 00020 { 00021 switch (type) 00022 { 00023 case ParameterTypes.IntByReference: return "getInt"; 00024 case ParameterTypes.StringByReference: return "getString"; 00025 default: return "getInt"; 00026 } 00027 } 00028 00036 public static string GetCppSetOperation(ParameterTypes type) 00037 { 00038 switch (type) 00039 { 00040 case ParameterTypes.IntByValue: return "setInt"; 00041 case ParameterTypes.StringByValue: return "setString"; 00042 default: return "setInt"; 00043 } 00044 } 00045 00051 public static string GetCppWrapperType(ParameterTypes type) 00052 { 00053 switch (type) 00054 { 00055 case ParameterTypes.IntByReference: return "int*"; 00056 case ParameterTypes.IntByValue: return "int"; 00057 case ParameterTypes.StringByReference: return "std::string&"; 00058 case ParameterTypes.StringByValue: return "const std::string&"; 00059 00060 default: 00061 throw new Exception("Error: Cpp type not implemented!"); 00062 } 00063 } 00064 00065 #endregion 00066 00072 public CppSetRoutineParam(string sql, int index) 00073 : base(sql, index) 00074 { 00075 } 00076 00081 public override string GetDeclaration() 00082 { 00083 string cppType = GetCppWrapperType(_type); 00084 string cppName = ParseHelper.ConvertUnderscoreToCamelCase(Name); 00085 return string.Format("{0} {1}", cppType, cppName); 00086 } 00087 00092 public override string GetPreExecuteCode() 00093 { 00094 //if this isn't an in param, then we do not perform a pre-execute work 00095 //our pre-execute setup is just sending in our named variable 00096 if (!_isInParam) 00097 return ""; 00098 00099 //If this is an IN paramter, then we have to set the value in the prepared statement 00100 //before execute is called. 00101 00102 if (_type == ParameterTypes.StringByValue) 00103 { 00104 return string.Format("{0}->setString({1},{2});", 00105 ParseHelper.PreparedStmtName, 00106 _index + 1, //MySQL library starts counting at 1 00107 ParseHelper.ConvertUnderscoreToCamelCase(Name)); 00108 } 00109 else 00110 { 00111 string setOperation = GetCppSetOperation(_type); 00112 return string.Format("{0}->{1}({2},{3});", 00113 ParseHelper.PreparedStmtName, 00114 setOperation, 00115 _index + 1, //MySQL library starts counting at 1 00116 ParseHelper.ConvertUnderscoreToCamelCase(Name)); 00117 } 00118 00119 throw new Exception("Error determining argument CPP code"); 00120 } 00121 00122 public override string GetPostExecuteCode() 00123 { 00124 //in parameters never have post execute code 00125 if (_isInParam) 00126 return ""; 00127 00128 //OUT parameters always have post execute code 00129 00130 //the post execute code will query the database for the variable named 00131 //for this argument's ParamMarker. It will traverse the result set 00132 //of this query, then 00133 StringBuilder builder = new StringBuilder(); 00134 00135 //we create a new scope so we don't have name collisions amongst multiple out parameters 00136 builder.AppendLine("{"); 00137 00138 //use auto_ptr for all declarations in here so we don't lost anything 00139 builder.AppendLine("std::auto_ptr< sql::ResultSet > res;"); 00140 //we create a whole new statement because the MySQL library doesn't like re-using the prepared statement used for the execute 00141 //In the future, it does seem like some performance gain could be had by eliminating making a whole new object (how much? who knows) 00142 builder.AppendLine("std::auto_ptr< sql::Statement > stmt;"); 00143 builder.AppendLine("stmt.reset(connection->createStatement());"); 00144 //we query out of the database the value of the variable we utilized during the execute (same name as our param marker) 00145 builder.AppendLine(string.Format("res.reset(stmt->executeQuery(\"SELECT {1} from dual\"));", 00146 ParseHelper.PreparedStmtName, GetParameter())); 00147 builder.AppendLine("res->next();"); 00148 string cppName = ParseHelper.ConvertUnderscoreToCamelCase(Name); 00149 string getOperation = GetCppGetOperation(_type); 00150 if (_type == ParameterTypes.IntByReference) 00151 builder.AppendLine(string.Format("*{0} = res->{1}(1);", cppName, getOperation)); 00152 else if (_type == ParameterTypes.StringByReference) 00153 builder.AppendLine(string.Format("{0} = res->getString(1);")); 00154 else 00155 throw new Exception("Error, parameter type not implemented"); 00156 00157 //close the new scope 00158 builder.AppendLine("}"); 00159 00160 return builder.ToString(); 00161 } 00162 } 00163 }
Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.