设计感很强的中文网站,重庆市建设医院网站,网站建设属什么资产,wordpress怎么集成码支付初级代码游戏的专栏介绍与文章目录-CSDN博客
我的github#xff1a;codetoys#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。
这些代码大部分以Linux为目标但部分代码是纯C的#xff0c;可以在任何平台上使用。 专题#xff1a;一个自制代码…初级代码游戏的专栏介绍与文章目录-CSDN博客
我的githubcodetoys所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。
这些代码大部分以Linux为目标但部分代码是纯C的可以在任何平台上使用。 专题一个自制代码生成器嵌入式脚本语言之总述-CSDN博客
专题一个自制代码生成器嵌入式脚本语言之对象模型-CSDN博客
专题一个自制代码生成器嵌入式脚本语言之堆栈结构和总入口-CSDN博客
专题一个自制代码生成器嵌入式脚本语言之核心逻辑-CSDN博客
专题一个自制代码生成器嵌入式脚本语言之辅助逻辑-CSDN博客
专题一个自制代码生成器嵌入式脚本语言之应用实例-CSDN博客
专题一个自制代码生成器嵌入式脚本语言之模型开发-CSDN博客本篇
专题一个自制代码生成器嵌入式脚本语言之代码模板详解-CSDN博客 这是对数据库操作的模型化实现原则上与代码生成器无关对同样的模型也可以直接写函数操作数据库就像普通的动态方法一样。不过使用了代码生成器生成静态代码性能会比较高也比较方便检查错误。
目录
一、回顾一下对象模型CCTObject
二、各种要素的定义
2.1 列 字段 member
2.2 索引 index
2.3 列组 group
2.4 增删改查 DML
2.5 表 table
2.6 序列 sequence
三、骨干代码
四、使用模型
五、代码模板详解 一、回顾一下对象模型CCTObject 代码生成器接受的模型用CCTObject来定义和一般脚本语言定义对象差不多通过级联实现任意复杂的对象树主要结构如下
struct CCTObject
{enum TYPE { OBJECT, POINTER, PROPERTY, ARRAY };TYPE m_type;//根据type决定哪个成员有效CCTObject* m_Pointer;//指针string m_Property;//属性值mapstring, CCTObject m_Object;//对象vectorCCTObject m_Array;//数组
......
} 整个模型最终生成到一个CCTObject对象里面。
二、各种要素的定义
2.1 列 字段 member 对应数据库的列最关键的属性是名字和类型。 //成员变量定义struct member{//group为空则为列定义使用下面一组成员string member_name;string member_comment;//单行string member_type;//long time double stringstring member_default;//默认值string member_show_type;//显示方式//group不为空则为列组访问使用下面一组成员string group;//组名string var_name;//变量名//生成数据库类型string makeDBType()const{stringstream ss;if (string member_type)ss COLUMN_TYPE_STRING_POOL;else if (long member_type)ss COLUMN_TYPE_LONG;else if (time member_type)ss COLUMN_TYPE_LONG;else if (double member_type)ss COLUMN_TYPE_DOUBLE;else ss 错误的类型 member_type;return ss.str();}//生成参数类型string makeParamType()const{stringstream ss;if (string member_type)ss char const *;else if (long member_type)ss long const;else if (time member_type)ss long const;else if (double member_type)ss double const;else ss 错误的类型 member_type;return ss.str();}//生成参数值string makeParamValue()const{stringstream ss;if (string member_type)ss member_name .c_str();else if (long member_type)ss member_name;else if (time member_type)ss member_name;else if (double member_type)ss member_name;else ss 错误的类型 member_type;return ss.str();}//生成printf类型string makePrintfType()const{stringstream ss;if (string member_type)ss %s;else if (long member_type)ss %ld;else if (time member_type)ss %ld;//else if (double member_type)ss %f;else ss 错误的类型 member_type;return ss.str();}//生成HTML输出类型string makeHtmlType()const{stringstream ss;if (string member_type)ss CHtmlDoc::CHtmlDoc_DATACLASS_LEFT;else if (time member_type)ss CHtmlDoc::CHtmlDoc_DATACLASS_TIME;else ss CHtmlDoc::CHtmlDoc_DATACLASS_RIGHT;return ss.str();}//输出到CCTObjectCCTObject toCCTObject(){CCTObject O;if (0 group.size()){O.SetObjectAddProperty(name, member_name);O.SetObjectAddProperty(GetName, member_name);O.SetObjectAddProperty(GroupIndexVar, );O.SetObjectAddProperty(comment, member_comment);O.SetObjectAddProperty(type, (time member_type ? long : member_type));O.SetObjectAddProperty(default, member_default);O.SetObjectAddProperty(show_type, member_show_type);O.SetObjectAddProperty(DBType, makeDBType());O.SetObjectAddProperty(ParamType, makeParamType());O.SetObjectAddProperty(ParamName, member_name);O.SetObjectAddProperty(PrintfType, makePrintfType());O.SetObjectAddProperty(ParamValue, makeParamValue());O.SetObjectAddProperty(HtmlType, makeHtmlType());}else{O.SetObjectAddProperty(name, var_name);O.SetObjectAddProperty(GetName, \ GetGroup group ColName( var_name ) \);O.SetObjectAddProperty(GroupIndexVar, var_name ,);O.SetObjectAddProperty(ParamType, long var_name , long);O.SetObjectAddProperty(ParamName, var_name);O.SetObjectAddProperty(PrintfType, %ld);}return O;}};成员变量的功能是比较显而易见的另外包含了一组把成员变量的值变成对象模型的属性的方法最后由toCCTObject()方法变成数据模型对象。
2.2 索引 index 索引比较简单因为只是在创建表的时候用一下 //索引定义struct index{string index_name;string index_comment;bool unique{ false };string index_members;//输出到CCTObjectCCTObject toCCTObject(){CCTObject O;O.SetObjectAddProperty(name, index_name);O.SetObjectAddProperty(comment, index_comment);O.SetObjectAddProperty(unique, (unique ? true : false));O.SetObjectAddProperty(members, index_members);return O;}};2.3 列组 group 这个只是为了简化经常使用的一组列并不对应数据库概念 //列组定义可以用下标标识的多个列struct group{string group_name;string group_comment;vectormember group_members;//输出到CCTObjectCCTObject toCCTObject(){CCTObject O;O.SetObjectAddProperty(name, group_name);O.SetObjectAddProperty(comment, group_comment);for (vectormember ::iterator it group_members.begin(); it ! group_members.end(); it){O.SetObjectArrayPushBack(members, it-toCCTObject());}return O;}};2.4 增删改查 DML 所有SQL都用函数包装起来这样客户代码不会直接使用SQL等于所有对数据库的操作都集中在一起以后想找出来哪些表被用到、哪些没有用到就很容易了只要包装函数没有被调用自然就没有被用到。 //DML定义struct dml{string dml_name;string dml_type;//select insert update deletestring dml_comment;vectormember op_members;//操作的列bool hasWhere;//是否有where当where_members和other_where均为空则不添加此属性vectormember where_members;//条件列仅支持 and string other_where;//直接写死的条件部分//输出到CCTObjectCCTObject toCCTObject(){hasWhere (where_members.size() ! 0 || other_where.size() ! 0);CCTObject O;O.SetObjectAddProperty(name, dml_name);O.SetObjectAddProperty(type, dml_type);O.SetObjectAddProperty(comment, dml_comment);for (vectormember ::iterator it op_members.begin(); it ! op_members.end(); it){O.SetObjectArrayPushBack(op_members, it-toCCTObject());}if (hasWhere)O.SetObjectAddProperty(hasWhere, hasWhere);for (vectormember ::iterator it where_members.begin(); it ! where_members.end(); it){O.SetObjectArrayPushBack(where_members, it-toCCTObject());}if(other_where.size() ! 0)O.SetObjectAddProperty(other_where, other_where);return O;}};这个模型不允许直接传入SQL的片段因为这样会破坏封装实际数据库操作无法预期。
2.5 表 table 表对象包含以上所有部分对应一张实体表。 class table{public:string table_name;string table_comment;vectormember table_members;string PK_cols;//主键的列vectorindex table_indexs;//主键名称为PKvectorgroup table_groups;//可以用下标访问的列组vectordml table_dmls;//数据操作对应一个sqlmember * _getMember(string const name){for (size_t i 0; i table_members.size(); i){if (name table_members[i].member_name)return table_members[i];}return NULL;}bool SetTable(char const * name, char const * comment){table_name name;table_comment comment;return true;}bool AddMember(char const * name, char const * type, char const * comment, char const * _default , char const * _show_type){member m;m.member_name name;m.member_type type;m.member_comment comment;m.member_default _default;m.member_show_type _show_type;if (string m.member_type)m.member_default \ m.member_default \;else{if (0 m.member_default.size())m.member_default 0;}table_members.push_back(m);return true;}//设置主键bool SetPK(char const * PK){PK_cols PK;StringTokenizer st(PK_cols, ,);for (size_t i 0; i st.size(); i){member * p _getMember(st[i].c_str());if (NULL p){thelog 主键指定的列不存在 st[i] ende;exit(0);}}return true;}bool AddIndex(char const * name, bool unique,char const * members, char const * comment){StringTokenizer st(members, ,);index tmp;tmp.index_name name;tmp.unique unique;tmp.index_comment comment;tmp.index_members members;//检查for (size_t i 0; i st.size(); i){member* p _getMember(st[i].c_str());if (NULL p){thelog 索引指定的列不存在 st[i] ende;exit(0);}}table_indexs.push_back(tmp);return true;}bool AddGroup(char const * name, char const * members, char const * comment){StringTokenizer st(members, ,);group tmp;tmp.group_name name;tmp.group_comment comment;for (size_t i 0; i st.size(); i){member * p _getMember(st[i].c_str());if (NULL p){thelog 列组指定的列不存在 st[i] ende;exit(0);}tmp.group_members.push_back(*p);}table_groups.push_back(tmp);return true;}bool AddDML(char const * name, char const * type, char const * op_members, char const * where_members, char const * comment, char const * other_where ){dml tmp;tmp.dml_name name;tmp.dml_type type;tmp.dml_comment comment;tmp.other_where other_where;if (0 ! strlen(op_members)){StringTokenizer st(op_members, ,);for (size_t i 0; i st.size(); i){if (* st[i]){//全部for (vectormember ::const_iterator it table_members.begin(); it ! table_members.end(); it){tmp.op_members.push_back(*it);}}else{StringTokenizer st2(st[i], :);if (2 st2.size()){//列组bool isGroupFound false;for (vectorgroup ::const_iterator it table_groups.begin(); it ! table_groups.end(); it){if (it-group_name st2[0]){isGroupFound true;}}if (!isGroupFound){thelog op_members指定的列组不存在 st2[0] ende;exit(0);}member tmpmember;tmpmember.group st2[0];tmpmember.var_name st2[1];tmp.op_members.push_back(tmpmember);}else{//简单列member * p _getMember(st[i].c_str());if (NULL p){thelog op_members指定的列不存在 st[i] ende;exit(0);}tmp.op_members.push_back(*p);}}}}if (0 ! strlen(where_members)){StringTokenizer st(where_members, ,);for (size_t i 0; i st.size(); i){member * p _getMember(st[i].c_str());if (NULL p){thelog where_members指定的列不存在 st[i] ende;exit(0);}tmp.where_members.push_back(*p);}}table_dmls.push_back(tmp);return true;}//输出到CCTObjectCCTObject toCCTObject(){CCTObject O;O.SetObjectAddProperty(name, table_name);O.SetObjectAddProperty(comment, table_comment);O.SetObjectAddProperty(PK_cols, PK_cols);for (vectormember ::iterator it table_members.begin(); it ! table_members.end(); it){O.SetObjectArrayPushBack(members, it-toCCTObject());}for (vectorindex ::iterator it table_indexs.begin(); it ! table_indexs.end(); it){O.SetObjectArrayPushBack(indexs, it-toCCTObject());}for (vectorgroup ::iterator it table_groups.begin(); it ! table_groups.end(); it){O.SetObjectArrayPushBack(groups, it-toCCTObject());}for (vectordml ::iterator it table_dmls.begin(); it ! table_dmls.end(); it){O.SetObjectArrayPushBack(dmls, it-toCCTObject());}return O;}};2.6 序列 sequence 序列是个比较头疼的东西因为不同数据库的支持很不一样Oracle的序列是独立的数据库对象Sql Server则是列可以被指定为自增列。 class sequence{public:string sequence_name;string sequence_init;string sequence_comment;//输出到CCTObjectCCTObject toCCTObject(){CCTObject O;O.SetObjectAddProperty(name, sequence_name);O.SetObjectAddProperty(comment, sequence_comment);O.SetObjectAddProperty(init, sequence_init);return O;}};三、骨干代码
class CCTModel_UniversalDB
{
private:vectortable m_tables;vectorsequence m_sequences;setstring _table_names;//用来检查是否已经存在setstring _sequence_names;//用来检查是否已经存在public:CCTObject toCCTObject(){CCTObject O;O.SetObjectAddProperty(name, CodeTemplate);for (vectortable ::iterator it m_tables.begin(); it ! m_tables.end(); it){O.SetObjectArrayPushBack(tables, it-toCCTObject());}for (vectorsequence ::iterator it m_sequences.begin(); it ! m_sequences.end(); it){O.SetObjectArrayPushBack(sequences, it-toCCTObject());}return O;}sequence * AddNewSequence(char const * sequencename, char const * comment, long init){if (_sequence_names.end() ! _sequence_names.find(sequencename)){thelog sequencename 已经存在 ende;return NULL;}else{_sequence_names.insert(sequencename);}m_sequences.resize(m_sequences.size() 1);sequence * p m_sequences[m_sequences.size() - 1];p-sequence_name sequencename;p-sequence_comment comment;char buf[256];sprintf(buf, %ld, init);p-sequence_init buf;return p;}table * AddNewTable(char const * tablename, char const * comment){if (_table_names.end() ! _table_names.find(tablename)){thelog tablename 已经存在 ende;return NULL;}else{_table_names.insert(tablename);}m_tables.resize(m_tables.size() 1);table * p m_tables[m_tables.size() - 1];p-SetTable(tablename, comment);return p;}
public://_ns 名字空间sys 总类的名称的一部分bool CreateCode(char const * _ns, char const * sys, char const * output_dir){CCTObject O;O toCCTObject();O.SetObjectAddProperty(NAMESPACE, _ns);O.SetObjectAddProperty(SYS, sys);CCTStack S;CCodeTemplate ct;string str;//thelog endl O.toString(str) endi;S.clear();if (!ct.ProcessFile(_t_UniversalDB.h.ct, (string(output_dir) /_cc_ sys .h).c_str(), O, S))return false;vectorCCTObject * p;if (NULL ! O.FindObject(tables)){p O.FindObject(tables)-m_Array;for (vectorCCTObject ::iterator it p-begin(); it ! p-end(); it){S.clear();S.Push();S.Add(table, *it);//thelog endl S.toString(str) endi;if (!ct.ProcessFile(_t_UniversalDB_table.h.ct, (string(output_dir) /_cc_ sys _ it-GetDefaultValue() .h).c_str(), O, S))return false;}}if (NULL ! O.FindObject(sequences)){p O.FindObject(sequences)-m_Array;for (vectorCCTObject ::iterator it p-begin(); it ! p-end(); it){S.clear();S.Push();S.Add(sequence, *it);thelog endl S.toString(str) endi;if (!ct.ProcessFile(_t_UniversalDB_sequence.h.ct, (string(output_dir) /_cc_ sys _ it-GetDefaultValue() .h).c_str(), O, S))return false;}}return true;}};代码很容易懂。
四、使用模型 专题一个自制代码生成器嵌入式脚本语言之应用实例-CSDN博客
五、代码模板详解 下一篇专题一个自制代码生成器嵌入式脚本语言之代码模板详解-CSDN博客 这里是结束但不是整个系列的结束