From 45dedd35948a895e646c486d47b74382b6e676f8 Mon Sep 17 00:00:00 2001 From: DeffPuzzL Date: Mon, 12 Mar 2018 15:01:29 +0800 Subject: [PATCH] stvm 1.2.2 --- README | 58 + demo/count | Bin 0 -> 15238 bytes demo/count.c | 51 + demo/create | Bin 0 -> 16195 bytes demo/create.c | 52 + demo/delete | Bin 0 -> 15005 bytes demo/delete.c | 50 + demo/drop | Bin 0 -> 14266 bytes demo/drop.c | 46 + demo/extreme | Bin 0 -> 15268 bytes demo/extreme.c | 52 + demo/group | Bin 0 -> 16184 bytes demo/group.c | 56 + demo/insert | Bin 0 -> 15335 bytes demo/insert.c | 58 + demo/makefile | 57 + demo/press_demo | Bin 0 -> 16199 bytes demo/press_demo.c | 59 + demo/query | Bin 0 -> 16208 bytes demo/query.c | 59 + demo/select | Bin 0 -> 15345 bytes demo/select.c | 53 + demo/truncate | Bin 0 -> 14305 bytes demo/truncate.c | 47 + demo/update | Bin 0 -> 15133 bytes demo/update.c | 52 + include/tmain.h | 135 + include/tstr.h | 174 + include/tvm.h | 747 ++++ src/conf.c | 1271 ++++++ src/detvm.c | 404 ++ src/list.c | 1099 ++++++ src/makefile | 44 + src/msg.c | 313 ++ src/sem.c | 144 + src/str.c | 480 +++ src/stvm.c | 4139 ++++++++++++++++++++ src/tcp.c | 4874 +++++++++++++++++++++++ src/tree.c | 9511 +++++++++++++++++++++++++++++++++++++++++++++ stvm.conf | 27 + tbl_user_info.def | 16 + 41 files changed, 24128 insertions(+) create mode 100644 README create mode 100755 demo/count create mode 100644 demo/count.c create mode 100755 demo/create create mode 100644 demo/create.c create mode 100755 demo/delete create mode 100644 demo/delete.c create mode 100755 demo/drop create mode 100644 demo/drop.c create mode 100755 demo/extreme create mode 100644 demo/extreme.c create mode 100755 demo/group create mode 100644 demo/group.c create mode 100755 demo/insert create mode 100644 demo/insert.c create mode 100755 demo/makefile create mode 100755 demo/press_demo create mode 100644 demo/press_demo.c create mode 100755 demo/query create mode 100644 demo/query.c create mode 100755 demo/select create mode 100644 demo/select.c create mode 100755 demo/truncate create mode 100644 demo/truncate.c create mode 100755 demo/update create mode 100644 demo/update.c create mode 100644 include/tmain.h create mode 100644 include/tstr.h create mode 100644 include/tvm.h create mode 100644 src/conf.c create mode 100644 src/detvm.c create mode 100644 src/list.c create mode 100755 src/makefile create mode 100644 src/msg.c create mode 100644 src/sem.c create mode 100644 src/str.c create mode 100644 src/stvm.c create mode 100644 src/tcp.c create mode 100644 src/tree.c create mode 100644 stvm.conf create mode 100644 tbl_user_info.def diff --git a/README b/README new file mode 100644 index 0000000..63b6bda --- /dev/null +++ b/README @@ -0,0 +1,58 @@ +/************************************************************************************************* + STVM 高效缓存数据库 + *************************************************************************************************/ + +启动环境变量 +TVMDBD=/home/stvm/tvmdb 指向stvm工作目录 +TVMCFG=/home/stvm/tvmdb/.tvm.run 启动参数 + +编译项目 +cd stvm-1.2/src目录 + ./make + +在../lib下生成 + libstvm.a + libstvm.so + libstvm.so.1.2 -> ../lib/libstvm.so + +在../bin下生成 + stvm + detvm + +使用方法: +如果不使用多机集群,无需配置域文件,直接 stvm -w 缺省启动单机模式。 + +stvm -s 停止系统 + +STVM也提供一个类型sqlpuls类型简单工具, 输入: +stvm SQL 进入SQL界面,该工具主要用来运维调试使用。 +stvm DOM 进入域的维护 + +关于域的配置,请参见: + stvm.conf + +配置域完成后,可以stvm -c stvm.conf编译到$TVMCFG下 +然后在stvm -w启动即可 + +目前本版本为测试版本,不保证无bug,建议以单机模式64位下运行,将性能发挥在极致。 + +作者:Savens Liu +邮箱:deffpuzzl@qq.com + + + + +====更新日期:20180312==== +1、支持动态创建表语句 +2、新增对表结构导出功能 + +用法: +表创建语法示例: tbl_acct_base.def +在stvm SQL中,利用 create $file来创建表 +提交人:Savens Liu + +下本版本: +1、新增多机资源共享方式。 +2、JAVA接口开发 + +不定时更新 diff --git a/demo/count b/demo/count new file mode 100755 index 0000000000000000000000000000000000000000..1e9554eee08e2c2d6cedcced0c2ed21d5fa7306c GIT binary patch literal 15238 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, sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; + } + + conditinit(pstSavm, stUser, TBL_USER_INFO); // 绑定变量 + stringset(pstSavm, stUser, user_type, "1"); // 查询条件赋值 + stringset(pstSavm, stUser, user_no, "20180224"); // 查询条件赋值 + + if(RC_SUCC != lCount(pstSavm, (void *)&lRow)) + { + fprintf(stderr, "Count error: (%d) (%s)\n", pstSavm->m_lErrno, sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; + } + + fprintf(stdout, "Count:%ld\n\n", lRow); + return RC_SUCC; +} + +int main(int argc, char *argv[]) +{ + if(RC_SUCC != lCountUserInfo()) + return RC_FAIL; + + return RC_SUCC; +} + + diff --git a/demo/create b/demo/create new file mode 100755 index 0000000000000000000000000000000000000000..a74aff39581336e0530437ee024284af2648044b GIT binary patch literal 16195 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 zm_lErrno)); + return RC_FAIL; + } + + fprintf(stdout, "初始化表成功, completed successfully!!!\n"); + fflush(stderr); + + return RC_SUCC; +} + + diff --git a/demo/delete b/demo/delete new file mode 100755 index 0000000000000000000000000000000000000000..0ece7809f1544ab5ba06e4ce3c907f4a2474d851 GIT binary patch literal 15005 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 dX#A+}c_?k%7zroT!8k$Qp literal 0 HcmV?d00001 diff --git a/demo/delete.c b/demo/delete.c new file mode 100644 index 0000000..4213e0a --- /dev/null +++ b/demo/delete.c @@ -0,0 +1,50 @@ +#include "tvm.h" +#include "tmain.h" + +#define TBL_USER_INFO 20 + +typedef struct __TBL_USER_INFO +{ + long acct_id; + char user_no[21]; + char user_type[2]; + char user_nm[81]; + char user_addr[161]; + char user_phone[31]; +}dbUser; + +long lDeleteUserInfo() +{ + dbUser stUser; + SATvm *pstSavm = (SATvm *)pGetSATvm(); + + /* 初始化TBL_USER_INFO表,每张表都需要初始化一次, 对于表重建后,需要重新初始化一次。*/ + if(RC_SUCC != lInitSATvm(pstSavm, TBL_USER_INFO)) + { + fprintf(stderr, "init failed, err:(%d)(%s)\n", pstSavm->m_lErrno, sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; + } + + conditinit(pstSavm, stUser, TBL_USER_INFO); // 绑定变量 + stringset(pstSavm, stUser, user_type, "1"); // 查询条件赋值 + stringset(pstSavm, stUser, user_no, "20180223"); // 查询条件赋值 + + if(RC_SUCC != lDelete(pstSavm)) + { + fprintf(stderr, "Delete error: (%d) (%s)\n", pstSavm->m_lErrno, sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; + } + + return RC_SUCC; +} + +int main(int argc, char *argv[]) +{ + + if(RC_SUCC != lDeleteUserInfo()) + return RC_FAIL; + + return RC_SUCC; +} + + diff --git a/demo/drop b/demo/drop new file mode 100755 index 0000000000000000000000000000000000000000..1d121cea7feb952c7ca8845e47acd03da2fb9b2e GIT binary patch literal 14266 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, sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; + } + + if(RC_SUCC != lDropTable(pstSavm, TBL_USER_INFO)) + { + fprintf(stderr, "drop table error:(%d)(%s)\n", pstSavm->m_lErrno, sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; + } + + return RC_SUCC; +} + +int main(int argc, char *argv[]) +{ + + if(RC_SUCC != lDropUserInfo()) + return RC_FAIL; + + return RC_SUCC; +} + + diff --git a/demo/extreme b/demo/extreme new file mode 100755 index 0000000000000000000000000000000000000000..492dcb6c9da9ae7f5c0e6ce24d051cae5a65dd7b GIT binary patch literal 15268 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, sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; + } + + conditinit(pstSavm, stUser, TBL_USER_INFO); // 绑定变量 + stringset(pstSavm, stUser, user_type, "1"); // 查询条件赋值 + + decorate(pstSavm, dbUser, user_nm, MATCH_MIN); + decorate(pstSavm, dbUser, user_phone, MATCH_MAX); + if(RC_SUCC != lExtreme(pstSavm, (void *)&stUser)) + { + fprintf(stderr, "Extreme error: (%d) (%s)\n", pstSavm->m_lErrno, sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; + } + + fprintf(stdout, "user_nm:%s, user_phone:%s\n", stUser.user_nm, stUser.user_phone); + + return RC_SUCC; +} + +int main(int argc, char *argv[]) +{ + if(RC_SUCC != lExtremeUserInfo()) + return RC_FAIL; + + return RC_SUCC; +} + + diff --git a/demo/group b/demo/group new file mode 100755 index 0000000000000000000000000000000000000000..a824dd0fc5e9438a96d3c23f4e659dc846bc977b GIT binary patch literal 16184 zcmeHOdwf(^oj>XIXwp#Z4{oQktnSp%t z^V$9EUmnQ)o!|5P&hPxrx%ZxP=hl|?R@<_aDYklpB6hSiA|&ss)Zps{)wBi`R1vj8 zy;=o8@#8Nd973;V;IuYvU{K5X083c6HNlQ}6%Chqm@?3KNXYhPOGH;a_(-LP8mLrQ z2-Ksms!CA6?OsL0N$tm!@ki?srQS-dw^GX+c$9`w3^e^?-}tvw+goZ!fDw-nsAjp& zLWu=vozG_Dte>dx1Wr^$q+;M|kE{$dde=Zt`ltDS3K&1vCWm@AZdjX)uSpJ#oBRu) zSE*l}o|?ZMwb}9vs-#aA(SI}tT_LYB*`344B$dg=Q@N}fP7L>r?p8ay6WQiOUn(8T zCRB2BI+Yt0T2m_CI+RGpRsU#uXe8TD`Aj0KMmHz2-HkmvhiNB~POA(EJuT^UDy@=j zBSV_mpH9HsP%m4o+o)W3U^q46X0ow#)^(M8)lRo7F))aSiY5PuvvxnAUS3pg$xs<}{)EjEJbHN^ zeKe1*mrUXA%A-4Z^3lD|2T%AAffMiN=gVk@euI{a6l>RUT7Qp?pvc{KaTGG>8Z}1wjtH%Xhe^+9221sQ(axp6y#HePo)$aB>+^fNDn~Vey02Jr6KXP{@cL zQT23GWU9mysmg2+f$^&7#BEcs`IzXyoxl1c8ldjPouo&{I%@^pI~_iJ9)uoa-qG(n zDLCOjNhh@I#8u}V_SoNuj{W0_y~dQEPJLxN6b~<>iEFfp^;+OaWY!~3c8apq(0Yst zY%WkFJ8>t29-Y{7Oxzp$4uu*ibhaP|$rvjP@;V8hKZh|d3i1+4>mVOy`$t-i1E}Y2 zjE+x8v*X*2N5_svpE&M|T1TVSG_Ow_FNsc+Ska07bUZqK@1KzLMJGC!VX&VNY5#8n zXZZ2{KfsT@Eypc%@mTbdmgDo@bu$J&IxY#vjxI5EbpAIl)9b=qjK1?prYbU>nTyF( zHTI4_M8|Tcylh&d<5l_)6Y4p?P?_f}zvk@7pC4n%<;U8`;>(XmC)Qk95?1XKD;fwu zKhZvxU4E*4?3U#(M#tW~9JBfPhW1s@Hje$VZR~f^C;sSb8~c|NFTVr_Z+juTbltyk zoogR^seSBs&11i8JiXxGqkF%GIs9Du=h5*uFUQi5Twc{a9$#MDj#{{VJiB~l`}i%( z>oIK`w0n9kdJD-RAA+~{#naiv5A*R_uLI8ov963`eR%P7?pJ!oduz{$`xq>)zPu+f zXJ^Y0ZtUUy*ibSNUmeC>|I(E!;;UA!$gB#fbxIx@NKK_L4U>TjIk`+C?T!pzx+1eW zEcMaB)JOtoNLlClF5@#Z7vyiVS-{(oyQ6>)0Zsxw1$YpUh4Ylfx~WT9yQ-{nD@uct z7{ukE@gemV*pO+~=v3WqH&q6<@Adiav>`<;PX^1Na$r-Q)s5VMCqnyi{Dr~K?>X(? zg1=hO#{kte@AcmvaGl8B()ZbS_$Es1>mA($xqm5tiNOCV0$g%fj1do;#SI;)FQpjn zETZ3Egg;({e^cY;S?yFHA{6rsyGy_C{`QsADKfU(5nN~A`L8eWa6UM(Oxh6w#Rnml zS3ID~HLTU}91RV?yhu!#8Nyq2XIK9MSNvG`vH@k7)Q=4Ik6c zw6jttz~-hVEa})ySQXw-x1sLh@cR07>+3IEcVT#CS0Wyc#VGm@yGznURz^!f2-3*Fp z=I-(c<)qk`0NCGaz||Kl9fwp&i65`A%2!f43CtJtS7NLIm|;FE_~8-&yYvWb`mDgc zg82^th=aa~Ewsm{Bi|iTeLdAad?l#l#={a`~~U9#q{KM zv|ZNVzx!GUg_ioEEjCo>c@X^fv_h^VREB2!_p%-gJp~2-M_8{2{hsvuSg#5l!qq>; z`hw6e(5(NX^rbfRW!n50>q|q^tl!VJ!=WRrKfwCR&<800N$S?C@&^Ck>_OWV@22sC zPlH&&(epq2c~&E=KEfU=`^$9YQF>lF1^mOPNXM3`%HM!>EHKZy7|{73%m=D0`k)+c zv;@wv?gj`tTc8qHC`gs_es~mEBuK6Exd4z_LBh@*a3!!~X0Jp0DDg0>D)fCu z>JfH77R3P{UDh4^srBfi$e;IF5InYA=sG-(iYL(QXbG~573@5+eqmEL-i5Ub=P<*wjf>tT?b4?r%sPvWPX z3=9Wv6GqUPrpE0ST|pk5gpa{@iyZQ32YLI2hddf1Z%lZ|Bl;D5k6_576~x8`I|Ub~ zVC`EZaROecsy{&0_gYtiRCyaNk>Fj{YvF}+5BR|kNejyP2A#ZHkf1Y6l@AM23-`bEqq)sL|{I#PlzBQ&`9i)!b1cq=+i;Ljw|N@`u-`w5P?_G=7XY#nY4_O zpB5hG&TA<7w}N5rTn~qWpAii6V+*m*3WoV1@&BA)m>++n(}%29sAGPtCiZuNJzzOg zY~l0LQ_Pm1v4y`E-a)@}Gi`oBc!&JX5n^8yn}^Dr9QD2=em+#@yp8?)vhb$Moa1ca zA!`E^o+@+rEED{S7l|_G3i1vMcC5^~kiC7_`ZbIlFLV0X!Xwryfa8mui)r&w8K0jn zc5b2MV}k8l;{1{}AGeqr2bZW)<^XL-o|JmHuT#aK6BH)(JAL zoO@||y~sU-_yOzZ3ZUn9Hq_`f;`}JzQb0p6weO^oG;RNM6gc<98Sz& zqhJpPoFCHsCc!=(aMHw@#J@uU=P^d6Sz`83z~OOHu*E)%{yh?Ky4ZND_&6PKZe^!8 z+n)sS$$%4J3sJ$I3OJu4)+X4u15OV;yGrzq2Auz(XID!Mjs={X$!iy1jt89g5Zhwk zhgkh6;MB9d4x4MtkAlt=d0Xwzfw#X5YjF+QD4l``DUv0pRVg##af832s^`%}r_F7x zK#+`@bD&mlS*6%2P@z@u#R@VfROm+Z$0{Q^72pO*7oxV*q>!7x}= zbkjU`atoKmy5|MxoHL}X`AjPNKZs=_JQjWA<8YX{*xW6mpi*@$2{g*_gsi4;@Y>+OugJ&4YPw*CRS&M%G`La)X$dZ2tJNQ*u#L9g8^}E;H^2(~VRyZ}~KIdGg+L~`wp*4G< z@;R55Usm2$gPtr`<>hYxA1jZpVz~YDK*gvNP^#3j+G;FRg0E6-HEY2ttFg+cZS?|bmi02aXQ2?m|FyYHnuo<}2m1Qf;*{9kxM58?5g&|Yy_4g$^18Nm zXrwQhizk$bYh-QjP&QLY$?Ps9sI`Ns;lx^=7|xhb13Vk7>w^P4`im#}>jvpccK2u^ zgDU2xsUp+#8J(ek31^2=ki(qFX0mD2kcm8!lnN{wF4Dm^lgn3SJ-qib{~COwy{YC= zJ6>a7zQA5xga5%}q}*qxtFiXKcEJrFefHU%H`qAJvs^dT-|uE|BA6MvDWSZx%BC&t zIBZmI-yn|@hh6VQvn!RtIjEbtsUw9LQC#$5$)SM}1=NfC!cPzr3bxKZrfIu zCy(xEHq9gUaMPdhR_wanQMYSTPghF|Ew!do!-PFJAeHuAcO>oJm>$AWXvTeeE|E*b z!S8L%X8Q(JPj9k0(T{ky#;;E7Rs(LbV<@?`KSK+f)1%u)QORUMgGf_qgqq2gT`+|+ z)6~d7ST20;o!x)cs_hAM(cO{QjV{v$&Aa{B;2lX(VoPjSSL(*u9`i`mbw^|I3stT) z8HX69y0bhr9(G4F+3Qm29W-=PCysa_+H>s|w`*HRPumvhc6XvPl@W7@s2tF`eYv#T zmrCY_#Z*%+EiuN~bZ?S2lb(k?o7&x`tsTv6J#K4zGw8id7y|grft1*BL=Zcb?M-&X zh7)Gn8BEP_Z;b6o;8+`e?re<5)2gR&Q+tbw_4Q@lA$AK1vvGsOA$?;q)wcsA^mK!C z$2$Z!xu0wuVjz$Q!?E;^M4C1;JDYg|jTm$!c4bv-Tn55*y>n@Z%HT@QcwyPv+0xb6 zBVj>|yP2ivR%beKqvty(jgssO=SDKfMeMY24Bb(LkOSP`pXdV$)0x=Lgxed-AUByt zro%dox~^+yZ+cUyB*r!w8_29z?y%&#{szEJw#9cLi{N~B3}^bV4njw6IDZ9*Cx#^_ z+A^Ix)V9P3xRCQc72r6f`eI2Pb;|8#D$QnJK^Hg#7-<;=`tOB?$)y(z*Bb$uhu)-^ z9lgxpa2qoK8Qz_^M*7duqAX0cwqZ=^zoZe|=!P3~FVQdgh&4|1iyBmJ{Ar=<5*=H54+izm!yfNR1zOP#Cy4C1$rjy z%}NZkXsWYHWGX_6ACOtl-|7sE_wsa@l7VXTdrY~7y^PGX(W@~HX5fVy-_%( z+?~?4anRLE2jwM`bYf<_0f{l)J&WFSlJo}QS}bz1T3|HVhenuznVY-@!R30$MFnZ0 zJC?*39#|P->48330CXz$q;p6x>Uuu+HpTh|k&Gjp2_$dH49Ms(GrdI3WV>=BJwuqN zGYRZ1E*S&`YoE-$bsks`8@;l!z?1eES8&eEigA8SLquir@$J)F9{85x^_FjMvi@+B#+```-x%~gnfnoXq2gPXw>I+~%$p9} zBgwyo@>N;Kldn>R6OHfBIu-biTof?AN$VRbUx14Tm9M$pZI*Ag#_-IYhc9}1ZRhJG z_<46YzU-K^<{OU3H48o8cD&~hzC?JIXV)S=>FWgqL!ne%X7@1WIAAvI!9i2QDv?N! zs=AR>Hc{8OsclU*HlVSAkz8GGZU|ovBLC}%4aPEqsxH2J1ok|LL>10X+%AVwBL#>H zUOJJCQ9;*6lUY^AlV4Sr<$SK|2LfJ7?re35LAO7R8?HNuHD(4=b$!_s?#6X-54^1p zOxTPK5A~rzJaF++C$>F1_;3qKso`NxmAZJMH#gwM(y@^N%mR&$=6YdZ79Zm2fD!HO zO(%9544+LVOdU}(RT$u1H6sE3Ke(I=8%TXV^m@gPXy^g%D(4r<=9kw1K@!dAFSR4U zuxYOih6S6wAkz!VI$-(wm)jBHU#|6+3pRTx)^7&ucR1rR{%^Mzi}T6I#KXdlKc@Y_a|wpwTb-$70THPicZ_$K!f!nL6PZ z{_^#Mr4f=<+pFXt9`K=43y&hHTnkr2r~Kl=DUHa z`J%2yJuq`MdItWyNPmys``V-Rji1JV(KGldR7f-ZpVa!3f2RI#p-cbk@t0qWKA+<9 z3uRdhM}I&%k2kJg(Q_Ag4j>)ap`9gXP?i<_lNmBRWt4niV$Y=W0Ir#n6+2j|_{63;k zevvZkb0NJ}nRU02zF3*{w2;0eADyZD6raY=EWVjvs}=Hmir;LXS$s+_K1D2_T2@5y zP@f9VL4Va5bj}|e_j2QfH1=gV4_$uNKhRZa5f0 zZMN_O3`@<%nf|f74S%HHrSE5E-Pi>>?MxQgnalruVrM?iq_?9sTMnRVAwM6|&r61L zpU}_r|I?te-AGaXKLPsL;`X%Isa57I%lQ92p`V$DCqc&<&>3-lX%4z~-#jz_c>o#4 zQ%i9^^D78_OBIXe!u!*F^ozd+VKK{Xi>90BX<_2h4tm%idGJkh(0Tuyf0p$mC-lmh z!%O*Q8us=HJh$Nci=Z2kQ%=v8Nl56{2PCjT7m+w;_9(YU`T z^cuwYTN&^3|=c-nlnb~k{2w%^r7=8)&NH)s2OUgsS0*UdqX zfzG*9Tyole@p^d69CmR0eO5ak7x_wM4w23K4L`V;k2iVq{y5V|ZtYZ0&Nn$H|}axy=RGRZV%Uc*-3}rg~#ZS9XKkSZNgj6m_lErrno, sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; + } + + conditinit(pstSavm, stUser, TBL_USER_INFO); // 绑定变量 + stringset(pstSavm, stUser, user_type, "1"); // 查询条件赋值 + + decorate(pstSavm, dbUser, user_nm, GROUP_BY | ORDER_ASC); + decorate(pstSavm, dbUser, user_phone, GROUP_BY | ORDER_DESC); + if(RC_SUCC != lGroup(pstSavm, &lRow, (void **)&pstUser)) + { + fprintf(stderr, "Group error: (%d) (%s)\n", pstSavm->m_lErrno, sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; + } + + for(i = 0; i < lRow; i ++) + fprintf(stdout, "user_nm:%s, user_phone:%s\n", pstUser[i].user_nm, pstUser[i].user_phone); + + TFree(pstUser); + + return RC_SUCC; +} + +int main(int argc, char *argv[]) +{ + if(RC_SUCC != lGroupUserInfo()) + return RC_FAIL; + + return RC_SUCC; +} + + diff --git a/demo/insert b/demo/insert new file mode 100755 index 0000000000000000000000000000000000000000..cc5341805228efc61481a747d17d09049183867b GIT binary patch literal 15335 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 O$9d9E=fk^v^8WysD;5X< literal 0 HcmV?d00001 diff --git a/demo/insert.c b/demo/insert.c new file mode 100644 index 0000000..87de483 --- /dev/null +++ b/demo/insert.c @@ -0,0 +1,58 @@ +#include "tvm.h" +#include "tmain.h" + +#define TBL_USER_INFO 20 + +typedef struct __TBL_USER_INFO +{ + long acct_id; + char user_no[21]; + char user_type[2]; + char user_nm[81]; + char user_addr[161]; + char user_phone[31]; +}dbUser; + +long lInsertUserInfo() +{ + dbUser stUser; + SATvm *pstSavm = (SATvm *)pGetSATvm(); + + /* 初始化TBL_USER_INFO表,每张表都需要初始化一次, 对于表重建后,需要重新初始化一次。*/ + if(RC_SUCC != lInitSATvm(pstSavm, TBL_USER_INFO)) + { + fprintf(stderr, "init failed, err:(%d)(%s)\n", pstSavm->m_lErrno, sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; + } + + memset(&stUser, 0, sizeof(dbUser)); + stUser.acct_id = 10021; // 对结构体赋值 + strcpy(stUser.user_no, "20180223"); // 对结构体赋值 + strcpy(stUser.user_type, "1"); // 对结构体赋值 + strcpy(stUser.user_nm, "Savens Liu"); // 对结构体赋值 + strcpy(stUser.user_addr, "China"); // 对结构体赋值 + strcpy(stUser.user_phone, "18672911111"); // 对结构体赋值 + insertinit(pstSavm, stUser, TBL_USER_INFO); // 绑定变量 + + if(RC_SUCC != lInsert(pstSavm)) // 插入记录 + { + fprintf(stderr, "Insert error:(%d)(%s)\n", pstSavm->m_lErrno, sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; + } + + return RC_SUCC; +} + +int main(int argc, char *argv[]) +{ + + if(RC_SUCC != lInsertUserInfo()) + return RC_FAIL; + + fprintf(stdout, "新增记录成功, completed successfully!!!\n"); + fflush(stderr); + + return RC_SUCC; +} + + diff --git a/demo/makefile b/demo/makefile new file mode 100755 index 0000000..81a50a0 --- /dev/null +++ b/demo/makefile @@ -0,0 +1,57 @@ +INCDIR= -I/usr/include -I$(HOME)/include -I./ -I./include -I../include +LIBDIR= -L$(HOME)/lib -L../lib -lstvm -lm -lc -ldl -lpthread +CC=cc -fPIC +CO=-c -g +OUTLIB=../lib +OUTBIN=../bin + +OBJFILE=tree.o sem.o msg.o tcp.o str.o list.o conf.o +CREATE=create +INSERT=insert +SELECT=select +QUERY=query +DELETE=delete +UPDATE=update +COUNT=count +GROUP=group +EXTREME=extreme +TRUNCATE=truncate +DROP=drop +PRESSURE=press_demo + +all: $(CREATE) $(INSERT) $(SELECT) $(QUERY) $(DELETE) $(UPDATE) $(COUNT) $(GROUP) $(EXTREME) $(TRUNCATE) $(DROP) $(PRESSURE) clean +$(CREATE): create.o + $(CC) -o $@ $< $(LIBDIR) +$(INSERT): insert.o + $(CC) -o $@ $< $(LIBDIR) +$(SELECT): select.o + $(CC) -o $@ $< $(LIBDIR) +$(QUERY): query.o + $(CC) -o $@ $< $(LIBDIR) +$(DELETE): delete.o + $(CC) -o $@ $< $(LIBDIR) +$(UPDATE): update.o + $(CC) -o $@ $< $(LIBDIR) +$(COUNT): count.o + $(CC) -o $@ $< $(LIBDIR) +$(GROUP): group.o + $(CC) -o $@ $< $(LIBDIR) +$(EXTREME): extreme.o + $(CC) -o $@ $< $(LIBDIR) +$(TRUNCATE): truncate.o + $(CC) -o $@ $< $(LIBDIR) +$(DROP): drop.o + $(CC) -o $@ $< $(LIBDIR) +$(PRESSURE): press_demo.o + $(CC) -o $@ $< $(LIBDIR) + +.SUFFIXES: .c .o + +.c.o: + $(CC) $(CO) $*.c $(INCDIR) $(LIBDIR) + +fall: + @touch *c + @make all +clean: + rm -f *.o diff --git a/demo/press_demo b/demo/press_demo new file mode 100755 index 0000000000000000000000000000000000000000..90a132ad2737a86c4b58a4f69ff2ca037cf3e1bb GIT binary patch literal 16199 zcmeHOe{@_`oxg7;Gnu5xYtj@*f6-A=Y=Nd}C?)(*rp*r~khUQS2>yDVWF|l8WG2jy z(pFpwt=b_5TU?Kbr~z3ix+~QML_kOtD6Sl->#o$F6a`N!;8sOXcU8Kd&-dLsnVB|6 z&)IYKpWU0xyZ8I^e((2w@4fHc``*p%T^%0FQYLxSyA+{dAS5XFs#N$~0X42g1yo2a zQEyj%V0`$6gu>h{nS4sCHhDnvd6Ac~?9m8M$Svr6p$jRK8w;7UzUdUwMK`aqUC`uc zi6AIPTUCvK$TzwLo!_bL*lX<3as(;2RLd>Z{3bt0#YiSM?PJ^cTd4Id^n?Hr4lz@0 za-Gh_7r=GDnu)U9QtdLdREMNs^7CA@GP#kv3UbmuP5*0|v2#Uyq<{6Q74hiu_(&qV zW%-tt)yr3}YD^~^o5g-Mn@zlY{net<_+t(r);$+L_9f}F*Y5f3FK)Z-_^UsC;h5U> zE9b0d*LIUui=XlTu27K00C9ErF+KLnJ8o)i|M%B_bi=i#yIn%TwF_m|S(^3$5iCUl zp2RPRUuj~Ur_%G}4ET4p~w}7uvzdf;c&PJ4`(`zUae`g8)cQfD>;w_!oJc?5 z#7H_u?Xgr!r9tg$PoHCzysL9< ztJB=r+;{=~XeJytFTQ#}weo)tiBBn`RCfMI1!cV)O-RRUH%iVqz-SbN?ib?q)F|jc z0p3iBBrMhVa+I}d;cqIyn>mMsmI8d?yc{aP7tTxJ0zB(5sk;Dg<|fjvEx@C}`LwYB zUzx`$HC%w7Re&EWz%#~8+ERemQ?8J<7vN_bX5`@=uLq9Q!81qh<)s>J4)1t6@a+>9 z{7Yp}omlcbuCo`1P$E1`$)kr)AT9Y8VY>9_L4hA5%&s~*CGgh>bGkgbPv9>RrmK%m z3VbhNy7=gBf$t(r*B;$2@EwHd(xYPn-$t0OJi1ZfTM5&JN4o{yMwqTU8WK1~coyL% zz{n-7e4{h>{SSn5zXe42W~=kWCaA?+`XH=36J~ksR*j@ zho>^069>gLy9?9R;oPgeWZeGFdQ_;gS3X{kB^6?G0ETaQt%lJ4KY7DDUbDg%9ZEM0 z&R&d3FT7*Q3g>)pK=+Bc&j{1F?XNop0~n?b>w9>(`=p4z#~Q9$`H4;#((9gmdjj!sGbm z4jj3VFv?GI)g$5~L_pnoV#l|0waZPB@P3ipFX-JwhbI~ZtcyF!?qpm zuUNNy=#`syo~i!sw(z*?fr&-G7AN|=TEWBwJ<~O@W^vdph9|ZzGQ}PH1L28>#dWtl zTT8)QrXi2o@$6VQx2j=XZhvR)cwxWZ|7Tbt?K^PfT$J7LyX9#H8se03hoMlD`_P}m zx$H4F7LwWt<&QEPUh@f-QR=4OGr9}oI~Q*_)Rl`i91c$`Ur`oRT@y=|G6Vid7py$i zmAk0{R=uwQqw)2Yu4S*T$^E4>_s8)5zj!-yFCIDfPjvblnT0EV!g;GJ_g`JPKepxm zW6g=VKMn8rHpbv+#xo5|yT)&7Xu_~-F$U(xH~MDM zi@w=${6uEn( zg?uk^CXQ1kYg>=9w$xY)s>%bq5e5yw@uv4C=-9$0ud!=B;%Tk+_wDd{9S^vGLn2Qb ze$OL3SZ|(h$Yr7aD1L`QFZ3Ms^B(gM@Hyn_s*m|T;&<%Oj`ELtZud@{Et=ik%$&vpJAoxi1XI}j?WYN-x{%UfG9fn!%;S#VY3s>Tb0nB$w9&R=ut}baQ1bks1y^sNJb`M;%6xcyRo=4lG$3!l zHy@pj>@;Rp;I1-cp7LLiX8G?H$oC*JvCuoQj{4e3yb#fbg_SR``~}t>to$L%_p!XR z@(%LfPuV6ltHt-J?WnuzURJvIJ3v;k`+Sdojl~d)Pq4+x^9ZZ|CM_?Y1pFBkq+yFy z_3uGC088z?Q0bp9K$CrdYzqWvu^*teg#t_|o9nIrOo5(Lb{iQN3v^J~-(XcifetDA zE!y{XD+$GimCYsH-(Y0{9Z`0eI?oo{k12aO>pn-IH2G4$(Sp6l zVCyin%9cZcH&FIGWIR+^-q`_3&t0ga{0i#zEG70mjEb6@fen^#sfJADA8{$)Dsfi1 z2bPv^qe}vnSHjZr50a&(@>P~^V!0j`9E2hd*OT%ON%3toWIjXLb0HK27D~B(!~(C=S5ORP84y`Z4P=psIJ`5(?aDoeeAOyFm|p zT53@C4`}3F0tD<)ihM?Z8hezDy<32K+hKD*YmI|DsA|i|_c`lDXr1$8lqahL_gKF~ z!QMc=d#y7;Q8r^U@CDJ(Vt2Em`^4HQWxt*7_y>XDfm%Xe6h?R;MCg8@!2=6e*It1R zEBij${(wO6KqGa2N#rn+8p-)(p<(QtMb3W|2xI5nFeva(0%3e~5&DWi7$4&Q2L;0T z_%n^(XLUdv<6|wMuL^XZWlyq(uSrWWT7J(O{#j^yefBo$d`M{feD<@19u}SZD(o!f z9uYeqt+2PUeP0*aRE7N#Yk1UJ1%c-(>{)ElH(XCt*uA7ZCeWb@J4D*!*6*S0aE0B^ z8lJG0Av-+JUQM0fl>T{To}DA-lLGCWZ~vKgK4mdB_Rd%3i~;J9I4O5wZ@GpStJ)uv zeadPETXi4!ssgh;ZJ^s1Q>e!CAdFJ>4Xm)%(}8lConU=)1PG|wUs6GxXEtQ!{1}v- zR^W8cR%)oDhBJgu*)Nl=UI=BXoHgX|)3bf;XBbHHJl#N5-vK4vfp>UTVbQQ>QO8mb zhpw_Wv*KlL#r95m>l^{9>=y}~>){ZqvCpQ=c>>hi&rtJn0fP4TX+)#v8E`MP8%bFq zs+;U{*}x`YYq9sUo|OVjVE|Egv+zBKJ@l`V^L)=IVd|W(Lq$tpV72GdxGl7gvyU$H za0XTOc4}`C_XX_pNx4XXD%(%W#U6HLjoZFUM0vek#(FRH&@n;#1a+%*A!6qkIx9#7LB! zQ00t>rwsg-s+~<0-JTH8{s0Meb0OAbS>@arsC*}Eu>$T2FoE`16+{Or4-sE^5z31y zZI)+sqP)1W95z^0*P(n&Rh|XAtm+W}SUkiM3Wz0hU6?`wTP{pNfxBIpvI0-K@Kyt# zsXS@eY1!Y0$#bn9lbU#l3qbKXm$tvg%~v+tYX2m2B4B z??R7f&$a3d>rGnSEX%f0V(wwByK8W}TOVg_&8~dB{!0h}tCr{90;LsS z!!u(eMMsPrnOvFbtxXS=W7HEqaM|a z-uI~AF>b4Hp~g}%oR39gqshhrSiy6f$&lG(AIWD+NtPI}w=B%DNck&DDfh7!t24<}QZ{_G&x+xyT$<#cXvcy8#7 zWl}sz54Qdd5511l8+Llu_Vu*4Q&UGOIm)~*6^lvzj+00^H>O5#kePOF$i}jyNj^c)Z#Xy)w2{4LR}kBk>J`X{x(CHFotF3h4}RV8Jp-atbNz4b9$~`-`BZLe9#-~PNqd2+$(3T&OkQh z3?$>(QBl>JO^L&C?%W@z&bVt~-`Xyxb;J6$&OWE3s}1=6R`dsKX0M7P**$Qi%Jj$A zM@D0AQxl``2=@%YqZynVBb#DbdTea-8tfgbzBOyR+RgSe_z*;^SBX1PH^!3#n}9-t zS4pefd47NMy+<38;_VfczjORxd+Z*k$#tOa-FoH zyS-;kpEwB~?_~g^k=?1-jc!XgmXri$u&7e@^xz;5+gWisvN`7T^KiY;CnmUh-rdFa z^e2;XbaFg0lx|kesEh#jpdZRQqgxP8=*iv)&g)&o`s`@o#K4(ADCzD^>gremRPf2T zVgYqT;@bV>+sc@tx6!xaa2o11pW&qE3deP}3`2KJOm|dzc(jv!j+pL^T_p`=$B-AQ zIy%vPG*kiy_4P`92%JHQKt#^fz3n|t=lYHffsURz$S={NgD&lQo~I&O zqdR~klEHfo<~W%j&>LMN2}W6Zn_D5MoDMmSp#Rs$wjiY4^BOi%cHO{&H#IOfL{dWo zG6m3a!1krGh%D-I+tA+{85l+sCa8tzb?G7LEty3nLerU^Y@%-jLp2|{?(~v|lQ0#^ zuv_V7&Ct;=a|PqFBj#rDaZk+c08CKpx;lIN zNW=6O!<5h)=4`LlYLRrt9bWL>W~s^@2I3By2xm;sj_xo{a~*P{D%`%N&1q}zpnjQE zzALv0T#~sH&|xWr+6PS$HEA8%dibf@wm)?Hco+-el(7aKmt=?R<($OB!~nBf3!90UMbQkJjA*swF0!W!!gW0J{3s&OEb!~)zHb+hXSK!nc7=*R#n z#0?iOjiTGtgV(MglpG!9P-%?D`m;k$Bo#>vVH9X^EZYwS)9?uQ{tat?e=4@wKzKVc zX3FrIDMA64&a^oAe{xv>VZ=P|blv0$>D!UrVTacf|^})m@@MZ;KwsLWB+zv zh-kH48@yB?Jap>Z@R@uQ@I2!)usP@3s|A8uuGD^wR@+dZsYc$MD?X>?!rZ{9x-YD48sxM}gcoI!C%qEOzPBk$4&&Dc69N~V5;oJ4{0#{YL# zg#h7fM9WVKG<`AtGnl<76v~_Twat6n=NU$wm)8GCiTrSNNH~YF<-l~Go8_;i^-qDq z`Z)$9)oj#xQRV`;mdYOhu27zD*fG`ANOqFHOXa@@wnBNnUdI&F@}>Nx@DISt*faK< zb7=G4y?MXh#HW$h>eWvnTUft&ANF`H2uP*zYvfJ-GI$E*&3gegb3|NiakKo@$eH}t zCGxxUuGcOtZ|pP*jGTdwp+KBz|D9U?&c9Lq50It(P52ciBhTBn!bDyslk@#bxA=l#ERi>i4097Z2FLu@ z%UtLKe?^{TGxxa??seBHH$SfD@dkja@iXyj#ue^APg(!=OI`T`CCW?8ahYbgdKoRA z&`DG;EH?K!g+wnbG50UU__F-_M8$Yt{ym~%ykD97h+=#>?h8VNC@Fj46|?Ra61}QI znf1IFU#ZMGU5uZVUw@17Raj3$g(xX|RdxP*twN#~Z~U8euoyoZ>sqJ~C1o#Wd9!X6 z6215$#H>ffcnoem&lltCux@NDL`m6;w;;{BP)PLR?JP6j7voRQf7eiqKSP=Mxfoxs z%)DESpQp@xT8y7x2m*NNxgip!cxI@@5F#okJF!%{Ooqf$@n>Nly!>uUjTd%cP*vyd^YgV za#G^EUvtndex1Q&rrRqt-rP?M5tplg4;r8#->CV`A&I<`4Eop%{5ysJc!51jj z#ZS$Ee+2kiH9aqx`{QSTuQ`Pu{&faDFU^2|o%%hq)nrM(^X<1 zb79KK6=!mS*FZsb&J6eqfIrpuacgGa@6!Bx^>{H=Tr~s#;0$=aczCKfVSjRrm8OpY ze=0jaF@qj{CwnSAPY8dtGRMm1xo5xNPqD6HH$PtR37#5A;RG*>FB}H2q1D>Ap~vB- zC%?>d+KQknS_??gq%#yx_DAB5Y!5k+>=uQspRsr>6N@&kKL3JdMFPG6*g|NPa(9@b z+0jv)NV)a2uWyrTI(pWuYj+I9YD{^$7TJrET8fS@r;pB@%eywLUDM@k=;-Ke?{j4L zk!|3%7j~gik*)6eR3SpXK~zrLb?eux>ugor#nRsm;;Tp;8-zlIpAI?>PCW;lfpiup zYS=&1tR>$wmTs}1>ib4lzUVVdt=#=8lBZxLbz^Imr>Y5u+v8|ffvrWKZi-U#MJCwN zNoP2cz{#HJPUG5qTV!9*{R*_W&Vmm)3qPqW_^4Anip@EGBw8%1y-@I}sJo$G%%wlr U)SsIc)4-2!Rf}=%>7W?=-?|icWB>pF literal 0 HcmV?d00001 diff --git a/demo/press_demo.c b/demo/press_demo.c new file mode 100644 index 0000000..06c5249 --- /dev/null +++ b/demo/press_demo.c @@ -0,0 +1,59 @@ +#include "tvm.h" +#include "tmain.h" + +#define TBL_USER_INFO 20 + +typedef struct __TBL_USER_INFO +{ + long acct_id; + char user_no[21]; + char user_type[2]; + char user_nm[81]; + char user_addr[161]; + char user_phone[31]; +}dbUser; + +long lSelectUserInfo() +{ + dbUser stUser; + int i = 0; + SATvm *pstSavm = (SATvm *)pGetSATvm(); + + /* 初始化TBL_USER_INFO表,每张表都需要初始化一次, 对于表重建后,需要重新初始化一次。*/ + vHoldConnect(pstSavm); // 让进程始终与STVM 保持链接,可以大大提高效率 + if(RC_SUCC != lInitSATvm(pstSavm, TBL_USER_INFO)) + { + fprintf(stderr, "init failed, err:(%d)(%s)\n", pstSavm->m_lErrno, sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; + } + + conditinit(pstSavm, stUser, TBL_USER_INFO); // 绑定变量 + stringset(pstSavm, stUser, user_type, "1"); // 查询条件赋值 + stringset(pstSavm, stUser, user_no, "20180223"); // 查询条件赋值 + + for(i = 0; i < 2000000; i ++) + { + if(RC_SUCC != lSelect(pstSavm, (void *)&stUser)) + { + fprintf(stderr, "Select error: (%d) (%s)\n", pstSavm->m_lErrno, sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; + } + } + + fprintf(stdout, "acct_id:%ld, user_no:%s, user_type:%s, user_nm:%s, user_addr:%s, user_phone:%s\n", + stUser.acct_id, stUser.user_no, stUser.user_type, stUser.user_nm, stUser.user_addr, stUser.user_phone); + + vHoldRelease(pstSavm); // 在进程退出时,断开链接 + return RC_SUCC; +} + +int main(int argc, char *argv[]) +{ + + if(RC_SUCC != lSelectUserInfo()) + return RC_FAIL; + + return RC_SUCC; +} + + diff --git a/demo/query b/demo/query new file mode 100755 index 0000000000000000000000000000000000000000..0e502aa69b3de1e6160a6e20ddd8038dd588052b GIT binary patch literal 16208 zcmeHudvsjYdG9_mn$c)v9ZQz6sS5-|LSksr#JzdBxoNAUg(U}Q$PGai?kibq|q2+fv;1?B!KHTF&c zHLg(wR9LN7Z&Q9?eE16sg|*u<^{iHH>VW3+qAp?EqY<94+tBq|7gDA+9uK%BjPXay5v1G(Ew@4QoBA{rqnO(CkA36cTCH!b zCk%*in3Zal--TLY0bJ*cnHbwADqMyW6=7+Z`U)4VOl{fOF= zb0W4WF*K4L+ceg=ebe@Bb?IbXgZR&Gvx_%&>=l(J9?JmH_Hz7jEJ^?6`0EdJTrvOX zw;P&c=|`44*ctUdO`6d`{~id3s4hSpb+A0~umA1trk3x&@{f1iYKGe-5dS>zmFgGgW|r+kYoUA}P2#7E@IPJzuaH;i%z3Bws-Wbnx@8~%&Ocn7|N~MA5X-TD$ zDV1m&8Pdf5R6I_5G*-7=InKava>PkzqN$AIC}-CJrz<`%l+MIcO^Ika9Z!?F&oHyC znTMl8Bc#O=?gT({G&7irM`MKRl@pIeGf^1mO{ZNEphjZq#`dpN3da4}pz);u zIq^)X&%>KFgtW#yeEvEc&co-gGm$(zZJ5%Thc{~tX}9L#(cxU#mxmALuu2W);mh;z zqj`AdvMFPEc)b+}DRTIg!2EB}oPQ8unEyKZ7CHP};A`iuTvi@Z=hiRB@6vT)vW=PM@2>dg`4CUErfqzPvAv}9X z;2#lY=+2G`{67dYWM}sY{C9*Ise+g!PMs|etNE+I`1m^Hu@AmnN$A<%cq4~jwjx)bN!Ru-UDvD-%vmck;cEfYx#eFMrb*vb6uJ6L z>ZjlEU52JbbGN_nwf_G8x~1!mpbM0H*RfLAq20`~lY)Y8foDRn^TN5g7rr(_3ky9;agz40M$9{M29GfCE|6M?liI(}uWXt^1+?65|r{*6f66!jLojlZuVVamF zAuim{3VNF8$kfGU7&P?rXMqqZi2pMfUEP03?o+c2|Jg?|^b|W44$-(Y4;^QIXee?@ z)zeYosT5D7DYJms$Yfb@E1d|G7S&i!w~07+9HAwDwEStH=#+0YXggXwAJ8~vUl z3L+I>b` znD{pBwvck6K&~ZWqA-vzNr-%pU|fp=c|EyxAfxVR&cQo%c8x@AN-R(Aor_GIjyyZ( zjaa86)+~RYohyk`&1E)RdlNZoljkET>$q{F1XZf4)v6YR|M! z#A@dvQ=6XghE)61`jf1HpKqVY)V|g}ad+(-k%{-#Vs&|?v3=uKe^tvPyD)l;#bWRKi_d~`Hv%qzlJsC<4egV6*VbbhX*53O)+@~1diW7J{KmP=swa7Quh*rQ16b!Kv0lA#F8d3; z0=aA9{8C1Yy8!n_ByC<9!qr8nKRT3%$F2zB(&L&9>th=?tWR$Ysx7LaeoJG0L&H`j zS1TkZ^BJfn+SiwHhGN&OPe4AKj;EZFj~w;ijlVO%PoP#e z|B>&0zhj3Fm;SNmL*A(p&#ksLLF)f6|BoZUdCy|paG?d*;E_5~it9Uy@VusFF?>(B zU=IGehRrqGygw`$b1nM@E?Zds<9FwhtoM1s_+7Z?zqQ1Lc>%>T?Fq9|ydYxvFSkW11gv z7TCn;H4S%Zx)%SxUYX|_#fDduh6Q!GuD9#DRoA!Zx?k4^bbY_B|GTa~qw6p0+Su8k z6X3?CrfWhQ@HAm#Xj|R3x~oE1Ya8mfZrK{z&=rq`BGHVC-?XK1qdWw02hI)u@qp{( z9cFZmc3r;%wab45`Edj}9In_+u-@J*QY zJwjh=!qAAT*A@w zJ^4j8!)!jq9xKn+Y5ptpymSWe$I+0Ety2{qXguRzYFz~u`_lmYl@@(a_U-ubUu1m@ zRlwd05&sGSD(y$$k$_3Am{#62Ou>S@s{i_A2w@;C6jR1`{uk!tC z1(;PfbHjg$K+h|?nT+cMI<4%#rKylWXOwLddYhGmz?`zVv-)eTETDO1H&N&1;`?jL zzK%NIA<*l}-ot)fVciLVHvbpN`8?3t^e%P|FpuO$Z zB%lW@yPKRhSoeZu+Oj!B{)lx9&@s#AAo<$_nz8I&TG%Df3CnJ0P;L_Fam#*{obA>o z$epz8X8PG7e$HC<>!fvBM}d6KQcM4n#J{RM2>BZS6YO>H!{m69O%?neBlQ%!9|-<} zHfA|+mC7Huo`L}mbLk9F^k2rCSPrycA2HZ!Os$gZ&^d3Q

B)N66CF3Q5n$V54*w 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

    cAYDKvPgN6J1)~Azg|Ym6F!gX zg~#SPC!gqrC+7O45MPpe|ELh}%e{A0i1#aV9Z`rcRp$Dj5Fb!x-!H_MDYKs!;)A*O zj|%bSx&5~gkIl^Nt9b;ks>prcm4`+YY-RSrLi|$fYvFv9w7u9>&AydS^r|Xl_M<{P zCbwSa3-Q(1H}>VDr0vC9jAmcRCwkRI_#W#*{3~+bO%(F4%)RGTh_6v*-7UngQf56Z z#IMc=b8WBU)%f|voBMjLkmgl@oXSBmn1 z>p%&<>nRpk3xvflhl=9N<-tWhBNAYXf2eZXj;h6F+03~MC+4+Ki~h)0Z+TLOTuU^lxNYr zP~2Vs-on*`IomS+e^>D5=iymVd48OKy$IgjH_y-i6$oGmc8l}*QsDKLDjLlXUm9D6 zeuZ?u%yP>UAmYvSwBc_DK4gHr`u0We+&`CHU_HqSK2L#e{t56^YGIu**Snuyg#WLB zue?Bizq$xN_rogBQdL>Bj{R8h)rudv98|`YRB?3&pu+5&Syf zFZ4YfUnRPbp6!}{M$Ze^8>Oxl{)*h;u)Na^;;u#XIE&zifahE)F82U`AwQ2SqUWQF z==p;1S15C+Z0>KqDEJHPUwBfV$or5_^`&r#m&KO|eRy`&)U&6{;qy&?-{&+JK)agq zNU@|dkVy7M6OKFya-!KWg{M5DiFhU+tJ}Wy$_7OO-qar>v`x7WlVaK7VVpp@c3L`` z#Y}70j@>PefoR6G7p%x*C$VA}hT7Zs~F486(~2!!0~(N=3)r zqo{m@e8i}n=G!`U>~3pPd{(7DJaj*i42Sc-J#-wLdG!*U5r@yY5vq8+h(XSkwAF&|JaOWbPCA3p5ggW;5i`-t`7BTQ+^<9n z_2z%}d9!>Vn*RxA-j|>fz@mc=Jb>e;rG*-czbq}J>hC=D$Ek%h1OOki7UJCFKXLzm E1JZ)OQ~&?~ literal 0 HcmV?d00001 diff --git a/demo/query.c b/demo/query.c new file mode 100644 index 0000000..7e16fcb --- /dev/null +++ b/demo/query.c @@ -0,0 +1,59 @@ +#include "tvm.h" +#include "tmain.h" + +#define TBL_USER_INFO 20 + +typedef struct __TBL_USER_INFO +{ + long acct_id; + char user_no[21]; + char user_type[2]; + char user_nm[81]; + char user_addr[161]; + char user_phone[31]; +}dbUser; + +long lQueryUserInfo() +{ + size_t i, lRow = 0; + dbUser stUser, *pstUser = NULL; + SATvm *pstSavm = (SATvm *)pGetSATvm(); + + /* 初始化TBL_USER_INFO表,每张表都需要初始化一次, 对于表重建后,需要重新初始化一次。*/ + if(RC_SUCC != lInitSATvm(pstSavm, TBL_USER_INFO)) + { + fprintf(stderr, "init failed, err:(%d)(%s)\n", pstSavm->m_lErrno, sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; + } + + conditinit(pstSavm, stUser, TBL_USER_INFO); // 绑定变量 + stringset(pstSavm, stUser, user_type, "1"); // 查询条件赋值 + stringset(pstSavm, stUser, user_no, "20180223"); // 查询条件赋值 + + if(RC_SUCC != lQuery(pstSavm, &lRow, (void **)&pstUser)) + { + fprintf(stderr, "Query error:(%d)(%s)\n", pstSavm->m_lErrno, sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; + } + + for(i = 0; i < lRow; i ++) + { + fprintf(stdout, "acct_id:%ld, user_no:%s, user_type:%s, user_nm:%s, user_addr:%s, user_phone:%s\n", + pstUser[i].acct_id, pstUser[i].user_no, pstUser[i].user_type, pstUser[i].user_nm, pstUser[i].user_addr, + pstUser[i].user_phone); + } + TFree(pstUser); + + return RC_SUCC; +} + +int main(int argc, char *argv[]) +{ + + if(RC_SUCC != lQueryUserInfo()) + return RC_FAIL; + + return RC_SUCC; +} + + diff --git a/demo/select b/demo/select new file mode 100755 index 0000000000000000000000000000000000000000..f6757466ab40f24c1a25f56a4d3a169eff11eb0b GIT binary patch literal 15345 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 literal 0 HcmV?d00001 diff --git a/demo/select.c b/demo/select.c new file mode 100644 index 0000000..4f074c8 --- /dev/null +++ b/demo/select.c @@ -0,0 +1,53 @@ +#include "tvm.h" +#include "tmain.h" + +#define TBL_USER_INFO 20 + +typedef struct __TBL_USER_INFO +{ + long acct_id; + char user_no[21]; + char user_type[2]; + char user_nm[81]; + char user_addr[161]; + char user_phone[31]; +}dbUser; + +long lSelectUserInfo() +{ + dbUser stUser; + SATvm *pstSavm = (SATvm *)pGetSATvm(); + + /* 初始化TBL_USER_INFO表,每张表都需要初始化一次, 对于表重建后,需要重新初始化一次。*/ + if(RC_SUCC != lInitSATvm(pstSavm, TBL_USER_INFO)) + { + fprintf(stderr, "init failed, err:(%d)(%s)\n", pstSavm->m_lErrno, sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; + } + + conditinit(pstSavm, stUser, TBL_USER_INFO); // 绑定变量 + stringset(pstSavm, stUser, user_type, "1"); // 查询条件赋值 + stringset(pstSavm, stUser, user_no, "20180223"); // 查询条件赋值 + + if(RC_SUCC != lSelect(pstSavm, (void *)&stUser)) + { + fprintf(stderr, "Select error: (%d) (%s)\n", pstSavm->m_lErrno, sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; + } + + fprintf(stdout, "acct_id:%ld, user_no:%s, user_type:%s, user_nm:%s, user_addr:%s, user_phone:%s\n", + stUser.acct_id, stUser.user_no, stUser.user_type, stUser.user_nm, stUser.user_addr, stUser.user_phone); + + return RC_SUCC; +} + +int main(int argc, char *argv[]) +{ + + if(RC_SUCC != lSelectUserInfo()) + return RC_FAIL; + + return RC_SUCC; +} + + diff --git a/demo/truncate b/demo/truncate new file mode 100755 index 0000000000000000000000000000000000000000..86f2e2ba279d63341ddc269275d86b0dcdc9f9b1 GIT binary patch literal 14305 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 literal 0 HcmV?d00001 diff --git a/demo/truncate.c b/demo/truncate.c new file mode 100644 index 0000000..74a17a2 --- /dev/null +++ b/demo/truncate.c @@ -0,0 +1,47 @@ +#include "tvm.h" +#include "tmain.h" + +#define TBL_USER_INFO 20 + +typedef struct __TBL_USER_INFO +{ + long acct_id; + char user_no[21]; + char user_type[2]; + char user_nm[81]; + char user_addr[161]; + char user_phone[31]; +}dbUser; + +long lTruncateUserInfo() +{ + dbUser stUser; + SATvm *pstSavm = (SATvm *)pGetSATvm(); + + /* 初始化TBL_USER_INFO表,每张表都需要初始化一次, 对于表重建后,需要重新初始化一次。*/ + if(RC_SUCC != lInitSATvm(pstSavm, TBL_USER_INFO)) + { + fprintf(stderr, "init failed, err:(%d)(%s)\n", pstSavm->m_lErrno, sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; + } + + if(RC_SUCC != lTruncate(pstSavm, TBL_USER_INFO)) + { + fprintf(stderr, "Truncate error: (%d)(%s)\n", pstSavm->m_lEType, pstSavm->m_lErrno, + sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; + } + + return RC_SUCC; +} + +int main(int argc, char *argv[]) +{ + + if(RC_SUCC != lTruncateUserInfo()) + return RC_FAIL; + + return RC_SUCC; +} + + diff --git a/demo/update b/demo/update new file mode 100755 index 0000000000000000000000000000000000000000..2fd3380815025cebb7437214e1d22a4612e2aee3 GIT binary patch literal 15133 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, sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; + } + + updateinit(stUpd); + conditinit(pstSavm, stUser, TBL_USER_INFO); // 绑定变量 + stringset(pstSavm, stUser, user_type, "1"); // 查询条件赋值 + stringset(pstSavm, stUser, user_no, "20180224"); // 查询条件赋值 + + stringupd(pstSavm, stUpd, user_phone, "1869112XXXX"); + if(RC_SUCC != lUpdate(pstSavm, (void *)&stUpd)) + { + fprintf(stderr, "Update error: (%d) (%s)\n", pstSavm->m_lErrno, sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; + } + + return RC_SUCC; +} + +int main(int argc, char *argv[]) +{ + + if(RC_SUCC != lUpdateUserInfo()) + return RC_FAIL; + + return RC_SUCC; +} + + diff --git a/include/tmain.h b/include/tmain.h new file mode 100644 index 0000000..5057813 --- /dev/null +++ b/include/tmain.h @@ -0,0 +1,135 @@ +/* +* Copyright (c) 2018 Savens Liu +* +* The original has been patented, Open source is not equal to open rights. +* Anyone can clone, download, learn and discuss for free. Without the permission +* of the copyright owner or author, it shall not be merged, published, licensed or sold. +* The copyright owner or author has the right to pursue his responsibility. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _HHH_TVM_DOMAIN_HHH__ +#define _HHH_TVM_DOMAIN_HHH__ +#include "tvm.h" + + +typedef struct epoll_event epollevt; +typedef long (*FUNCEXEC)(SATvm *pstSavm, void *arg); + +/************************************************************************************************* + + *************************************************************************************************/ +#define SET_BLOCK 0 +#define SET_UNBLOCK 1 +#define READ_BUFFER 4096 +#define MAX_EVENTS 5000 +#define READ_MAX_LEN 1024 * 10 +#define DATA_MAX_LEN 1048576 // 1024*1024 Maximum self-protection single record 1M +#define MAX_CON_EVENTS 65535 +#define TVM_PORT_LISTEN 1801 +#define TVM_PORT_DOMAIN 1800 +#define TVM_LOCAL_SERV "LIS.tvm" +#define TVM_REMOTE_DOM "RDS.tvm" +#define LOCAL_HOST_IP "127.0.0.1" + + +/************************************************************************************************* + 表结构&索引定义区 + *************************************************************************************************/ +typedef struct __SOCK_CONNECT +{ + char m_szCltIp[16]; + int m_lCltPort; + BSock m_skSock; + int m_isListen; + BOOL m_bWork; + ulong m_uWorker; + CMList *m_pstWork; +}SKCon; + +typedef struct __TVM_INTERFACE +{ + Benum m_enum; + Uenum m_lFind; + TABLE m_table; + uint m_lDLen; + uint m_lErrno; + size_t m_lRows; +}TFace; + +/************************************************************************************************* + macro + *************************************************************************************************/ + +/************************************************************************************************* + function + *************************************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + +extern void lInitTitle(int argc, char **argv, char **envp); +extern void vSetTitile(const char *name); +extern void vDeleteRowgrp(Rowgrp *pstNode); +extern Rowgrp* pFindRowList(Rowgrp *root, long idx); +extern void vSortRowgrp(Rowgrp **pproot, TblKey *pstKey, Benum em); +extern long lCountRowgrp(Rowgrp *pstRoot, void *psvData, long lLen, size_t lCount); +extern long lSortRowList(SATvm *, size_t lRow, void *pvData, size_t lTruck); +extern long lConvRowList(SATvm *pstSavm, Rowgrp *root, size_t *plOut, void **ppsvOut); +extern long lParsRowList(SATvm *pstSavm, void *pszBuffer, long lData, Rowgrp **root); +extern Rowgrp* pInsertRowgrp(SATvm *, Rowgrp *, Rowgrp *, Rowgrp *, void *, long , size_t ); +extern bool bRepeatLstgrp(FdCond *pstRrp, void *pvData, TABLE t, size_t lOut, void *psvOut); +extern long lInsertLstgrp(SATvm *, FdCond *, void *, TABLE , size_t *, void **ppsvOut); + +extern bool bExistProcess(long lPid); +extern void vInitTitle(int argc, char **argv, char **envp); +extern long lBootLocal(SATvm *pstSavm, TBoot *pstBoot, Benum eMode); +extern long lBootDomain(SATvm *pstSavm, TBoot *pstBoot, long lMode); +extern long lMultListen(SATvm *pstSavm, long lPort, long , FUNCEXEC , void *arg, FUNCEXEC ); +extern long lOfflineNotify(SATvm *pstSavm, long lPort); +extern long lRefreshNotify(SATvm *pstSavm, long lPort); +extern long lPullNotify(SATvm *pstSavm, TDomain *pstDom, size_t lCount); +extern long lConnectNotify(SATvm *pstSavm, TDomain *pstDom, long lPort); +extern long lTvmGetTblIndex(SATvm *pstSavm, char *pszTable, char *pszPart, TIndex *pstIndex); +extern long lTvmGetTblField(SATvm *pstSavm, TABLE t, size_t *plOut, TField **ppstField); + + + +extern long lTvmBeginWork(SATvm *pstSavm); +extern long lTvmRollbackWork(SATvm *pstSavm); +extern long lTvmCommitWork(SATvm *pstSavm); +extern long lTvmEndWork(SATvm *pstSavm); +extern void vTvmDisconnect(SATvm *pstSavm); +extern long lTvmConnect(SATvm *pstSavm, char *pszIp, long lPort, int times); +extern long lTvmTruncate(SATvm *pstSavm, TABLE t); +extern long lTvmGroup(SATvm *pstSavm, size_t *plOut, void **ppvOut); +extern long lTvmCount(SATvm *pstSavm, size_t *plCount); +extern long lTvmInsert(SATvm *pstSavm); +extern long lTvmSelect(SATvm *pstSavm, void *pvOut); +extern long lTvmQuery(SATvm *pstSavm, size_t *plOut, void **ppvOut); +extern long lTvmUpdate(SATvm *pstSavm, void *pvData); +extern long lTvmDelete(SATvm *pstSavm); +extern long lTvmExtreme(SATvm *pstSavm, void *pvOut); +extern long lTvmDropTable(SATvm *pstSavm, TABLE t); +extern long lTvmRenameTable(SATvm *pstSavm, TABLE to, TABLE tn); +extern long lTvmSelectSeque(SATvm *pstSavm, char *pszSQName, ulong *pulNumber); +extern long lTvmSetSequence(SATvm *pstSavm, char *pszSQName, ulong uStart); +extern long lTvmRebuildIndex(SATvm *pstSavm, TABLE t); +extern long lTvmResetLock(SATvm *pstSavm, TABLE t); + +#ifdef __cplusplus +} +#endif + +#endif // _HHH_TVM_DOMAIN_HHH__ diff --git a/include/tstr.h b/include/tstr.h new file mode 100644 index 0000000..fe0f108 --- /dev/null +++ b/include/tstr.h @@ -0,0 +1,174 @@ +/* +* Copyright (c) 2018 Savens Liu +* +* The original has been patented, Open source is not equal to open rights. +* Anyone can clone, download, learn and discuss for free. Without the permission +* of the copyright owner or author, it shall not be merged, published, licensed or sold. +* The copyright owner or author has the right to pursue his responsibility. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _HHH_TVM_BASE_STR_HHH__ +#define _HHH_TVM_BASE_STR_HHH__ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef short int sint; +typedef unsigned int uint; +typedef unsigned long ulong; +typedef long long llong; +typedef unsigned char ushar; +typedef unsigned short ushort; +typedef unsigned char Byte; +typedef long int Benum; +typedef unsigned int Uenum; +typedef int BSock; + +#ifndef BOOL +typedef unsigned int BOOL; +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef __cplusplus +#ifndef bool +typedef unsigned char bool; +#endif + +#ifndef true +#define true 1 +#endif + +#ifndef false +#define false 0 +#endif + +#endif // __cplusplus + + +#define RC_NOTFOUND 24 +#define RC_MATCH 2 +#define RC_MISMA 1 +#define RC_SUCC 0 +#define RC_FAIL -1 +#define RC_CONTU -5 +#define RC_CLOSE -9 + +#define LOG_DEFU_SIZE 20480000 +#define LOG_DEFU_NAME "tvm.log" + +typedef pthread_mutex_t pmutex; +/************************************************************************************************* + function + *************************************************************************************************/ +typedef struct __COMLIST +{ + long m_lSize; + void *m_psvData; + struct __COMLIST *pstNext; + struct __COMLIST *pstLast; +}CMList; + +typedef struct __ROWGROUP +{ + long lIdx; + long lLen; + size_t lCount; + pmutex lock; + void *psvData; + struct __ROWGROUP *pstSSet; + struct __ROWGROUP *pstFset; + struct __ROWGROUP *pstNext; + struct __ROWGROUP *pstLast; +}Rowgrp; + +#ifdef __cplusplus +extern "C" { +#endif + +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#define MIN(a, b) ((a) > (b) ? (b) : (a)) +#define bool(x) (x == 0 ? false : true) +#define BOOL(x) (x == 0 ? false : true) + +extern CMList* pGetCMTail(CMList *pstRoot); +extern CMList* pSearchNode(CMList *pstRoot, void *psvData, long lSize); +extern CMList* pInsertList(CMList *pstRoot, void *pszData, long lSize); +extern CMList* pDeleteNode(CMList *pstRoot, void *psvData, long lSize); +extern void vDestroyList(CMList *pstRoot); + +extern char* supper(char *s); +extern char* slower(char *s); +extern char* strimcrlf(char *p); +extern char* sltrim(char *p); +extern char* srtrim(char *p); +extern char* strimall(char *p); +extern char* strimfield(char *s); +extern char* strimcpy(char *d, char *s, int l); +extern char* strimabout(char *s, char *o, char *d); +extern long lfieldnum(char *p, char *k); +extern char* sfieldvalue(char *p, char *k, int id); +extern long lgetstrnum(char *p, char *s); +extern char* sgetvalue(char *p, char *s, int id); +extern char* sfieldreplace(char *p, char o, char d); + +#ifdef __cplusplus +} +#endif + +#endif // _HHH_TVM_BASE_STR_HHH__ diff --git a/include/tvm.h b/include/tvm.h new file mode 100644 index 0000000..a6d83ba --- /dev/null +++ b/include/tvm.h @@ -0,0 +1,747 @@ +/* +* Copyright (c) 2018 Savens Liu +* +* The original has been patented, Open source is not equal to open rights. +* Anyone can clone, download, learn and discuss for free. Without the permission +* of the copyright owner or author, it shall not be merged, published, licensed or sold. +* The copyright owner or author has the right to pursue his responsibility. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef __TVM_DEFIND_HHHH___ +#define __TVM_DEFIND_HHHH___ +#include "tstr.h" + +typedef pthread_rwlock_t RWLock; +typedef pthread_rwlockattr_t RWAttr; +typedef unsigned int TABLE; +typedef long long llSEQ; +typedef long (*TCREATE)(TABLE t); +typedef long CREATE; + +//#pragma pack(4) + +#define TVM_VKERNEL "1.2.0.0" +#define TVM_VERSION "1.2.2.0" +/************************************************************************************************* + custom macro + *************************************************************************************************/ +#define PROT_JAVA 512 +#define FIRST_ROW 256 +#define ORDER_DESC 128 +#define ORDER_ASC 64 +#define ORDER_BY 64 +#define GROUP_BY 32 +#define MATCH_MAX 16 +#define MATCH_MIN 8 + +#define FIELD_DOUB 4 +#define FIELD_LONG 2 +#define FIELD_CHAR 1 + +// execution plan +#define EXE_PLAN_ALL 0 +#define EXE_PLAN_IDX 1 +#define EXE_PLAN_GRP 2 + +#define CHK_SELECT 0 +#define IDX_SELECT 1 +#define RCD_SELECT 2 +#define NIL_IGNORE 8 + +#define OPERATE_NULL 0 +#define OPERATE_INSERT 1 +#define OPERATE_DELETE 2 +#define OPERATE_UPDATE 4 +#define OPERATE_SELECT 8 +#define OPERATE_TRCATE 14 +#define OPERATE_COUNT 15 +#define OPERATE_GROUP 16 +#define OPERATE_QUERY 17 +#define OPERATE_EXTREM 18 +#define OPERATE_TBDROP 19 +#define OPERATE_RENAME 20 +#define OPERATE_SELSEQ 21 +#define OPERATE_SETSEQ 22 +#define OPERATE_RBDIDX 23 +#define OPERATE_RETLOK 24 +#define OPERATE_DMKEEP 25 +#define OPERATE_DOMPUL 26 +#define OPERATE_DOMPSH 27 +#define OPERATE_DMRECN 28 +#define OPERATE_REFRESH 29 +#define OPERATE_DOMLOFF 30 +#define OPERATE_DOMROFF 31 +#define OPERATE_PULTBL 32 +#define OPERATE_BEGWORK 33 +#define OPERATE_ROLWORK 34 +#define OPERATE_CMTWORK 35 +#define OPERATE_ENDWORK 36 +#define OPERATE_EXEEXIT 99 + +#define OPERATE_DEFAULT (OPERATE_SELECT | OPERATE_UPDATE | OPERATE_DELETE | OPERATE_INSERT) +/************************************************************************************************* + Internal definition + *************************************************************************************************/ +#define SYS_TVM_INDEX 0x01 +#define SYS_TVM_FIELD 0x02 // field table +#define SYS_TVM_DOMAIN 0x03 // domain table +#define SYS_TVM_SEQUE 0x04 +#define TVM_MAX_TABLE 0xFF // maximum number of creation of the system + +#define MAX_STRIG_LEN 256 + +#ifndef MAX_INDEX_LEN +#define MAX_INDEX_LEN 64 +#endif + +#define MAX_FIELD_LEN 32 // maxinum length of Field name + +#ifndef MAX_FILED_NUM +#define MAX_FILED_NUM 32 // maximum number of fields in a table +#endif + +#define MAX_REMOTE_IP 20 +#define MAX_TIMESTAMP 20 +#define MAX_FILED_IDX 8 + +// resource flag +#define RES_LOCAL_SID 1 +#define RES_REMOT_SID 2 +#define RESOURCE_ROFF 5 +#define RESOURCE_AUTH 4 +#define RESOURCE_EXCP 3 +#define RESOURCE_ABLE 2 +#define RESOURCE_STOP 1 +#define RESOURCE_INIT 0 + +#define IPC_MSG 0x01 +#define IPC_SEM 0x02 +#define IPC_SHM 0x03 + +#define SEM_INIT 1 +#define SEM_O_V 1 // Semaphore V operation +#define SEM_O_P -1 // Semaphore P operation +#define SEM_RD 0 +#define SEM_WD 1 + +#define UNQIUE 1 +#define NORMAL 16 +#define HASHID 32 + +#define TYPE_SYSTEM 0x01 +#define TYPE_INCORE 0x02 +#define TYPE_CLIENT 0x03 // custom +#define TYPE_KEYVAL 0x04 +#define TVM_NODE_INFO "localhost" +#define TVM_RUNCFG_TAG "\x01\x33\xC8\x48" + +#define TVM_BOOT_CLUSTER 2 +#define TVM_BOOT_LOCAL 1 +#define TVM_BOOT_SIMPLE 0 + + +#define HAVE_INDEX(t) (((TblDef *)pGetTblDef(t))->m_lIType != 0) +#define HAVE_UNIQ_IDX(t) (((TblDef *)pGetTblDef(t))->m_lIType & UNQIUE) +#define HAVE_NORL_IDX(t) (((TblDef *)pGetTblDef(t))->m_lIType & NORMAL) +#define HAVE_HASH_IDX(t) (((TblDef *)pGetTblDef(t))->m_lIType & HASHID) + +#define IS_RED(x) (x->m_eColor == COLOR_RED) +#define FPOS(t, f) ((size_t)&((t *)0)->f) +#define FLEN(t, f) (sizeof(((t *)0)->f)) +#define NODE_NULL g_lNilOfs +#define ReField(t, f) (FPOS(t, f) << 16 | FLEN(t, f)) +#define REFrom(t) (t >> 16) +#define REFLen(t) (t & 0xffff) + +#define WORK_ERROR_LOG "work.err" +#define STVM_SQL_LINE ".stvmrc" +#define COLOR_BLK 0 +#define COLOR_RED 1 +#define SELF_POS_UNUSE 0 +#define DATA_TRUCK_NULL 0x00 +#define DATA_TRUCK_NRML 0x01 +#define DATA_TRUCK_LOCK 0x02 +#define TABLE_LOCK_READ 1 +#define TABLE_LOCK_WRITE 2 +#define IS_TRUCK_NULL(p) ((p)->m_chTag == DATA_TRUCK_NULL) +#define IS_TRUCK_NRML(p) ((p)->m_chTag == DATA_TRUCK_NRML) +#define IS_TRUCK_LOCK(p) ((p)->m_chTag == DATA_TRUCK_LOCK) +#define SET_DATA_TRUCK(p, type) ((p)->m_chTag = type) +#define TFree(p) if(p) { free(p); p = NULL; } +#define TFgrp(p) do{vDeleteRowgrp(p);p = NULL;}while(0); +#define TFlst(p) do{vDestroyList(p);p = NULL;}while(0); +#define TClose(f) if(f) { fclose(f); f = NULL; } + +/************************************************************************************************* + 错误码定义区 + *************************************************************************************************/ +#define TVM_DONE_SUCC 0 // completed successfully +#define SVR_EXCEPTION 1 // sever exception +#define IDX_FIELD_NIL 2 // index field values is null +#define CONDIT_IS_NIL 3 // condition is null +#define DATA_SPC_FULL 4 // no space for create data +#define GENER_KEY_ERR 5 // generate shm key failure +#define SHM_ERR_INVAL 6 // Invalid parameter or shm has disappeared +#define SHM_ERR_EXIST 7 // shared memory already exists +#define SHM_ERR_EIDRM 8 // shared memory has been deleted +#define SHM_ERR_ACCES 9 // Permission denied +#define SHM_ERR_NOMEM 10 // Insufficient(shm) core memory +#define VER_NOT_MATCH 11 // data truck version mismatch +#define BLCK_SIZE_ERR 12 // size is error to creat data block +#define IDX_DEF_SPILL 13 // unique Index definition overflow +#define IDX_LEN_SPILL 14 // unique Index length overflow +#define GRP_DEF_SPILL 15 // normal Index definition overflow +#define GRP_LEN_SPILL 16 // normal Index length overflow +#define IDX_TYP_NODEF 17 // index type not define +#define FLD_DEF_SPILL 18 // field define overflow +#define IDX_DATA_MISM 19 // index data mismatch +#define FTYPE_NOT_DEF 20 // field type not define +#define SHMT_NOT_INIT 21 // memory has not been initialized +#define UNIQ_IDX_REPT 22 // unique index repeat +#define IDX_SPC_SPILL 23 // no space for create index +#define NO_DATA_FOUND 24 // no data be found +#define MORE_ROWS_SEL 25 // more then one records be selected +#define MALLC_MEM_ERR 26 // malloc memory error +#define CURS_IS_INVAL 27 // cursor invalid +#define TABLE_NOT_DEF 28 // table not define +#define FIL_NOT_EXIST 29 // file not exist +#define SEM_CDIT_NULL 30 // semget condition is null +#define SEM_ERR_INVAL 31 // Invalid parameter or sem has disappeared +#define SEM_ERR_EXIST 32 // semaphore already exists +#define SEM_ERR_EIDRM 33 // semaphore has been deleted +#define SEM_ERR_ACCES 34 // Permission denied(sem) +#define SEM_ERR_NOMEM 35 // Insufficient(sem) core memory +#define SEM_ERR_LIMIT 36 // Semaphore value out of limit +#define SQL_SYNTX_ERR 37 // SQL syntax is error +#define SQL_NOT_SUPPT 38 // SQL operation not be supported +#define SQL_TABLE_NIL 39 // SQL no table name be inputted +#define SQL_FIELD_NIL 40 // SQL field is not selected +#define SQL_WHERE_NIL 41 // SQL conditional syntax error +#define SQL_ERR_FIELD 42 // SQL field syntax error +#define SQL_ERR_WHERE 43 // SQL where syntax error +#define TBL_NOT_FOUND 44 // table not found +#define SQL_FAV_MATCH 45 // SQL fields does not match the value +#define LOCK_DORD_ERR 46 // set the read lock failure +#define LOCK_UNRD_ERR 47 // unlock read lock failure +#define LOCK_DOWR_ERR 48 // set the write lock failure +#define LOCK_UNWR_ERR 49 // unlock write lock failure +#define SOCK_CONN_ERR 50 // socket connect failure +#define SOCK_CONN_TMO 51 // socket connect timeout +#define SOCK_ERR_CRTE 52 // create socket failure +#define SOCK_READ_ERR 53 // socket recv failure +#define SOCK_SEND_ERR 54 // socket send failure +#define SOCK_BIND_ERR 55 // socket bind failure +#define SOCK_LSEN_ERR 56 // socket listen failure +#define SOCK_SEND_TMO 57 // socket send timeout +#define SOCK_READ_TMO 58 // socket read timeout +#define SOCK_IO_RESET 59 // socket reset +#define SOCK_COM_EXCP 60 // Socket communication anomaly +#define EPOLL_ADD_ERR 61 // epoll add fd error +#define EPOLL_CRT_ERR 62 // create epoll fd failure +#define EPOLL_DEL_ERR 63 // delete epoll fd failure +#define SOCK_ACPT_ERR 64 // socket accept failure +#define RMT_NOT_SUPPT 65 // SQL remote does not support +#define FILE_NOTFOUND 66 // file not found +#define BOOT_PARM_ERR 67 // boot parameters error +#define BOOT_RELA_ERR 68 // parameters table related error +#define BOOT_VER_ICMP 69 // Incompatible version +#define DOM_NOT_REGST 70 // domain not register +#define DMWORK_NOTSUP 71 // domain work does not support +#define SEQ_NOT_FOUND 72 // sequence does not exist +#define FILE_NOT_RSET 73 // file is not set +#define RECD_TOO_LONG 74 // record data too long +#define RESOU_DISABLE 75 // Resource unavailable +#define MSG_ERR_EXIST 76 // message queue already exists +#define MSG_ERR_ACCES 77 // Permission denied .msg +#define MSG_ERR_NOMEM 78 // Insufficient(msg) core memory +#define MSG_ERR_INVAL 79 // Invalid parameter or msg has disappeared +#define MSG_ERR_FAULT 80 // msg Invalid address +#define MSG_ERR_EIDRM 81 // message queue has been deleted +#define MSG_ERR_E2BIG 82 // message text length is greater than msgsz +#define MSG_ERR_EINTR 83 // Interrupted by signal +#define MSG_ERR_SNDEG 84 // msgsnd queue overrun +#define INI_ERR_CHLDP 85 // initial child process failed +#define FLD_NOT_EXIST 86 // field not exist +#define TBL_ARD_EXIST 87 // table already exist +#define WORK_NOT_OPEN 88 // The transaction has not been opened yet +#define WORK_NOT_REGT 89 // The transaction has not been register +#define DOM_NOT_INITL 90 // domain not initail +#define FIELD_NOT_DEF 91 // table field not define +#define FIELD_NOT_SET 92 // field not set +#define UPDFD_NOT_SET 93 // update field not set +#define EXTRE_SET_ERR 94 // extreme set decorate error +#define GROUP_SET_ERR 95 // group set decorate error + +/************************************************************************************************* + 创建表宏函数 + *************************************************************************************************/ +#define DEFINE(t, n, p, s) TABLE tbl = t; long type = 0; \ + ((TblDef *)pGetTblDef(t))->m_table = t; \ + ((TblDef *)pGetTblDef(t))->m_lReSize = sizeof(s); \ + strncpy(((TblDef *)pGetTblDef(t))->m_szPart, p, MAX_FIELD_LEN); \ + strncpy(((TblDef *)pGetTblDef(t))->m_szTable, n, MAX_FIELD_LEN); \ + ((TblDef *)pGetTblDef(t))->m_lTruck = sizeof(s) + sizeof(SHTruck); + +#define CREATE_IDX(t) type = t; +#define IDX_FIELD(t, f, a) if(RC_SUCC != lAddIdxField(tbl, type, FPOS(t, f), FLEN(t, f), a)) \ + return RC_FAIL; +#define FIELD(t, f, d, a) if(RC_SUCC != lSetTableIdx(tbl, FPOS(t, f), FLEN(t, f), d, a, CHK_SELECT)) \ + return RC_FAIL; +#define FIELU(t, f, d, a) if(RC_SUCC != lSetTableIdx(tbl, FPOS(t, f), FLEN(t, f), d, a, IDX_SELECT)) \ + return RC_FAIL; +#define FIELR(t, f, d, a) if(RC_SUCC != lSetTableIdx(tbl, FPOS(t, f), FLEN(t, f), d, a, RCD_SELECT)) \ + return RC_FAIL; +#define FINISH return RC_SUCC; + +/************************************************************************************************* + Field assignment + *************************************************************************************************/ +#define defineinit(p,s,t) do{ \ + p->stCond.uFldcmp = 0; \ + p->stUpdt.uFldcmp = 0; \ + p->lSize = sizeof(s); \ + p->tblName = t; \ + p->pstVoid = (void *)&(s); \ + }while(0); + +#define insertinit(p,s,t) do{ \ + p->lSize = sizeof(s); \ + p->tblName = t; \ + p->pstVoid = (void *)&(s); \ + }while(0); + +#define conditinit(p,s,t) do{ \ + p->stCond.uFldcmp = 0; \ + p->stUpdt.uFldcmp = 0; \ + p->lSize = sizeof(s); \ + p->tblName = t; \ + p->lFind = 0; \ + memset(&(s), 0, p->lSize); \ + p->pstVoid = (void *)&(s); \ + }while(0); + +#define conditnull(p,d,t) do{ \ + p->stCond.uFldcmp = 0; \ + p->stUpdt.uFldcmp = 0; \ + p->lFind = 0; \ + p->lSize = sizeof(d); \ + p->tblName = t; \ + p->pstVoid = NULL; \ + }while(0); + +#define stringsetv(p,s,f,...) vSetCodField(&p->stCond, sizeof((s).f), (void *)(s).f - (void *)&(s)); \ + snprintf((s).f, sizeof((s).f), __VA_ARGS__); + +#define stringset(p,s,f,v) vSetCodField(&p->stCond, sizeof((s).f), (void *)(s).f - (void *)&(s)); \ + strncpy((s).f, v, sizeof((s).f)); + +#define stringcpy(p,s,f,v) vSetCodField(&p->stCond, sizeof((s).f), (void *)(s).f - (void *)&(s)); \ + memcpy(&(s) + ((void *)(s).f - (void *)&(s)), (void *)v, sizeof((s).f)); + +#define numberset(p,s,f,v) vSetCodField(&p->stCond, sizeof((s).f), (void *)&(s).f - (void *)&(s)); \ + (s).f = v; + +#define decorate(p,d,f,v) vSetDecorate(&p->stUpdt, FLEN(d, f), FPOS(d, f), v); \ + p->lFind = (v) & FIRST_ROW; + +#define stringreset(s,f,v) strncpy((s).f, v, sizeof((s).f)); +#define stringresetv(s,f,...) snprintf((s).f, sizeof((s).f), __VA_ARGS__); +#define stringrecpy(s,f,v) memcpy((s).f, v, sizeof((s).f)); +#define numberreset(s,f,v) (s).f = v; + +// UPDATE Field assignment +#define updateinit(s) memset(&(s), 0, sizeof(s)); + +#define stringupd(p,s,f,v) vSetCodField(&p->stUpdt, sizeof((s).f), (void *)(s).f - (void *)&(s)); \ + strncpy((s).f, v, sizeof((s).f)); + +#define stringupy(p,s,f,v) vSetCodField(&p->stUpdt, sizeof((s).f), (void *)(s).f - (void *)&(s)); \ + memcpy(&(s) + ((void *)(s).f - (void *)&(s)), (void *)v, sizeof((s).f)); + +#define numberupd(p,s,f,v) vSetCodField(&p->stUpdt, sizeof((s).f), (void *)&(s).f - (void *)&(s)); \ + (s).f = v; + +/************************************************************************************************* + Table structure & index definition area + *************************************************************************************************/ +typedef struct __SH_DATA_TRUCK +{ + ulong m_lTimes; + char m_chTag; + char m_pvData[0]; +}SHTruck, *PSHTruck; + +typedef struct __SH_RBTREE +{ + size_t m_lSePos; + char m_szIdx[MAX_INDEX_LEN]; + long m_lIdx; + size_t m_lData; + long m_eColor; + size_t m_lParent; + size_t m_lLeft; + size_t m_lRight; +}SHTree; + +typedef struct __SH_LIST +{ + size_t m_lPos; + size_t m_lNode; + size_t m_lData; + size_t m_lNext; + size_t m_lLast; +}SHList; + +typedef struct __TBL_COM_KEY +{ + long m_lFrom; + long m_lLen; + long m_lAttr; + long m_lIsPk; + char m_szField[MAX_FIELD_LEN]; +}TblKey; + +typedef struct __TBL_HEAD_DEF +{ + RWLock m_rwlock; // rwlock + long m_lGroup; // index group + size_t m_lMaxRow; // maximum support + size_t m_lValid; // number of valid + long m_lIdxLen; // unique index length + size_t m_lNodeNil; // NIL + size_t m_lTreePos; // unique tree position + size_t m_lTreeRoot; // unique tree root + long m_lGrpLen; // index length + size_t m_lGroupPos; // index position + size_t m_lGroupRoot; // index root + size_t m_lListPos; // list position + size_t m_lListOfs; // list offset + size_t m_lData; // data offset + uint m_lIType; // index type + uint m_lIdxUp; // unique index field + TblKey m_stIdxUp[MAX_FILED_IDX]; // unique index + uint m_lGrpUp; // index field + TblKey m_stGrpUp[MAX_FILED_IDX]; // index + size_t m_lTable; // table size + long m_lReSize; // row size + size_t m_lTruck; // truck size + llSEQ m_lExSeQ; // extern sequence + long m_lExtern; // extern table space(standby) + long m_lIdxNum; // Number of fields + TblKey m_stKey[MAX_FILED_NUM]; // fields + TABLE m_table; // table + char m_szTable[MAX_FIELD_LEN]; // table name + char m_szPart[MAX_FIELD_LEN]; // + SHTree m_stNil; +}TblDef; + +static long g_lNilOfs = FPOS(TblDef, m_stNil); + +typedef struct __SQL_FIELD +{ + TblKey m_stKey; + struct __SQL_FIELD *pstNext; +}SQLFld; + +/************************************************************************************************* + TVM engine starts the required table (do not move) + *************************************************************************************************/ +typedef struct __SYS_TVM_INDEX +{ + TABLE m_table; // table + long m_lType; // table type + char m_szTable[MAX_FIELD_LEN]; // table name + char m_szPart[MAX_FIELD_LEN]; // partition name + char m_szOwner[MAX_FIELD_LEN]; // owner + key_t m_yKey; + long m_shmID; // Memory Key + long m_semID; // semaphore key + long m_lPid; // pid + long m_lValid; // valid + long m_lMaxRows; // Table maximum support record number. + long m_lRowSize; // truck size + long m_lLocal; // Local/remote + uint m_lState; // available + long m_lPers; // permissions + char m_szTime[MAX_TIMESTAMP]; // create time +}TIndex; + +typedef struct __SYS_TVM_FIELD +{ + TABLE m_table; // table + long m_lSeq; // filed seq + char m_szOwner[MAX_FIELD_LEN]; // owner + char m_szTable[MAX_FIELD_LEN]; // table name + char m_szField[MAX_FIELD_LEN]; // field name + long m_lAttr; // attr + long m_lFrom; // field from + long m_lLen; // field length + long m_lIsPk; +}TField; + +typedef struct __SYS_TVM_DOMAIN +{ + BSock m_skSock; + TABLE m_table; + TABLE m_mtable; + long m_lLock; + long m_lGroup; + long m_lKeepLive; + long m_lLastTime; + long m_lTimeOut; + long m_lTryMax; + long m_lTryTimes; + long m_lRowSize; + long m_lStatus; // remote domain state + long m_lPers; // perms + long m_lPort; + long m_lRelia; + char m_szIp[MAX_REMOTE_IP]; + char m_szTable[MAX_FIELD_LEN]; + char m_szPart[MAX_FIELD_LEN]; + char m_szOwner[MAX_FIELD_LEN]; +}TDomain; + +typedef struct __SYS_TVM_SEQUE +{ + char m_szSQName[MAX_INDEX_LEN]; // Name of sequence + uint m_uIncrement; +}TSeque; + +/************************************************************************************************* + Operating handle + *************************************************************************************************/ +typedef struct __TBL_FILED_KEY +{ + Uenum uDecorate; + uint uFldpos; + uint uFldlen; +}FdKey; + +typedef struct __TBL_CONDIT_FLD +{ + uint uFldcmp; + FdKey stFdKey[MAX_FILED_NUM]; +}FdCond; + +typedef struct __TVM_WORK +{ + TABLE m_table; + long m_lRowSize; + long m_lOperate; + FdCond m_stCond; + FdCond m_stUpdt; + void *m_pvData; + void *m_pvNew; +}TWork; + +typedef struct __TVM_RUNTIME +{ + void *pstVoid; + uint m_lState; + uint m_lLocal; + long m_shmID; // Memory Key + long m_semID; // semaphore key + long m_lRowSize; // Record block size + bool m_bAttch; // Does it initialize + void *m_pvAddr; + long m_lCurLine; // cursor line + long m_lCurType; // cursor type + void *m_pvCurAddr; // cursor address +}RunTime; + +typedef struct __TVM_OPERATE +{ + size_t lSize; // struck size + Uenum lFind; // find type + Uenum bSearch; // find table type + TABLE tblName; // table + void *pstVoid; // condition + FdCond stCond; + FdCond stUpdt; + + bool m_bWork; // work + bool m_bPrew; // work on or off + bool m_bHold; // memory hold + bool m_bCreat; + CMList *m_pstWork; // work list + uint m_lTimes; + BSock m_skSock; + Uenum m_lEType; + key_t m_yKey; + key_t m_ySey; + key_t m_yMey; + Uenum m_lErrno; + size_t m_lEffect; // effect record line + bool m_bCache; + char m_szMsg[256]; // Custom message + char m_szNode[MAX_FIELD_LEN]; + RunTime stRunTime[TVM_MAX_TABLE]; // table handle +}SATvm; + +typedef struct __TVM_BOOT_PARAM +{ + long m_lMaxTable; + long m_lMaxField; + long m_lMaxDomain; + long m_lMaxSeque; + long m_lBootExec; + long m_lBootPort; + long m_lBootType; + char m_szNode[MAX_FIELD_LEN]; + char m_szLog[MAX_STRIG_LEN]; +}TBoot; + +/************************************************************************************************* + 内部函数 + *************************************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif +extern char* sGetLog(); +extern char* sGetNode(); +extern void* pGetBoot(); +extern void* pGetSATvm(); +extern long lDefaultBoot(); +extern TBoot* pBootInitial(); +extern size_t lGetTblRow(TABLE t); +extern long lGetPermit(TABLE t); +extern long lGetRowSize(TABLE t); +extern TblDef* pGetTblDef(TABLE t); +extern TblKey* pGetTblIdx(TABLE t); +extern uint lGetIdxNum(TABLE t); +extern uint lGetGrpNum(TABLE t); +extern size_t lGetTblData(TABLE t); +extern size_t lGetListOfs(TABLE t); +extern size_t lGetRowTruck(TABLE t); +extern size_t lGetIdxPos(TABLE t); +extern size_t lGetGrpPos(TABLE t); +extern long lGetFldNum(TABLE t); +extern size_t lGetIdxRoot(TABLE t); +extern long lGetTblGroup(TABLE t); +extern size_t lGetTblValid(TABLE t); +extern TblKey* pGetTblGrp(TABLE t); +extern TblKey* pGetTblKey(TABLE t); +extern RWLock* pGetRWLock(char* pvAddr); +extern void vRedeError(long err, char *s); +extern void* pGetAddr(SATvm *pstSavm, TABLE t); +extern RunTime* pGetRunTime(SATvm *pstSavm, TABLE t); +extern void* pGetNode(void *pvData, size_t lOfs); +extern void* pInitMemTable(SATvm *pstSavm, TABLE t); +extern void* pInitHitTest(SATvm *pstSavm, TABLE t); +extern long lTableMaxRow(SATvm *pstSavm, TABLE t); +extern key_t yGetIPCPath(SATvm *pstSavm, Benum em); +extern long lGetBootConfig(SATvm *pstSavm, TBoot *pstBoot); +extern long lAddIdxField(TABLE, long, long, long, long); +extern long lSetTableIdx(TABLE, long, long, char*, long, long); +extern long lUpdIndexPart(SATvm *pstSavm, TABLE t, char *pszPart); +extern TblKey* pFindField(TblKey *pstIdx, long lNum, char *pszField); +extern long lGetTblField(TABLE t, size_t *plOut, TField **ppstField); +extern void vSetCodField(FdCond *pstCond, uint ulen, uint uPos); +extern bool bSetCondAttr(FdCond *pstCond, TABLE t, Uenum eCheck); +extern void vSetDecorate(FdCond *pstCond, uint ulen, uint uPos, Uenum em); +extern long lGetDomainIndex(SATvm *pstSavm, long *plOut, TIndex **ppstIndex); +extern long lGetDomainTable(SATvm *pstSavm, long *plOut, TDomain **ppstDomain); +extern long lGetLocalIndex(SATvm *pstSavm, long *plOut, TIndex **ppstIndex); +extern long lGetTblIndex(SATvm *pstSavm, char *pszTable, char *pszPart, TIndex *pstIndex); + +/************************************************************************************************* + config make&unmake + *************************************************************************************************/ +extern long lUnmakeConfig(char *pszFile); +extern long lMakeConfig(char *pszFile); + +/************************************************************************************************* + IPC Message and semaphore + *************************************************************************************************/ +extern long lGetQueueNum(SATvm *pstSavm, long lQid); +extern long lQueueMaxByte(SATvm *pstSavm, long lQid); +extern long lQueueRcvTime(SATvm *pstSavm, long lQid); +extern long lCreateQueue(SATvm *pstSavm, bool bCreate); +extern long lOperateSems(SATvm *pstSavm, long semID, long lSems, Benum evp); +extern long lEventWrite(SATvm *pstSavm, long lQid, void *psvData, long lSize); +extern long lCreateSems(SATvm *pstSavm, RunTime *pstRun, long lSems, long lValue); +extern long lEventRead(SATvm *pstSavm, long lQid, void *pstVoid, long lSize, long lMType); +extern long lReadNoWait(SATvm *pstSavm, long lQid, void *psvVoid, long lSize, long lMType); + +/************************************************************************************************* + api + *************************************************************************************************/ +extern long lShutdownTvm(); +extern long lStartupTvm(TBoot *pstBoot); + +extern char* sGetUpdTime(); +extern long lGetTErrno(); +extern void vSetTvmMsg(SATvm *pstSavm, char *fmt, ...); +extern char* sGetTvmMsg(SATvm *pstSavm); +extern void vSetTErrno(long err); +extern char* sGetTError(long err); +extern size_t lGetEffect(); +extern bool bIsTvmBoot(); +extern void* pInitSATvm(TABLE t); +extern long lInitSvCache(SATvm *pstSavm); +extern void vInitSATvm(SATvm *pstSavm); +extern bool bTableIsExist(TABLE t); +extern bool bPartIsExist(char *pszTable, char *pszPart); +extern long lInitSATvm(SATvm *pstSavm, TABLE t); +extern void* pPartSatvm(SATvm *pstSavm, char *pszTable, char *pszPart); + +extern long lResetLock(SATvm *pstSavm, TABLE t); +extern long lRebuildIndex(SATvm *pstSavm, TABLE t); +extern void vHoldConnect(SATvm *pstSavm); +extern void vHoldRelease(SATvm *pstSavm); +extern void vTblDisconnect(SATvm *pstSamo, TABLE t); +extern void vForceDisconnect(SATvm *pstSamo, TABLE t); +extern void vBeginWork(SATvm *pstSavm); +extern void vEndWork(SATvm *pstSavm); +extern long lCommitWork(SATvm *pstSavm); +extern long lRollbackWork(SATvm *pstSavm); +extern long lDropTable(SATvm *pstSavm, TABLE t); +extern long lImportFile(TABLE t, char *pszFile, char *pszFlag); +extern long lExportFile(TABLE t, char *pszFile, char *pszFlag); +extern long lImportTable(TABLE t, size_t lCount, void *psvOut); +extern long lExportTable(TABLE t, size_t *plOut, void **ppsvOut); + +extern long lRenameTable(SATvm *pstSavm, TABLE to, TABLE tn); +extern long lCreateSeque(SATvm *pstSavm, char *pszSQName, uint uIncre); +extern long lSelectSeque(SATvm *pstSavm, char *pszSQName, ulong *pulNumber); +extern long lSetSequence(SATvm *pstSavm, char *pszSQName, ulong uStart); +extern long lCustomTable(SATvm *pstSavm, TABLE t, size_t lRow, TblDef *pstDef); +extern long lCreateTable(SATvm *pstSavm, TABLE t, size_t lRow, TCREATE pfCreateFunc); +extern long lInsertTrans(SATvm *pstSavm, size_t *plOffset, llSEQ *pllSeq); + + +extern long lDelete(SATvm *pstSavm); +extern long lInsert(SATvm *pstSavm); +extern long lTruncate(SATvm *pstSavm, TABLE t); +extern long lSelect(SATvm *pstSavm, void *psvOut); +extern long lUpdate(SATvm *pstSavm, void *psvUpd); +extern long lCount(SATvm *pstSavm, size_t *plCount); +extern long lExtreme(SATvm *pstSavm, void *psvOut); +extern long lGroup(SATvm *pstSavm, size_t *plOut, void **ppsvOut); +extern long lQuery(SATvm *pstSavm, size_t *plOut, void **ppsvOut); + +extern long lTableDeclare(SATvm *pstSavm); +extern long lTableFetch(SATvm *pstSavm, void *psvOut); +extern long lNextFetch(SATvm *pstSavm, void **ppvOAddr); +extern void vTableClose(SATvm *pstSavm); +#ifdef __cplusplus +} +#endif + +/************************************************************************************************* + code end + *************************************************************************************************/ +#endif // __TVM_DEFIND_HHHH___ diff --git a/src/conf.c b/src/conf.c new file mode 100644 index 0000000..e9faaf3 --- /dev/null +++ b/src/conf.c @@ -0,0 +1,1271 @@ +/* +* Copyright (c) 2018 Savens Liu +* +* The original has been patented, Open source is not equal to open rights. +* Anyone can clone, download, learn and discuss for free. Without the permission +* of the copyright owner or author, it shall not be merged, published, licensed or sold. +* The copyright owner or author has the right to pursue his responsibility. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "tvm.h" +#include "tmain.h" + +/************************************************************************************************* + global + *************************************************************************************************/ +TBoot g_stBoot = {0}; + +/************************************************************************************************* + description:get the config of boot + parameters: + return: + void* + *************************************************************************************************/ +void* pGetBoot() +{ + return &g_stBoot; +} + +/************************************************************************************************* + description:get log file + parameters: + return: + void* + *************************************************************************************************/ +char* pGetLog() +{ + return g_stBoot.m_szLog; +} + +/************************************************************************************************* + description:Get the current node + parameters: + return: + void* + *************************************************************************************************/ +char* sGetNode() +{ + return g_stBoot.m_szNode; +} + +/************************************************************************************************* + description:Set the current node + parameters: + return: + *************************************************************************************************/ +void vSetNode(char *s) +{ + if(!s) return ; + strncpy(g_stBoot.m_szNode, s, sizeof(g_stBoot.m_szNode)); +} + +/************************************************************************************************* + description:Set STVM boot type + parameters: + return: + *************************************************************************************************/ +void vSetBootType(long lType) +{ + g_stBoot.m_lBootType = lType; +} + +/************************************************************************************************* + description:Get current type of boot + parameters: + return: + lBootType + *************************************************************************************************/ +long lGetBootType() +{ + return g_stBoot.m_lBootType; +} + +/************************************************************************************************* + 函数说明:获取配置日志名称 + 参数说明: + 返回值: + void --日志名 + *************************************************************************************************/ +char* sGetLog() +{ + return g_stBoot.m_szLog; +} + +/************************************************************************************************* + description:create default config + parameters: + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lDefaultBoot() +{ + FILE *fp = NULL; + char szPath[512]; + TBoot *pstBoot = (TBoot *)pGetBoot(); + + memset(szPath, 0, sizeof(szPath)); + memset(pstBoot, 0, sizeof(TBoot)); + snprintf(szPath, sizeof(szPath), "%s", getenv("TVMCFG")); + + pstBoot->m_lMaxTable = 255; + pstBoot->m_lMaxField = 3000; + pstBoot->m_lMaxDomain = 1024; + pstBoot->m_lMaxSeque = 1024; + pstBoot->m_lBootExec = get_nprocs(); + pstBoot->m_lBootPort = 2000; + pstBoot->m_lBootType = TVM_BOOT_SIMPLE; + strcpy(pstBoot->m_szNode, "STVM"); + strcpy(pstBoot->m_szLog, "stvm.log"); + + if(NULL == (fp = fopen(szPath, "wb"))) + { + fprintf(stderr, "create default param failed, %s\n", strerror(errno)); + return RC_FAIL; + } + + fwrite(TVM_RUNCFG_TAG, 4, 1, fp); + fwrite(pstBoot, sizeof(TBoot), 1, fp); + fclose(fp); + + return RC_SUCC; +} + +/************************************************************************************************* + description:from the config to boot system + parameters: + pstSavm --stvm handle + pstBoot --boot paramer + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lGetBootConfig(SATvm *pstSavm, TBoot *pstBoot) +{ + FILE *fp = NULL; + char szPath[512], szVersion[10]; + + if(!pstSavm || !pstBoot) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + memset(szPath, 0, sizeof(szPath)); + memset(szVersion, 0, sizeof(szVersion)); + snprintf(szPath, sizeof(szPath), "%s", getenv("TVMCFG")); + if(NULL == (fp = fopen(szPath, "rb"))) + { + pstSavm->m_lErrno = FILE_NOTFOUND; + return RC_FAIL; + } + + fread(szVersion, 4, 1, fp); + if(memcmp(szVersion, TVM_RUNCFG_TAG, 4)) + { + fclose(fp); + pstSavm->m_lErrno = BOOT_VER_ICMP; + return RC_FAIL; + } + + fread(pstBoot, sizeof(TBoot), 1, fp); + fclose(fp); + + return RC_SUCC; +} + +/************************************************************************************************* + description: Startup initialization + parameters: + return: + void * + *************************************************************************************************/ +TBoot* pBootInitial() +{ + static int i = 0; + SATvm *pstSavm = (SATvm *)pGetSATvm(); + + if(1 == i ++) return &g_stBoot; + + memset(&g_stBoot, 0, sizeof(TBoot)); + + pstSavm->m_lErrno = TVM_DONE_SUCC; + lGetBootConfig(pstSavm, &g_stBoot); + + return &g_stBoot; +} + +/************************************************************************************************* + description:from the config to initial table index + parameters: + pstSavm --stvm handle + plOut --number + ppstIndex --out of index group + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lGetLocalIndex(SATvm *pstSavm, long *plOut, TIndex **ppstIndex) +{ + FILE *fp = NULL; + char szPath[512], szVersion[10]; + + if(!pstSavm || !ppstIndex || !plOut) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + memset(szPath, 0, sizeof(szPath)); + memset(szVersion, 0, sizeof(szVersion)); + snprintf(szPath, sizeof(szPath), "%s", getenv("TVMCFG")); + if(NULL == (fp = fopen(szPath, "rb"))) + { + pstSavm->m_lErrno = FILE_NOTFOUND; + return RC_FAIL; + } + + fread(szVersion, 4, 1, fp); + if(memcmp(szVersion, TVM_RUNCFG_TAG, 4)) + { + fclose(fp); + pstSavm->m_lErrno = BOOT_VER_ICMP; + return RC_FAIL; + } + + fseek(fp, sizeof(TBoot), SEEK_CUR); + fread((void *)plOut, sizeof(long), 1, fp); + if(*plOut <= 0) + { + fclose(fp); + return RC_SUCC; + } + + if(NULL == (*ppstIndex = (void *)calloc(*plOut, sizeof(TIndex)))) + { + fclose(fp); + pstSavm->m_lErrno = MALLC_MEM_ERR; + return RC_FAIL; + } + + fread(*ppstIndex, (*plOut) * sizeof(TIndex), 1, fp); + fclose(fp); + + return RC_SUCC; +} + +/************************************************************************************************* + description:from the config to initial domain + parameters: + pstSavm --stvm handle + plOut --number + ppstIndex --out of index group + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lGetDomainIndex(SATvm *pstSavm, long *plOut, TIndex **ppstIndex) +{ + FILE *fp = NULL; + char szPath[512], szVersion[10]; + + if(!pstSavm || !ppstIndex || !plOut) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + memset(szPath, 0, sizeof(szPath)); + memset(szVersion, 0, sizeof(szVersion)); + snprintf(szPath, sizeof(szPath), "%s", getenv("TVMCFG")); + if(NULL == (fp = fopen(szPath, "rb"))) + { + pstSavm->m_lErrno = FILE_NOTFOUND; + return RC_FAIL; + } + + fread(szVersion, 4, 1, fp); + if(memcmp(szVersion, TVM_RUNCFG_TAG, 4)) + { + fclose(fp); + pstSavm->m_lErrno = BOOT_VER_ICMP; + return RC_FAIL; + } + + fseek(fp, sizeof(TBoot), SEEK_CUR); + fread((void *)plOut, sizeof(long), 1, fp); + if(*plOut <= 0) + { + fclose(fp); + return RC_SUCC; + } + + fseek(fp, (*plOut) * sizeof(TIndex), SEEK_CUR); + fread((void *)plOut, sizeof(long), 1, fp); + if(NULL == (*ppstIndex = (void *)calloc(*plOut, sizeof(TIndex)))) + { + fclose(fp); + pstSavm->m_lErrno = MALLC_MEM_ERR; + return RC_FAIL; + } + + fread(*ppstIndex, (*plOut) * sizeof(TIndex), 1, fp); + fclose(fp); + + return RC_SUCC; +} + +/************************************************************************************************* + description:from the config to initial table of domain + parameters: + pstSavm --stvm handle + plOut --number + ppstIndex --out of index group + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lGetDomainTable(SATvm *pstSavm, long *plOut, TDomain **ppstDomain) +{ + FILE *fp = NULL; + char szPath[512], szVersion[10]; + + if(!pstSavm || !ppstDomain || !plOut) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + memset(szPath, 0, sizeof(szPath)); + memset(szVersion, 0, sizeof(szVersion)); + snprintf(szPath, sizeof(szPath), "%s", getenv("TVMCFG")); + if(NULL == (fp = fopen(szPath, "rb"))) + { + pstSavm->m_lErrno = FILE_NOTFOUND; + return RC_FAIL; + } + + fread(szVersion, 4, 1, fp); + if(memcmp(szVersion, TVM_RUNCFG_TAG, 4)) + { + fclose(fp); + pstSavm->m_lErrno = BOOT_VER_ICMP; + return RC_FAIL; + } + + fseek(fp, sizeof(TBoot), SEEK_CUR); + fread((void *)plOut, sizeof(long), 1, fp); + fseek(fp, (*plOut) * sizeof(TIndex), SEEK_CUR); + fread((void *)plOut, sizeof(long), 1, fp); + fseek(fp, (*plOut) * sizeof(TIndex), SEEK_CUR); + fread((void *)plOut, sizeof(long), 1, fp); + if(*plOut <= 0) + { + fclose(fp); + return RC_SUCC; + } + + if(NULL == (*ppstDomain = (void *)calloc(*plOut, sizeof(TDomain)))) + { + fclose(fp); + pstSavm->m_lErrno = MALLC_MEM_ERR; + return RC_FAIL; + } + + fread(*ppstDomain, (*plOut) * sizeof(TDomain), 1, fp); + fclose(fp); + + return RC_SUCC; +} + +/************************************************************************************************* + description:parse config field + parameters: + pszBuffer --file content + pszTarg --target + nTarg --target length + pszValue --The label value + nValue --value max length + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lPraseField(char *pszBuffer, char *pszTarg, long nTarg, char *pszValue, long nValue) +{ + char szAttr[512]; + + memset(szAttr, 0, sizeof(szAttr)); + strncpy(szAttr, pszBuffer, sizeof(szAttr)); + if(!strstr(szAttr, "=")) + { + fprintf(stdout, "%s\n*may be lost '='\n", szAttr); + return RC_FAIL; + } + + strncpy(pszTarg, sgetvalue(szAttr, "=", 1), nTarg); + strncpy(pszValue, sgetvalue(szAttr, "=", 2), nValue); + srtrim(pszTarg); + sltrim(pszValue); + strimabout(pszValue, "\"", "\""); + if(!strlen(pszValue)) + { + fprintf(stdout, "%s\n*config error, The initial value is not set\n", szAttr); + return RC_FAIL; + } + + return RC_SUCC; +} + +/************************************************************************************************* + description:from the config to initial table index + parameters: + pstSavm --stvm handle + ppstRoot --content list + pszFile --config file + pszTarge --target + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lParseFile(SATvm *pstSavm, CMList **ppstRoot, char *pszFile, const char *pszTarget) +{ + FILE *fp = NULL; + char szLine[4098]; + BOOL bFlag = FALSE; + CMList *pstList = NULL; + + if(NULL == (fp = fopen(pszFile, "rb"))) + { + pstSavm->m_lErrno = FILE_NOTFOUND; + return RC_FAIL; + } + + memset(szLine, 0, sizeof(szLine)); + while(fgets(szLine, sizeof(szLine), fp)) + { + strimcrlf(szLine); + sltrim(szLine); + srtrim(szLine); + if(!strlen(szLine)) + continue; + + if('#' == szLine[0] || !memcmp("//", szLine, 2) || !memcmp("/*", szLine, 2) || + !memcmp("#", szLine, 2) || !memcmp("--", szLine, 2)) + continue; + + if(!strcmp(pszTarget, szLine) && !bFlag) + { + bFlag = TRUE; + memset(szLine, 0, sizeof(szLine)); + continue; + } + else if(szLine[0] == '*' && bFlag) + break; + + if(!bFlag) + { + memset(szLine, 0, sizeof(szLine)); + continue; + } + + if(NULL == (pstList = pInsertList(pstList, (void *)szLine, sizeof(szLine)))) + { + fclose(fp); + vDestroyList(pstList); + return RC_FAIL; + } + } + + fclose(fp); + *ppstRoot = pstList; + + return RC_SUCC; +} + +/************************************************************************************************* + description:parse STVM boot parameter + parameters: + pstSavm --stvm handle + pszFile --config file + pstBoot --target + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lParseBoot(SATvm *pstSavm, char *pszFile, TBoot *pstBoot) +{ + char szTarg[128], szValue[64]; + CMList *pstNode = NULL, *pstRoot = NULL; + + if(RC_SUCC != _lParseFile(pstSavm, &pstRoot, pszFile, "*GLOBLE")) + { + fprintf(stderr, "parse file, err:(%d)(%s)\n", pstSavm->m_lErrno, sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; + } + + for(pstNode = pstRoot; pstNode; pstNode = pstNode->pstNext) + { + memset(szTarg, 0, sizeof(szTarg)); + memset(szValue, 0, sizeof(szValue)); + if(RC_SUCC != lPraseField((char *)pstNode->m_psvData, szTarg, sizeof(szTarg), szValue, + sizeof(szValue))) + goto PBOOT_ERROR; + + if(!strcasecmp(szTarg, "MACHINE")) + strncpy(pstBoot->m_szNode, szValue, sizeof(pstBoot->m_szNode)); + else if(!strcasecmp(szTarg, "LOGNAME")) + strncpy(pstBoot->m_szLog, szValue, sizeof(pstBoot->m_szLog)); + else if(!strcasecmp(szTarg, "DEPLOY")) + { + if(!strcasecmp(szValue, "cluster")) + pstBoot->m_lBootType = TVM_BOOT_CLUSTER; + else if(!strcasecmp(szValue, "local")) + pstBoot->m_lBootType = TVM_BOOT_LOCAL; + else // local + pstBoot->m_lBootType = TVM_BOOT_SIMPLE; + } + else if(!strcasecmp(szTarg, "MAXTABLE")) + { + pstBoot->m_lMaxTable = atol(szValue); + if(pstBoot->m_lMaxTable <= 5) + { + fprintf(stdout, "%s\n*Set STVM maximum support table number error\n", + (char *)pstNode->m_psvData); + } + else if(pstBoot->m_lMaxTable > 255) + { + fprintf(stdout, "%s\n*STVM maximum support table 255\n", + (char *)pstNode->m_psvData); + goto PBOOT_ERROR; + } + } + else if(!strcasecmp(szTarg, "MAXFILED")) + { + pstBoot->m_lMaxField = atol(szValue); + if(pstBoot->m_lMaxField <= 100) + { + fprintf(stdout, "%s\n*Set the number of STVM field details error\n", + (char *)pstNode->m_psvData); + goto PBOOT_ERROR; + } + } + else if(!strcasecmp(szTarg, "MAXDOMAIN")) + { + pstBoot->m_lMaxDomain = atol(szValue); + if(pstBoot->m_lMaxDomain <= 0) + { + fprintf(stdout, "%s\n*Error in setting maximum number of domain\n", + (char *)pstNode->m_psvData); + goto PBOOT_ERROR; + } + } + else if(!strcasecmp(szTarg, "MAXSEQUE")) + { + pstBoot->m_lMaxSeque = atol(szValue); + if(pstBoot->m_lMaxSeque <= 0) + { + fprintf(stdout, "%s\n*Error in setting maximum number of sequences\n", + (char *)pstNode->m_psvData); + goto PBOOT_ERROR; + } + } + else if(!strcasecmp(szTarg, "SERVER_EXEC")) + { + pstBoot->m_lBootExec = atol(szValue); + if(pstBoot->m_lBootExec <= 0) + { + fprintf(stdout, "%s\n*LIS.tvm: startup number set error", + (char *)pstNode->m_psvData); + goto PBOOT_ERROR; + } + } + else if(!strcasecmp(szTarg, "SERVER_PORT")) + { + pstBoot->m_lBootPort = atol(szValue); + if(pstBoot->m_lBootPort <= 0) + { + fprintf(stdout, "%s\n*LIS.tvm: Error starting port setting\n", + (char *)pstNode->m_psvData); + goto PBOOT_ERROR; + } + } + else + { + fprintf(stdout, "%s\n*Invalid parameter\n", (char *)pstNode->m_psvData); + goto PBOOT_ERROR; + } + } + + if(!strlen(pstBoot->m_szNode)) + { + fprintf(stdout, "MACHINE\n*The local node is not set\n"); + goto PBOOT_ERROR; + } + + if(pstBoot->m_lMaxTable <= 0) + pstBoot->m_lMaxTable = TVM_MAX_TABLE; + if(pstBoot->m_lMaxField <= 0) + pstBoot->m_lMaxField = 3000; + if(pstBoot->m_lMaxDomain <= 0) + pstBoot->m_lMaxDomain = 500; + if(pstBoot->m_lMaxSeque <= 0) + pstBoot->m_lMaxSeque = 500; + if(pstBoot->m_lBootExec <= 0) + pstBoot->m_lBootExec = get_nprocs() > 0 ? get_nprocs() : 1; + if(pstBoot->m_lBootPort <= 0) + pstBoot->m_lBootPort = TVM_PORT_LISTEN; + + vDestroyList(pstRoot); + + return RC_SUCC; + +PBOOT_ERROR: + vDestroyList(pstRoot); + return RC_FAIL; +} + +/************************************************************************************************* + description:get config domain resource + parameters: + lDomain --number of domain + pstDomain --domain group + pszDomain --domain + return: + void* --domain + *************************************************************************************************/ +TDomain* pGetResourse(long lDomain, TDomain *pstDomain, char *pszDomain) +{ + long i = 0; + + for(i = 0; i < lDomain; i ++) + { + if(!strcmp(pstDomain[i].m_szOwner, pszDomain)) + return &pstDomain[i]; + } + + return NULL; +} + +/************************************************************************************************* + description:parse local table config + parameters: + pstSavm --stvm handle + pszFile --config + plOut --number + ppstIndex --out of index group + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lParseIndex(SATvm *pstSavm, char *pszFile, long *plOut, TIndex **ppstIndex) +{ + long i, j, n; + TIndex *pstIndex = NULL; + CMList *pstNode = NULL, *pstRoot = NULL; + char szTarg[128], szValue[64], szAttr[1024]; + + memset(szTarg, 0, sizeof(szTarg)); + memset(szAttr, 0, sizeof(szAttr)); + memset(szValue, 0, sizeof(szValue)); + if(RC_SUCC != _lParseFile(pstSavm, &pstRoot, pszFile, "*LOCAL_RESOURCE")) + { + fprintf(stderr, "parse file, err:(%d)(%s)\n", pstSavm->m_lErrno, sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; + } + + for(pstNode = pstRoot, j = 0; pstNode; pstNode = pstNode->pstNext) + { + sfieldreplace((char *)pstNode->m_psvData, '\t', ' '); + if(!strlen((char *)pstNode->m_psvData)) continue; + + if(NULL == (pstIndex = (TIndex *)realloc(pstIndex, (++ j) * sizeof(TIndex)))) + { + pstSavm->m_lErrno = MALLC_MEM_ERR; + return RC_FAIL; + } + + memset(&pstIndex[j - 1], 0, sizeof(TIndex)); + for(i = 0, n = lfieldnum((char *)pstNode->m_psvData, " "); i < n; i ++) + { + memset(szTarg, 0, sizeof(szTarg)); + memset(szValue, 0, sizeof(szValue)); + if(RC_SUCC != lPraseField(sfieldvalue((char *)pstNode->m_psvData, " ", i + 1), + szTarg, sizeof(szTarg), szValue, sizeof(szValue))) + goto PINDEX_ERROR; + + if(!strcasecmp(szTarg, "TABLE")) + pstIndex[j - 1].m_table = atol(szValue); + else if(!strcasecmp(szTarg, "PERMIT")) + pstIndex[j - 1].m_lPers = atol(szValue); + else + { + fprintf(stdout, "%s\n*Invalid parameter\n", (char *)pstNode->m_psvData); + goto PINDEX_ERROR; + } + } + + if(pstIndex[j - 1].m_table <= 0) + { + fprintf(stdout, "%s\n*Table setting error\n", (char *)pstNode->m_psvData); + goto PINDEX_ERROR; + } + + if(pstIndex[j - 1].m_lPers <= 0) + pstIndex[j - 1].m_lPers = OPERATE_DEFAULT; + } + *plOut = j; + *ppstIndex = pstIndex; + + vDestroyList(pstRoot); + return RC_SUCC; + +PINDEX_ERROR: + TFree(*ppstIndex); + vDestroyList(pstRoot); + return RC_FAIL; +} + +/************************************************************************************************* + description:parse domain + parameters: + pstSavm --stvm handle + pszFile --config + plCount --number + ppstDom --out of domain group + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lParseResouce(SATvm *pstSavm, char *pszFile, long *plCout, TDomain **ppstDom) +{ + TDomain *pv; + long i, n; + char szTarg[128], szValue[64]; + CMList *pstNode = NULL, *pstRoot = NULL; + + if(RC_SUCC != _lParseFile(pstSavm, &pstRoot, pszFile, "*REMOTE_DOMAIN")) + { + fprintf(stderr, "parse file, err:(%d)(%s)\n", pstSavm->m_lErrno, sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; + } + + for(pstNode = pstRoot, *plCout = 0; pstNode; pstNode = pstNode->pstNext) + { + sfieldreplace((char *)pstNode->m_psvData, '\t', ' '); + if(!strlen((char *)pstNode->m_psvData)) continue; + + if(NULL == (*ppstDom = (TDomain *)realloc(*ppstDom, (++ (*plCout)) * sizeof(TDomain)))) + { + pstSavm->m_lErrno = MALLC_MEM_ERR; + return RC_FAIL; + } + + pv = &(*ppstDom)[(*plCout) - 1]; + memset(pv, 0, sizeof(TDomain)); + for(i = 0, n = lfieldnum((char *)pstNode->m_psvData, " "); i < n; i ++) + { + memset(szTarg, 0, sizeof(szTarg)); + memset(szValue, 0, sizeof(szValue)); + if(RC_SUCC != lPraseField(sfieldvalue((char *)pstNode->m_psvData, " ", i + 1), + szTarg, sizeof(szTarg), szValue, sizeof(szValue))) + goto PDOMAIN_ERROR; + + if(!strcasecmp(szTarg, "DOMAINID")) + strncpy(pv->m_szOwner, szValue, sizeof(pv->m_szOwner)); + else if(!strcasecmp(szTarg, "GROUP")) + pv->m_lGroup = atol(szValue); + else if(!strcasecmp(szTarg, "WSADDR")) + { + strncpy(pv->m_szIp, sgetvalue(szValue, ":", 1), sizeof(pv->m_szIp)); + pv->m_lPort = atol(sgetvalue(szValue, ":", 2)); + } + else if(!strcasecmp(szTarg, "TIMTOUT")) + pv->m_lTimeOut = atol(szValue); + else if(!strcasecmp(szTarg, "MAXTRY")) + pv->m_lTryMax = atol(szValue); + else if(!strcasecmp(szTarg, "KEEPALIVE")) + pv->m_lKeepLive = atol(szValue); + } + + if(!strlen(pv->m_szOwner)) + { + fprintf(stdout, "%s\n*域名未设置\n", (char *)pstNode->m_psvData); + goto PDOMAIN_ERROR; + } + + if(!strlen(pv->m_szIp)) + { + fprintf(stdout, "%s\n*域地址未设置\n", (char *)pstNode->m_psvData); + goto PDOMAIN_ERROR; + } + + if(pv->m_lPort <= 0) + { + fprintf(stdout, "%s\n*The domain port is set incorrectly or unset\n", + (char *)pstNode->m_psvData); + goto PDOMAIN_ERROR; + } + + pv->m_lGroup = pv->m_lGroup > 0 ? pv->m_lGroup : 1; + pv->m_lTimeOut = pv->m_lTimeOut > 0 ? pv->m_lTimeOut : 5; + pv->m_lTryMax = pv->m_lTryMax > 0 ? pv->m_lTryMax : 3; + pv->m_lKeepLive= pv->m_lKeepLive > 0 ? pv->m_lKeepLive : 30; + } + TFlst(pstRoot); + return RC_SUCC; + +PDOMAIN_ERROR: + TFree(*ppstDom); + TFlst(pstRoot); + return RC_FAIL; +} + +/************************************************************************************************* + description:parse the table of domain + parameters: + pszNode --node + pszBuffer --content + plOut --number + ppIndx --out of index + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lParseTable(char *pszNode, char *pszBuffer, long *plOut, TIndex **ppIndx) +{ + long i, n; + TIndex *pv = NULL; + char szTarg[128], szValue[64]; + + if(NULL == (*ppIndx = (TIndex *)realloc(*ppIndx, (++ (*plOut)) * sizeof(TIndex)))) + return RC_FAIL; + + pv = &(*ppIndx)[(*plOut) - 1]; + memset(pv, 0, sizeof(TIndex)); + sfieldreplace(pszBuffer, '\t', ' '); + for(i = 0, n = lfieldnum(pszBuffer, " "); i < n; i ++) + { + memset(szTarg, 0, sizeof(szTarg)); + memset(szValue, 0, sizeof(szValue)); + if(RC_SUCC != lPraseField(sfieldvalue(pszBuffer, " ", i + 1), szTarg, sizeof(szTarg), + szValue, sizeof(szValue))) + return RC_FAIL; + + if(!strcasecmp(szTarg, "TABLE")) + pv->m_table = atol(szValue); + else if(!strcasecmp(szTarg, "TABLENAME")) + strncpy(pv->m_szTable, szValue, sizeof(pv->m_szTable)); + else if(!strcasecmp(szTarg, "PART")) + strncpy(pv->m_szPart, szValue, sizeof(pv->m_szPart)); + + if(!strlen(pv->m_szPart)) + strcpy(pv->m_szPart, pszNode); + strcpy(pv->m_szOwner, pszNode); + } + pv->m_lLocal = RES_REMOT_SID; + pv->m_lPers = OPERATE_NULL; + pv->m_lType = TYPE_CLIENT; + strncpy(pv->m_szTime, sGetUpdTime(), sizeof(pv->m_szTime)); + + return RC_SUCC; +} + +/************************************************************************************************* + description:parse domain resource + parameters: + pszBuffer --content + pstIndex --index + pstDom --domain + plDom --number + ppstDom --domain list + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lParseDomain(char *pszBuffer, TIndex *pstIndex, TDomain *pstDom, long *plDom, + TDomain **ppstDom) +{ + long i, n; + TDomain *pv = NULL; + char szTarg[128], szValue[64]; + + if(NULL == (*ppstDom = (TDomain *)realloc(*ppstDom, (++ (*plDom)) * sizeof(TDomain)))) + return RC_FAIL; + + pv = &(*ppstDom)[(*plDom) - 1]; + memset(pv, 0, sizeof(TDomain)); + for(i = 0, n = lfieldnum(pszBuffer, " "); i < n; i ++) + { + memset(szTarg, 0, sizeof(szTarg)); + memset(szValue, 0, sizeof(szValue)); + if(RC_SUCC != lPraseField(sfieldvalue(pszBuffer, " ", i + 1), szTarg, sizeof(szTarg), + szValue, sizeof(szValue))) + return RC_FAIL; + + if(!strcasecmp(szTarg, "MTABLE")) + pv->m_mtable = atol(szValue); + else if(!strcasecmp(szTarg, "DOMAINID")) + strncpy(pv->m_szOwner, szValue, sizeof(pv->m_szOwner)); + else + { + fprintf(stdout, "%s\n*Invalid parameter\n", pszBuffer); + return RC_FAIL; + } + } + + pv->m_lTryMax = 0; + pv->m_lLastTime = 0; + pv->m_lStatus = RESOURCE_INIT; + pv->m_table = pstIndex->m_table; + pv->m_lPort = pstDom->m_lPort; + pv->m_lGroup = pstDom->m_lGroup; + pv->m_lKeepLive = pstDom->m_lKeepLive; + pv->m_lTimeOut = pstDom->m_lTimeOut; + pv->m_lTryMax = pstDom->m_lTryMax; + strcpy(pv->m_szIp, pstDom->m_szIp); + strcpy(pv->m_szTable, pstIndex->m_szTable); + strcpy(pv->m_szOwner, pstDom->m_szOwner); + if(!strlen(pv->m_szPart)) + strcpy(pv->m_szPart, pstDom->m_szOwner); + + return RC_SUCC; +} + +/************************************************************************************************* + description:parse domain table of remote + parameters: + pstSavm --stvm handle + pszFile --config + pstBoot --boot paramter + plOut --number of index + ppstIndex --out of index list + plDom --number of domain + ppstDom --out of domain list + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lParseRemote(SATvm *pstSavm, char *pszFile, TBoot *pstBoot, long *plOut, TIndex **ppstIndex, + long *plDom, TDomain **ppstDom) +{ + long i, lResource; + TIndex *pv = NULL; + CMList *pstNode = NULL, *pstRoot = NULL; + TDomain *pstRes = NULL, *pstResouce = NULL; + char szTarg[128], szValue[64], *p = NULL; + + if(RC_SUCC != lParseResouce(pstSavm, pszFile, &lResource, &pstResouce)) + return RC_FAIL; + + if(RC_SUCC != _lParseFile(pstSavm, &pstRoot, pszFile, "*REMOTE_TABLE")) + { + fprintf(stderr, "parse file, err:(%d)(%s)\n", pstSavm->m_lErrno, sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; + } + + if(!pstRoot) + { + for(i = 0; i < lResource; i ++) + { + pstResouce[i].m_table = SYS_TVM_INDEX; + pstResouce[i].m_mtable = SYS_TVM_INDEX; + strcpy(pstResouce[i].m_szTable, "SYS_TVM_INDEX"); + strcpy(pstResouce[i].m_szPart, pstResouce[i].m_szOwner); + } + + *plOut = 0; + *ppstIndex = NULL; + *plDom = lResource; + *ppstDom = pstResouce; + return RC_SUCC; + } + else + { + for(pstNode = pstRoot, *plDom = 0, *plOut = 0; pstNode; pstNode = pstNode->pstNext) + { + sfieldreplace((char *)pstNode->m_psvData, '\t', ' '); + if(!strncmp((char *)pstNode->m_psvData, "TABLE", 5)) + { + if(RC_SUCC != lParseTable(pstBoot->m_szNode, (char *)pstNode->m_psvData, + plOut, ppstIndex)) + goto PREMOTE_ERROR; + pv = &(*ppstIndex)[(*plOut) - 1]; + continue; + } + + if(NULL == (p = strstr((char *)pstNode->m_psvData, "DOMAINID"))) + { + fprintf(stderr, "set error:%s\n", (char *)pstNode->m_psvData); + goto PREMOTE_ERROR; + } + + if(NULL == (pstRes = pGetResourse(lResource, pstResouce, + strimabout(sfieldvalue(p, "=", 2), "\"", "\"")))) + { + fprintf(stderr, "No domain (%s) is found\n", sfieldvalue(p, "=", 2)); + goto PREMOTE_ERROR; + } + + if(RC_SUCC != lParseDomain((char *)pstNode->m_psvData, pv, pstRes, plDom, ppstDom)) + { + TFlst(pstRoot); + return RC_FAIL; + } + } + } + TFree(pstResouce); + TFlst(pstRoot); + + return RC_SUCC; + +PREMOTE_ERROR: + TFlst(pstRoot); + TFree(*ppstIndex); + TFree(pstResouce); + return RC_FAIL; +} + +/************************************************************************************************* + description:Domain uniqueness checks + parameters: + lCount --number + pstDomain --domain list + return: + true --repeat + false + *************************************************************************************************/ +BOOL bDomIsRepeat(long lCount, TDomain *pstDomain) +{ + int i, j; + + for(i = 0; i < lCount; i ++) + { + for(j = 0; j < lCount; j ++) + { + if(i == j) continue; + + if(pstDomain[i].m_lPort == pstDomain[j].m_lPort && + !strcmp(pstDomain[i].m_szIp, pstDomain[j].m_szIp) && + !strcmp(pstDomain[i].m_szPart, pstDomain[j].m_szPart) && + !strcmp(pstDomain[i].m_szTable, pstDomain[j].m_szTable)) + { + if(SYS_TVM_INDEX == pstDomain[i].m_table) + { + fprintf(stderr, "*domain(%s)(%s:%ld)repeate\n", pstDomain[i].m_szOwner, + pstDomain[i].m_szIp, pstDomain[i].m_lPort); + } + else + { + fprintf(stderr, "*table(%s)(%s)repeate\n", pstDomain[i].m_szTable, + pstDomain[i].m_szPart); + } + return true; + } + } + } + + return false; +} + +/************************************************************************************************* + description:Compile configuration file + parameters: + pszFile --config file + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lMakeConfig(char *pszFile) +{ + TBoot stBoot; + FILE *fp = NULL; + TIndex *pstIndex = NULL; + TDomain *pstDomain = NULL; + long i, lOut = 0, lCount = 0; + SATvm *pstSavm = (SATvm *)pGetSATvm(); + + if(!pszFile || !strlen(pszFile)) + { + fprintf(stderr, "The configuration file is not set\n"); + return RC_FAIL; + } + + if(RC_SUCC != access(pszFile, R_OK | F_OK )) + { + fprintf(stderr, "Insufficient authority(%s), please confirm!!!\n\n", pszFile); + return RC_FAIL; + } + + memset(&stBoot, 0, sizeof(TBoot)); + if(NULL == (fp = fopen(getenv("TVMCFG"), "wb"))) + { + fprintf(stderr, "open (%s) failure, err:(%d)(%s)", getenv("TVMCFG"), + errno, strerror(errno)); + return RC_FAIL; + } + + fwrite(TVM_RUNCFG_TAG, 4, 1, fp); + if(RC_SUCC != lParseBoot(pstSavm, pszFile, &stBoot)) + goto CREATE_ERROR; + + fwrite(&stBoot, sizeof(stBoot), 1, fp); + if(TVM_BOOT_CLUSTER != stBoot.m_lBootType) // 单机部署 + { + fclose(fp); + fprintf(stdout, "create completed successfully!!!\n"); + return RC_FAIL; + } + + if(RC_SUCC != lParseIndex(pstSavm, pszFile, &lOut, &pstIndex)) + goto CREATE_ERROR; + + fwrite(&lOut, sizeof(long), 1, fp); + fwrite(pstIndex, sizeof(TIndex), lOut, fp); + TFree(pstIndex); + + if(RC_SUCC != lParseRemote(pstSavm, pszFile, &stBoot, &lOut, &pstIndex, + &lCount, &pstDomain)) + goto CREATE_ERROR; + + if(bDomIsRepeat(lCount, pstDomain)) + goto CREATE_ERROR; + + fwrite(&lOut, sizeof(long), 1, fp); + if(lOut > 0) + { + fwrite(pstIndex, sizeof(TIndex), lOut, fp); + TFree(pstIndex); + } + + fwrite(&lCount, sizeof(long), 1, fp); + if(lCount > 0) + { + fwrite(pstDomain, sizeof(TDomain), lCount, fp); + TFree(pstDomain); + } + fclose(fp); + + fprintf(stdout, "create completed successfully!!!\n"); + + return RC_SUCC; + +CREATE_ERROR: + TFree(pstDomain); + TFree(pstIndex); + fclose(fp); + return RC_FAIL; +} + +/************************************************************************************************* + description:Decompilate compilation configuration + parameters: + pszFile --config file + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lUnmakeConfig(char *pszFile) +{ + char ch; + TBoot stBoot; + FILE *fp = NULL; + BOOL bf = false; + TIndex *pstIndex = NULL; + TDomain *pstDomain = NULL; + long i, j, lOut = 0, lCount = 0; + SATvm *pstSavm = (SATvm *)pGetSATvm(); + + if(RC_SUCC == access(pszFile, F_OK)) + { + fprintf(stderr, "The configuration already exists, Confirm the cover(Y/N)?:"); + ch = getchar(); + if(ch != 'y' && 'Y' != ch) + return RC_SUCC; + } + + if(NULL == (fp = fopen(pszFile, "w"))) + { + fprintf(stderr, "open file error, %s\n", strerror(errno)); + return RC_FAIL; + } + + if(RC_SUCC != lGetBootConfig(pstSavm, &stBoot)) + goto UNMAKE_ERR; + + fprintf(fp, "*GLOBLE\n"); + fprintf(fp, "MACHINE=\"%s\"\n", stBoot.m_szNode); + fprintf(fp, "MAXTABLE=%ld\n", stBoot.m_lMaxTable); + fprintf(fp, "MAXFILED=%ld\n", stBoot.m_lMaxField); + fprintf(fp, "MAXDOMAIN=%ld\n", stBoot.m_lMaxDomain); + fprintf(fp, "MAXSEQUE=%ld\n", stBoot.m_lMaxSeque); + fprintf(fp, "SERVER_EXEC=%ld\n", stBoot.m_lBootExec); + fprintf(fp, "SERVER_PORT=%ld\n", stBoot.m_lBootPort); + fprintf(fp, "LOGNAME=\"%s\"\n\n", stBoot.m_szLog); + + fprintf(fp, "*LOCAL_RESOURCE\n"); + if(RC_SUCC != lGetLocalIndex(pstSavm, &lCount, (void *)&pstIndex)) + goto UNMAKE_ERR; + + for(i = 0; i < lCount; i ++) + fprintf(fp, "TABLE=%d PERMIT=%ld\n", pstIndex[i].m_table, pstIndex[i].m_lPers); + TFree(pstIndex); + + fprintf(fp, "\n*REMOTE_DOMAIN"); + if(RC_SUCC != lGetDomainIndex(pstSavm, &lCount, &pstIndex)) + goto UNMAKE_ERR; + + if(RC_SUCC != lGetDomainTable(pstSavm, &lOut, &pstDomain)) + goto UNMAKE_ERR; + + for(i = 0; i < lCount; i ++) + { + fprintf(fp, "\nTABLE=%d TABLENAME=\"%s\" PART=\"%s\" ", pstIndex[i].m_table, + pstIndex[i].m_szTable, pstIndex[i].m_szPart); + for(j = 0, bf = false; j < lOut; j ++) + { + if(strcmp(pstDomain[j].m_szTable, pstIndex[i].m_szTable) || + strcmp(pstDomain[j].m_szPart, pstIndex[i].m_szPart)) + continue; + + if(!bf) + { + bf = !bf; + fprintf(fp, "GROUP=%ld TIMTOUT=%ld MAXTRY=%ld KEEPALIVE=%ld\n", + pstDomain[j].m_lGroup, pstDomain[j].m_lTimeOut, pstDomain[j].m_lTryMax, + pstDomain[j].m_lKeepLive); + } + + fprintf(fp, "\tDOMAINID=\"%s\" WSADDR=\"%s:%ld\"\n", pstDomain[j].m_szOwner, + pstDomain[j].m_szIp, pstDomain[j].m_lPort); + } + } + TFree(pstIndex); + TFree(pstDomain); + + fclose(fp); + fprintf(stdout, "导出文件(%s)成功,completed successfully!!!\n", pszFile); + + return RC_SUCC; +UNMAKE_ERR: + fclose(fp); + TFree(pstIndex); + TFree(pstDomain); + fprintf(stderr, "get config err:(%d)(%s)\n", pstSavm->m_lErrno, sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; +} + +/************************************************************************************************** + code end + **************************************************************************************************/ diff --git a/src/detvm.c b/src/detvm.c new file mode 100644 index 0000000..654dbd1 --- /dev/null +++ b/src/detvm.c @@ -0,0 +1,404 @@ +/* +* Copyright (c) 2018 Savens Liu +* +* The original has been patented, Open source is not equal to open rights. +* Anyone can clone, download, learn and discuss for free. Without the permission +* of the copyright owner or author, it shall not be merged, published, licensed or sold. +* The copyright owner or author has the right to pursue his responsibility. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "tvm.h" + +/************************************************************************************************* + macro + *************************************************************************************************/ +#define DEBUG_HEAD_INFO 1 +#define DEBUG_UNIQ_IDEX 2 +#define DEBUG_GROP_IDEX 4 +#define DEBUG_GROP_LIST 8 +#define DEBUG_DATA_LIST 16 +#define DEBUG_IDEX_TREE 32 +#define DEBUG_IDEX_DATA 64 +#define DEBUG_IDEX_DALL 128 +#define DEBUG_ALLD_INFO (DEBUG_HEAD_INFO|DEBUG_UNIQ_IDEX|DEBUG_GROP_IDEX|DEBUG_GROP_LIST|DEBUG_DATA_LIST) + +/************************************************************************************************* + function + *************************************************************************************************/ +extern void vPrintHex(char *s, long lIdx, bool bf); + +/************************************************************************************************* + description:debug tree node + parameters: + pvData --memory address + pstTree --tree node + return: + *************************************************************************************************/ +void vDebugTree(void *pvData, SHTree *pstTree) +{ + + if(!pvData || !pstTree) return ; + + fprintf(stderr, "DugTree:%p-SePos:[%8ld], Idx(%ld):[%15s](%2ld), Color[%ld], lSePos:[%4ld], " + "lParent[%4ld], left[%4ld], right[%4ld]\n" , (char *)pstTree, (void *)pstTree - pvData, + pstTree->m_lIdx, pstTree->m_szIdx, pstTree->m_lData, pstTree->m_eColor, pstTree->m_lSePos, + pstTree->m_lParent, pstTree->m_lLeft, pstTree->m_lRight); + + if(SELF_POS_UNUSE == pstTree->m_lSePos || NODE_NULL == pstTree->m_lSePos) + return ; + + if(NODE_NULL != pstTree->m_lLeft) + vDebugTree(pvData, (SHTree *)pGetNode(pvData, pstTree->m_lLeft)); + + if(NODE_NULL != pstTree->m_lRight) + vDebugTree(pvData, (SHTree *)pGetNode(pvData, pstTree->m_lRight)); +} + +/************************************************************************************************* + description:debug table + parameters: + pvData --memory address + pstTree --tree node + return: + *************************************************************************************************/ +void vDebugTable(TABLE t, long eType) +{ + long i = 0, j = 0; + RunTime *pstRun = NULL; + TblKey *pstKey = NULL; + SHTree *pstTree = NULL; + SHList *pstList = NULL; + SHTruck *pstTruck = NULL; + TIndex *pstIndex = NULL; + SATvm *pstSavm = (SATvm *)pGetSATvm(); + + if(NULL == (pstSavm = (SATvm *)pInitSATvm(t))) + { + fprintf(stderr, "initial table (%d) failed\n", t); + return ; + } + + if(NULL == (pstRun = pInitHitTest(pstSavm, pstSavm->tblName))) + { + fprintf(stderr, "hit test table (%d) failed, err:(%d)(%s)\n", t,pstSavm->m_lErrno, + sGetTError(pstSavm->m_lErrno)); + return ; + } + + if(eType & DEBUG_HEAD_INFO) + { + fprintf(stdout, "\n==========================================TABLE HEAND INFO=============" + "============================\n"); + fprintf(stdout, "TABLE:%d, NAME:%s\tSHTree(%ld),SHList(%ld),TblDef(%ld)\n" + "extern:%ld, Group:%ld, MaxRow:%ld, Valid:%ld, lNodeNil:%ld, lIType:%d, " + "Table:%ld\nIdxLen:%ld, TreePos:%ld, TreeRoot:%ld, GrpLen:%ld, GroupPos:%ld, " + "GroupRoot:%ld\nListPos:%ld, ListOfs:%ld, Data:%ld, ReSize:%ld, Truck:%ld\n", + ((TblDef *)pGetTblDef(t))->m_table, ((TblDef *)pGetTblDef(t))->m_szTable, + sizeof(SHTree), sizeof(SHList), sizeof(TblDef), ((TblDef *)pGetTblDef(t))->m_lExtern, + ((TblDef *)pGetTblDef(t))->m_lGroup, ((TblDef *)pGetTblDef(t))->m_lMaxRow, + ((TblDef *)pGetTblDef(t))->m_lValid, ((TblDef *)pGetTblDef(t))->m_lNodeNil, + ((TblDef *)pGetTblDef(t))->m_lIType, + ((TblDef *)pGetTblDef(t))->m_lTable, ((TblDef *)pGetTblDef(t))->m_lIdxLen, + ((TblDef *)pGetTblDef(t))->m_lTreePos, ((TblDef *)pGetTblDef(t))->m_lTreeRoot, + ((TblDef *)pGetTblDef(t))->m_lGrpLen, ((TblDef *)pGetTblDef(t))->m_lGroupPos, + ((TblDef *)pGetTblDef(t))->m_lGroupRoot, ((TblDef *)pGetTblDef(t))->m_lListPos, + ((TblDef *)pGetTblDef(t))->m_lListOfs, ((TblDef *)pGetTblDef(t))->m_lData, + ((TblDef *)pGetTblDef(t))->m_lReSize, ((TblDef *)pGetTblDef(t))->m_lTruck); + + pstTree = &((TblDef *)pGetTblDef(t))->m_stNil; + fprintf(stdout, ">>NODE_NULL POS:[%8ld], Idx:[%s](%ld)(%ld), Color[%ld], lSePos:[%4ld], lParent[%4ld]" + ", left[%4ld], right[%4ld]\n" , (void *)pstTree - (void *)pGetTblDef(t), pstTree->m_szIdx, + pstTree->m_lIdx, pstTree->m_lData, pstTree->m_eColor, pstTree->m_lSePos, pstTree->m_lParent, + pstTree->m_lLeft, pstTree->m_lRight); + + fprintf(stdout, "==========UNIQ INDEX FIELD=========\n"); + for(i = 0, pstKey = pGetTblIdx(t); i < lGetIdxNum(t); i ++) + { + fprintf(stdout, "From:%4ld, len:%3ld, attr:%ld, IsPk:%ld, field:%s\n", pstKey[i].m_lFrom, + pstKey[i].m_lLen, pstKey[i].m_lAttr, pstKey[i].m_lIsPk, pstKey[i].m_szField); + } + + fprintf(stdout, "==========GROUP INDEX FIELD========\n"); + for(i = 0, pstKey = pGetTblGrp(t); i < lGetGrpNum(t); i ++) + { + fprintf(stdout, "From:%4ld, len:%3ld, attr:%ld, IsPk:%ld, field:%s\n", pstKey[i].m_lFrom, + pstKey[i].m_lLen, pstKey[i].m_lAttr, pstKey[i].m_lIsPk, pstKey[i].m_szField); + } + + fprintf(stdout, "==================== TABLE FIELD ====================\n"); + for(i = 0, pstKey = pGetTblKey(t); i < lGetFldNum(t); i ++) + { + fprintf(stdout, "From:%4ld, len:%3ld, attr:%ld, IsPk:%ld, field:%s\n", pstKey[i].m_lFrom, + pstKey[i].m_lLen, pstKey[i].m_lAttr, pstKey[i].m_lIsPk, pstKey[i].m_szField); + } + } + + if(eType & DEBUG_UNIQ_IDEX) + { + fprintf(stdout, "\n===================================UNIQUE_INDEX=====================" + "==============lValid(%ld)=========================\n", lGetTblValid(t)); + if(eType & DEBUG_IDEX_DALL) + { + for(i = 0; i < lGetTblRow(t); i ++) + { + pstTree = (SHTree *)(pstRun->m_pvAddr + lGetIdxPos(t) + i * sizeof(SHTree)); + vPrintHex(pstTree->m_szIdx, pstTree->m_lIdx, 0); + fprintf(stdout, "NODE:[%ld](%02ld), Idx:[%4s](%ld)(%2ld), Color[%ld], lSePos:[%4ld], " + "lParent[%4ld], left[%4ld], right[%4ld]\n" , (void *)pstTree - pstRun->m_pvAddr, + i, pstTree->m_szIdx, pstTree->m_lIdx, pstTree->m_lData, pstTree->m_eColor, + pstTree->m_lSePos, pstTree->m_lParent, pstTree->m_lLeft, pstTree->m_lRight); + } + } + else + { + for(i = 0; i < lGetTblValid(t); i ++) + { + pstTree = (SHTree *)(pstRun->m_pvAddr + lGetIdxPos(t) + i * sizeof(SHTree)); + if(SELF_POS_UNUSE == pstTree->m_lSePos || NODE_NULL == pstTree->m_lSePos) + continue; + + vPrintHex(pstTree->m_szIdx, pstTree->m_lIdx, 0); + fprintf(stdout, "NODE:[%6ld]->(%02ld), Idx:[%15s](%6ld), Color[%ld], lSePos:[%4ld], " + "lParent[%4ld], left[%4ld], right[%4ld]\n" , (void *)pstTree - pstRun->m_pvAddr, i, + pstTree->m_szIdx, pstTree->m_lData, pstTree->m_eColor, pstTree->m_lSePos, + pstTree->m_lParent, pstTree->m_lLeft, pstTree->m_lRight); + } + } + } + + if(eType & DEBUG_GROP_IDEX) + { + fprintf(stdout, "\n===================================INDEX_GROUP=====================" + "==============Valid:%ld, Group:%ld================\n", lGetTblValid(t), lGetTblGroup(t)); + if(eType & DEBUG_IDEX_DALL) + { + for(i = 0; i < lGetTblRow(t); i ++) + { + pstTree = (SHTree *)(pstRun->m_pvAddr + lGetGrpPos(t) + i * sizeof(SHTree)); + vPrintHex(pstTree->m_szIdx, pstTree->m_lIdx, 0); + fprintf(stdout, "NODE:[%ld](%02ld), Idx:[%4s](%ld)(%2ld), Color[%ld], lSePos:[%4ld]," + " lParent[%4ld], left[%4ld], right[%4ld]\n" , (void *)pstTree - pstRun->m_pvAddr, + i, pstTree->m_szIdx, pstTree->m_lIdx, pstTree->m_lData, pstTree->m_eColor, + pstTree->m_lSePos, pstTree->m_lParent, pstTree->m_lLeft, pstTree->m_lRight); + } + } + else + { + for(i = 0; i < lGetTblValid(t); i ++) + { + pstTree = (SHTree *)(pstRun->m_pvAddr + lGetGrpPos(t) + i * sizeof(SHTree)); + if(SELF_POS_UNUSE == pstTree->m_lSePos || NODE_NULL == pstTree->m_lSePos) + continue; + + vPrintHex(pstTree->m_szIdx, pstTree->m_lIdx, 0); + fprintf(stdout, "NODE:[%ld](%02ld), Idx:[%4s](%ld)(%2ld), Color[%ld], lSePos:[%4ld]," + " lParent[%4ld], left[%4ld], right[%4ld]\n" , (void *)pstTree - pstRun->m_pvAddr, + i, pstTree->m_szIdx, pstTree->m_lIdx, pstTree->m_lData, pstTree->m_eColor, + pstTree->m_lSePos, pstTree->m_lParent, pstTree->m_lLeft, pstTree->m_lRight); + } + } + } + + if(eType & DEBUG_GROP_LIST) + { + fprintf(stdout, "\n=================================INDEX_LIST========================" + "==============Valid(%ld)=============\n", lGetTblValid(t)); + if(eType & DEBUG_IDEX_DALL) + { + for(i = 0, j = lGetListOfs(t); i < lGetTblRow(t); i ++) + { + pstList = (SHList *)(pstRun->m_pvAddr + j + i * sizeof(SHList)); + fprintf(stdout, "LIST:[%8ld][%02ld], lSePos:[%4ld], lData[%8ld], Node[%8ld], " + "Next[%8ld], Last[%8ld]\n" , (void *)pstList - pstRun->m_pvAddr, i, + pstList->m_lPos, pstList->m_lData, pstList->m_lNode, pstList->m_lNext, + pstList->m_lLast); + } + } + else + { + for(i = 0, j = lGetListOfs(t); i < lGetTblValid(t); i ++) + { + pstList = (SHList *)(pstRun->m_pvAddr + j + i * sizeof(SHList)); + if(SELF_POS_UNUSE == pstList->m_lPos) + continue; + + fprintf(stdout, "LIST:[%8ld][%02ld], lSePos:[%4ld], lData[%8ld], Node[%8ld], " + "Next[%8ld], Last[%8ld]\n" , (void *)pstList - pstRun->m_pvAddr, i, + pstList->m_lPos, pstList->m_lData, pstList->m_lNode, + pstList->m_lNext, pstList->m_lLast); + } + } + } + + if(eType & DEBUG_IDEX_TREE) + { + fprintf(stdout, "\n=================================TREE DEUBG========================" + "==============Valid(%ld)=============\n", lGetTblValid(t)); + vDebugTree(pstRun->m_pvAddr, pGetNode(pstRun->m_pvAddr, lGetIdxRoot(t))); + } + + if(eType & DEBUG_IDEX_DATA) + { + fprintf(stdout, "\n===================================UNIQUE_INDEX=====================" + "==============lValid(%ld)=========================\n", lGetTblValid(t)); + for(i = 0; i < lGetTblRow(t); i ++) + { + pstTruck = (void *)(pstRun->m_pvAddr + lGetTblData(t) + i * lGetRowTruck(t)); + fprintf(stdout, "SePos[%ld]\n", (void *)pstTruck - pstRun->m_pvAddr); + vPrintHex(pstTruck->m_pvData, lGetRowSize(t), 0); + } + } + + vTblDisconnect(pstSavm, pstSavm->tblName); + fprintf(stdout, "==========================================================================" + "===================================\n"); +} + +/************************************************************************************************* + description:get action + parameters: + return: + *************************************************************************************************/ +void vGetAction(char *s, long *plAction) +{ + int i, nLen; + + if(!s) return ; + + for(i = 0, nLen = strlen(s); i < nLen; i ++) + { + switch(s[i]) + { + case 'h': + *plAction |= DEBUG_HEAD_INFO; + break; + case 'u': + *plAction |= DEBUG_UNIQ_IDEX; + break; + case 'g': + *plAction |= DEBUG_GROP_IDEX; + break; + case 'l': + *plAction |= DEBUG_GROP_LIST; + break; + case 'd': + *plAction |= DEBUG_DATA_LIST; + break; + case 't': + *plAction |= DEBUG_IDEX_TREE; + break; + case 'e': + *plAction |= DEBUG_IDEX_DALL; + break; + case 'a': + *plAction |= DEBUG_IDEX_DATA; + break; + default: + break; + } + } +} + +/************************************************************************************************* + description:print func + parameters: + return: + *************************************************************************************************/ +void vPrintFunc(char *s) +{ + fprintf(stdout, "\nUsage:\t%s -[tpu][hugldtui]\n", s); + fprintf(stdout, "\t-t\t\t--table\n"); + fprintf(stdout, "\t-p[hugldta]\t--debug\n"); + fprintf(stdout, "\t-u(ui)\t\t--reset lock\n"); + fprintf(stdout, "\n"); +} + +/************************************************************************************************* + description:debug action + parameters: + return: + *************************************************************************************************/ +void vDebugAction(TABLE t, int iAction, char *pszApp, char *pszParam) +{ + long lRet, lDebug = 0; + SATvm *pstSavm = (SATvm *)pGetSATvm(); + + if(3 == iAction) + { + if(RC_SUCC != lResetLock((SATvm *)pGetSATvm(), t)) + { + fprintf(stderr, "reset the table lock (%d) failed, err:(%d)(%s)\n", t, + pstSavm->m_lErrno, sGetTError(pstSavm->m_lErrno)); + return ; + } + } + else if(5 == iAction) + { + vGetAction(pszParam, &lDebug); + vDebugTable(t, lDebug); + } + else + vPrintFunc(pszApp); + + return ; +} + +/************************************************************************************************* + description:main + parameters: + return: + *************************************************************************************************/ +int main(int argc, char *argv[]) +{ + TABLE t; + char szCom[256]; + int iChoose = 0, iAction = 0; + + memset(szCom, 0, sizeof(szCom)); + while(-1 != (iChoose = getopt(argc, argv, "t:p:u::v?::"))) + { + switch(iChoose) + { + case 't': + iAction |= 1; + t = atol(optarg); + break; + case 'u': + if(!optarg) + strcpy(szCom, "u"); + else + strcpy(szCom, optarg); + iAction |= 2; + break; + case 'p': + iAction |= 4; + strcpy(szCom, optarg); + break; + case 'v': + case '?': + default: + vPrintFunc(basename(argv[0])); + return RC_FAIL; + } + } + + vDebugAction(t, iAction, basename(argv[0]), szCom); + + return RC_SUCC; +} + +/************************************************************************************************* + code end + *************************************************************************************************/ diff --git a/src/list.c b/src/list.c new file mode 100644 index 0000000..33e00e9 --- /dev/null +++ b/src/list.c @@ -0,0 +1,1099 @@ +/* +* Copyright (c) 2018 Savens Liu +* +* The original has been patented, Open source is not equal to open rights. +* Anyone can clone, download, learn and discuss for free. Without the permission +* of the copyright owner or author, it shall not be merged, published, licensed or sold. +* The copyright owner or author has the right to pursue his responsibility. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "tmain.h" + +/************************************************************************************************ + function + ************************************************************************************************/ +/************************************************************************************************* + description:get the tailf of list + parameters: + root --list of root + return: + void* + *************************************************************************************************/ +CMList* pGetCMTail(CMList *root) +{ + CMList *list = root; + + if(!list) return NULL; + + while(list->pstNext) + list = list->pstNext; + + return list; +} + +/************************************************************************************************* + description:insert to list + parameters: + return: + root -root node + *************************************************************************************************/ +CMList* pInsertList(CMList *root, void *pszData, long lSize) +{ + CMList *node = NULL, *tail = pGetCMTail(root); + + if(NULL == (node = (CMList *)malloc(sizeof(CMList)))) + { + vSetTErrno(MALLC_MEM_ERR); + return root; + } + + node->m_lSize = lSize; + if(NULL == (node->m_psvData = (char *)malloc(node->m_lSize))) + { + vSetTErrno(MALLC_MEM_ERR); + return root; + } + + node->pstNext = NULL; + node->pstLast = NULL; + memcpy(node->m_psvData, pszData, node->m_lSize); + + if(!root) + root = node; + else + { + node->pstLast = tail; + tail->pstNext = node; + } + + return root; +} + +/************************************************************************************************* + description:find node from the list + parameters: + return: + node --list node + *************************************************************************************************/ +CMList* pSearchNode(CMList *root, void *pv, long n) +{ + CMList *node; + + for(node = root; node; node = node->pstNext) + { + if(!memcmp(node->m_psvData, pv, n)) + return node; + } + + return NULL; +} + +/************************************************************************************************* + description:destroy list + parameters: + root --list root + return: + void* + *************************************************************************************************/ +void vDestroyList(CMList *root) +{ + CMList *node = root, *list = NULL; + + while(node) + { + list = node; + node = node->pstNext; + TFree(list->m_psvData); + TFree(list); + } + + root = NULL; +} + +/************************************************************************************************* + description:delete node + parameters: + root --root node + psvData --node value + lSize --length of value + return: + root --root node + *************************************************************************************************/ +CMList* pDeleteNode(CMList *root, void *psvData, long lSize) +{ + CMList *node = root; + + while(node) + { + if(!memcmp(node->m_psvData, psvData, lSize)) + break; + node = node->pstNext; + } + if(!node) return root; + + if(node->pstNext) + node->pstNext->pstLast = node->pstLast; + + if(!node->pstLast) + root = node->pstNext; + else + node->pstLast->pstNext = node->pstNext; + + TFree(node->m_psvData); + TFree(node); + + return root; +} + +/************************************************************************************************* + description:node number + parameters: + root --root node + return: + long --count the number of list + *************************************************************************************************/ +long lListNodeCount(CMList *root) +{ + long lCount = 0; + CMList *node = root; + + while(node) + { + ++ lCount; + node = node->pstNext; + } + + return lCount; +} + +/************************************************************************************************* + description:Check if rowgrp is repeated + parameters: + pstRrp --field index list + pvData --check data + t --table + lOut --number + psvOut --truck list + return: + true --repeate + false + *************************************************************************************************/ +bool bRepeatLstgrp(FdCond *pstRrp, void *pvData, TABLE t, size_t lOut, void *psvOut) +{ + uint i, j; + FdKey *pstFd; + bool bRepeat = false; + + if(!psvOut || 0 == lOut) return false; + + for(i = 0; i < lOut; i ++) + { + for(j = 0, bRepeat = true; j < pstRrp->uFldcmp; j ++) + { + pstFd = &pstRrp->stFdKey[j]; + if(0 == (GROUP_BY & pstFd->uDecorate)) + continue; + + if(memcmp(psvOut + (i * lGetRowSize(t)) + pstFd->uFldpos, pvData + pstFd->uFldpos, + pstFd->uFldlen)) + bRepeat = false; + } + + if(bRepeat) return bRepeat; + } + + return bRepeat; +} + +/************************************************************************************************* + description:insert group node + parameters: + pstSavm --stvm handle + pstRrp --field index list + pvData --insert data + lOut --number + psvOut --truck list + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lInsertLstgrp(SATvm *pstSavm, FdCond *pstRrp, void *pvData, TABLE t, size_t *plOut, + void **ppsvOut) +{ + FdKey *pstFd; + size_t i, lOffset = (*plOut) * lGetRowSize(t); + + if(NULL == (*ppsvOut = (char *)realloc(*ppsvOut, lOffset + lGetRowSize(t)))) + { + pstSavm->m_lErrno = MALLC_MEM_ERR; + return RC_FAIL; + } + + memset(*ppsvOut + lOffset, 0, lGetRowSize(t)); + for(i = 0; i < pstRrp->uFldcmp; i ++) + { + pstFd = &pstRrp->stFdKey[i]; + if(0 == (GROUP_BY & pstFd->uDecorate)) + continue; + + memcpy(*ppsvOut + lOffset + pstFd->uFldpos, pvData + pstFd->uFldpos, pstFd->uFldlen); + } + + (*plOut) ++; + return RC_SUCC; +} + +/************************************************************************************************* + Rowgrp + *************************************************************************************************/ +/************************************************************************************************* + description:get rowgrp tail + parameters: + root --root of rowgrp + return: + void* --tailf of rowgrp + *************************************************************************************************/ +Rowgrp* pRowgrpTail(Rowgrp *root) +{ + Rowgrp *node = root; + + if(!node) return NULL; + + while(node->pstNext) + node = node->pstNext; + + return node; +} + +/************************************************************************************************* + description:free rowgrp list + parameters: + root --root of rowgrp + return: + *************************************************************************************************/ +void vDeleteRowgrp(Rowgrp *root) +{ + Rowgrp *list, *node; + + for(list = root, node = root; NULL != list; node = list) + { + list = list->pstNext; + vDeleteRowgrp(node->pstSSet); + TFree(node->psvData); + TFree(node); + } + + return ; +} + +/************************************************************************************************* + description:delete node from rowgrp + parameters: + root --root of rowgrp + delete --delete node + return: + *************************************************************************************************/ +void vDropNodegrp(Rowgrp **root, Rowgrp *delete) +{ + Rowgrp *list, *node; + + if(!root) return ; + + for(list = *root; NULL != list; ) + { + if(list != delete) + { + list = list->pstNext; + continue; + } + + if(list->pstLast) + list->pstLast->pstNext = list->pstNext; + else + *root = list->pstNext; + + if(list->pstNext) + list->pstNext->pstLast = list->pstLast; + node = list; + list = list->pstNext; + vDeleteRowgrp(node->pstSSet); + TFree(node->psvData); + TFree(node); + } + + return ; +} + +/************************************************************************************************* + description:count rowgrp + parameters: + root --root of rowgrp + pv --data + lLen --data length + lCount --count + return: + long --number of count + *************************************************************************************************/ +long lCountRowgrp(Rowgrp *root, void *pv, long lLen, size_t lCount) +{ + long n; + Rowgrp *node, *list; + + for(node = root; NULL != node; node = node->pstNext) + { + if(!memcmp(node->psvData, pv, lLen)) + { + node->lCount += lCount; + return node->lCount; + } + + if(0 != (n = lCountRowgrp(node->pstSSet, pv, lLen, lCount))) + return n; + } + + return 0; +} + +/************************************************************************************************* + description:insert node from rowgrp + parameters: + pstSavm --stvm handle + root --root of rowgrp + pstFSet --parent node + pstSSet --child node + pv --data + n --length + lCount --count + return: + void* --root of rowgrp + *************************************************************************************************/ +Rowgrp* pInsertRowgrp(SATvm *pstSavm, Rowgrp *root, Rowgrp *pstFset, Rowgrp *pstSSet, void *pv, + long n, size_t lCount) +{ + Rowgrp *node = NULL, *tail = (Rowgrp *)pRowgrpTail(root); + + if(NULL == (node = (Rowgrp *)calloc(1, sizeof(Rowgrp)))) + { + pstSavm->m_lErrno = MALLC_MEM_ERR; + return root; + } + + if(NULL == (node->psvData = (char *)calloc(n + 1, sizeof(char)))) + { + pstSavm->m_lErrno = MALLC_MEM_ERR; + return root; + } + + node->lLen = n; + if(0 == lCount) + node->lCount ++; + else + node->lCount = lCount; + node->pstFset = pstFset; + node->pstSSet = pstSSet; + memcpy(node->psvData, pv, node->lLen); + + if(!root) + { + root = node; + tail = node; + root->lIdx = 0; + return root; + } + + node->lIdx = tail->lIdx + 1; + node->pstLast = tail; + tail->pstNext = node; + tail = node; + + return root; +} + +/************************************************************************************************* + description:get middle of rowgrp + parameters: + root --root of rowgrp + return: + void* --root of rowgrp + *************************************************************************************************/ +Rowgrp* pGetListMid(Rowgrp *root) +{ + Rowgrp *fast = NULL, *slow = NULL; + + if(root == NULL || root->pstNext == NULL) + return NULL; + + for(slow = root, fast = root->pstNext; fast; slow = slow->pstNext) + { + fast = fast->pstNext; + if(NULL == fast) + break; + fast = fast->pstNext; + } + + fast = slow->pstNext; + slow->pstNext = NULL; + return fast; +} + +/************************************************************************************************* + description:Sort list with ASC. + parameters: + root --root of rowgrp + return: + void* --root of rowgrp + *************************************************************************************************/ +Rowgrp* pSortMergeAsc(Rowgrp *pa, Rowgrp *pb, FdKey *pstKey) +{ + Rowgrp *pstRes = NULL; + + if(pa == NULL) + return pb; + else if(pb == NULL) + return pa; + + switch(pstKey->uDecorate & 0x0f) + { + case FIELD_DOUB: + switch(pstKey->uFldlen) + { + case 4: + if(*((float *)(pa->psvData)) < *((float *)(pb->psvData))) + { + pstRes = pa; + pstRes->pstNext = pSortMergeAsc(pa->pstNext, pb, pstKey); + } + else + { + pstRes = pb; + pstRes->pstNext = pSortMergeAsc(pa, pb->pstNext, pstKey); + } + break; + case 8: + if(*((double *)(pa->psvData)) < *((double *)(pb->psvData))) + { + pstRes = pa; + pstRes->pstNext = pSortMergeAsc(pa->pstNext, pb, pstKey); + } + else + { + pstRes = pb; + pstRes->pstNext = pSortMergeAsc(pa, pb->pstNext, pstKey); + } + break; + default: + break; + } + break; + case FIELD_LONG: + switch(pstKey->uFldlen) + { + case 2: + if(*((sint *)(pa->psvData)) < *((sint *)(pb->psvData))) + { + pstRes = pa; + pstRes->pstNext = pSortMergeAsc(pa->pstNext, pb, pstKey); + } + else + { + pstRes = pb; + pstRes->pstNext = pSortMergeAsc(pa, pb->pstNext, pstKey); + } + break; + case 4: + if(*((int *)(pa->psvData)) < *((int *)(pb->psvData))) + { + pstRes = pa; + pstRes->pstNext = pSortMergeAsc(pa->pstNext, pb, pstKey); + } + else + { + pstRes = pb; + pstRes->pstNext = pSortMergeAsc(pa, pb->pstNext, pstKey); + } + break; + case 8: + if(*((llong *)(pa->psvData)) < *((llong *)(pb->psvData))) + { + pstRes = pa; + pstRes->pstNext = pSortMergeAsc(pa->pstNext, pb, pstKey); + } + else + { + pstRes = pb; + pstRes->pstNext = pSortMergeAsc(pa, pb->pstNext, pstKey); + } + break; + default: + break; + } + break; + case FIELD_CHAR: + if(0 < memcmp(pb->psvData, pa->psvData, pstKey->uFldlen)) + { + pstRes = pa; + pstRes->pstNext = pSortMergeAsc(pa->pstNext, pb, pstKey); + } + else + { + pstRes = pb; + pstRes->pstNext = pSortMergeAsc(pa, pb->pstNext, pstKey); + } + break; + default: + break; + } + + if(pstRes->pstNext) pstRes->pstNext->pstLast = pstRes; + + return pstRes; +} + +/************************************************************************************************* + description:Sort list with DESC. + parameters: + root --root of rowgrp + return: + void* --root of rowgrp + *************************************************************************************************/ +Rowgrp* pSortMergeDes(Rowgrp *pa, Rowgrp *pb, FdKey *pstKey) +{ + Rowgrp *pstRes = NULL; + + if(pa == NULL) + return pb; + else if(pb == NULL) + return pa; + + switch(pstKey->uDecorate & 0x0f) + { + case FIELD_DOUB: + switch(pstKey->uFldlen) + { + case 4: + if(*((float *)(pa->psvData)) > *((float *)(pb->psvData))) + { + pstRes = pa; + pstRes->pstNext = pSortMergeDes(pa->pstNext, pb, pstKey); + } + else + { + pstRes = pb; + pstRes->pstNext = pSortMergeDes(pa, pb->pstNext, pstKey); + } + break; + case 8: + if(*((double *)(pa->psvData)) > *((double *)(pb->psvData))) + { + pstRes = pa; + pstRes->pstNext = pSortMergeDes(pa->pstNext, pb, pstKey); + } + else + { + pstRes = pb; + pstRes->pstNext = pSortMergeDes(pa, pb->pstNext, pstKey); + } + break; + default: + break; + } + break; + case FIELD_LONG: + switch(pstKey->uFldlen) + { + case 2: + if(*((sint *)(pa->psvData)) > *((sint *)(pb->psvData))) + { + pstRes = pa; + pstRes->pstNext = pSortMergeDes(pa->pstNext, pb, pstKey); + } + else + { + pstRes = pb; + pstRes->pstNext = pSortMergeDes(pa, pb->pstNext, pstKey); + } + break; + case 4: + if(*((int *)(pa->psvData)) > *((int *)(pb->psvData))) + { + pstRes = pa; + pstRes->pstNext = pSortMergeDes(pa->pstNext, pb, pstKey); + } + else + { + pstRes = pb; + pstRes->pstNext = pSortMergeDes(pa, pb->pstNext, pstKey); + } + break; + case 8: + if(*((llong *)(pa->psvData)) > *((llong *)(pb->psvData))) + { + pstRes = pa; + pstRes->pstNext = pSortMergeDes(pa->pstNext, pb, pstKey); + } + else + { + pstRes = pb; + pstRes->pstNext = pSortMergeDes(pa, pb->pstNext, pstKey); + } + break; + default: + break; + } + break; + case FIELD_CHAR: + if(0 > memcmp(pb->psvData, pa->psvData, pstKey->uFldlen)) + { + pstRes = pa; + pstRes->pstNext = pSortMergeDes(pa->pstNext, pb, pstKey); + } + else + { + pstRes = pb; + pstRes->pstNext = pSortMergeDes(pa, pb->pstNext, pstKey); + } + break; + default: + break; + } + + if(pstRes->pstNext) pstRes->pstNext->pstLast = pstRes; + + return pstRes; +} + +/************************************************************************************************* + description:Sort list by field + parameters: + root --root + pstFd --field + return: + *************************************************************************************************/ +void _vSortField(Rowgrp **root, FdKey *pstFd) +{ + Rowgrp *slow = NULL; + + if(NULL == *root || NULL == (*root)->pstNext) + return; + + slow = pGetListMid(*root); + _vSortField(root, pstFd); + _vSortField(&slow, pstFd); + + if(ORDER_DESC & pstFd->uDecorate) + *root = pSortMergeDes(*root, slow, pstFd); + else + *root = pSortMergeAsc(*root, slow, pstFd); + return ; +} + +/************************************************************************************************* + description:Sort subset + parameters: + root --root + pstFd --field + return: + *************************************************************************************************/ +void vSubsetSort(Rowgrp *root, FdCond *pstExm, uint ug) +{ + Rowgrp *node; + FdKey *pstFd; + + for(node = root, pstFd = &pstExm->stFdKey[ug]; node; node = node->pstNext) + { + if(0 == (pstFd->uDecorate & (ORDER_ASC | ORDER_DESC))) + continue; + + _vSortField(&node->pstSSet, pstFd); + vSubsetSort(node->pstSSet, pstExm, ++ ug); + } + + return ; +} + +/************************************************************************************************* + description:Sort Rowgrp + parameters: + root --root + pstFd --field + t --t + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lSortRowgrp(Rowgrp **root, FdCond *pstExm, TABLE t) +{ + FdKey *pstFd = &pstExm->stFdKey[0]; + + if(!bSetCondAttr(pstExm, t, ORDER_ASC | ORDER_DESC)) + return RC_SUCC; + + if(pstFd->uDecorate & (ORDER_ASC | ORDER_DESC)) + _vSortField(root, pstFd); + vSubsetSort(*root, pstExm, 1); + return RC_SUCC; +} + +/************************************************************************************************* + description:compare data by field + parameters: + s --data + p --to be compared + pstCond --field list + uNice --next index of field + return: + TRUE --success + FALSE --failure + *************************************************************************************************/ +bool bCompare(void *s, void *p, FdCond *pstCond, uint uNice) +{ + FdKey *pstKey; + + if(pstCond->uFldcmp <= uNice) + return TRUE; + + pstKey = &pstCond->stFdKey[uNice]; + if(pstKey->uDecorate & ORDER_ASC) + { + switch(pstKey->uDecorate & 0x0f) + { + case FIELD_DOUB: + switch(pstKey->uFldlen) + { + case 4: + if(*((float *)(s + pstKey->uFldpos)) > *((float *)(p + pstKey->uFldpos))) + return TRUE; + else if(*((float *)(s + pstKey->uFldpos)) == *((float *)(p + pstKey->uFldpos))) + return bCompare(s, p, pstCond, ++ uNice); + else + return FALSE; + case 8: + if(*((double *)(s + pstKey->uFldpos)) > *((double *)(p + pstKey->uFldpos))) + return TRUE; + else if(*((float *)(s + pstKey->uFldpos)) == *((float *)(p + pstKey->uFldpos))) + return bCompare(s, p, pstCond, ++ uNice); + else + return FALSE; + default: + return FALSE; + } + break; + case FIELD_LONG: + switch(pstKey->uFldlen) + { + case 2: + if(*((sint *)(s + pstKey->uFldpos)) > *((sint *)(p + pstKey->uFldpos))) + return TRUE; + else if(*((sint *)(s + pstKey->uFldpos)) == *((sint *)(p + pstKey->uFldpos))) + return bCompare(s, p, pstCond, ++ uNice); + else + return FALSE; + case 4: + if(*((int *)(s + pstKey->uFldpos)) > *((int *)(p + pstKey->uFldpos))) + return TRUE; + else if(*((int *)(s + pstKey->uFldpos)) == *((int *)(p + pstKey->uFldpos))) + return bCompare(s, p, pstCond, ++ uNice); + else + return FALSE; + case 8: + if(*((llong *)(s + pstKey->uFldpos)) > *((llong *)(p + pstKey->uFldpos))) + return TRUE; + else if(*((llong *)(s + pstKey->uFldpos)) == *((llong *)(p + pstKey->uFldpos))) + return bCompare(s, p, pstCond, ++ uNice); + else + return FALSE; + default: + return FALSE; + } + break; + case FIELD_CHAR: + if(0 < memcmp(s + pstKey->uFldpos, p + pstKey->uFldpos, pstKey->uFldlen)) + return TRUE; + else if(0 == memcmp(s + pstKey->uFldpos, p + pstKey->uFldpos, pstKey->uFldlen)) + return bCompare(s, p, pstCond, ++ uNice); + else + return FALSE; + break; + default: + break; + } + } + else if(pstKey->uDecorate & ORDER_DESC) + { + switch(pstKey->uDecorate & 0x0f) + { + case FIELD_DOUB: + switch(pstKey->uFldlen) + { + case 4: + if(*((float *)(s + pstKey->uFldpos)) < *((float *)(p + pstKey->uFldpos))) + return TRUE; + else if(*((float *)(s + pstKey->uFldpos)) == *((float *)(p + pstKey->uFldpos))) + return bCompare(s, p, pstCond, ++ uNice); + else + return FALSE; + case 8: + if(*((double *)(s + pstKey->uFldpos)) < *((double *)(p + pstKey->uFldpos))) + return TRUE; + else if(*((float *)(s + pstKey->uFldpos)) == *((float *)(p + pstKey->uFldpos))) + return bCompare(s, p, pstCond, ++ uNice); + else + return FALSE; + default: + return FALSE; + } + break; + case FIELD_LONG: + switch(pstKey->uFldlen) + { + case 2: + if(*((sint *)(s + pstKey->uFldpos)) < *((sint *)(p + pstKey->uFldpos))) + return TRUE; + else if(*((sint *)(s + pstKey->uFldpos)) == *((sint *)(p + pstKey->uFldpos))) + return bCompare(s, p, pstCond, ++ uNice); + else + return FALSE; + case 4: + if(*((int *)(s + pstKey->uFldpos)) < *((int *)(p + pstKey->uFldpos))) + return TRUE; + else if(*((int *)(s + pstKey->uFldpos)) == *((int *)(p + pstKey->uFldpos))) + return bCompare(s, p, pstCond, ++ uNice); + else + return FALSE; + case 8: + if(*((llong *)(s + pstKey->uFldpos)) < *((llong *)(p + pstKey->uFldpos))) + return TRUE; + else if(*((llong *)(s + pstKey->uFldpos)) == *((llong *)(p + pstKey->uFldpos))) + return bCompare(s, p, pstCond, ++ uNice); + else + return FALSE; + default: + return FALSE; + } + break; + case FIELD_CHAR: + if(0 > memcmp(s + pstKey->uFldpos, p + pstKey->uFldpos, pstKey->uFldlen)) + return TRUE; + else if(0 == memcmp(s + pstKey->uFldpos, p + pstKey->uFldpos, pstKey->uFldlen)) + return bCompare(s, p, pstCond, ++ uNice); + else + return FALSE; + break; + default: + break; + } + } + + return bCompare(s, p, pstCond, ++ uNice); +} + +/************************************************************************************************* + description:QSort list row + parameters: + pvData --data + low --low water + high --high water + lTruck --the length of truck + pstCond --field list + pvKey --next index of field + return: + *************************************************************************************************/ +void vQsortRow(void *pvData, long low, long high, size_t lTurck, FdCond *pstCond, void *pvKey) +{ + long first = low, last = high; + + if(low >= high) + return; + + memcpy(pvKey, pvData + first * lTurck, lTurck); + while(first < last) + { + while(first < last && bCompare(pvData + last * lTurck, pvKey, pstCond, 0)) + -- last; + + memcpy(pvData + first * lTurck, pvData + last * lTurck, lTurck); + + while(first < last && bCompare(pvKey, pvData + first * lTurck, pstCond, 0)) + ++ first; + memcpy(pvData + last * lTurck, pvData + first * lTurck, lTurck); + } + + memcpy(pvData + first * lTurck, pvKey, lTurck); + vQsortRow(pvData, low, first - 1, lTurck, pstCond, pvKey); + vQsortRow(pvData, first + 1, high, lTurck, pstCond, pvKey); +} + +/************************************************************************************************* + description:sort rowlist + parameters: + pstSavm --stvm handle + lRow --rows + pvData --data list + lTruck --the length of truck + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lSortRowList(SATvm *pstSavm, size_t lRow, void *pvData, size_t lTruck) +{ + void *pvKey; + FdCond *pstCond = &pstSavm->stUpdt; + + if(!bSetCondAttr(pstCond, pstSavm->tblName, ORDER_ASC | ORDER_DESC)) + return RC_SUCC; + + if(NULL == (pvKey = (char *)malloc(lTruck))) + { + pstSavm->m_lErrno = MALLC_MEM_ERR; + return RC_FAIL; + } + + vQsortRow(pvData, 0, (long)(lRow - 1), lTruck, pstCond, pvKey); + TFree(pvKey); + return RC_SUCC; +} + +/************************************************************************************************* + description:Collapse the rowgrp node to buffer. + parameters: + root --rowgrp root + return: + *************************************************************************************************/ +void _vConvRowList(Rowgrp *root, long lParant, void *pszBuffer, size_t *plOffset) +{ + Rowgrp *node; + + for(node = root; NULL != node; node = node->pstNext) + { + memcpy(pszBuffer + *plOffset, &lParant, sizeof(long)); *plOffset += sizeof(long); + memcpy(pszBuffer + *plOffset, &node->lLen, sizeof(long)); *plOffset += sizeof(long); + memcpy(pszBuffer + *plOffset, &node->lCount, sizeof(size_t)); *plOffset += sizeof(size_t); + memcpy(pszBuffer + *plOffset, node->psvData, node->lLen); *plOffset += node->lLen; + + _vConvRowList(node->pstSSet, node->lIdx, pszBuffer, plOffset); + } +} + +/************************************************************************************************* + description:Collapse the rowgrp + parameters: + root --rowgrp root + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lConvRowList(SATvm *pstSavm, Rowgrp *root, size_t *plOut, void **ppsvOut) +{ + Rowgrp *node; + size_t lOffset = 0; + + if(!root) + { + *plOut = 0; + return RC_SUCC; + } + + if(!ppsvOut || !plOut) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + for(node = root; NULL != node->pstNext; node = node->pstNext); + + *plOut = (node->lIdx + 1) * (sizeof(long) * 2 + sizeof(size_t) + node->lLen); + if(NULL == (*ppsvOut = (char *)calloc(1, *plOut))) + { + pstSavm->m_lErrno = MALLC_MEM_ERR; + return RC_FAIL; + } + + _vConvRowList(root, 0, *ppsvOut, &lOffset); + + return RC_SUCC; +} + +/************************************************************************************************* + description:find node from the rowgrp list by idx + parameters: + root --rowgrp root + idx --idx of node + return: + node --rowgrp node + *************************************************************************************************/ +Rowgrp* pFindRowList(Rowgrp *root, long idx) +{ + Rowgrp *node, *list; + + for(node = root; NULL != node; node = node->pstNext) + { + if(node->lIdx == idx) + return node; + + if(NULL != (list = pFindRowList(node->pstSSet, idx))) + return list; + } + + return NULL; +} + +/************************************************************************************************* + description:Collapse the buffer to rowgrp list + parameters: + pstSavm --stvm handle + pszBuffer --buffer + lData --the length of buffer + root --rowgrp root + return: + *************************************************************************************************/ +long lParsRowList(SATvm *pstSavm, void *pszBuffer, long lData, Rowgrp **root) +{ + Rowgrp row, *node; + long lOffset, idx; + + for(lOffset = 0; lOffset < lData; lOffset += row.lLen) + { + memcpy(&idx, pszBuffer + lOffset, sizeof(long)); lOffset += sizeof(long); + memcpy(&row.lLen, pszBuffer + lOffset, sizeof(long)); lOffset += sizeof(long); + memcpy(&row.lCount, pszBuffer + lOffset, sizeof(size_t)); lOffset += sizeof(size_t); + if(0 == idx) + { + if(NULL == (*root = (Rowgrp *)pInsertRowgrp(pstSavm, *root, NULL, NULL, + pszBuffer + lOffset, row.lLen, row.lCount))) + { + TFgrp(*root); + return RC_FAIL; + } + + continue; + } + + if(NULL == (node = pFindRowList(*root, idx))) + continue; + + if(NULL == (node = pInsertRowgrp(pstSavm, node, NULL, NULL, pszBuffer + lOffset, + row.lLen, row.lCount))) + { + TFgrp(*root); + return RC_FAIL; + } + } + + return RC_SUCC; +} + +/**************************************************************************************** + code end + ****************************************************************************************/ diff --git a/src/makefile b/src/makefile new file mode 100755 index 0000000..8e70d98 --- /dev/null +++ b/src/makefile @@ -0,0 +1,44 @@ +INCDIR= -I/usr/include -I$(HOME)/include -I./ -I./include -I../include +LIBDIR= -L$(HOME)/lib -L../lib -lstvm -lreadline -lm -lc -ldl -lpthread +AR=ar +LD=ld +LN=ln +CC=cc -fPIC +CO=-c -g +LDFLAG=-shared -g +OUTLIB=../lib +OUTBIN=../bin + +OBJFILE=tree.o sem.o msg.o tcp.o str.o list.o conf.o +TARGET=$(OUTLIB)/libstvm.a +TARDLL=$(OUTLIB)/libstvm.so +TARVER=$(OUTLIB)/libstvm.so.1.2 +STVM=$(OUTBIN)/stvm +DETVM=$(OUTBIN)/detvm + +all: $(TARGET) $(TARDLL) $(STVM) $(DETVM) clean +$(TARGET): $(OBJFILE) + rm -f $@ + $(AR) -cr $@ $(OBJFILE) + +$(TARDLL): $(OBJFILE) + $(LD) $(LDFLAG) -o $@ $(OBJFILE) + rm -f $(TARVER) + $(LN) -s $@ $(TARVER) + +$(STVM): stvm.o + $(CC) -o $@ $< $(LIBDIR) + +$(DETVM): detvm.o + $(CC) -o $@ $< $(LIBDIR) + +.SUFFIXES: .c .o + +.c.o: + $(CC) $(CO) $*.c $(INCDIR) $(LIBDIR) + +fall: + @touch *c + @make all +clean: + rm -f *.o diff --git a/src/msg.c b/src/msg.c new file mode 100644 index 0000000..2ee4e7f --- /dev/null +++ b/src/msg.c @@ -0,0 +1,313 @@ +/* +* Copyright (c) 2018 Savens Liu +* +* The original has been patented, Open source is not equal to open rights. +* Anyone can clone, download, learn and discuss for free. Without the permission +* of the copyright owner or author, it shall not be merged, published, licensed or sold. +* The copyright owner or author has the right to pursue his responsibility. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "tvm.h" + +/************************************************************************************************ + ipc msg function + ************************************************************************************************/ +/************************************************************************************************* + description:create message queue + parameters: + pstSavm --stvm handle + bCreate --create type + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lCreateQueue(SATvm *pstSavm, bool bCreate) +{ + long lQid; + + if(bCreate) + { + pstSavm->m_yMey = yGetIPCPath(pstSavm, IPC_MSG); + if(pstSavm->m_yMey <= RC_FAIL) + return RC_FAIL; + lQid = msgget(pstSavm->m_yMey, IPC_CREAT|0600); + } + else + lQid = msgget(IPC_PRIVATE, IPC_CREAT|0600); + if(RC_FAIL >= lQid) + { + switch(errno) + { + case EEXIST: + pstSavm->m_lErrno = MSG_ERR_EXIST; + break; + case EACCES: + pstSavm->m_lErrno = MSG_ERR_ACCES; + break; + case ENOMEM: + pstSavm->m_lErrno = MSG_ERR_NOMEM; + break; + default: + pstSavm->m_lErrno = MSG_ERR_INVAL; + break; + } + return RC_FAIL; + } + + return lQid; +} + +/************************************************************************************************* + description:Get the number of message queues + parameters: + pstSavm --stvm handle + lQid --msg id + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lGetQueueNum(SATvm *pstSavm, long lQid) +{ + struct msqid_ds stQueue; + + if(msgctl(lQid, IPC_STAT, &stQueue) <= -1) + { + switch(errno) + { + case EFAULT: + pstSavm->m_lErrno = MSG_ERR_FAULT; + break; + case EIDRM: + pstSavm->m_lErrno = MSG_ERR_EIDRM; + break; + default: + pstSavm->m_lErrno = MSG_ERR_INVAL; + break; + } + + return RC_FAIL; + } + + return stQueue.msg_qnum; +} + +/************************************************************************************************* + description:Get the maximum queue support byte + parameters: + pstSavm --stvm handle + lQid --msg id + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lQueueMaxByte(SATvm *pstSavm, long lQid) +{ + struct msqid_ds stQueue; + + if(msgctl(lQid, IPC_STAT, &stQueue) <= -1) + { + switch(errno) + { + case EFAULT: + pstSavm->m_lErrno = MSG_ERR_FAULT; + break; + case EIDRM: + pstSavm->m_lErrno = MSG_ERR_EIDRM; + break; + default: + pstSavm->m_lErrno = MSG_ERR_INVAL; + break; + } + + return RC_FAIL; + } + + return stQueue.msg_qbytes; +} + +/************************************************************************************************* + description:Gets the final processing time in the queue + parameters: + pstSavm --stvm handle + lQid --msg id + return: + long --success + RC_FAIL --failure + *************************************************************************************************/ +long lQueueRcvTime(SATvm *pstSavm, long lQid) +{ + struct msqid_ds stQueue; + + if(msgctl(lQid, IPC_STAT, &stQueue) <= -1) + { + switch(errno) + { + case EFAULT: + pstSavm->m_lErrno = MSG_ERR_FAULT; + break; + case EIDRM: + pstSavm->m_lErrno = MSG_ERR_EIDRM; + break; + default: + pstSavm->m_lErrno = MSG_ERR_INVAL; + break; + } + + return RC_FAIL; + } + +// return (long)time(&stQueue.msg_rtime); + return (long)stQueue.msg_rtime > 0 ? (long)stQueue.msg_rtime : (long)stQueue.msg_ctime; +} + +/************************************************************************************************* + description:read from message queue + parameters: + pstSavm --stvm handle + lQid --msg id + pstVoid --create type + lSize --create type + lMType --msg type + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lEventRead(SATvm *pstSavm, long lQid, void *pstVoid, long lSize, long lMType) +{ + if(RC_SUCC > msgrcv(lQid, pstVoid, lSize - sizeof(long), lMType, 0)) + { + switch(errno) + { + case E2BIG: + pstSavm->m_lErrno = MSG_ERR_E2BIG; + break; + case EACCES: + pstSavm->m_lErrno = MSG_ERR_ACCES; + break; + case EFAULT: + pstSavm->m_lErrno = MSG_ERR_FAULT; + break; + case EIDRM: + pstSavm->m_lErrno = MSG_ERR_EIDRM; + break; + case EINTR: + pstSavm->m_lErrno = MSG_ERR_EINTR; + break; + default: + pstSavm->m_lErrno = MSG_ERR_INVAL; + break; + } + + return RC_FAIL; + } + + return RC_SUCC; +} + +/************************************************************************************************* + description:non-blocking read from message queue + parameters: + pstSavm --stvm handle + lQid --msg id + pstVoid --create type + lSize --create type + lMType --msg type + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lReadNoWait(SATvm *pstSavm, long lQid, void *psvVoid, long lSize, long lMType) +{ + errno = 0; + if(RC_SUCC > msgrcv(lQid, psvVoid, lSize - sizeof(long), lMType, IPC_NOWAIT)) + { + switch(errno) + { + case EAGAIN: + case ENOMSG: + return RC_SUCC; + case E2BIG: + pstSavm->m_lErrno = MSG_ERR_E2BIG; + break; + case EACCES: + pstSavm->m_lErrno = MSG_ERR_ACCES; + break; + case EFAULT: + pstSavm->m_lErrno = MSG_ERR_FAULT; + break; + case EIDRM: + pstSavm->m_lErrno = MSG_ERR_EIDRM; + break; + case EINTR: + pstSavm->m_lErrno = MSG_ERR_EINTR; + return RC_FAIL; + default: + pstSavm->m_lErrno = MSG_ERR_INVAL; + break; + } + + return RC_FAIL; + } + + return RC_SUCC; +} + +/************************************************************************************************* + description:write to message queue + parameters: + pstSavm --stvm handle + lQid --msg id + pstVoid --create type + lSize --create type + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lEventWrite(SATvm *pstSavm, long lQid, void *psvData, long lSize) +{ + if(msgsnd(lQid, psvData, lSize - sizeof(long), 0) < RC_SUCC) + { + switch(errno) + { + case EACCES: + pstSavm->m_lErrno = MSG_ERR_ACCES; + break; + case EAGAIN: + pstSavm->m_lErrno = MSG_ERR_SNDEG; + break; + case EFAULT: + pstSavm->m_lErrno = MSG_ERR_FAULT; + break; + case EIDRM: + pstSavm->m_lErrno = MSG_ERR_EIDRM; + break; + case EINTR: + pstSavm->m_lErrno = MSG_ERR_EINTR; + break; + default: + pstSavm->m_lErrno = MSG_ERR_INVAL; + break; + } + + return RC_FAIL; + } + + return RC_SUCC; +} + +/**************************************************************************************** + code end + ****************************************************************************************/ + diff --git a/src/sem.c b/src/sem.c new file mode 100644 index 0000000..860c1ac --- /dev/null +++ b/src/sem.c @@ -0,0 +1,144 @@ +/* +* Copyright (c) 2018 Savens Liu +* +* The original has been patented, Open source is not equal to open rights. +* Anyone can clone, download, learn and discuss for free. Without the permission +* of the copyright owner or author, it shall not be merged, published, licensed or sold. +* The copyright owner or author has the right to pursue his responsibility. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "tvm.h" + +/**************************************************************************************** + senum union + ****************************************************************************************/ +union semun { + int val; + struct semid_ds *buf; + struct seminfo *__buf; +}; + +/************************************************************************************************ + sems function + ************************************************************************************************/ +/************************************************************************************************* + description:create semaphore + parameters: + pstSavm --stvm handle + pstRun --table handle + lSems --the number of semaphores + lValue --The index of the semaphores + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lCreateSems(SATvm *pstSavm, RunTime *pstRun, long lSems, long lValue) +{ + long i = 0; + union semun uSem; + + if(lSems <= 0) + { + pstSavm->m_lErrno = SEM_CDIT_NULL; + return RC_FAIL; + } + + if(RC_FAIL == (pstRun->m_semID = semget(pstSavm->m_ySey, lSems, IPC_CREAT|0600))) + { + switch(errno) + { + case EEXIST: + pstSavm->m_lErrno = SEM_ERR_EXIST; + break; + case EIDRM: + pstSavm->m_lErrno = SEM_ERR_EIDRM; + break; + case EACCES: + pstSavm->m_lErrno = SEM_ERR_ACCES; + break; + case ENOMEM: + pstSavm->m_lErrno = SEM_ERR_NOMEM; + break; + default: + pstSavm->m_lErrno = SEM_ERR_INVAL; + break; + } + + return RC_FAIL; + } + + for(i = 0, uSem.val = lValue; i < lSems; i ++) + semctl(pstRun->m_semID, i, SETVAL, uSem); + + return RC_SUCC; +} + +/************************************************************************************************* + description:create semaphore + parameters: + pstSavm --stvm handle + semID --the idx of semaphores + lSems --the number of semaphores + evp --opereate of P-V + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lOperateSems(SATvm *pstSavm, long semID, long lSems, Benum evp) +{ + struct sembuf se; + + se.sem_num = lSems; + se.sem_op = evp; + se.sem_flg = SEM_UNDO; + + if(RC_SUCC != semop(semID, &se, 1)) + { + switch(errno) + { + case EINTR: + return RC_SUCC; + case EEXIST: + pstSavm->m_lErrno = SEM_ERR_EXIST; + break; + case EIDRM: + pstSavm->m_lErrno = SEM_ERR_EIDRM; + break; + case EACCES: + pstSavm->m_lErrno = SEM_ERR_ACCES; + break; + case ENOMEM: + pstSavm->m_lErrno = SEM_ERR_NOMEM; + break; + case E2BIG: + case ERANGE: + pstSavm->m_lErrno = SEM_ERR_INVAL; + break; + default: + pstSavm->m_lErrno = SEM_ERR_INVAL; + break; + } + + return RC_FAIL; + } + + return RC_SUCC; +} + + +/**************************************************************************************** + code end + ****************************************************************************************/ + diff --git a/src/str.c b/src/str.c new file mode 100644 index 0000000..1677afc --- /dev/null +++ b/src/str.c @@ -0,0 +1,480 @@ +/* +* Copyright (c) 2018 Savens Liu +* +* The original has been patented, Open source is not equal to open rights. +* Anyone can clone, download, learn and discuss for free. Without the permission +* of the copyright owner or author, it shall not be merged, published, licensed or sold. +* The copyright owner or author has the right to pursue his responsibility. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "tstr.h" + +/************************************************************************************************ + strs function + ************************************************************************************************/ +/************************************************************************************************* + description:uppercase string + parameters: + s --string + return: + s + *************************************************************************************************/ +char *supper(char *s) +{ + long i, l = strlen(s), fg = 0; + + for(i=0; i < l; i++) + s[i] = toupper(s[i]); + + return s; +} + +/************************************************************************************************* + description:lowercas string + parameters: + s --string + return: + s + *************************************************************************************************/ +char *slower(char *s) +{ + long i, l = strlen(s), fg = 0; + + for(i = 0; i < l; i++) + s[i] = tolower(s[i]); + + return s; +} + +/************************************************************************************************* + description:drop CRLF from string + parameters: + p --string + return: + p + *************************************************************************************************/ +char* strimcrlf(char *p) +{ + int i = 0, j = 0, m = 0; + char *s = NULL; + + if(!p) return p; + if(!strlen(p)) return p; + + s = p; + m = strlen(p); + for(i = 0; i < m; i ++) + { + if(p[i] == 10 || p[i] == 13) + continue; + s[j] = p[i]; + j ++; + } + s[j] = 0x00; + return s; +} + +/************************************************************************************************* + description:trim the left space from string + parameters: + p --string + return: + p + *************************************************************************************************/ +char* sltrim(char *p) +{ + char *s = p; + long i, k = 0, l; + + if(!p || (0 == (l = strlen(p)))) + return p; + + for(i = 0; i < l; i ++, k ++) + { + if(p[i] != ' ' && '\t' != p[i]) + break; + } + + if(0 == k) return p; + + for(i = 0; i < l - k; i ++) + p[i] = s[i + k]; + p[i] = 0x00; + + return p; +} + +/************************************************************************************************* + description:trim the right space from string + parameters: + p --string + return: + p + *************************************************************************************************/ +char* srtrim(char *p) +{ + long i, k = 0, l = 0; + + if(!p || 0 == (l = strlen(p))) + return p; + + for(i = l - 1; i >= 0; i --) + { + if(p[i] == ' ' || '\t' == p[i]) + continue; + break; + } + +// p[i + 1] = '\0'; + memset(p + i + 1, 0, l - i - 1); + + return p; +} + +/************************************************************************************************* + description:trimall space from string + parameters: + p --string + return: + p + *************************************************************************************************/ +char* strimall(char *p) +{ + long i, k = 0, l = 0; + char *q = p; + + if(!p || !strlen(p)) + return p; + + l = strlen(p); + for(i = 0; i < l; i ++) + { + if(p[i] == ' ') + continue; + q[k ++] = p[i]; + } + memset(q + k, 0, l - k); + p = q; + + return q; +} + +/************************************************************************************************* + description:trim the left space from field string + parameters: + p --string + return: + p + *************************************************************************************************/ +char* strimfield(char *s) +{ + register int i, n, m; + BOOL bf = false; + + if(!s || 0 == (n = strlen(s))) + return s; + + for(i = 0, m = 0; i < n; i ++) + { + if(s[i] == '\"') + bf = !bf; + + if(bf) s[m ++] = s[i]; + else if(s[i] != ' ' && s[i] != '\t') + s[m ++] = s[i]; + } + + s[m] = 0x00; + + return s; +} + +/************************************************************************************************* + description:calcute the number of field string + parameters: + p --string + k --string + return: + p + *************************************************************************************************/ +long lfieldnum(char *p, char *k) +{ + char *y = p; + BOOL bf = false; + long idx, i, m, n; + + if(!p || !k) return 0; + + for(i = 0, idx = 0, m = strlen(p), n = strlen(k); i < m; i ++) + { + if(p[i] == '\\') + { + i ++; + continue; + } + + if(p[i] == '\"' || p[i] == '\'') + bf = !bf; + + if(bf) continue; + + if(!memcmp(p + i, k, n)) + { + ++ idx; + for(i += n; i < m; i ++) + { + if(p[i] != ' ' && p[i] != '\t' && memcmp(p + i, k, n)) + break; + } + + y = p + i; + i --; + } + } + + for(i = y - p ; i < m; i ++) + { + if(y[i] != ' ' && y[i] != '\t') + return ++ idx; + } + + return idx; +} + +/************************************************************************************************* + description:is or not gbk-Character set + parameters: + s --string + return: + 1 --yes + 0 --no + *************************************************************************************************/ +int bIsgbk(const char *s) +{ + if((ushar)s[0] > 0x80 && (ushar)s[1] >= 0x40) + return 1; + return 0; +} + +/************************************************************************************************* + description:Gets the field value of the specified character position + parameters: + p --string + s --characters + id --position + return: + char --values + *************************************************************************************************/ +char* sfieldvalue(char *p, char *k, int id) +{ + char *y = p; + BOOL bf = false; + long idx, i = 0, m = 0, n = 0; + static char szOut[1024]; + + memset(szOut, 0, sizeof(szOut)); + if(!p || !k || id <= 0) return szOut; + + for(i = 0, idx = 0, m = strlen(p), n = strlen(k); i < m; i ++) + { + if(p[i] == '\\') + { + i ++; + continue; + } + + if(p[i] == '\"' || p[i] == '\'') + { + bf = !bf; + continue; + } + if(bf) continue; + + if(!memcmp(p + i, k, n)) + { + if(++idx == id) + break; + + for(i += n; i < m; i ++) + { + if(p[i] != ' ' && p[i] != '\t' && memcmp(p + i, k, n)) + break; + } + + y = p + i; + i --; + } + } + + if(idx + 1 < id) return szOut; + memcpy(szOut, y, i - (long )(y - p)); + + return szOut; +} + +/************************************************************************************************* + description:Gets the number of specified characters + parameters: + p --string + s --characters + return: + long --number + *************************************************************************************************/ +long lgetstrnum(char *p, char *s) +{ + char *q = p; + long i, m, n, k; + + if(!p || 0 == (n = strlen(s)) || 0 == (m = strlen(p))) + return 0; + + for(i = 0, k = 0; i < m; i += n, q += n) + { + if(0 == memcmp(q, s, n)) + k ++; + } + + return k; +} + +/************************************************************************************************* + description:Gets the value of the specified character position + parameters: + p --string + s --characters + id --position + return: + char --values + *************************************************************************************************/ +char* sgetvalue(char *p, char *s, int id) +{ + char *y = p; + long i, m, n, idx = 0; + static char szOut[1024]; + + memset(szOut, 0, sizeof(szOut)); + if(!p || !s || id <= 0 || (n = strlen(s)) <= 0) + return szOut; + + for(i = 0, idx = 0, m = strlen(p); i < m; i ++) + { + if(!memcmp(p + i, s, n)) + { + if(i > 0 && bIsgbk(p + i - 1)) + continue; + + if(++ idx == id) + break; + + y = p + i + n; + } + } + + if(idx + 1 < id) return szOut; + memcpy(szOut, y, i - (int)(y - p)); + + return szOut; +} + +/************************************************************************************************* + description:Characters to replace + parameters: + p --The original string + o --key characters + d --target character + return: + char --values + *************************************************************************************************/ +char* sfieldreplace(char *p, char o, char d) +{ + char *s = p; + bool bf = false; + long idx, i, j = 0, m = 0; + + if(!p) return p; + + for(i = 0, idx = 0, m = strlen(p); i < m; i ++) + { + if(p[i] == '\"' || p[i] == '\'') + bf = !bf; + + if(bf) + { + s[j ++] = p[i]; + continue; + } + + if(o == p[i]) + { + if(i > 0 && bIsgbk(p + i - 1)) + continue; + + p[i] = d; + } + + if((j == 0 && ' ' == p[i]) || (j > 0 && ' ' == s[j - 1] && p[i] == ' ')) + continue; + s[j ++] = p[i]; + } + s[j] = 0x00; + + return s; +} + +/************************************************************************************************* + description:Get the value between o-d + parameters: + p --The original string + o --key characters + d --target character + return: + char* --values + *************************************************************************************************/ +char* strimabout(char *s, char *o, char *d) +{ + long l = 0; + char *p = NULL, *q = NULL, *m = NULL; + + if(!s || !o || !d) return NULL; + if(0 == (l = strlen(s))) return NULL; + if(NULL == (p = strstr(s, o))) return NULL; + + for(l; l > 0; l --) + { + if(NULL != (q = strstr(s + l, d))) + break; + } + if(!q) return NULL; + + l = strlen(o); + if((p - q) >= 0) return NULL; + + if(((p - q + l) == 0)) + { + s[0] = 0x00; + return NULL; + } + + for(m = s, p += l; p != q; *p ++, *m ++) + *m = *p; + *m = 0x00; + + return s; +} + +/**************************************************************************************** + code end +****************************************************************************************/ + diff --git a/src/stvm.c b/src/stvm.c new file mode 100644 index 0000000..c17a0c4 --- /dev/null +++ b/src/stvm.c @@ -0,0 +1,4139 @@ +/* +* Copyright (c) 2018 Savens Liu +* +* The original has been patented, Open source is not equal to open rights. +* Anyone can clone, download, learn and discuss for free. Without the permission +* of the copyright owner or author, it shall not be merged, published, licensed or sold. +* The copyright owner or author has the right to pursue his responsibility. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +#define _GNU_SOURCE +#include "tvm.h" +#include "tmain.h" +#include +#include + +/************************************************************************************************* + macro + *************************************************************************************************/ +#define DEL_TAIL_CHAR(s,c) if(c == s[strlen(s) - 1]) s[strlen(s) - 1] = 0x00; + +/************************************************************************************************* + function + *************************************************************************************************/ +Benum elog = 0; +extern char **environ; +extern long lShutdownTvm(); +extern void vSetNode(char *s); +extern long lStartupTvm(TBoot *pstBoot); + +/************************************************************************************************* + description:get stvm version + parameters: + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +static char* sGetTVMVers() +{ + struct utsname sinf; + static char szVersion[512]; + + memset(szVersion, 0, sizeof(szVersion)); + sprintf(szVersion, "Compile %s %s on ", __DATE__, __TIME__); + if(RC_SUCC != uname(&sinf)) + strcat(szVersion, "Linux"); + else + strcat(szVersion, sinf.sysname); + + sprintf(szVersion + strlen(szVersion), " %s Runtime\nRelease TVM C/C++ Library Version V%s on", + sinf.machine, TVM_VKERNEL); + if(8 == sizeof(long)) + strcat(szVersion, " Linux x64\n"); + else + strcat(szVersion, " Linux x32\n"); + sprintf(szVersion + strlen(szVersion), "Release STVM %s Production on %s %s\n", + TVM_VERSION, sinf.sysname, sinf.machine); + + strcat(szVersion, "Author:DeffPuzzL\n"); + strcat(szVersion, "Mail:deffpuzzl@qq.com\n"); + + return szVersion; +} + +/************************************************************************************************* + description:Get the Domain version + parameters: + return: + char* + *************************************************************************************************/ +char* sFuncVersion() +{ + struct utsname sinf; + static char szVersion[512]; + + memset(szVersion, 0, sizeof(szVersion)); + sprintf(szVersion, "Compile %s %s ", __DATE__, __TIME__); + uname(&sinf); + + sprintf(szVersion + strlen(szVersion), "Release %s Production on %s", TVM_VERSION, + sinf.sysname); + + if(8 == sizeof(long)) + strcat(szVersion, " x64\n"); + else + strcat(szVersion, " x32\n"); + + return szVersion; +} + +/************************************************************************************************* + description:Screen output debugging + parameters: + return: + *************************************************************************************************/ +void vSCRDebug(const char *fmt, ...) +{ + char szMsg[1024]; + va_list ap; + + if(0 == elog) return ; + + memset(szMsg, 0, sizeof(szMsg)); + va_start(ap, fmt); + vsnprintf(szMsg, sizeof(szMsg), fmt, ap); + va_end(ap); + + fprintf(stdout, "%s\n", szMsg); +} + +/************************************************************************************************* + description:get pragma pack + parameters: + return: + int --align + *************************************************************************************************/ +int getpack() +{ + int pack; + + struct Test + { + int a; + long b; + long long c; + char d; + }; + + pack = sizeof(struct Test); + if(8 == sizeof(long)) + { + switch(pack) + { + case 21: + return 1; + case 22: + return 2; + case 24: + return 4; + case 32: + return 8; + default: + fprintf(stdout, "当前环境对齐数值(%d)过大\n", pack); + fflush(stdout); + return -1; + } + } + else + { + switch(pack) + { + case 17: + return 1; + case 18: + return 2; + case 20: + return 4; + case 24: + return 8; + default: + fprintf(stdout, "当前环境对齐数值(%d)过大\n", pack); + fflush(stdout); + return -1; + } + } + + return pack; +} + +/************************************************************************************************* + description:Sizeof function + parameters: + return: + sizeof + *************************************************************************************************/ +int sizecn(TblKey *pstKey, long lfld) +{ + TblKey *pv; + int i, n, k, pack, size = 0; + + if(0 == lfld) return 0; + + if(-1 == (pack = getpack())) + return pack; + + for(i = 0, k = 0; i < lfld; i ++) + { + pv = &pstKey[i]; + if(FIELD_CHAR != pv->m_lAttr && pv->m_lLen > k) + k = pv->m_lLen; + } + + /* 若使用了#pragma pack(n)命令强制对齐标准, 则取n和结构体中 + 最长数据类型占的字节数两者之中的小者作为对齐标准。 */ + if(k < pack) pack = k; + if(pack == 0) return 0; + + for(i = 0, n = 0, k = 0; i < lfld; i ++) + { + pv = &pstKey[i]; + if(0 == pv->m_lLen) continue; + if(FIELD_CHAR != pv->m_lAttr) + { + /* 数据对齐原则----内存按结构成员的先后顺序排列,当排到该成员变量时, + * 其前面已摆放的空间大小必须是该成员类型大小的整倍数,如果不够则补齐 */ + /* 没有考虑用户指定 指定对齐值:#pragma pack (value)时指定的对齐value。 */ + if(pack > pv->m_lLen) + n = pv->m_lLen; + else + n = pack; + + if(0 != (k = size % n)) + size += (n - k); + } + + pv->m_lFrom = size; + size += pv->m_lLen; + } + + /* 整体空间是 占用空间最大的成员(的类型)所占字节数的整倍数 */ + if(0 != (k = size % pack)) + size += (pack - k); + + return size; +} + +/************************************************************************************************* + description:analysis of the table header + parameters: + s --string + len --strlen length + pstTde --Table define + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lAnalysHead(char *s, long len, TblDef *pstTde) +{ + long i, n; + char szTemp[512], szHead[512], szTar[64], *p = NULL; + + memset(szHead, 0, sizeof(szHead)); + if(len > sizeof(szHead)) + { + fprintf(stderr, "table head define error\n"); + return RC_FAIL; + } + + strncpy(szHead, s, len); + for(i = 0, n = lgetstrnum(szHead, "\n"); i < n; i ++) + { + memset(szTemp, 0, sizeof(szTemp)); + strncpy(szTemp, sfieldvalue(szHead, "\n", i + 1), sizeof(szTemp)); + if('#' == szTemp[0] || !strncmp(szTemp, "--", 2) || !strlen(szTemp)) + continue; + + if(strncasecmp(szTemp, "set ", 4)) + { + fprintf(stderr, "definition table syntax error\n*%s\n", szTemp); + return RC_FAIL; + } + + memset(szTar, 0, sizeof(szTar)); + strncpy(szTar, sfieldvalue(szTemp + 4, "=", 1), sizeof(szTar)); + sltrim(szTar); + if(!strcasecmp(szTar, "TABLE")) + { + pstTde->m_table = atol(sfieldvalue(szTemp + 4, "=", 2)); + if(pstTde->m_table < 5) + { + fprintf(stderr, "definition table error\n"); + return RC_FAIL; + } + } + else if(!strcasecmp(szTar, "TABLESPACE")) + pstTde->m_lMaxRow = atol(sfieldvalue(szTemp + 4, "=", 2)); + else + { + fprintf(stderr, "Unrecognized command\n*%s\n", szTemp); + return RC_FAIL; + } + } + if(pstTde->m_table < 5) + { + fprintf(stderr, "table not define\n"); + return RC_FAIL; + } + + if(pstTde->m_lMaxRow <= 0) + { + fprintf(stderr, "table size node define\n"); + return RC_FAIL; + } + + strcpy(pstTde->m_szPart, sGetNode()); + + return RC_SUCC; +} + +/************************************************************************************************* + description:analysis of the table + parameters: + s --string + len --strlen length + pstTde --Table define + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lAnalysTable(char *s, long len, TblDef *pstTde) +{ + long i, n, k; + TblKey *pv = NULL; + char szTemp[512], szField[1024], szTar[128], *p = NULL; + + memset(szField, 0, sizeof(szField)); + if(len > sizeof(szField) || len < 1) + { + fprintf(stderr, "table head define error\n"); + return RC_FAIL; + } + + strncpy(szField, s, len); + strimabout(szField, "(", ")"); + for(i = 0, n = lgetstrnum(szField, "\n"), pstTde->m_lIdxNum = 0; i < n; i ++) + { + memset(szTemp, 0, sizeof(szTemp)); + strncpy(szTemp, sfieldvalue(szField, "\n", i + 1), sizeof(szTemp)); + strimcrlf(szTemp); + sltrim(szTemp); + srtrim(szTemp); + DEL_TAIL_CHAR(szTemp, ','); + if('#' == szTemp[0] || !strncmp(szTemp, "--", 2) || !strlen(szTemp)) + continue; + + pv = &pstTde->m_stKey[pstTde->m_lIdxNum]; + strncpy(pv->m_szField, sfieldvalue(szTemp, " ", 1), MAX_FIELD_LEN); + if(!strlen(pv->m_szField)) + { + fprintf(stderr, "field define error\n"); + return RC_FAIL; + } + memset(szTar, 0, sizeof(szTar)); + strncpy(szTar, sfieldvalue(szTemp, " ", 2), MAX_FIELD_LEN); + if(!strcasecmp(szTar, "short")) + { + pv->m_lAttr = FIELD_LONG; + pv->m_lLen = sizeof(short); + } + else if(!strcasecmp(szTar, "int")) + { + pv->m_lAttr = FIELD_LONG; + pv->m_lLen = sizeof(int); + } + else if(!strcasecmp(szTar, "long")) + { + pv->m_lAttr = FIELD_LONG; + pv->m_lLen = sizeof(long); + } + else if(!strcasecmp(szTar, "llong")) + { + pv->m_lAttr = FIELD_LONG; + pv->m_lLen = sizeof(long long); + } + else if(!strcasecmp(szTar, "double")) + { + pv->m_lAttr = FIELD_DOUB; + pv->m_lLen = sizeof(double); + } + else if(!strcasecmp(szTar, "float")) + { + pv->m_lAttr = FIELD_DOUB; + pv->m_lLen = sizeof(float); + } + else if(!strncasecmp(szTar, "char", 1)) + { + pv->m_lAttr = FIELD_CHAR; + if(!strcasecmp(szTar, "char")) + pv->m_lLen = sizeof(char); + else + { + p = szTar + 4; + strimabout(p, "(", ")"); + strimabout(p, "[", "]"); + if(!strlen(p) || atol(p) <= 0) + { + fprintf(stderr, "Character size setting error\n"); + return RC_FAIL; + } + pv->m_lLen = atol(p); + } + } + else + { + fprintf(stderr, "Undefined field type\n"); + return RC_FAIL; + } + + pstTde->m_lIdxNum ++; + } + + return RC_SUCC; +} + +/************************************************************************************************* + description:creates the table index + parameters: + s --string + pstTde --Table define + em --index type + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lIndexField(char *s, TblDef *pstTde, Uenum em) +{ + long i, n; + TblKey *pstKey = NULL; + char szField[MAX_FIELD_LEN]; + + n = lfieldnum(s, ","); + if(UNQIUE == em) + { + for(i = 0, pstTde->m_lIType |= UNQIUE, pstTde->m_lIdxUp = 0; i < n; i ++) + { + memset(szField, 0, MAX_FIELD_LEN); + strncpy(szField, sfieldvalue(s, ",", i + 1), MAX_FIELD_LEN); + strimcrlf(szField); + strimall(szField); + if(NULL == (pstKey = pFindField(pstTde->m_stKey, pstTde->m_lIdxNum, szField))) + return RC_FAIL; + + strcpy(pstTde->m_stIdxUp[pstTde->m_lIdxUp].m_szField, szField); + pstTde->m_stIdxUp[pstTde->m_lIdxUp].m_lFrom = pstKey->m_lFrom; + pstTde->m_stIdxUp[pstTde->m_lIdxUp].m_lLen = pstKey->m_lLen; + pstTde->m_stIdxUp[pstTde->m_lIdxUp].m_lAttr = pstKey->m_lAttr; + pstTde->m_lIdxLen += pstKey->m_lLen; + pstTde->m_lIdxUp ++; + } + if(0 == pstTde->m_lIdxUp) + return RC_FAIL; + return RC_SUCC; + } + else if(NORMAL == em) + { + for(i = 0, pstTde->m_lIType |= NORMAL, pstTde->m_lGrpUp = 0; i < n; i ++) + { + memset(szField, 0, MAX_FIELD_LEN); + strncpy(szField, sfieldvalue(s, ",", i + 1), MAX_FIELD_LEN); + strimcrlf(szField); + strimall(szField); + if(NULL == (pstKey = pFindField(pstTde->m_stKey, pstTde->m_lIdxNum, szField))) + return RC_FAIL; + + strcpy(pstTde->m_stGrpUp[pstTde->m_lGrpUp].m_szField, szField); + pstTde->m_stGrpUp[pstTde->m_lGrpUp].m_lFrom = pstKey->m_lFrom; + pstTde->m_stGrpUp[pstTde->m_lGrpUp].m_lLen = pstKey->m_lLen; + pstTde->m_stGrpUp[pstTde->m_lGrpUp].m_lAttr = pstKey->m_lAttr; + pstTde->m_lGrpLen += pstKey->m_lLen; + pstTde->m_lGrpUp ++; + } + + if(0 == pstTde->m_lGrpUp) + return RC_FAIL; + return RC_SUCC; + } + else if(HASHID == em) + { + for(i = 0, pstTde->m_lIType |= HASHID, pstTde->m_lGrpUp = 0; i < n; i ++) + { + memset(szField, 0, MAX_FIELD_LEN); + strncpy(szField, sfieldvalue(s, ",", i + 1), MAX_FIELD_LEN); + strimcrlf(szField); + strimall(szField); + if(NULL == (pstKey = pFindField(pstTde->m_stKey, pstTde->m_lIdxNum, szField))) + return RC_FAIL; + strcpy(pstTde->m_stGrpUp[pstTde->m_lGrpUp].m_szField, szField); + pstTde->m_stGrpUp[pstTde->m_lGrpUp].m_lFrom = pstKey->m_lFrom; + pstTde->m_stGrpUp[pstTde->m_lGrpUp].m_lLen = pstKey->m_lLen; + pstTde->m_stGrpUp[pstTde->m_lGrpUp].m_lAttr = pstKey->m_lAttr; + pstTde->m_lGrpLen += pstKey->m_lLen; + pstTde->m_lGrpUp ++; + } + + if(0 == pstTde->m_lGrpUp) + return RC_FAIL; + return RC_SUCC; + } + + return RC_FAIL; +} + +/************************************************************************************************* + description:analysis of the header index + parameters: + s --string + pstTde --Table define + em --index type + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lAnalysIndex(char *s, long len, TblDef *pstTde) +{ + long i, n, k, lRet; + char szIndex[1024], szTemp[256], *p = NULL; + + memset(szIndex, 0, sizeof(szIndex)); + if(len > sizeof(szIndex) || len < 1) + { + fprintf(stderr, "table head define error\n"); + return RC_FAIL; + } + + strncpy(szIndex, s, len); + strcat(szIndex, "\n"); + for(i = 0, k = 0, n = lgetstrnum(szIndex, "\n"), pstTde->m_lIType = 0; i < n; i ++) + { + memset(szTemp, 0, sizeof(szTemp)); + strncpy(szTemp, sfieldvalue(szIndex, "\n", i + 1), sizeof(szTemp)); + strimcrlf(szTemp); + sltrim(szTemp); + srtrim(szTemp); + DEL_TAIL_CHAR(szTemp, ','); + if('#' == szTemp[0] || !strncmp(szTemp, "--", 2) || !strlen(szTemp)) + continue; + + if(p = strcasestr(szTemp, "create unique index")) + { + strimabout(p, "(", ")"); + if(k & UNQIUE) + { + fprintf(stderr, "Only one unique index can be created\n"); + return RC_FAIL; + } + + k |= UNQIUE; + lRet = lIndexField(p, pstTde, UNQIUE); + } + else if(p = strcasestr(szTemp, "create index")) + { + strimabout(p, "(", ")"); + if(k & NORMAL) + { + fprintf(stderr, "Only one index can be created\n"); + return RC_FAIL; + } + + k |= NORMAL; + lRet = lIndexField(p, pstTde, NORMAL); + } + else if(p = strcasestr(szTemp, "create hash")) + { + strimabout(p, "(", ")"); + if(k & NORMAL) + { + fprintf(stderr, "Only one index can be created\n"); + return RC_FAIL; + } + + k |= NORMAL; + lRet = lIndexField(p, pstTde, HASHID); + } + else + { + fprintf(stderr, "index define error\n"); + return RC_FAIL; + } + + if(RC_SUCC != lRet) + { + fprintf(stderr, "parse index field error\n"); + return RC_FAIL; + } + } + + return RC_SUCC; +} + +/************************************************************************************************* + description: + parameters: + pszTable --table name + return: + char* --struck name + *************************************************************************************************/ +char* sGetTabName(char *pszTable) +{ + long l = 0; + static char szName[512]; + char *p = NULL, *q = NULL; + + slower(pszTable); + memset(szName, 0, sizeof(szName)); + if(!pszTable || !strlen(pszTable)) + return szName; + + l = 0; + strcpy(szName, "db"); + while(p = strstr(pszTable + l, "_")) + { + p[0 + 1]= p[0 + 1] - 32; + q = strstr(p + 1, "_"); + if(!q) + strcat(szName, p + 1); + else + strncpy(szName + strlen(szName), p + 1, q - p - 1); + l = p - pszTable + 1; + } + return szName; +} + +/************************************************************************************************* + description:creates the table struck + parameters: + pstTde --Table define + em --index type + return: + *************************************************************************************************/ +void vCreateStruck(TblDef *pstTde, bool bf) +{ + long i; + TblKey *pv = NULL; + + fprintf(stdout, "\n#Table definition\n"); + if(bf) + { + fprintf(stdout, "\nset TABLE=%d\n", pstTde->m_table); + fprintf(stdout, "set TABLESPACE=%d\n\n", pstTde->m_lMaxRow); + } + + fprintf(stdout, "typedef struct __%s\n{\n", supper(pstTde->m_szTable)); + for(i = 0; i < pstTde->m_lIdxNum; i ++) + { + pv = &pstTde->m_stKey[i]; + if(FIELD_CHAR == pv->m_lAttr) + fprintf(stdout, " char %s[%d];\n", pv->m_szField, pv->m_lLen); + else if(FIELD_LONG == pv->m_lAttr) + { + switch(pv->m_lLen) + { + case 2: + fprintf(stdout, " short %s;\n", pv->m_szField); + break; + case 4: + fprintf(stdout, " int %s;\n", pv->m_szField); + break; + case 8: + if(8 == sizeof(long)) + fprintf(stdout, " long %s;\n", pv->m_szField); + else + fprintf(stdout, " llong %s;\n", pv->m_szField); + break; + default: + break; + } + } + else if(FIELD_DOUB == pv->m_lAttr) + { + switch(pv->m_lLen) + { + case 4: + fprintf(stdout, " float %s;\n", pv->m_szField); + break; + case 8: + fprintf(stdout, " double %s;\n", pv->m_szField); + break; + default: + break; + } + } + } + + fprintf(stdout, "}%s;\n", sGetTabName(supper(pstTde->m_szTable))); + + if(bf) + { + fprintf(stdout, "\n-- Create indexes\n"); + if(pstTde->m_lIType & UNQIUE) + { + pv = &pstTde->m_stIdxUp[0]; + fprintf(stdout, "create unique index (%s", pv->m_szField); + for(i = 1; i < pstTde->m_lIdxUp; i ++) + { + pv = &pstTde->m_stKey[i]; + fprintf(stdout, ", %s", pv->m_szField); + } + fprintf(stdout, ");\n"); + } + + if(pstTde->m_lIType & NORMAL) + { + pv = &pstTde->m_stGrpUp[0]; + fprintf(stdout, "create index (%s", pv->m_szField); + for(i = 1; i < pstTde->m_lGrpUp; i ++) + { + pv = &pstTde->m_stKey[i]; + fprintf(stdout, ", %s", pv->m_szField); + } + fprintf(stdout, ");\n"); + + } + else if(pstTde->m_lIType & HASHID) + { + pv = &pstTde->m_stGrpUp[0]; + fprintf(stdout, "create hash (%s", pv->m_szField); + for(i = 1; i < pstTde->m_lGrpUp; i ++) + { + pv = &pstTde->m_stKey[i]; + fprintf(stdout, ", %s", pv->m_szField); + } + fprintf(stdout, ");\n"); + } + } + fprintf(stdout, "\n"); + return ; +} + +/************************************************************************************************* + description:out put table struct + parameters: + t --table + return: + *************************************************************************************************/ +void vTableStruck(TABLE t) +{ + RunTime *pstRun = NULL; + SATvm *pstSavm = (SATvm *)pGetSATvm(); + + if(NULL == (pstSavm = (SATvm *)pInitSATvm(t))) + { + fprintf(stderr, "initial table (%d) failed\n", t); + return ; + } + + if(NULL == (pstRun = pInitHitTest(pstSavm, pstSavm->tblName))) + { + fprintf(stderr, "hit test table (%d) failed, err:(%d)(%s)\n", t,pstSavm->m_lErrno, + sGetTError(pstSavm->m_lErrno)); + return ; + } + + vCreateStruck((TblDef *)pGetTblDef(t), 0); + vTblDisconnect(pstSavm, pstSavm->tblName); + + return ; +} + +/************************************************************************************************* + description:user define table + parameters: + pszCreate --create string + return: + *************************************************************************************************/ +long lDefineTable(char *pszCreate, char *pszTable) +{ + long i; + TblDef stTde; + char *p = NULL, *q = NULL; + SATvm *pstSavm = (SATvm *)pGetSATvm(); + + sfieldreplace(pszCreate, '\t', ' '); + if(NULL == (p = strcasestr(pszCreate, "create table"))) + { + fprintf(stderr, "Lost table syntax\n"); + return RC_FAIL; + } + + memset(&stTde, 0, sizeof(TblDef)); + if(RC_SUCC != lAnalysHead(pszCreate, p - pszCreate, &stTde)) + return RC_FAIL; + + strncpy(stTde.m_szTable, sfieldvalue(p + 12, "\n", 1), sizeof(stTde.m_szTable)); + srtrim(stTde.m_szTable); + sltrim(stTde.m_szTable); + + if(NULL == (q = strcasestr(p, ";"))) + { + fprintf(stderr, "Separator missing\n"); + return RC_FAIL; + } + + if(RC_SUCC != lAnalysTable(p + 12, q - p - 12, &stTde)) + return RC_FAIL; + + stTde.m_lReSize = sizecn(stTde.m_stKey, stTde.m_lIdxNum); + stTde.m_lTruck = stTde.m_lReSize + sizeof(SHTruck); + + if(RC_SUCC != lAnalysIndex(q + 1, strlen(q + 1), &stTde)) + return RC_FAIL; + + if(RC_SUCC != lCustomTable(pstSavm, stTde.m_table, stTde.m_lMaxRow, &stTde)) + { + fprintf(stderr, "create table error: %s\n", sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; + } + + strcpy(pszTable, stTde.m_szTable); + return RC_SUCC; +} + +/************************************************************************************************* + description:create table by file + parameters: + return: + SQLFld + *************************************************************************************************/ +long lCreateByFile(char *pszFile) +{ + FILE *fp = NULL; + struct stat stBuf; + SATvm *pstSavm = (SATvm *)pGetSATvm(); + char *pszCreate = NULL, szTable[MAX_FIELD_LEN]; + + sltrim(pszFile); + srtrim(pszFile); + fprintf(stdout, "\n------------------------------------------------------SQL Result" + "-----------------------------------------------------\n"); + if(0 == strlen(pszFile)) + { + fprintf(stderr, "create table syntax error\n"); + return RC_FAIL; + } + + if(0 != access(pszFile, F_OK | R_OK )) + { + fprintf(stderr, "%s is't exist, %s\n", pszFile, strerror(errno)); + return RC_FAIL; + } + + if(0 != stat(pszFile, &stBuf)) + { + fprintf(stderr, "get %s stat error: %s\n", pszFile, strerror(errno)); + return RC_FAIL; + } + + if(!(S_IFREG == (S_IFREG & stBuf.st_mode))) + { + fprintf(stderr, "file stat error\n"); + return RC_FAIL; + } + + if(NULL == (pszCreate = (char *)calloc(stBuf.st_size, 1))) + { + fprintf(stderr, "create memory error, %s\n", strerror(errno)); + return RC_FAIL; + } + + if(NULL == (fp = fopen(pszFile, "r"))) + { + TFree(pszFile); + fprintf(stderr, "open file %s error, %s\n", strerror(errno)); + return RC_FAIL; + } + + fread(pszCreate, stBuf.st_size, 1, fp); + fclose(fp); + + if(RC_SUCC != lDefineTable(pszCreate, szTable)) + return RC_FAIL; + + fprintf(stdout, "---(%s) was created ---\n", szTable); + + + TFree(pszCreate); + return RC_SUCC; +} + +/************************************************************************************************* + description:Get the end node of the list + parameters: + return: + SQLFld + *************************************************************************************************/ +SQLFld* pGetFieldTail(SQLFld *pstRoot) +{ + SQLFld *pstList = pstRoot; + + if(!pstList) return NULL; + + while(pstList->pstNext) + pstList = pstList->pstNext; + + return pstList; +} + +/************************************************************************************************* + description:add node + parameters: + return: + SQLFld + *************************************************************************************************/ +SQLFld* pInsertFiled(SQLFld *pstRoot, SQLFld *pstNode) +{ + SQLFld *pstNext = NULL, *pstTail = pGetFieldTail(pstRoot); + + if(NULL == (pstNext = (SQLFld *)malloc(sizeof(SQLFld)))) + return pstRoot; + + memcpy(pstNext, pstNode, sizeof(SQLFld)); + pstNext->pstNext = NULL; + + if(!pstRoot) + pstRoot = pstNext; + else + pstTail->pstNext = pstNext; + + return pstRoot; +} + +/************************************************************************************************* + description:Clean up the list + parameters: + return: + *************************************************************************************************/ +void vDestroyFiled(SQLFld *pstRoot) +{ + SQLFld *pstNode = pstRoot, *pstList = NULL; + + while(pstNode) + { + pstList = pstNode; + pstNode = pstNode->pstNext; + TFree(pstList); + } +} + +/************************************************************************************************* + description:Get the number of nodes + parameters: + return: + lCnt --number of nodes + *************************************************************************************************/ +long lGetNodeFiled(SQLFld *pstRoot) +{ + long lCnt; + SQLFld *pstNode = NULL; + + for(pstNode = pstRoot, lCnt = 0; pstNode; pstNode = pstNode->pstNext, lCnt ++); + + return lCnt; +} + +/************************************************************************************************* + description:sort the field + parameters: + return: + SQLFld --root + *************************************************************************************************/ +SQLFld* pSortSQLField(SQLFld *pstRoot) +{ + TblKey stKey; + SQLFld *pstNode = NULL, *pstList = NULL; + + for(pstNode = pstRoot; pstNode; pstNode = pstNode->pstNext) + { + for(pstList = pstNode->pstNext; pstList; pstList = pstList->pstNext) + { + if(pstNode->m_stKey.m_lFrom < pstList->m_stKey.m_lFrom) + continue; + + memcpy(&stKey, &pstNode->m_stKey, sizeof(TblKey)); + memcpy(&pstNode->m_stKey, &pstList->m_stKey, sizeof(TblKey)); + memcpy(&pstList->m_stKey, &stKey, sizeof(TblKey)); + } + } + + return pstRoot; +} + +/************************************************************************************************* + description:Returns the current time in millisecond + parameters: + return: + lTime --millisecond + *************************************************************************************************/ +long lGetTiskTime() +{ + long lTime; + struct timeval t; + struct tm *ptm; + + gettimeofday(&t, NULL); + ptm = localtime(&t.tv_sec); + + lTime = ptm->tm_min * 60 * 1000 + ptm->tm_sec * 1000 + t.tv_usec / 1000; + return lTime; +} + +/************************************************************************************************* + description:Calculate time consumption (milliseconds) + parameters: + return: + szTime --Time string + *************************************************************************************************/ +char* sGetCostTime(long lTime) +{ + static char szTime[30]; + + memset(szTime, 0, sizeof(szTime)); + + if(lTime < 0) + return szTime; + if(lTime < 1000) + snprintf(szTime, sizeof(szTime), "cost:%ldms", lTime); + else + snprintf(szTime, sizeof(szTime), "cost:%lds%ldms", lTime / 1000, lTime % 1000); + return szTime; +} + +/************************************************************************************************* + description:Printing system index + parameters: + return: + *************************************************************************************************/ +void vPrintIndex() +{ + TIndex stIndex; + SATvm *pstSavm = NULL; + long lRet = 0, nRecord = 0, lTime = 0; + + memset(&stIndex, 0, sizeof(TIndex)); + if(NULL == (pstSavm = (SATvm *)pInitSATvm(SYS_TVM_INDEX))) + { + fprintf(stderr, "init SYS_TABLE_IDX failure, %s\n", sGetTError(pstSavm->m_lErrno)); + return ; + } + + pstSavm->bSearch = TYPE_SYSTEM; + pstSavm->tblName = SYS_TVM_INDEX; + pstSavm->lSize = sizeof(TIndex); + lRet = lTableDeclare(pstSavm); + if(RC_SUCC != lRet) + { + fprintf(stderr, "declare SYS_TABLE_IDX failure, (%d)(%s)\n", pstSavm->m_lErrno, + sGetTError(pstSavm->m_lErrno)); + return ; + } + + fprintf(stdout, "------------------------------------------------------------------" + "------------------------------------------------------------------------------\n"); + fprintf(stdout, "line table type table_name mark ownner Key" + " shm_id sem_id maxrows size flag stat pers update-time \n"); + fprintf(stdout, "------------------------------------------------------------------" + "------------------------------------------------------------------------------\n"); + lTime = lGetTiskTime(); + while(1) + { + memset(&stIndex, 0, sizeof(stIndex)); + lRet = lTableFetch(pstSavm, (void *)&stIndex); + if(RC_FAIL == lRet) + { + fprintf(stderr, "Fetch SYS_TABLE_IDX failure, err:(%d)(%s)\n", pstSavm->m_lErrno, + sGetTError(pstSavm->m_lErrno)); + vTableClose(pstSavm); + return ; + } + else if(RC_NOTFOUND == lRet) + break; + + nRecord ++; + + fprintf(stdout, "[%3ld]: %4d|%4ld|%-22s|%-15s|%10s|%8d|%8ld|%8ld|%8ld|%4ld|%4ld|%4d|%4ld|%20s|\n", + nRecord, stIndex.m_table, stIndex.m_lType, stIndex.m_szTable, stIndex.m_szPart, + stIndex.m_szOwner, stIndex.m_yKey, stIndex.m_shmID, stIndex.m_semID, stIndex.m_lMaxRows, + stIndex.m_lRowSize, stIndex.m_lLocal, stIndex.m_lState, stIndex.m_lPers, stIndex.m_szTime); + } + lTime -= lGetTiskTime(); + vTableClose(pstSavm); + fprintf(stdout, "----------------------------------------------------------------------%s----" + "--------------------------------------------------------------\n", sGetCostTime(-1 * lTime)); + + return ; +} + +/************************************************************************************************* + description:Print table field information + parameters: + return: + *************************************************************************************************/ +void vPrintField() +{ + TField stField; + SATvm *pstSavm = NULL; + char szPrint[256]; + long lRet = 0, lRow = 0, lTime = 0; + + memset(&stField, 0, sizeof(TField)); + if(NULL == (pstSavm = (SATvm *)pInitSATvm(SYS_TVM_FIELD))) + { + fprintf(stderr, "initial SYS_TVM_FIELD failure\n"); + return ; + } + + pstSavm->lSize = sizeof(TField); + pstSavm->tblName = SYS_TVM_FIELD; + lRet = lTableDeclare(pstSavm); + if(RC_SUCC != lRet) + { + fprintf(stderr, "declare SYS_TVM_FIELD failure, err:(%d)(%s)\n", pstSavm->m_lErrno, + sGetTError(pstSavm->m_lErrno)); + return ; + } + fprintf(stdout, "------------------------------------------------------------------------" + "------------------------\n"); + fprintf(stdout, "line table seq owner table_name field_name" + " attr len PK\n"); + fprintf(stdout, "------------------------------------------------------------------------" + "------------------------\n"); + lTime = lGetTiskTime(); + while(1) + { + memset(&stField, 0, sizeof(TField)); + lRet = lTableFetch(pstSavm, (void *)&stField); + if(RC_FAIL == lRet) + { + fprintf(stderr, "fetch SYS_TVM_FIELD failure, err:(%d)(%s)\n", pstSavm->m_lErrno, + sGetTError(pstSavm->m_lErrno)); + vTableClose(pstSavm); + return ; + } + else if(RC_NOTFOUND == lRet) + break; + + lRow ++; + + memset(szPrint, 0, sizeof(szPrint)); + if(FIELD_CHAR == stField.m_lAttr) + { + snprintf(szPrint, sizeof(szPrint), "[%3ld]: %4d|%3ld|%-20s|%-22s|%18s|STRING|" + "%4ld|%4ld|\n", lRow, stField.m_table, stField.m_lSeq, stField.m_szOwner, + stField.m_szTable, stField.m_szField, stField.m_lLen, stField.m_lIsPk); + } + else if(FIELD_LONG == stField.m_lAttr) + { + snprintf(szPrint, sizeof(szPrint), "[%3ld]: %4d|%3ld|%-20s|%-22s|%18s|NUMBER|" + "%4ld|%4ld|\n", lRow, stField.m_table, stField.m_lSeq, stField.m_szOwner, + stField.m_szTable, stField.m_szField, stField.m_lLen, stField.m_lIsPk); + } + else if(FIELD_DOUB == stField.m_lAttr) + { + snprintf(szPrint, sizeof(szPrint), "[%3ld]: %4d|%3ld|%-20s|%-22s|%18s|DOUBLE|" + "%4ld|%4ld|\n", lRow, stField.m_table, stField.m_lSeq, stField.m_szOwner, + stField.m_szTable, stField.m_szField, stField.m_lLen, stField.m_lIsPk); + } + else + { + snprintf(szPrint, sizeof(szPrint), "[%3ld]: %4d|%3ld|%-20s|%-22s|%18s| NAN |" + "%4ld|%4ld|\n", lRow, stField.m_table, stField.m_lSeq, stField.m_szOwner, + stField.m_szTable, stField.m_szField, stField.m_lLen, stField.m_lIsPk); + } + + fprintf(stdout, "%s", szPrint); + } + lTime -= lGetTiskTime(); + vTableClose(pstSavm); + fprintf(stdout, "-------------------------------------------%s-----------------------------" + "----------------\n", sGetCostTime(-1 * lTime)); + + return ; +} + +/************************************************************************************************* + description:get permit + parameters: + return: + char* + *************************************************************************************************/ +char* sPermitConv(long lPers) +{ + static char szPers[5]; + + strcpy(szPers, "----"); + szPers[4] = 0x00; + + if(lPers & OPERATE_SELECT) + szPers[0] = 's'; + if(lPers & OPERATE_UPDATE) + szPers[1] = 'u'; + if(lPers & OPERATE_DELETE) + szPers[2] = 'd'; + if(lPers & OPERATE_INSERT) + szPers[3] = 'i'; + + return szPers; +} + +/************************************************************************************************* + description:Print table field information + parameters: + return: + *************************************************************************************************/ +void vPrintDomain() +{ + TDomain stDomain; + SATvm *pstSavm = NULL; + char szPrint[512]; + long lRet = 0, lRow = 0, lTime = 0; + + memset(&stDomain, 0, sizeof(TDomain)); + if(NULL == (pstSavm = (SATvm *)pInitSATvm(SYS_TVM_DOMAIN))) + { + fprintf(stderr, "initail SYS_TVM_DOMAIN failure\n"); + return ; + } + + pstSavm->lSize = sizeof(TDomain); + pstSavm->tblName = SYS_TVM_DOMAIN; + lRet = lTableDeclare(pstSavm); + if(RC_SUCC != lRet) + { + fprintf(stderr, "declare SYS_TVM_DOMAIN failure, err:(%d)(%s)\n", pstSavm->m_lErrno, + sGetTError(pstSavm->m_lErrno)); + return ; + } + fprintf(stdout, "------------------------------------------------------------------------" + "--------------------------\n"); + fprintf(stdout, "line table mtbl table_name part ip port keep " + "tmout mtry ctry stat pers\n"); + fprintf(stdout, "------------------------------------------------------------------------" + "--------------------------\n"); + lTime = lGetTiskTime(); + while(1) + { + memset(&stDomain, 0, sizeof(TDomain)); + lRet = lTableFetch(pstSavm, (void *)&stDomain); + if(RC_FAIL == lRet) + { + fprintf(stderr, "fetch SYS_TVM_DOMAIN failure, %s\n", sGetTError(pstSavm->m_lErrno)); + vTableClose(pstSavm); + return ; + } + else if(RC_NOTFOUND == lRet) + break; + + lRow ++; + + memset(szPrint, 0, sizeof(szPrint)); + snprintf(szPrint, sizeof(szPrint), "[%3ld]: %3d|%3d|%18s|%10s|%15s|%5ld|%4ld|%5ld|%4ld|%4ld|", + lRow, stDomain.m_table, stDomain.m_mtable, stDomain.m_szTable, stDomain.m_szPart, + stDomain.m_szIp, stDomain.m_lPort, stDomain.m_lKeepLive, stDomain.m_lTimeOut, + stDomain.m_lTryMax, stDomain.m_lTryTimes); + + if(RESOURCE_INIT == stDomain.m_lStatus) + strcat(szPrint, "INIT|"); + else if(RESOURCE_EXCP == stDomain.m_lStatus) + strcat(szPrint, "EXCP|"); + else if(RESOURCE_ABLE == stDomain.m_lStatus) + strcat(szPrint, "ABLE|"); + else if(RESOURCE_STOP == stDomain.m_lStatus) + strcat(szPrint, "STOP|"); + else if(RESOURCE_AUTH == stDomain.m_lStatus) + strcat(szPrint, "AUTH|"); + + strcat(szPrint, sPermitConv(stDomain.m_lPers)); + fprintf(stdout, "%s|\n", szPrint); + fflush(stdout); + } + lTime -= lGetTiskTime(); + vTableClose(pstSavm); + fprintf(stdout, "----------------------------------------%s-----------------------------" + "---------------------\n", sGetCostTime(-1 * lTime)); + + return ; +} + +/************************************************************************************************* + description:Gets the value between the string o/d + parameters: + flag --Ignore case + return: + char* + *************************************************************************************************/ +char* sGetTruckValue(const char *s, char *o, char *d, bool flag, char *out, int olen) +{ + int len = 0; + char *p = NULL, *q = NULL; + + if (!o) + { + if (!d) + { + len = strlen(s); + return memcpy(out, s, len > olen ? olen : len); + } + + if (!(q = (flag ? strcasestr(s, d) : strstr(s, d)))) + return NULL; + + return memcpy(out, s, q - s > olen ? olen : q - s); + } + else if(!d) + { + if (!o) + { + len = strlen(s); + return memcpy(out, s, len > olen ? olen : len); + } + + if (!(p = (flag ? strcasestr(s, o) : strstr(s, o)))) + return NULL; + + snprintf(out, olen, "%s", p + strlen(o)); + return out; + } + else + { + if (!(p = (flag ? strcasestr(s, o) : strstr(s, o)))) + return NULL; + + len = strlen(o); + + if (!(q = (flag ? strcasestr(p + len, d) : strstr(s, d)))) + return NULL; + + return memcpy(out, p + len, q - p - len > olen ? olen : q - p - len); + } +} + +/************************************************************************************************* + description:Ignore case-sensitive substitution of characters in strings + parameters: + return: + s + *************************************************************************************************/ +char* sUpperWord(char *s, char *w) +{ + long len; + char *p = NULL, *q = s; + + if(!s || !w || !strlen(s)) return NULL; + + if(0 == (len = strlen(w))) return NULL; + + while(NULL != (p = strcasestr(q, w))) + { + memcpy(p, w, len); + q += len; + } + + return s; +} + +/************************************************************************************************* + description:pitch field + parameters: + return: + void --success + NULL --failure + *************************************************************************************************/ +TField *pPitchField(long lCount, TField *pstField, char *pszField) +{ + int i; + + for(i = 0; i < lCount; i ++) + { + if(!strcasecmp(pszField, pstField[i].m_szField)) + return &pstField[i]; + } + + return NULL; +} + +/************************************************************************************************* + description:User-selected field when parsing extreme + parameters: + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lExtremeField(SATvm *pstSavm, char *p, long lCount, TField *pstField, SQLFld **ppstRoot) +{ + Uenum uDeco; + long lRec = 0, i; + TField *pfld = NULL; + char szField[MAX_FIELD_LEN]; + SQLFld stQField, *pstRoot = NULL; + + for(i = 0, lRec = lfieldnum(p, ","); i < lRec; i ++) + { + memset(szField, 0, sizeof(szField)); + memset(&stQField, 0, sizeof(SQLFld)); + strncpy(stQField.m_stKey.m_szField, sfieldvalue(p, ",", i + 1), + sizeof(stQField.m_stKey.m_szField)); + if(!strncmp(stQField.m_stKey.m_szField, "max(", 4)) + uDeco = MATCH_MAX; + else if(!strncmp(stQField.m_stKey.m_szField, "min(", 4)) + uDeco = MATCH_MIN; + else + return RC_FAIL; + + if(!sGetTruckValue(stQField.m_stKey.m_szField, "(", ")", true, szField, sizeof(szField))) + return RC_FAIL; + + if(NULL == (pfld = pPitchField(lCount, pstField, szField))) + { + fprintf(stderr, "field (%s) undefine\n", szField); + return RC_FAIL; + } + + vSetDecorate(&pstSavm->stUpdt, pfld->m_lLen, pfld->m_lFrom, uDeco); + stQField.m_stKey.m_lLen = pfld->m_lLen; + stQField.m_stKey.m_lAttr = pfld->m_lAttr; + stQField.m_stKey.m_lFrom = pfld->m_lFrom; + if(NULL == (pstRoot = pInsertFiled(pstRoot, &stQField))) + return RC_FAIL; + } + + *ppstRoot = pstRoot; + + return RC_SUCC; +} + +/************************************************************************************************* + description:Parse SQL condition fields + parameters: + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lSelectField(SATvm *pstSavm, char *p, long lCount, TField *pstField, SQLFld **ppstRoot) +{ + TField *pfld = NULL; + long lRec = 0, i, j; + char szField[MAX_FIELD_LEN]; + SQLFld stQField, *pstRoot = NULL; + FdCond *pstExm = &pstSavm->stUpdt; + + if(0 == strcmp(p, "*")) + { + if(pstSavm->lFind & GROUP_BY) + return RC_FAIL; + + for(i = 0; i < lCount; i ++) + { + memset(&stQField, 0, sizeof(SQLFld)); + stQField.m_stKey.m_lLen = pstField[i].m_lLen; + stQField.m_stKey.m_lAttr = pstField[i].m_lAttr; + stQField.m_stKey.m_lFrom = pstField[i].m_lFrom; + strcpy(stQField.m_stKey.m_szField, pstField[i].m_szField); + + if(NULL == (pstRoot = pInsertFiled(pstRoot, &stQField))) + return RC_FAIL; + } + + *ppstRoot = pSortSQLField(pstRoot); + return RC_SUCC; + } + + for(i = 0, lRec = lfieldnum(p, ","); i < lRec; i ++) + { + memset(szField, 0, sizeof(szField)); + strncpy(szField, sfieldvalue(p, ",", i + 1), MAX_FIELD_LEN); + strimall(szField); + + if((!strcasecmp(szField, "count(*)") || + !strcasecmp(szField, "count(1)"))) + { + fprintf(stderr, "%s, Temporarily not supported\n", szField); + return RC_FAIL; + } + + if(NULL == (pfld = pPitchField(lCount, pstField, szField))) + { + fprintf(stderr, "field (%s) undefine\n", szField); + return RC_FAIL; + } + + if(pstSavm->lFind & GROUP_BY) + { + for(j = 0; j < pstExm->uFldcmp; j ++) + { + if(pstExm->stFdKey[j].uFldpos == pfld->m_lFrom) + break; + } + + if(j == pstExm->uFldcmp) + { + fprintf(stderr, "Fields (%s) are not grouped\n", szField); + return RC_FAIL; + } + } + + memset(&stQField, 0, sizeof(SQLFld)); + stQField.m_stKey.m_lLen = pfld->m_lLen; + stQField.m_stKey.m_lAttr = pfld->m_lAttr; + stQField.m_stKey.m_lFrom = pfld->m_lFrom; + strcpy(stQField.m_stKey.m_szField, szField); + if(NULL == (pstRoot = pInsertFiled(pstRoot, &stQField))) + return RC_FAIL; + } + + *ppstRoot = pstRoot; + return RC_SUCC; +} + +/************************************************************************************************* + description:Parse SQL update fields + parameters: + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lUpdateField(SATvm *pstSavm, char *pszField, long lCount, TField *pstField, void *pvUpdate) +{ + void *v = NULL; + TField *pfld = NULL; + long lRec = 0, i, j; + char szValue[512], szContent[1024], szField[512], szNumber[16]; + + memset(szNumber, 0, sizeof(szNumber)); + for(i = 0, lRec = lfieldnum(pszField, ","), v = (void *)szNumber; i < lRec; i ++) + { + memset(szValue, 0, sizeof(szValue)); + memset(szField, 0, sizeof(szField)); + memset(szContent, 0, sizeof(szContent)); + strncpy(szContent, sfieldvalue(pszField, ",", i + 1), sizeof(szContent)); + strncpy(szField, sfieldvalue(szContent, "=", 1), sizeof(szField)); + strimall(szField); + + strncpy(szValue, sfieldvalue(szContent, "=", 2), sizeof(szValue)); + sltrim(szValue); + srtrim(szValue); + strimabout(szValue, "\'", "\'"); + if(NULL == (pfld = pPitchField(lCount, pstField, szField))) + { + fprintf(stderr, "field (%s) undefine\n", szField); + return RC_FAIL; + } + + vSetCodField(&pstSavm->stUpdt, pfld->m_lLen, pfld->m_lFrom); + switch(pfld->m_lAttr) + { + case FIELD_DOUB: + switch(pfld->m_lLen) + { + case 4: + *((float *)v) = atof(szValue); + break; + case 8: + *((double *)v) = atof(szValue); + break; + default: + return RC_FAIL; + } + memcpy(pvUpdate + pfld->m_lFrom, v, pfld->m_lLen); + break; + case FIELD_LONG: + switch(pfld->m_lLen) + { + case 2: + *((sint *)v) = atoi(szValue); + break; + case 4: + *((int *)v) = atoi(szValue); + break; + case 8: + *((llong *)v) = atol(szValue); + break; + default: + return RC_FAIL; + } + memcpy(pvUpdate + pfld->m_lFrom, v, pfld->m_lLen); + break; + case FIELD_CHAR: + strncpy(pvUpdate + pfld->m_lFrom, szValue, pfld->m_lLen); + break; + default: + return RC_FAIL; + } + } + + return RC_SUCC; +} + +/************************************************************************************************* + description:execute SQL-select + parameters: + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lExeUpdate(SATvm *pstSavm, TIndex *pstIndex, void *pvNew, char *pvData, BOOL bRmt) +{ + long lRet; + + pstSavm->pstVoid = (void *)pvData; + pstSavm->tblName = pstIndex->m_table; + pstSavm->lSize = pstIndex->m_lRowSize; + if(bRmt) + lRet = lTvmUpdate(pstSavm, (void *)pvNew); + else + lRet = lUpdate(pstSavm, (void *)pvNew); + if(RC_SUCC != lRet) + { + fprintf(stderr, "update table (%s) failure, %s\n", pstIndex->m_szTable, + sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; + } + + fprintf(stdout, "---(%ld) records updated -ep(%d)--\n", pstSavm->m_lEffect, pstSavm->m_lEType); + return RC_SUCC; +} + +/************************************************************************************************* + description:execute SQL-delete + parameters: + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lExeDelete(SATvm *pstSavm, TIndex *pstIndex, char *pvData, BOOL bRmt) +{ + long lRet; + + pstSavm->pstVoid = (void *)pvData; + pstSavm->tblName = pstIndex->m_table; + pstSavm->lSize = pstIndex->m_lRowSize; + if(bRmt) + lRet = lTvmDelete(pstSavm); + else + lRet = lDelete(pstSavm); + if(RC_SUCC != lRet) + return RC_FAIL; + + fprintf(stdout, "---(%ld) records deleted -ep(%d)--\n", pstSavm->m_lEffect, pstSavm->m_lEType); + return RC_SUCC; +} + +/************************************************************************************************* + description:execute SQL-insert + parameters: + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lExeInsert(SATvm *pstSavm, TIndex *pstIndex, void *pvInsert, BOOL bRmt) +{ + long lRet; + + if(bRmt) + pstSavm->tblName = pstIndex->m_table; + else + { + if(RC_SUCC != lInitSATvm(pstSavm, pstIndex->m_table)) + return RC_FAIL; + } + + pstSavm->pstVoid = (void *)pvInsert; + pstSavm->lSize = pstIndex->m_lRowSize; + if(bRmt) + lRet = lTvmInsert(pstSavm); + else + lRet = lInsert(pstSavm); + if(RC_SUCC != lRet) + { + fprintf(stderr, "insert table (%s) failure, %s\n", pstIndex->m_szTable, + sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; + } + + fprintf(stdout, "---(%ld) records inserted ---\n", pstSavm->m_lEffect); + return RC_SUCC; +} + +/************************************************************************************************* + description:Parse SQL condition fields + parameters: + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lConditField(SATvm *pstSavm, char *pszWhere, long lCount, TField *pstField, void *pvWhere) +{ + long n, i, j; + void *v = NULL; + TField *pfld = NULL; + char szValue[512], szCondit[1024], szField[512], szNumber[16]; + + if(strcasestr(pszWhere, " or ")) + { + fprintf(stderr, "Unsupported query methods\n"); + return RC_FAIL; + } + + memset(szNumber, 0, sizeof(szNumber)); + for(i = 0, v = (void *)szNumber, n = lfieldnum(pszWhere, " AND "); i < n; i ++) + { + memset(szValue, 0, sizeof(szValue)); + memset(szField, 0, sizeof(szField)); + memset(szCondit, 0, sizeof(szCondit)); + strncpy(szCondit, sfieldvalue(pszWhere, " AND ", i + 1), sizeof(szCondit)); + + strncpy(szField, sfieldvalue(szCondit, "=", 1), sizeof(szField)); + strimall(szField); + strncpy(szValue, sfieldvalue(szCondit, "=", 2), sizeof(szValue)); + sltrim(szValue); + srtrim(szValue); + strimabout(szValue, "\'", "\'"); + if(!strcmp(szField, "1") && !strcmp(szValue, "1")) + continue; + + if(NULL == (pfld = pPitchField(lCount, pstField, szField))) + { + fprintf(stderr, "field (%s) undefine\n", szField); + return RC_FAIL; + } + + vSetCodField(&pstSavm->stCond, pfld->m_lLen, pfld->m_lFrom); + switch(pfld->m_lAttr) + { + case FIELD_DOUB: + switch(pfld->m_lLen) + { + case 4: + *((float *)v) = atof(szValue); + break; + case 8: + *((double *)v) = atof(szValue); + break; + default: + return RC_FAIL; + } + memcpy(pvWhere + pfld->m_lFrom, v, pfld->m_lLen); + break; + case FIELD_LONG: + switch(pfld->m_lLen) + { + case 2: + *((sint *)v) = atoi(szValue); + break; + case 4: + *((int *)v) = atoi(szValue); + break; + case 8: + *((llong *)v) = atol(szValue); + break; + default: + return RC_FAIL; + } + memcpy(pvWhere + pfld->m_lFrom, v, pfld->m_lLen); + break; + case FIELD_CHAR: + strncpy(pvWhere + pfld->m_lFrom, szValue, pfld->m_lLen); + break; + default: + return RC_FAIL; + } + } + + return RC_SUCC; +} + +/************************************************************************************************* + description:execute SQL-count + parameters: + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lCountSelect(SATvm *pstSavm, TIndex *pstIndex, char *pvData, BOOL bRmt) +{ + size_t lRet, lSum = 0; + + pstSavm->pstVoid = (void *)pvData; + pstSavm->tblName = pstIndex->m_table; + pstSavm->lSize = pstIndex->m_lRowSize; + if(bRmt) + lRet = lTvmCount(pstSavm, &lSum); + else + lRet = lCount(pstSavm, &lSum); + if(lRet != RC_SUCC) + { + fprintf(stderr, "count table (%s) failure, %s\n", pstIndex->m_szTable, + sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; + } + + fprintf(stdout, "---(%ld) records selected -ep(%d)--\n", pstSavm->m_lEffect, pstSavm->m_lEType); + fprintf(stdout, "COUNT(*)\n"); + fprintf(stdout, "%zu\n", lSum); + fflush(stdout); + + return RC_SUCC; +} + +/************************************************************************************************* + description:execute SQL-group + parameters: + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lExeGroup(SATvm *pstSavm, TIndex *pstIndex, SQLFld *pstRoot, char *pvData, BOOL bRmt) +{ + TblKey *pstKey = NULL; + SQLFld *pstNode = NULL; + Rowgrp *pstList = NULL; + char *pvResult = NULL; + size_t i, lOffset, lRows, lRet; + + pstSavm->pstVoid = (void *)pvData; + pstSavm->tblName = pstIndex->m_table; + pstSavm->lSize = pstIndex->m_lRowSize; + + if(bRmt) + lRet = lTvmGroup(pstSavm, &lRows, (void **)&pvResult); + else + lRet = lGroup(pstSavm, &lRows, (void **)&pvResult); + if(RC_SUCC != lRet) + { + if(NO_DATA_FOUND != pstSavm->m_lErrno) + { + fprintf(stderr, "Group table (%s) failure,%s\n", pstIndex->m_szTable, + sGetTError(pstSavm->m_lErrno)); + } + + return RC_FAIL; + } + + for(pstNode = pstRoot; pstNode; pstNode = pstNode->pstNext) + fprintf(stdout, "%s ", pstNode->m_stKey.m_szField); + fprintf(stdout, "\n"); + + for(i = 0; i < lRows && i < pstSavm->m_lEffect; i ++) + { + lOffset = pstIndex->m_lRowSize * i; + for(pstNode = pstRoot; pstNode; pstNode = pstNode->pstNext) + { + if(!strcasecmp(pstNode->m_stKey.m_szField, "count(*)") || + !strcasecmp(pstNode->m_stKey.m_szField, "count(1)")) + continue; + + pstKey = &pstNode->m_stKey; + switch(pstKey->m_lAttr) + { + case FIELD_DOUB: + switch(pstKey->m_lLen) + { + case 4: + fprintf(stdout, "%f ", *((float *)(pvResult + lOffset + pstKey->m_lFrom))); + break; + case 8: + fprintf(stdout, "%f ", *((double *)(pvResult + lOffset + pstKey->m_lFrom))); + break; + default: + break; + } + break; + case FIELD_LONG: + switch(pstKey->m_lLen) + { + case 2: + fprintf(stdout, "%d ", *((sint *)(pvResult + lOffset + pstKey->m_lFrom))); + break; + case 4: + fprintf(stdout, "%d ", *((int *)(pvResult + lOffset + pstKey->m_lFrom))); + break; + case 8: + fprintf(stdout, "%lld ", *((llong *)(pvResult + lOffset + pstKey->m_lFrom))); + break; + default: + break; + } + break; + case FIELD_CHAR: + fprintf(stdout, "%.*s ", (int)pstKey->m_lLen, pvResult + lOffset + pstKey->m_lFrom); + break; + default: + break; + } + } + fprintf(stdout, "\n"); + fflush(stdout); + } + TFree(pvResult); + + fprintf(stdout, "---(%ld) records selected, ep(%d)---\n", pstSavm->m_lEffect, pstSavm->m_lEType); + return RC_SUCC; +} + +/************************************************************************************************* + description:execute SQL-select + parameters: + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lExeSelect(SATvm *pstSavm, TIndex *pstIndex, SQLFld *pstRoot, char *pvData, char *pszFile, + char *pszDem, BOOL bRmt) +{ + FILE *fp = NULL; + TblKey *pstKey = NULL; + SQLFld *pstNode = NULL; + Rowgrp *pstList = NULL; + size_t i, lOffset, lRows, lRet; + char szDelmit[64], *pvResult = NULL; + + memset(szDelmit, 0, sizeof(szDelmit)); + pstSavm->pstVoid = (void *)pvData; + pstSavm->tblName = pstIndex->m_table; + pstSavm->lSize = pstIndex->m_lRowSize; + if(bRmt) + lRet = lTvmQuery(pstSavm, &lRows, (void **)&pvResult); + else + lRet = lQuery(pstSavm, &lRows, (void **)&pvResult); + if(RC_SUCC != lRet) + { + if(NO_DATA_FOUND != pstSavm->m_lErrno) + { + fprintf(stderr, "Query table (%s) failure,%s\n", pstIndex->m_szTable, + sGetTError(pstSavm->m_lErrno)); + } + + return RC_FAIL; + } + + if(pszFile) + { + if(NULL == (fp = fopen(pszFile, "wb"))) + { + pstSavm->m_lErrno = FILE_NOTFOUND; + return RC_FAIL; + } + + strncpy(szDelmit, pszDem, sizeof(szDelmit)); + } + else + { + fp = stdout; + strcpy(szDelmit, " "); + } + + for(pstNode = pstRoot; pstNode; pstNode = pstNode->pstNext) + fprintf(fp, "%s ", pstNode->m_stKey.m_szField); + fprintf(fp, "\n"); + + for(i = 0; i < lRows && i < pstSavm->m_lEffect; i ++) + { + lOffset = pstIndex->m_lRowSize * i; + for(pstNode = pstRoot; pstNode; pstNode = pstNode->pstNext) + { + if(!strcasecmp(pstNode->m_stKey.m_szField, "count(*)") || + !strcasecmp(pstNode->m_stKey.m_szField, "count(1)")) + continue; + + pstKey = &pstNode->m_stKey; + switch(pstKey->m_lAttr) + { + case FIELD_DOUB: + switch(pstKey->m_lLen) + { + case 4: + fprintf(fp, "%f%s", *((float *)(pvResult + lOffset + pstKey->m_lFrom)), szDelmit); + break; + case 8: + fprintf(fp, "%f%s", *((double *)(pvResult + lOffset + pstKey->m_lFrom)), szDelmit); + break; + default: + break; + } + break; + case FIELD_LONG: + switch(pstKey->m_lLen) + { + case 2: + fprintf(fp, "%d%s", *((sint *)(pvResult + lOffset + pstKey->m_lFrom)), szDelmit); + break; + case 4: + fprintf(fp, "%d%s", *((int *)(pvResult + lOffset + pstKey->m_lFrom)), szDelmit); + break; + case 8: + fprintf(fp, "%lld%s", *((llong *)(pvResult + lOffset + pstKey->m_lFrom)), szDelmit); + break; + default: + break; + } + break; + case FIELD_CHAR: + fprintf(fp, "%.*s%s", (int)pstKey->m_lLen, pvResult + lOffset + pstKey->m_lFrom, szDelmit); + break; + default: + break; + } + } + fprintf(fp, "\n"); + fflush(fp); + } + TFree(pvResult); + + if(pszFile) + { + fprintf(stdout, "---(%ld) records unload ---\n", pstSavm->m_lEffect); + fclose(fp); + } + else + fprintf(stdout, "---(%ld) records selected, ep(%d)---\n", pstSavm->m_lEffect, pstSavm->m_lEType); + + return RC_SUCC; +} + +/************************************************************************************************* + description:execute SQL-Seque + parameters: + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lParseSequece(SATvm *pstSavm, char *pszSQName, char *pszFiled, BOOL bRmt) +{ + long lRet; + ulong ulSeque; + + if(strcasecmp(pszFiled, "nextval")) + { + pstSavm->m_lErrno = SQL_ERR_FIELD; + return RC_FAIL; + } + + if(bRmt) + lRet = lTvmSelectSeque(pstSavm, pszSQName, &ulSeque); + else + lRet = lSelectSeque(pstSavm, pszSQName, &ulSeque); + if(RC_SUCC != lRet) + return RC_FAIL; + + fprintf(stdout, "%s\n", pszFiled); + fprintf(stdout, "%lu\n", ulSeque); + + return RC_SUCC; +} + +/************************************************************************************************* + description:Parse SQL decorative fields + parameters: + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lParseAdorn(SATvm *pstSavm, char *pszAdorn, long lCount, TField *pstField) +{ + TField *pfld = NULL; + long lNumber, i, j; + char szWord[64], szField[512], szOrder[512]; + + if(0 == strlen(pszAdorn)) + return RC_SUCC; + + memset(szField, 0, sizeof(szField)); + memset(szOrder, 0, sizeof(szOrder)); + if(!strncasecmp(pszAdorn, "group by", 8)) + { + pstSavm->lFind |= GROUP_BY; + if(!strcasestr(pszAdorn, "order by")) + { + if(!sGetTruckValue(pszAdorn, "group by", NULL, true, szField, sizeof(szField))) + return RC_FAIL; + strimall(szField); + } + else + { + if(!sGetTruckValue(pszAdorn, "group by", "order by", true, szField, sizeof(szField))) + return RC_FAIL; + strimall(szField); + + if(!sGetTruckValue(pszAdorn, "order by", NULL, true, szOrder, sizeof(szOrder))) + return RC_FAIL; + sltrim(szOrder); + } + + for(i = 0, lNumber = lgetstrnum(szField, ",") + 1; i < lNumber; i ++) + { + memset(szWord, 0, sizeof(szWord)); + strncpy(szWord, sgetvalue(szField, ",", i + 1), sizeof(szWord)); + if(NULL == (pfld = pPitchField(lCount, pstField, szWord))) + { + fprintf(stderr, "field (%s) undefine\n", szWord); + return RC_FAIL; + } + + vSetDecorate(&pstSavm->stUpdt, pfld->m_lLen, pfld->m_lFrom, GROUP_BY); + } + + if(strlen(szOrder) > 0) + { + for(i = 0, lNumber = lgetstrnum(szOrder, ",") + 1; i < lNumber; i ++) + { + memset(szWord, 0, sizeof(szWord)); + strncpy(szWord, sfieldvalue(szOrder, ",", i + 1), sizeof(szWord)); + if(NULL == (pfld = pPitchField(lCount, pstField, sfieldvalue(szWord, " ", 1)))) + { + fprintf(stderr, "field (%s) undefine\n", sfieldvalue(szWord, " ", 1)); + return RC_FAIL; + } + + for(j = 0; j < pstSavm->stUpdt.uFldcmp; j ++) + { + if(pstSavm->stUpdt.stFdKey[j].uFldpos == pfld->m_lFrom) + { + if(!strcasecmp(sfieldvalue(szWord, " ", 2), "desc")) + pstSavm->stUpdt.stFdKey[j].uDecorate |= ORDER_DESC; + else + pstSavm->stUpdt.stFdKey[j].uDecorate |= ORDER_ASC; + break; + } + } + + if(j == pstSavm->stUpdt.uFldcmp) + return RC_FAIL; + } + } + + return RC_SUCC; + } + else if(!strncasecmp(pszAdorn, "order by", 8)) + { + pstSavm->lFind |= ORDER_BY; + if(!sGetTruckValue(pszAdorn, "order by", NULL, true, szOrder, sizeof(szOrder))) + return RC_FAIL; + sltrim(szOrder); + + for(i = 0, lNumber = lgetstrnum(szOrder, ",") + 1; i < lNumber; i ++) + { + memset(szWord, 0, sizeof(szWord)); + strncpy(szWord, sfieldvalue(szOrder, ",", i + 1), sizeof(szWord)); + if(NULL == (pfld = pPitchField(lCount, pstField, sfieldvalue(szWord, " ", 1)))) + { + fprintf(stderr, "field (%s) undefine\n", sfieldvalue(szWord, " ", 1)); + return RC_FAIL; + } + + if(!strcasecmp(sfieldvalue(szWord, " ", 2), "desc")) + vSetDecorate(&pstSavm->stUpdt, pfld->m_lLen, pfld->m_lFrom, ORDER_DESC); + else + vSetDecorate(&pstSavm->stUpdt, pfld->m_lLen, pfld->m_lFrom, ORDER_ASC); + } + + return RC_SUCC; + } + + return RC_FAIL; +} + +/************************************************************************************************* + description:execute SQL-extreme + parameters: + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lExeExtreme(SATvm *pstSavm, TIndex *pstIndex, SQLFld *pstRoot, void *pvData, BOOL bRmt) +{ + long lRet; + TblKey *pstKey = NULL; + SQLFld *pstNode = NULL; + void *pvResult = NULL; + + if(NULL == (pvResult = malloc(pstIndex->m_lRowSize))) + return RC_FAIL; + + pstSavm->pstVoid = (void *)pvData; + pstSavm->tblName = pstIndex->m_table; + pstSavm->lSize = pstIndex->m_lRowSize; + if(bRmt) + lRet = lTvmExtreme(pstSavm, pvResult); + else + lRet = lExtreme(pstSavm, pvResult); + if(RC_SUCC != lRet) + { + TFree(pvResult); + vDestroyFiled(pstRoot); + fprintf(stderr, "extreme table (%s) failure, %s\n", pstIndex->m_szTable, + sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; + } + + for(pstNode = pstRoot; pstNode; pstNode = pstNode->pstNext) + fprintf(stdout, "%s ", pstNode->m_stKey.m_szField); + fprintf(stdout, "\n"); + + for(pstNode = pstRoot; pstNode; pstNode = pstNode->pstNext) + { + pstKey = &pstNode->m_stKey; + switch(pstKey->m_lAttr) + { + case FIELD_DOUB: + switch(pstKey->m_lLen) + { + case 4: + fprintf(stdout, "%f ", *((float *)(pvResult + pstKey->m_lFrom))); + break; + case 8: + fprintf(stdout, "%f ", *((double *)(pvResult + pstKey->m_lFrom))); + break; + default: + break; + } + break; + case FIELD_LONG: + switch(pstKey->m_lLen) + { + case 2: + fprintf(stdout, "%d ", *((sint *)(pvResult + pstKey->m_lFrom))); + break; + case 4: + fprintf(stdout, "%d ", *((int *)(pvResult + pstKey->m_lFrom))); + break; + case 8: + fprintf(stdout, "%lld ", *((llong *)(pvResult + pstKey->m_lFrom))); + break; + default: + break; + } + break; + case FIELD_CHAR: + fprintf(stdout, "%.*s ", (int)pstKey->m_lLen, (char *)(pvResult + pstKey->m_lFrom)); + break; + default: + break; + } + } + + fprintf(stdout, "\n"); + fflush(stdout); + TFree(pvResult); + fprintf(stdout, "---(%ld)records selected -ep(%d)--\n", pstSavm->m_lEffect, pstSavm->m_lEType); + + vDestroyFiled(pstRoot); + return RC_SUCC; +} + +/************************************************************************************************* + description:Parse SQL-select fields + parameters: + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lParseSelect(SATvm *pstSavm, char *pszTable, char *pszField, char *pszWhere, char *pszFile, + char *pszDem, char *pszAdorn, BOOL bRmt) +{ + TIndex stIndex; + SQLFld *pstRoot = NULL; + void *pvWhere = NULL; + TField *pstField = NULL; + size_t lOut = 0, lRet; + + memset(&stIndex, 0, sizeof(TIndex)); + strncpy(stIndex.m_szPart, sgetvalue(pszTable, "@", 2), sizeof(stIndex.m_szPart)); + strncpy(stIndex.m_szTable, sgetvalue(pszTable, "@", 1), sizeof(stIndex.m_szTable)); + supper(stIndex.m_szTable); + if(0x00 == stIndex.m_szPart[0]) + strcpy(stIndex.m_szPart, sGetNode()); + + if(!strcmp(stIndex.m_szTable, "SEQUENCE")) + return lParseSequece(pstSavm, stIndex.m_szPart, pszField, bRmt); + + if(bRmt) + { + if(RC_SUCC != lTvmGetTblIndex(pstSavm, stIndex.m_szTable, stIndex.m_szPart, &stIndex)) + return RC_FAIL; + + if(RC_SUCC != lTvmGetTblField(pstSavm, stIndex.m_table, &lOut, &pstField)) + return RC_FAIL; + } + else + { + if(RC_SUCC != lGetTblIndex(pstSavm, stIndex.m_szTable, stIndex.m_szPart, &stIndex)) + return RC_FAIL; + + if(RC_SUCC != lGetTblField(stIndex.m_table, &lOut, &pstField)) + return RC_FAIL; + + if(RC_SUCC != lInitSATvm(pstSavm, stIndex.m_table)) + return RC_FAIL; + } + + pstSavm->stCond.uFldcmp = 0; + pstSavm->stUpdt.uFldcmp = 0; + if(RC_SUCC != lParseAdorn(pstSavm, pszAdorn, lOut, pstField)) + { + pstSavm->m_lErrno = SQL_SYNTX_ERR; + goto ERR_SELECT; + } + + if(NULL == (pvWhere = (char *)calloc(stIndex.m_lRowSize, sizeof(char)))) + { + pstSavm->m_lErrno = MALLC_MEM_ERR; + goto ERR_SELECT; + } + + if(RC_SUCC != _lConditField(pstSavm, pszWhere, lOut, pstField, pvWhere)) + { + pstSavm->m_lErrno = SQL_ERR_WHERE; + goto ERR_SELECT; + } + + if((!strcasecmp(pszField, "count(*)") || !strcasecmp(pszField, "count(1)")) && + !(pstSavm->lFind & GROUP_BY)) + { + TFree(pstField); + if(RC_SUCC != _lCountSelect(pstSavm, &stIndex, pvWhere, bRmt)) + goto ERR_SELECT; + + TFree(pvWhere); + return RC_SUCC; + } + else if(!strncasecmp(pszField, "max(", 4) || !strncasecmp(pszField, "min(", 4)) + { + if(RC_SUCC != _lExtremeField(pstSavm, pszField, lOut, pstField, &pstRoot)) + { + pstSavm->m_lErrno = SQL_ERR_FIELD; + goto ERR_SELECT; + } + + if(RC_SUCC != _lExeExtreme(pstSavm, &stIndex, pstRoot, pvWhere, bRmt)) + goto ERR_SELECT; + + TFree(pstField); + TFree(pvWhere); + return RC_SUCC; + } + + if(RC_SUCC != _lSelectField(pstSavm, pszField, lOut, pstField, &pstRoot)) + { + pstSavm->m_lErrno = SQL_ERR_FIELD; + goto ERR_SELECT; + } + + TFree(pstField); + if(pstSavm->lFind & GROUP_BY) + lRet = _lExeGroup(pstSavm, &stIndex, pstRoot, pvWhere, bRmt); + else + lRet = _lExeSelect(pstSavm, &stIndex, pstRoot, pvWhere, pszFile, pszDem, bRmt); + if(RC_SUCC != lRet) + goto ERR_SELECT; + + TFree(pvWhere); + vDestroyFiled(pstRoot); + return RC_SUCC; + +ERR_SELECT: + TFree(pvWhere); + TFree(pstField); + vDestroyFiled(pstRoot); + return RC_FAIL; +} + +/************************************************************************************************** + description:Parse SQL-select syntax + parameters: + return: + RC_SUCC --success + RC_FAIL --failure + **************************************************************************************************/ +long _lSelectSyntax(SATvm *pstSavm, char *pszSQL, char *pszFile, char *pszDem, BOOL bRmt) +{ + char szTable[512], *p = NULL; + char szWhere[512], szField[512], szAdorn[1024]; + + memset(szWhere, 0, sizeof(szWhere)); + memset(szField, 0, sizeof(szField)); + memset(szTable, 0, sizeof(szTable)); + memset(szAdorn, 0, sizeof(szAdorn)); + + if(!sGetTruckValue(pszSQL, "select ", "from ", true, szField, sizeof(szField))) + { + pstSavm->m_lErrno = SQL_FIELD_NIL; + return RC_FAIL; + } + + strimall(szField); + if(!strlen(szField)) + { + pstSavm->m_lErrno = SQL_FIELD_NIL; + return RC_FAIL; + } + + if(NULL != strcasestr(pszSQL, "where ")) + { + if(!sGetTruckValue(pszSQL, "from ", "where", true, szTable, sizeof(szTable))) + { + pstSavm->m_lErrno = SQL_TABLE_NIL; + return RC_FAIL; + } + + if(!sGetTruckValue(pszSQL, "where ", NULL, true, szWhere, sizeof(szWhere))) + { + pstSavm->m_lErrno = SQL_TABLE_NIL; + return RC_FAIL; + } + + if((p = strcasestr(szWhere, "group")) || (p = strcasestr(szWhere, "order"))) + { + strcpy(szAdorn, p); + memset(p, 0, sizeof(szWhere) - (p - szWhere)); + } + + sltrim(szWhere); + srtrim(szWhere); + sUpperWord(szWhere, " AND "); + DEL_TAIL_CHAR(szWhere, ';'); + } + else + { + if(!sGetTruckValue(pszSQL, "from ", NULL, true, szTable, sizeof(szTable))) + { + pstSavm->m_lErrno = SQL_TABLE_NIL; + return RC_FAIL; + } + + sltrim(szTable); + if((p = strcasestr(szTable, "group")) || (p = strcasestr(szTable, "order"))) + { + strcpy(szAdorn, p); + memset(p, 0, sizeof(szTable) - (p - szTable)); + } + + DEL_TAIL_CHAR(szTable, ';'); + } + + strimall(szTable); + vSCRDebug("DEBUG:select field:[%s]", szField); + vSCRDebug("DEBUG:select table:[%s]", szTable); + vSCRDebug("DEBUG:select where:[%s]", szWhere); + vSCRDebug("DEBUG:select adorn:[%s]", szAdorn); + + return _lParseSelect(pstSavm, szTable, szField, szWhere, pszFile, pszDem, szAdorn, bRmt); +} + +/************************************************************************************************* + description:Parse SQL-update fields + parameters: + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lParseUpdate(SATvm *pstSavm, char *pszTable, char *pszField, char *pszWhere, BOOL bRmt) +{ + TIndex stIndex; + size_t lOut = 0, lRet; + TField *pstField = NULL; + void *pvWhere = NULL, *pvUpdate = NULL; + + memset(&stIndex, 0, sizeof(TIndex)); + strncpy(stIndex.m_szPart, sgetvalue(pszTable, "@", 2), sizeof(stIndex.m_szPart)); + strncpy(stIndex.m_szTable, sgetvalue(pszTable, "@", 1), sizeof(stIndex.m_szTable)); + supper(stIndex.m_szTable); + if(0x00 == stIndex.m_szPart[0]) + strcpy(stIndex.m_szPart, sGetNode()); + + if(bRmt) + { + if(RC_SUCC != lTvmGetTblIndex(pstSavm, stIndex.m_szTable, stIndex.m_szPart, &stIndex)) + return RC_FAIL; + + if(RC_SUCC != lTvmGetTblField(pstSavm, stIndex.m_table, &lOut, &pstField)) + return RC_FAIL; + } + else + { + if(RC_SUCC != lGetTblIndex(pstSavm, stIndex.m_szTable, stIndex.m_szPart, &stIndex)) + return RC_FAIL; + + if(RC_SUCC != lGetTblField(stIndex.m_table, &lOut, &pstField)) + return RC_FAIL; + + if(RC_SUCC != lInitSATvm(pstSavm, stIndex.m_table)) + return RC_FAIL; + } + + pstSavm->stCond.uFldcmp = 0; + pstSavm->stUpdt.uFldcmp = 0; + if(NULL == (pvUpdate = (char *)calloc(stIndex.m_lRowSize, sizeof(char)))) + { + pstSavm->m_lErrno = MALLC_MEM_ERR; + goto ERR_UPDATE; + } + + if(RC_SUCC != _lUpdateField(pstSavm, pszField, lOut, pstField, pvUpdate)) + { + pstSavm->m_lErrno = SQL_ERR_FIELD; + goto ERR_UPDATE; + } + + if(NULL == (pvWhere = (char *)calloc(stIndex.m_lRowSize, sizeof(char)))) + { + pstSavm->m_lErrno = MALLC_MEM_ERR; + goto ERR_UPDATE; + } + + if(RC_SUCC != _lConditField(pstSavm, pszWhere, lOut, pstField, pvWhere)) + { + pstSavm->m_lErrno = SQL_ERR_WHERE; + goto ERR_UPDATE; + } + + TFree(pstField); + if(RC_SUCC != _lExeUpdate(pstSavm, &stIndex, pvUpdate, pvWhere, bRmt)) + goto ERR_UPDATE; + + TFree(pvWhere); + TFree(pvUpdate); + return RC_SUCC; + +ERR_UPDATE: + TFree(pvWhere); + TFree(pvUpdate); + TFree(pstField); + return RC_FAIL; +} + + +/************************************************************************************************** + description:Parse SQL-update syntax + parameters: + return: + RC_SUCC --success + RC_FAIL --failure + **************************************************************************************************/ +long _lUpdateSyntax(SATvm *pstSavm, char *pszSQL, BOOL bRmt) +{ + char szTable[MAX_FIELD_LEN]; + char szWhere[1024], szField[1024]; + + memset(szWhere, 0, sizeof(szWhere)); + memset(szField, 0, sizeof(szField)); + memset(szTable, 0, sizeof(szTable)); + + if(!sGetTruckValue(pszSQL, "update ", "set ", true, szTable, sizeof(szTable))) + { + pstSavm->m_lErrno = SQL_TABLE_NIL; + return RC_FAIL; + } + strimall(szTable); + + if(!strcasestr(pszSQL, "where")) + { + pstSavm->m_lErrno = SQL_WHERE_NIL; + return RC_FAIL; + } + + if(!sGetTruckValue(pszSQL, "set ", "where", true, szField, sizeof(szField))) + { + pstSavm->m_lErrno = SQL_FIELD_NIL; + return RC_FAIL; + } + + sltrim(szField); + srtrim(szField); + if(!strlen(szField)) + { + pstSavm->m_lErrno = SQL_FIELD_NIL; + return RC_FAIL; + } + + if(!sGetTruckValue(pszSQL, "where ", NULL, true, szWhere, sizeof(szWhere))) + { + pstSavm->m_lErrno = SQL_WHERE_NIL; + return RC_FAIL; + } + + sltrim(szWhere); + srtrim(szWhere); + sUpperWord(szWhere, " AND "); + DEL_TAIL_CHAR(szWhere, ';'); + + vSCRDebug("DEBUG:update field:[%s]", szField); + vSCRDebug("DEBUG:update table:[%s]", szTable); + vSCRDebug("DEBUG:update where:[%s]", szWhere); + + return _lParseUpdate(pstSavm, szTable, szField, szWhere, bRmt); +} + +/************************************************************************************************* + description:Parse SQL-delete fields + parameters: + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lParseDelete(SATvm *pstSavm, char *pszTable, char *pszWhere, BOOL bRmt) +{ + TIndex stIndex; + size_t lOut = 0, lRet; + TField *pstField = NULL; + void *pvWhere = NULL; + + memset(&stIndex, 0, sizeof(TIndex)); + strncpy(stIndex.m_szPart, sgetvalue(pszTable, "@", 2), sizeof(stIndex.m_szPart)); + strncpy(stIndex.m_szTable, sgetvalue(pszTable, "@", 1), sizeof(stIndex.m_szTable)); + supper(stIndex.m_szTable); + if(0x00 == stIndex.m_szPart[0]) + strcpy(stIndex.m_szPart, sGetNode()); + + if(bRmt) + { + if(RC_SUCC != lTvmGetTblIndex(pstSavm, stIndex.m_szTable, stIndex.m_szPart, &stIndex)) + return RC_FAIL; + + if(RC_SUCC != lTvmGetTblField(pstSavm, stIndex.m_table, &lOut, &pstField)) + return RC_FAIL; + } + else + { + if(RC_SUCC != lGetTblIndex(pstSavm, stIndex.m_szTable, stIndex.m_szPart, &stIndex)) + return RC_FAIL; + + if(RC_SUCC != lGetTblField(stIndex.m_table, &lOut, &pstField)) + return RC_FAIL; + + if(RC_SUCC != lInitSATvm(pstSavm, stIndex.m_table)) + return RC_FAIL; + } + + pstSavm->stCond.uFldcmp = 0; + pstSavm->stUpdt.uFldcmp = 0; + if(NULL == (pvWhere = (char *)calloc(stIndex.m_lRowSize, sizeof(char)))) + { + pstSavm->m_lErrno = MALLC_MEM_ERR; + goto ERR_DELETE; + } + + if(RC_SUCC != _lConditField(pstSavm, pszWhere, lOut, pstField, pvWhere)) + { + pstSavm->m_lErrno = SQL_ERR_WHERE; + goto ERR_DELETE; + } + + TFree(pstField); + if(RC_SUCC != _lExeDelete(pstSavm, &stIndex, pvWhere, bRmt)) + goto ERR_DELETE; + + TFree(pvWhere); + return RC_SUCC; + +ERR_DELETE: + TFree(pvWhere); + TFree(pstField); + return RC_FAIL; +} + +/************************************************************************************************** + description:Parse SQL-delete syntax + parameters: + return: + RC_SUCC --success + RC_FAIL --failure + **************************************************************************************************/ +long _lDeleteSyntax(SATvm *pstSavm, char *pszSQL, BOOL bRmt) +{ + char szTable[MAX_FIELD_LEN], szWhere[1024]; + + memset(szWhere, 0, sizeof(szWhere)); + memset(szTable, 0, sizeof(szTable)); + if(strcasestr(pszSQL, " where ")) + { + if(!sGetTruckValue(pszSQL, " from ", " where ", true, szTable, sizeof(szTable))) + { + pstSavm->m_lErrno = SQL_TABLE_NIL; + return RC_FAIL; + } + strimall(szTable); + + if(!sGetTruckValue(pszSQL, " where ", NULL, true, szWhere, sizeof(szWhere))) + { + pstSavm->m_lErrno = SQL_WHERE_NIL; + return RC_FAIL; + } + sltrim(szWhere); + srtrim(szWhere); + sUpperWord(szWhere, " AND "); + DEL_TAIL_CHAR(szWhere, ';'); + } + else + { + if(!sGetTruckValue(pszSQL, " from ", NULL, true, szTable, sizeof(szTable))) + { + pstSavm->m_lErrno = SQL_TABLE_NIL; + return RC_FAIL; + } + DEL_TAIL_CHAR(szTable, ';'); + strimall(szTable); + } + + vSCRDebug("DEBUG:delete table:[%s]", szTable); + vSCRDebug("DEBUG:delete where:[%s]", szWhere); + + return _lParseDelete(pstSavm, szTable, szWhere, bRmt); +} + +/************************************************************************************************* + description:Parse SQL-insert values + parameters: + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lInsertField(SATvm *pstSavm, char *pszValues, SQLFld *pstRoot, void *pvInsert) +{ + void *v = NULL; + TblKey *pstKey = NULL; + SQLFld *pstNode = NULL; + long lRec = 0, i, j, lFld; + char szValue[512], szNumber[16]; + + memset(szNumber, 0, sizeof(szNumber)); + lFld = lGetNodeFiled(pstRoot); + if(lFld != (lRec = lfieldnum(pszValues, ","))) + { + pstSavm->m_lErrno = SQL_FAV_MATCH; + return RC_FAIL; + } + + for(i = 0, v = (void *)szNumber, pstNode = pstRoot; i < lRec; i ++, pstNode = pstNode->pstNext) + { + memset(szValue, 0, sizeof(szValue)); + strncpy(szValue, sfieldvalue(pszValues, ",", i + 1), sizeof(szValue)); + sltrim(szValue); + srtrim(szValue); + strimabout(szValue, "\'", "\'"); + + if(!pstNode) + { + pstSavm->m_lErrno = SQL_FAV_MATCH; + return RC_FAIL; + } + + pstKey = &pstNode->m_stKey; + switch(pstKey->m_lAttr) + { + case FIELD_DOUB: + switch(pstKey->m_lLen) + { + case 4: + *((float *)v) = atof(szValue); + memcpy(pvInsert + pstKey->m_lFrom, v, pstKey->m_lLen); + break; + case 8: + *((double *)v) = atof(szValue); + memcpy(pvInsert + pstKey->m_lFrom, v, pstKey->m_lLen); + break; + default: + break; + } + break; + case FIELD_LONG: + switch(pstKey->m_lLen) + { + case 2: + *((sint *)v) = atoi(szValue); + memcpy(pvInsert + pstKey->m_lFrom, v, pstKey->m_lLen); + break; + case 4: + *((int *)v) = atoi(szValue); + memcpy(pvInsert + pstKey->m_lFrom, v, pstKey->m_lLen); + break; + case 8: + *((llong *)v) = atol(szValue); + memcpy(pvInsert + pstKey->m_lFrom, v, pstKey->m_lLen); + break; + default: + break; + } + break; + case FIELD_CHAR: + memcpy(pvInsert + pstKey->m_lFrom, szValue, + MIN(strlen(szValue), pstKey->m_lLen)); + break; + default: + break; + } + } + + if(pstNode) + { + pstSavm->m_lErrno = SQL_FAV_MATCH; + return RC_FAIL; + } + + return RC_SUCC; +} + +/************************************************************************************************* + description:Parse SQL-insert fields + parameters: + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lParseInsert(SATvm *pstSavm, char *pszTable, char *pszField, char *pszValues, BOOL bRmt) +{ + TIndex stIndex; + size_t lOut = 0, lRet; + SQLFld *pstRoot = NULL; + TField *pstField = NULL; + void *pvInsert = NULL; + + memset(&stIndex, 0, sizeof(TIndex)); + strncpy(stIndex.m_szPart, sgetvalue(pszTable, "@", 2), sizeof(stIndex.m_szPart)); + strncpy(stIndex.m_szTable, sgetvalue(pszTable, "@", 1), sizeof(stIndex.m_szTable)); + supper(stIndex.m_szTable); + if(0x00 == stIndex.m_szPart[0]) + strcpy(stIndex.m_szPart, sGetNode()); + + if(bRmt) + { + if(RC_SUCC != lTvmGetTblIndex(pstSavm, stIndex.m_szTable, stIndex.m_szPart, &stIndex)) + return RC_FAIL; + + if(RC_SUCC != lTvmGetTblField(pstSavm, stIndex.m_table, &lOut, &pstField)) + return RC_FAIL; + } + else + { + if(RC_SUCC != lGetTblIndex(pstSavm, stIndex.m_szTable, stIndex.m_szPart, &stIndex)) + return RC_FAIL; + + if(RC_SUCC != lGetTblField(stIndex.m_table, &lOut, &pstField)) + return RC_FAIL; + + if(RC_SUCC != lInitSATvm(pstSavm, stIndex.m_table)) + return RC_FAIL; + } + + pstSavm->stCond.uFldcmp = 0; + pstSavm->stUpdt.uFldcmp = 0; + if(NULL == (pvInsert = (char *)calloc(stIndex.m_lRowSize, sizeof(char)))) + { + pstSavm->m_lErrno = MALLC_MEM_ERR; + goto ERR_INSERT; + } + + if(RC_SUCC != _lSelectField(pstSavm, pszField, lOut, pstField, &pstRoot)) + { + pstSavm->m_lErrno = SQL_ERR_FIELD; + goto ERR_INSERT; + } + + if(RC_SUCC != _lInsertField(pstSavm, pszValues, pstRoot, pvInsert)) + goto ERR_INSERT; + +//vPrintHex(pvInsert, stIndex.m_lRowSize); + + TFree(pstField); + if(RC_SUCC != _lExeInsert(pstSavm, &stIndex, pvInsert, bRmt)) + goto ERR_INSERT; + + TFree(pvInsert); + return RC_SUCC; + +ERR_INSERT: + TFree(pvInsert); + TFree(pstField); + return RC_FAIL; +} + +/************************************************************************************************** + description:Parse SQL-insert syntax + parameters: + return: + RC_SUCC --success + RC_FAIL --failure + **************************************************************************************************/ +long _lInsertSyntax(SATvm *pstSavm, char *pszSQL, BOOL bRmt) +{ + char szTable[MAX_FIELD_LEN]; + char szValues[1024], szField[1024]; + + memset(szField, 0, sizeof(szField)); + memset(szTable, 0, sizeof(szTable)); + memset(szValues, 0, sizeof(szValues)); + if(!sGetTruckValue(pszSQL, " into ", "values", true, szValues, sizeof(szValues))) + { + pstSavm->m_lErrno = SQL_TABLE_NIL; + return RC_FAIL; + } + + if(strstr(szValues, "(")) // 说明有选定字段 + { + if(!sGetTruckValue(szValues, NULL, "(", true, szTable, sizeof(szTable))) + { + pstSavm->m_lErrno = SQL_TABLE_NIL; + return RC_FAIL; + } + + if(!sGetTruckValue(szValues, "(", ")", true, szField, sizeof(szField))) + { + pstSavm->m_lErrno = SQL_FIELD_NIL; + return RC_FAIL; + } + + if(!strlen(strimall(szField))) + { + pstSavm->m_lErrno = SQL_FIELD_NIL; + return RC_FAIL; + } + } + else + { + strcpy(szField, "*"); + strncpy(szTable, szValues, sizeof(szTable)); + } + strimall(szTable); + + memset(szValues, 0, sizeof(szValues)); + if(!sGetTruckValue(pszSQL, "values", NULL, true, szValues, sizeof(szValues))) + { + pstSavm->m_lErrno = SQL_WHERE_NIL; + return RC_FAIL; + } + + if(!strimabout(szValues, "(", ")")) + { + pstSavm->m_lErrno = SQL_WHERE_NIL; + return RC_FAIL; + } + + if(!strlen(szValues)) + { + pstSavm->m_lErrno = SQL_WHERE_NIL; + return RC_FAIL; + } + + sltrim(szValues); + srtrim(szValues); + sUpperWord(szValues, " AND "); + + vSCRDebug("DEBUG:insert field:[%s]", szField); + vSCRDebug("DEBUG:insert table:[%s]", szTable); + vSCRDebug("DEBUG:insert field:[%s]", szValues); + + return _lParseInsert(pstSavm, szTable, szField, szValues, bRmt); +} + +/************************************************************************************************** + description:Parse SQL-truncate syntax + parameters: + return: + RC_SUCC --success + RC_FAIL --failure + **************************************************************************************************/ +long _lTruncateSyntax(SATvm *pstSavm, char *pszSQL, BOOL bRmt) +{ + long lRet; + TIndex stIndex; + char szTable[MAX_FIELD_LEN]; + + memset(szTable, 0, sizeof(szTable)); + memset(&stIndex, 0, sizeof(TIndex)); + if(!sGetTruckValue(pszSQL, " table ", NULL, true, szTable, sizeof(szTable))) + { + pstSavm->m_lErrno = SQL_TABLE_NIL; + return RC_FAIL; + } + + strimall(szTable); + strncpy(stIndex.m_szPart, sgetvalue(szTable, "@", 2), sizeof(stIndex.m_szPart)); + strncpy(stIndex.m_szTable, sgetvalue(szTable, "@", 1), sizeof(stIndex.m_szTable)); + supper(stIndex.m_szTable); + if(0x00 == stIndex.m_szPart[0]) + strcpy(stIndex.m_szPart, sGetNode()); + + if(bRmt) + { + if(RC_SUCC != lTvmGetTblIndex(pstSavm, stIndex.m_szTable, stIndex.m_szPart, &stIndex)) + return RC_FAIL; + + pstSavm->tblName = stIndex.m_table; + } + else + { + if(RC_SUCC != lGetTblIndex(pstSavm, stIndex.m_szTable, stIndex.m_szPart, &stIndex)) + return RC_FAIL; + + if(NULL == (pstSavm = (SATvm *)pInitSATvm(stIndex.m_table))) + return RC_FAIL; + } + + pstSavm->lSize = stIndex.m_lRowSize; + if(bRmt) + lRet = lTvmTruncate(pstSavm, stIndex.m_table); + else + lRet = lTruncate(pstSavm, stIndex.m_table); + if(RC_SUCC != lRet) + return RC_FAIL; + + fprintf(stdout, "---(%ld) records deleted ---\n", pstSavm->m_lEffect); + return RC_SUCC; +} + +/************************************************************************************************** + description:Parse SQL-drop syntax + parameters: + return: + RC_SUCC --success + RC_FAIL --failure + **************************************************************************************************/ +long _lDropSyntax(SATvm *pstSavm, char *pszSQL, BOOL bRmt) +{ + long lRet; + TIndex stIndex; + char szTable[MAX_FIELD_LEN]; + + memset(szTable, 0, sizeof(szTable)); + memset(&stIndex, 0, sizeof(TIndex)); + if(!sGetTruckValue(pszSQL, " table ", NULL, true, szTable, sizeof(szTable))) + { + pstSavm->m_lErrno = SQL_TABLE_NIL; + return RC_FAIL; + } + + strimall(szTable); + strncpy(stIndex.m_szPart, sgetvalue(szTable, "@", 2), sizeof(stIndex.m_szPart)); + strncpy(stIndex.m_szTable, sgetvalue(szTable, "@", 1), sizeof(stIndex.m_szTable)); + supper(stIndex.m_szTable); + if(0x00 == stIndex.m_szPart[0]) + strcpy(stIndex.m_szPart, sGetNode()); + + if(bRmt) + { + if(RC_SUCC != lTvmGetTblIndex(pstSavm, stIndex.m_szTable, stIndex.m_szPart, &stIndex)) + return RC_FAIL; + + pstSavm->tblName = stIndex.m_table; + } + else + { + if(RC_SUCC != lGetTblIndex(pstSavm, stIndex.m_szTable, stIndex.m_szPart, &stIndex)) + return RC_FAIL; + + if(NULL == (pstSavm = (SATvm *)pInitSATvm(stIndex.m_table))) + return RC_FAIL; + } + + pstSavm->lSize = stIndex.m_lRowSize; + if(bRmt) + lRet = lTvmDropTable(pstSavm, stIndex.m_table); + else + lRet = lDropTable(pstSavm, stIndex.m_table); + if(RC_SUCC != lRet) + return RC_FAIL; + + fprintf(stdout, "---(%s) was deleted ---\n", szTable); + + return RC_SUCC; +} + +/************************************************************************************************** + description:Parse SQL-load syntax + parameters: + return: + RC_SUCC --success + RC_FAIL --failure + **************************************************************************************************/ +long _lLoadSyntax(SATvm *pstSavm, char *pszSQL) +{ + TIndex stIndex; + char szFile[256], szParam[256], szDelmit[64]; + +// load from a.txt DELIMITER ',' insert into tablename@bcs + memset(szFile, 0, sizeof(szFile)); + memset(szParam, 0, sizeof(szParam)); + memset(szDelmit, 0, sizeof(szDelmit)); + memset(&stIndex, 0, sizeof(TIndex)); + + if(!sGetTruckValue(pszSQL, "insert into ", NULL, true, szParam, sizeof(szParam))) + { + pstSavm->m_lErrno = SQL_TABLE_NIL; + return RC_FAIL; + } + + sltrim(szParam); + srtrim(szParam); + strimall(szParam); + strncpy(stIndex.m_szPart, sgetvalue(szParam, "@", 2), sizeof(stIndex.m_szPart)); + strncpy(stIndex.m_szTable, sgetvalue(szParam, "@", 1), sizeof(stIndex.m_szTable)); + supper(stIndex.m_szTable); + if(0x00 == stIndex.m_szPart[0]) + strcpy(stIndex.m_szPart, sGetNode()); + + if(RC_SUCC != lGetTblIndex(pstSavm, stIndex.m_szTable, stIndex.m_szPart, &stIndex)) + return RC_FAIL; + + memset(szParam, 0, sizeof(szParam)); + if(!sGetTruckValue(pszSQL, "load from ", "insert", true, szParam, sizeof(szParam))) + { + pstSavm->m_lErrno = FILE_NOT_RSET; + return RC_FAIL; + } + + strncpy(szFile, sfieldvalue(szParam, " ", 1), sizeof(szFile)); + strimall(szFile); + + strncpy(szDelmit, sfieldvalue(szParam, " ", 2), sizeof(szDelmit)); + strimall(szDelmit); + if(!strcasecmp(szDelmit, "DELIMITER")) + { + strncpy(szDelmit, sfieldvalue(szParam, " ", 3), sizeof(szDelmit)); + strimall(szDelmit); + strimabout(szDelmit, "\"", "\""); + strimabout(szDelmit, "\'", "\'"); + } + else + strcpy(szDelmit, ","); + + if(strlen(sfieldvalue(szParam, " ", 4))) + { + pstSavm->m_lErrno = SQL_SYNTX_ERR; + return RC_FAIL; + } + + if(RC_SUCC != lImportFile(stIndex.m_table, szFile, szDelmit)) + return RC_FAIL; + + fprintf(stdout, "---(%ld) records inserted ---\n", pstSavm->m_lEffect); + + return RC_SUCC; +} + +/************************************************************************************************** + description:Parse SQL-unload syntax + parameters: + return: + RC_SUCC --success + RC_FAIL --failure + **************************************************************************************************/ +long _lUnloadSyntax(SATvm *pstSavm, char *pszSQL, BOOL bRmt) +{ + char szFile[256], szParam[256], szDelmit[64], *p = NULL; + +// unload to a.txt DELIMITER ',' select * from tablename@bcs + memset(szFile, 0, sizeof(szFile)); + memset(szParam, 0, sizeof(szParam)); + memset(szDelmit, 0, sizeof(szDelmit)); + + if(NULL == (p = strcasestr(pszSQL, "select"))) + { + pstSavm->m_lErrno = SQL_SYNTX_ERR; + return RC_FAIL; + } + + memset(szParam, 0, sizeof(szParam)); + if(!sGetTruckValue(pszSQL, "unload to ", "select", true, szParam, sizeof(szParam))) + { + pstSavm->m_lErrno = FILE_NOT_RSET; + return RC_FAIL; + } + + sltrim(szParam); + srtrim(szParam); + strncpy(szFile, sfieldvalue(szParam, " ", 1), sizeof(szFile)); + strimall(szFile); + + strncpy(szDelmit, sfieldvalue(szParam, " ", 2), sizeof(szDelmit)); + strimall(szDelmit); + if(!strcasecmp(szDelmit, "DELIMITER")) + { + strncpy(szDelmit, sfieldvalue(szParam, " ", 3), sizeof(szDelmit)); + strimall(szDelmit); + strimabout(szDelmit, "\"", "\""); + strimabout(szDelmit, "\'", "\'"); + } + else + strcpy(szDelmit, ","); + + if(strlen(sfieldvalue(szParam, " ", 4))) + { + pstSavm->m_lErrno = SQL_SYNTX_ERR; + return RC_FAIL; + } + + return _lSelectSyntax(pstSavm, p, szFile, szDelmit, bRmt); +} + +/************************************************************************************************** + description:Parse and execute SQL statements + parameters: + return: + RC_SUCC --success + RC_FAIL --failure + **************************************************************************************************/ +long lExecuteSQL(SATvm *pstSavm, char *pszSQL) +{ + if(!pszSQL || !strlen(pszSQL)) + { + pstSavm->m_lErrno = SQL_SYNTX_ERR; + return RC_FAIL; + } + + pstSavm->lFind = 0; + pstSavm->stCond.uFldcmp = 0; + pstSavm->stUpdt.uFldcmp = 0; + if(!strncasecmp(pszSQL, "begin ", 6) && strcmp(sfieldvalue(pszSQL, ";", 2), "work")) + { + vBeginWork(pstSavm); + fprintf(stdout, "---begin work, %s---\n", sGetTError(pstSavm->m_lErrno)); + return RC_SUCC; + } + + else if(!strncasecmp(pszSQL, "end ", 4) && strcmp(sfieldvalue(pszSQL, ";", 2), "work")) + { + vEndWork(pstSavm); + fprintf(stdout, "---end work, %s---\n", sGetTError(pstSavm->m_lErrno)); + return RC_SUCC; + } + else if(!strncasecmp(pszSQL, "commit ", 7) && strcmp(sfieldvalue(pszSQL, ";", 2), "work")) + { + lCommitWork(pstSavm); + fprintf(stdout, "---commit work, %s---\n", sGetTError(pstSavm->m_lErrno)); + return RC_SUCC; + } + else if(!strncasecmp(pszSQL, "rollback ", 9) && strcmp(sfieldvalue(pszSQL, ";", 2), "work")) + { + lRollbackWork(pstSavm); + fprintf(stdout, "---(%ld) records rollback, %s---\n", pstSavm->m_lEffect, + sGetTError(pstSavm->m_lErrno)); + return RC_SUCC; + } + else if(!strncasecmp(pszSQL, "select ", 7)) + return _lSelectSyntax(pstSavm, pszSQL, NULL, NULL, false); + else if(!strncasecmp(pszSQL, "update ", 7)) + return _lUpdateSyntax(pstSavm, pszSQL, false); + else if(!strncasecmp(pszSQL, "delete ", 7)) + return _lDeleteSyntax(pstSavm, pszSQL, false); + else if(!strncasecmp(pszSQL, "insert ", 7)) + return _lInsertSyntax(pstSavm, pszSQL, false); + else if(!strncasecmp(pszSQL, "truncate ", 9)) + return _lTruncateSyntax(pstSavm, pszSQL, false); + else if(!strncasecmp(pszSQL, "drop ", 5)) + return _lDropSyntax(pstSavm, pszSQL, false); + else if(!strncasecmp(pszSQL, "load ", 5)) + return _lLoadSyntax(pstSavm, pszSQL); + else if(!strncasecmp(pszSQL, "unload ", 7)) + return _lUnloadSyntax(pstSavm, pszSQL, false); + else + { + pstSavm->m_lErrno = SQL_NOT_SUPPT; + return RC_FAIL; + } + + return RC_SUCC; +} + +/************************************************************************************************** + description:Parse and execute SQL statements + parameters: + return: + RC_SUCC --success + RC_FAIL --failure + **************************************************************************************************/ +long lExecuteTvm(SATvm *pstSavm, char *pszSQL) +{ + if(!pszSQL || !strlen(pszSQL)) + { + pstSavm->m_lErrno = SQL_SYNTX_ERR; + return RC_FAIL; + } + + pstSavm->m_lTimes = 0; + pstSavm->m_lErrno = 0; + sfieldreplace(pszSQL, '\t', ' '); + if(!strncasecmp(pszSQL, "begin ", 6) && strcmp(sfieldvalue(pszSQL, ";", 2), "work")) + { + lTvmBeginWork(pstSavm); + fprintf(stdout, "---begin work, %s---\n", sGetTError(pstSavm->m_lErrno)); + return RC_SUCC; + } + else if(!strncasecmp(pszSQL, "end ", 4) && strcmp(sfieldvalue(pszSQL, ";", 2), "work")) + { + lTvmEndWork(pstSavm); + fprintf(stdout, "---end work, %s---\n", sGetTError(pstSavm->m_lErrno)); + return RC_SUCC; + } + else if(!strncasecmp(pszSQL, "commit ", 7) && strcmp(sfieldvalue(pszSQL, ";", 2), "work")) + { + lTvmCommitWork(pstSavm); + fprintf(stdout, "---commit work, %s---\n", sGetTError(pstSavm->m_lErrno)); + return RC_SUCC; + } + else if(!strncasecmp(pszSQL, "rollback ", 9) && strcmp(sfieldvalue(pszSQL, ";", 2), "work")) + { + lTvmRollbackWork(pstSavm); + fprintf(stdout, "---(%ld) records rollback, %s---\n", pstSavm->m_lEffect, + sGetTError(pstSavm->m_lErrno)); + return RC_SUCC; + } + else if(!strncasecmp(pszSQL, "select ", 7)) + return _lSelectSyntax(pstSavm, pszSQL, NULL, NULL, true); + else if(!strncasecmp(pszSQL, "update ", 7)) + return _lUpdateSyntax(pstSavm, pszSQL, true); + else if(!strncasecmp(pszSQL, "delete ", 7)) + return _lDeleteSyntax(pstSavm, pszSQL, true); + else if(!strncasecmp(pszSQL, "insert ", 7)) + return _lInsertSyntax(pstSavm, pszSQL, true); + else if(!strncasecmp(pszSQL, "truncate ", 9)) + return _lTruncateSyntax(pstSavm, pszSQL, true); + else if(!strncasecmp(pszSQL, "drop ", 5)) + return _lDropSyntax(pstSavm, pszSQL, true); +/* + else if(!strncasecmp(pszSQL, "load ", 5)) + return _lLoadSyntax(pstSavm, pszSQL, true); +*/ + else if(!strncasecmp(pszSQL, "unload ", 7)) + return _lUnloadSyntax(pstSavm, pszSQL, true); + else + { + pstSavm->m_lErrno = SQL_NOT_SUPPT; + return RC_FAIL; + } + + return RC_SUCC; + return RC_SUCC; +} + +/************************************************************************************************** + description:Boot STVM + parameters: + return: + RC_SUCC --success + RC_FAIL --failure + **************************************************************************************************/ +long lStartSystem(TBoot *pstBoot, char *pszMode) +{ + Benum eMode = 0; + SATvm *pstSavm = (SATvm *)pGetSATvm(); + + if(0 != access(getenv("TVMCFG"), R_OK)) + { + fprintf(stdout, "The startup parameter is not set and started by default\n"); + if(RC_SUCC != lDefaultBoot()) + return RC_FAIL; + } + + if(pszMode && !strcmp(pszMode, "o")) // offline + { + fprintf(stdout, "Warning:TVM will start offline\n"); + fflush(stdout); + eMode = 1; + } + + if(!bIsTvmBoot()) + { + if(RC_SUCC != lStartupTvm(pstBoot)) + { + fprintf(stderr, "failed to boot TVM, %s\n", sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; + } + } + + if(RC_SUCC != lBootLocal(pstSavm, pstBoot, eMode)) + { + fprintf(stderr, "failed to boot LIS, %s\n", sGetTError(pstSavm->m_lErrno)); + return RC_SUCC; + } + + fprintf(stderr, "start TVM : (%s)\n", sGetTError(pstSavm->m_lErrno)); + + return RC_SUCC; +} + +/************************************************************************************************** + description:Stop STVM + parameters: + return: + RC_SUCC --success + RC_FAIL --failure + **************************************************************************************************/ +long lStopSystem(TBoot *pstBoot, char *pszApp) +{ + BOOL bRet; + long i, lPid = 0; + FILE *fp = NULL; + static char szCmd[128], szPid[20]; + SATvm *pstSavm = (SATvm *)pGetSATvm(); + + memset(szPid, 0, sizeof(szPid)); + memset(szCmd, 0, sizeof(szCmd)); + snprintf(szCmd, sizeof(szCmd), "ps -u %s|grep -E \"%s|%s\"|awk '{print $1}'", + getenv("LOGNAME"), TVM_LOCAL_SERV, TVM_REMOTE_DOM); + + if(TVM_BOOT_CLUSTER == pstBoot->m_lBootType) + lOfflineNotify(pstSavm, pstBoot->m_lBootPort); + + if(NULL == (fp = popen(szCmd, "r"))) + { + fprintf(stderr, "popen execute comman err:(%s)\n", strerror(errno)); + return RC_FAIL; + } + + for(fp; fgets(szPid, sizeof(szPid), fp) != NULL; memset(szPid, 0, sizeof(szPid))) + { + strimall(szPid); + lPid = atol(szPid); + if(lPid <= 0 || lPid == getpid()) + continue; + + for(i = 0; i < 200; i ++, usleep(50000)) + { + if(FALSE == (bRet = bExistProcess(lPid))) + break; + } + + if(!bRet) continue; + kill(atol(szPid), SIGKILL); + } + pclose(fp); + + if(!bIsTvmBoot()) return RC_SUCC; + + if(RC_SUCC != lShutdownTvm()) + { + fprintf(stderr, "showdown node failed, %s\n", sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; + } + + return RC_SUCC; +} + +/************************************************************************************************** + description:Print Stvm parameter information + parameters: + return: + RC_SUCC --success + RC_FAIL --failure + **************************************************************************************************/ +void vPrintParam(char *pszOpt) +{ + long n = 0, i = 0; + + if(!pszOpt || (0 == (n = strlen(pszOpt)))) return ; + + if(!bIsTvmBoot()) + return ; + + for(i = 0, n = strlen(pszOpt); i < n; i ++) + { + switch(pszOpt[i]) + { + case 'y': + vPrintIndex(); + break; + case 't': + vPrintField(); + break; + case 'd': + vPrintDomain(); + break; + default: + return ; + } + } + + return ; +} + +/************************************************************************************************** + description:Output table space Usage + parameters: + return: + **************************************************************************************************/ +void vPrintAmount(int t, char *pszTable, int nValid, int nMax) +{ + double dPer; + int i, nPer; + + if(nValid < 0 || nMax <= 0) return ; + + dPer = nValid * 100.0 / nMax; + nPer = nValid * 50 / nMax > 0 ? nValid * 50 / nMax : 1; + + fprintf(stdout, "TABLE:[%3d][%-20s]: [", t, pszTable); + if(dPer < 60.00) + fprintf(stdout, "\033[42;32m"); + else if(dPer < 70.00) + fprintf(stdout, "\033[45;35m"); + else if(dPer < 80.00) + fprintf(stdout, "\033[46;36m"); + else if(dPer < 90.00) + fprintf(stdout, "\033[43;33m"); + else + fprintf(stdout, "\033[41;31m"); + + fflush(stdout); + for(i = 0; i < nPer; i ++) + { + fprintf(stdout, "|"); + fflush(stdout); + } + + fprintf(stdout, "\033[0m"); + for(i; i < 50; i ++) + fprintf(stdout, " "); + fprintf(stdout, "] %.4f%%, (%d/%d)\n", dPer, nValid, nMax); + fflush(stdout); +} + +/************************************************************************************************** + description:print system table space usage + parameters: + return: + **************************************************************************************************/ +void vTableAmount() +{ + size_t i, lOut = 0; + RunTime *pstRun = NULL; + TIndex stIndex, *pstIndex = NULL; + SATvm *pstSavm = (SATvm *)pGetSATvm(); + + memset(&stIndex, 0, sizeof(TIndex)); + stIndex.m_lLocal = RES_LOCAL_SID; + + pstSavm->pstVoid = &stIndex; + pstSavm->bSearch = TYPE_SYSTEM; + pstSavm->tblName = SYS_TVM_INDEX; + pstSavm->lSize = sizeof(TIndex); + if(RC_SUCC != lQuery(pstSavm, &lOut, (void *)&pstIndex)) + { + if(NO_DATA_FOUND == pstSavm->m_lErrno) + pstSavm->m_lErrno = TBL_NOT_FOUND; + return ; + } + + if(lOut <= 0) return ; + + fprintf(stdout, "The amount of table is using as follows:\n\n"); + for(i = 0; i < lOut; i ++) + { + pstRun = (RunTime *)pGetRunTime(pstSavm, pstIndex[i].m_table); + pstRun->m_shmID = pstIndex[i].m_shmID; + if(NULL == (pstRun = pInitHitTest(pstSavm, pstIndex[i].m_table))) + continue; + + vPrintAmount(pstIndex[i].m_table, pstIndex[i].m_szTable, lGetTblValid(pstIndex[i].m_table), + lGetTblRow(pstIndex[i].m_table)); + vTblDisconnect(pstSavm, pstIndex[i].m_table); + } + TFree(pstIndex); + fprintf(stdout, "\n"); + + return ; +} + +/************************************************************************************************** + description:STVM operation function description + parameters: + return: + **************************************************************************************************/ +void vPrintFunc(char *s) +{ + fprintf(stdout, "\nUsage:\t%s -wspfco[oytd]\n", s); + fprintf(stdout, "\t-w[o]\t\t--Startup STVM\n"); + fprintf(stdout, "\t-s[o]\t\t--Shutdown STVM\n"); + fprintf(stdout, "\t-p(ytd)\t\t--Output STVM Running information\n"); + fprintf(stdout, "\t-f\t\t--Display the amount of table\n"); + fprintf(stdout, "\t-t\t\t--Output the table struck\n"); + fprintf(stdout, "\t-c[file]\t--Compile the startup config file\n"); + fprintf(stdout, "\t-o[file]\t--Decompile the startup config\n"); + fprintf(stdout, "\n"); + fprintf(stdout, "\n"); + fprintf(stdout, "\033[4m\033[45;33mDESCRIPTION\033[0m\n"); + fprintf(stdout, "\t\033[0m\033[33;40mSQL\t\t--SQL control\033[0m\n"); + fprintf(stdout, "\t\033[0m\033[33;40mDOM\t\t--DOM control\033[0m\n"); + fprintf(stdout, "\n"); +} + +/************************************************************************************************* + description:add history command + parameters: + return: + *************************************************************************************************/ +void vAddHistory(char *s) +{ + FILE *fp = NULL; + char szPath[512]; + + memset(szPath, 0, sizeof(szPath)); + snprintf(szPath, sizeof(szPath), "%s/%s", getenv("TVMDBD"), STVM_SQL_LINE); + if(NULL == (fp = fopen(szPath, "a+"))) + return ; + + fprintf(fp, "%s\n", s); + fclose(fp); +} + +/************************************************************************************************* + description:set user history command + parameters: + return: + *************************************************************************************************/ +void vSetHistory() +{ + long lRow = 0, i; + FILE *fp = NULL, *fb = NULL; + char szPath[512], szLine[512], szBak[512]; + + memset(szBak, 0, sizeof(szBak)); + memset(szPath, 0, sizeof(szPath)); + memset(szLine, 0, sizeof(szLine)); + snprintf(szBak, sizeof(szBak), "%s/%s@", getenv("TVMDBD"), STVM_SQL_LINE); + snprintf(szPath, sizeof(szPath), "%s/%s", getenv("TVMDBD"), STVM_SQL_LINE); + if(NULL == (fp = fopen(szPath, "r"))) + return ; + + if(NULL == (fb = fopen(szBak, "w"))) + { + fclose(fp); + return ; + } + + while(fgets(szLine, sizeof(szLine), fp) != NULL) + lRow ++; + + fseek(fp, 0L, SEEK_SET); + for(i = 0; i < lRow && fgets(szLine, sizeof(szLine), fp); i ++) + { + if(100 < lRow - i) + continue; + fprintf(fb, "%s", szLine); + strimcrlf(szLine); + add_history(szLine); + memset(szLine, 0, sizeof(szLine)); + } + + fclose(fp); + fclose(fb); + + rename(szBak, szPath); +} + +/************************************************************************************************** + description:Execute SQL functions + parameters: + return: + **************************************************************************************************/ +void vSQLStatement(int argc, char *argv[]) +{ + char *pszUser, *p, szSQL[2048]; + long i = 0, lRec, lRemote = 0, lRet; + SATvm *pstSavm = (SATvm *)pGetSATvm(); + + system("stty erase ^?"); + system("stty erase ^H"); + fprintf(stdout, "\n%s\n", sFuncVersion()); + for(i = 2; i < argc; i ++) + { + if(!strcasecmp(argv[i], "--debug=on")) + elog = 1; + else if(!strncasecmp(argv[i], "--connect=", 10)) + { + if(NULL == (pszUser = strstr(argv[i], "--connect="))) + { + fprintf(stderr, "Invalid address:%s\n", argv[i]); + exit(-1); + } + + pszUser += 10; + if(NULL == (p = strstr(pszUser, "@"))) + { + fprintf(stderr, "Invalid domain:%s\n", pszUser); + exit(-1); + } + + vSetNode(sfieldvalue(pszUser, "@", 1)); + pszUser = pszUser + (p - pszUser) + 1; + lRemote = atol(sfieldvalue(pszUser, ":", 2)); + if(RC_SUCC != lTvmConnect(pstSavm, sfieldvalue(pszUser, ":", 1), lRemote, 5)) + { + fprintf(stderr, "connect to the server %s:%ld failure, %s\n", + sfieldvalue(pszUser, ":", 1), lRemote, sGetTError(pstSavm->m_lErrno)); + exit(-1); + } + + fprintf(stdout, "Connect domain:%s@%s:%ld server successfully!!\n\n", sGetNode(), + sfieldvalue(pszUser, ":", 1), lRemote); + fflush(stdout); + } + } + + vSetHistory(); + while(1) + { + if(NULL == (pszUser = readline("M-SQL>"))) + continue; + + if(!strcmp(pszUser, "q") || !strcmp(pszUser, "Q") || !strcmp(pszUser, "exit")) + break; + + add_history(pszUser); + vAddHistory(pszUser); + if(!strcasecmp(pszUser, "clear")) + { + system("clear"); + TFree(pszUser); + continue; + } + else if(!strncasecmp(pszUser, "create", 6)) + { + if(lRemote > 0) + { + fprintf(stderr, "could not create table on Remte mode\n"); + TFree(pszUser); + continue; + } + + lCreateByFile(pszUser + 6); + fprintf(stdout, "\n\n\n"); + TFree(pszUser); + continue; + } + + strimcrlf(pszUser); + lRec = lfieldnum(pszUser, ";"); + for(i = 0; i < lRec; i ++) + { + memset(szSQL, 0, sizeof(szSQL)); + strncpy(szSQL, sfieldvalue(pszUser, ";", i + 1), sizeof(szSQL)); + sltrim(szSQL); + srtrim(szSQL); + if(!strlen(szSQL)) continue; + + sfieldreplace(szSQL, '\t', ' '); + fprintf(stdout, "\n------------------------------------------------------SQL Result" + "-----------------------------------------------------\n"); + if(lRemote > 0) + lRet = lExecuteTvm(pstSavm, szSQL); + else + lRet = lExecuteSQL(pstSavm, szSQL); + if(RC_SUCC != lRet) + { + fprintf(stderr, "execute M-SQL error, (%d)(%s)\n", pstSavm->m_lErrno, + sGetTError(pstSavm->m_lErrno)); + continue; + } + } + TFree(pszUser); + fprintf(stdout, "\n\n\n"); + } + + if(lRemote) vTvmDisconnect(pstSavm); + exit(0); +} + +/************************************************************************************************** + description:Output domain table information + parameters: + return: + **************************************************************************************************/ +void vPrintDomTable() +{ + size_t i, lOut = 0; + char szPrint[512]; + TDomain *pstDomain = NULL; + SATvm *pstSavm = (SATvm *)pGetSATvm(); + + if(RC_SUCC != lExportTable(SYS_TVM_DOMAIN, &lOut, (void **)&pstDomain)) + { + fprintf(stderr, "get domain node info failed, %s\n", sGetTError(pstSavm->m_lErrno)); + return ; + } + + fprintf(stdout, "\tROW DOMAINID TABLE_NAME PART STAT PERS\n"); + fprintf(stdout, "\t----------------------------------------------------------\n"); + for(i = 0; i < lOut; i ++) + { + memset(szPrint, 0, sizeof(szPrint)); + snprintf(szPrint, sizeof(szPrint), "\t[%-3ld]: %-10s %-18s %-10s ", i, + pstDomain[i].m_szOwner, pstDomain[i].m_szTable, pstDomain[i].m_szPart); + + if(RESOURCE_INIT == pstDomain[i].m_lStatus) + strcat(szPrint, "INIT "); + else if(RESOURCE_EXCP == pstDomain[i].m_lStatus) + strcat(szPrint, "EXCP "); + else if(RESOURCE_ABLE == pstDomain[i].m_lStatus) + strcat(szPrint, "ABLE "); + else if(RESOURCE_STOP == pstDomain[i].m_lStatus) + strcat(szPrint, "STOP "); + else if(RESOURCE_AUTH == pstDomain[i].m_lStatus) + strcat(szPrint, "AUTH "); + + fprintf(stdout, "%s %s\n", szPrint, sPermitConv(pstDomain[i].m_lPers)); + fflush(stdout); + } + TFree(pstDomain); + fprintf(stdout, "\t----------------------------------------------------------\n"); + + return ; +} + +/************************************************************************************************** + description:Manually connect to the remote domain + parameters: + return: + **************************************************************************************************/ +void vConnectDomain(char *pszDomain, TBoot *pstBoot) +{ + TDomain stDomain; + SATvm *pstSavm = (SATvm *)pGetSATvm(); + + if(!strlen(strimall(pszDomain))) + { + fprintf(stderr, "*illegal domain name\n"); + return ; + } + + if(RC_SUCC != lInitSATvm(pstSavm, SYS_TVM_DOMAIN)) + { + fprintf(stderr, "*initail SYS_TVM_DOMAIN failure, %s\n", sGetTError(pstSavm->m_lErrno)); + return ; + } + + conditinit(pstSavm, stDomain, SYS_TVM_DOMAIN); + stringsetv(pstSavm, stDomain, m_szOwner, pszDomain); + decorate(pstSavm, TDomain, m_szOwner, FIRST_ROW); + if(RC_SUCC != lSelect(pstSavm, (void *)&stDomain)) + { + fprintf(stderr, "*get domain %s error, %s\n", pszDomain, sGetTError(pstSavm->m_lErrno)); + return ; + } + + if(RC_SUCC != lConnectNotify(pstSavm, &stDomain, pstBoot->m_lBootPort)) + { + fprintf(stderr, "*reconnect remote domain(%s) failure, %s\n", pszDomain, + sGetTError(pstSavm->m_lErrno)); + return ; + } + + vPrintDomTable(); + return ; +} + +/************************************************************************************************** + description:Clone remote domain table data + parameters: + return: + **************************************************************************************************/ +void vPullTableDomain(char *pszParam) +{ + TABLE table = 0; + TDomain stDomain; + char szCmd[512], szTable[128]; + SATvm *pstSavm = (SATvm *)pGetSATvm(); + +// BCS@TBL_ACCT_INFO/PART --table=1 + memset(szCmd, 0, sizeof(szCmd)); + memset(szTable, 0, sizeof(szTable)); + if(NULL == strstr(pszParam, "/")) + { + fprintf(stderr, "*pull Invalid parameter:\"%s\"\n", szCmd); + return ; + } + + if(RC_SUCC != lInitSATvm(pstSavm, SYS_TVM_DOMAIN)) + { + fprintf(stderr, "*initail SYS_TVM_DOMAIN failure, %s\n", sGetTError(pstSavm->m_lErrno)); + return ; + } + + conditinit(pstSavm, stDomain, SYS_TVM_DOMAIN); + stringsetv(pstSavm, stDomain, m_szOwner, sgetvalue(pszParam, "/", 1)); + if(!strlen(strimall(stDomain.m_szOwner))) + { + fprintf(stderr, "*illegal domain name\n"); + return ; + } + + // TBL_ACCT_INFO/PART --table=1 + strncpy(szCmd, sgetvalue(pszParam, "/", 2), sizeof(szCmd)); + strncpy(szTable, sgetvalue(szCmd, " ", 1), sizeof(szTable)); + strimall(szTable); + + stringsetv(pstSavm, stDomain, m_szTable, sgetvalue(szTable, "@", 1)); + supper(stDomain.m_szTable); + if(!strlen(stDomain.m_szTable)) + { + fprintf(stderr, "*Please input table name\n"); + return ; + } + + stringsetv(pstSavm, stDomain, m_szPart, sgetvalue(szTable, "@", 2)); + if(!strlen(stDomain.m_szPart)) + strcpy(stDomain.m_szPart, stDomain.m_szOwner); + + memset(szTable, 0, sizeof(szTable)); + strncpy(szTable, sgetvalue(szCmd, " ", 2), sizeof(szTable)); + strimall(szTable); + if(strlen(szTable) > 0) + { + if(!strncmp(szTable, "--table=", 8)) + { + table = atol(szTable + 8); + if(table <= 0 || table > TVM_MAX_TABLE) + { + fprintf(stderr, "*Local table set error \"%s\"\n", szTable + 8); + return ; + } + } + else + { + fprintf(stderr, "*command not supported \"%s\"\n", szTable); + return ; + } + } + + if(RC_SUCC != lSelect(pstSavm, (void *)&stDomain)) + { + fprintf(stderr, "*Select domain (%s)(%s) failure, %s\n", stDomain.m_szOwner, + stDomain.m_szTable, sGetTError(pstSavm->m_lErrno)); + return ; + } + + if(table != 0) + stDomain.m_table = table; + else + stDomain.m_table = stDomain.m_mtable; + + if(bTableIsExist(stDomain.m_table) || bPartIsExist(stDomain.m_szTable, pstSavm->m_szNode)) + { + fprintf(stderr, "*Table number (%d) already exists\n", stDomain.m_table); + return ; + } + + if((RESOURCE_ABLE != stDomain.m_lStatus) || !(stDomain.m_lPers & OPERATE_SELECT)) + { + fprintf(stderr, "*(%s)(%s) Resources are not available\n", stDomain.m_szTable, stDomain.m_szPart); + return ; + } + + if(RC_SUCC != lPullNotify(pstSavm, &stDomain, 1)) + { + fprintf(stderr, "*Cloning domain (%s) data failure, %s\n", stDomain.m_szOwner, + sGetTError(pstSavm->m_lErrno)); + return ; + } + + return ; +} + +/************************************************************************************************** + description:domain function + parameters: + return: + **************************************************************************************************/ +void vPrintDomFunc() +{ + fprintf(stderr, "Usage:\n"); + fprintf(stderr, " table\t\t--show remote tables\n"); + fprintf(stderr, " connect $DOM\t--connect remote domain\n"); + fprintf(stderr, " pull\t\t--pull remote table\n"); + fprintf(stderr, " exp:pull domain/table_name@part --table=table\n"); + return ; +} + +/************************************************************************************************** + description:Remote domain control + parameters: + return: + **************************************************************************************************/ +void vDomainCrontrl(TBoot *pstBoot) +{ + char *p = NULL, *pszUser = NULL; + SATvm *pstSavm = (SATvm *)pGetSATvm(); + + if(!bIsTvmBoot()) + { + fprintf(stderr, "stvm has not been started yet!\n"); + exit(0); + } + + system("stty erase ^?"); + system("stty erase ^H"); + fprintf(stdout, "\n%s\n", sFuncVersion()); + while(1) + { + if(NULL == (pszUser = readline("DOMAIN>"))) + continue; + + strimcrlf(pszUser); + sltrim(pszUser); + srtrim(pszUser); + if(!strlen(pszUser)) continue; + + add_history(pszUser); + + if(!strcasecmp(pszUser, "help") || !strcasecmp(pszUser, "--help") || + !strcasecmp(pszUser, "-?")) + vPrintDomFunc(); + else if(!strcasecmp(pszUser, "table")) + vPrintDomTable(); + else if(!strncasecmp(pszUser, "connect", 7)) + { + if(strncasecmp(pszUser, "connect ", 8)) + { + fprintf(stderr, "Usage:\n\t--connect domain\n\n"); + TFree(pszUser); + continue; + } + + vConnectDomain(sgetvalue(pszUser, " ", 2), pstBoot); + } + else if(!strncasecmp(pszUser, "pull", 4)) + { + if(strncasecmp(pszUser, "pull ", 5)) + { + fprintf(stderr, "Usage:\n\tpull domain/table_name@part\n\n"); + TFree(pszUser); + continue; + } + + p = pszUser + 5; + vPullTableDomain(p); + } + else if(!strcasecmp(pszUser, "q") || !strcasecmp(pszUser, "exit") || + !strcasecmp(pszUser, "quit")) + exit(0); + else + { + fprintf(stderr, "invalid option -- \"%s\"\n", pszUser); + vPrintDomFunc(); + } + + fprintf(stdout, "\n"); + TFree(pszUser); + } + + exit(0); +} + +/************************************************************************************************** + description:Check the stvm operating environment variables + parameters: + return: + **************************************************************************************************/ +void vCheckTvmEnv() +{ + int nRet; + + if(!getenv("TVMCFG")) + { + fprintf(stderr, "Environment variable \"TVMCFG\" is not set\n"); + exit(-1); + } + + if(!getenv("TVMDBD")) + { + fprintf(stderr, "Environment variable \"TVMDBD\" is not set\n"); + exit(-1); + } + +/* + if(0 != access(getenv("TVMDBD"), F_OK | X_OK )) + { + fprintf(stderr, "\"TVMDBD\" directory isnot set yet!\n"); + exit(-1); + } +*/ + + mkdir(getenv("TVMDBD"), S_IRWXU | S_IRWXG | S_IROTH | S_IEXEC ); +} + +/************************************************************************************************** + description:main(int argc, char *argv[]) + parameters: + return: + RC_SUCC --success + RC_FAIL --failure + **************************************************************************************************/ +int main(int argc, char *argv[]) +{ + TABLE table; + char szCom[256]; + SATvm *pstSavm = (SATvm *)pGetSATvm(); + int iChoose = 0, lAction = 0, lRet = 0; + TBoot *pstBoot = (TBoot *)pBootInitial(); + + if(3 == argc && !strcmp(argv[1], "-c")) + return lMakeConfig(argv[2]); + else if(3 == argc && !strcmp(argv[1], "-o")) + return lUnmakeConfig(argv[2]); + + memset(szCom, 0, sizeof(szCom)); + if(2 <= argc && (!strcasecmp(argv[1], "sql"))) + vSQLStatement(argc, argv); + if(2 <= argc && (!strcasecmp(argv[1], "dom"))) + vDomainCrontrl(pstBoot); + + vCheckTvmEnv(); + memset(szCom, 0, sizeof(szCom)); + while(-1 != (iChoose = getopt(argc, argv, "w::s::p::f::t:i:c:v?::"))) + { + switch(iChoose) + { + case 'w': + vInitTitle(argc, argv, environ); + return lStartSystem(pstBoot, optarg); + case 's': + return lStopSystem(pstBoot, argv[0]); + case 'p': + vPrintParam(optarg); + return RC_SUCC; + case 't': + vTableStruck(atol(optarg)); + return RC_SUCC; + case 'f': + vTableAmount(); + return RC_SUCC; + case 'i': + table = atol(optarg); + if(RC_SUCC != lRebuildIndex(pstSavm, table)) + fprintf(stderr, "rebuild index failure, %s\n", sGetTError(pstSavm->m_lErrno)); + return RC_SUCC; + case 'v': + fprintf(stdout, "%s\n", sGetTVMVers()); + fflush(stdout); + return RC_SUCC; + case '?': + default: + break; + } + } + + vPrintFunc(basename(argv[0])); + return RC_SUCC; +} + +/************************************************************************************************** + * code end + **************************************************************************************************/ diff --git a/src/tcp.c b/src/tcp.c new file mode 100644 index 0000000..c9ae23b --- /dev/null +++ b/src/tcp.c @@ -0,0 +1,4874 @@ +/* +* Copyright (c) 2018 Savens Liu +* +* The original has been patented, Open source is not equal to open rights. +* Anyone can clone, download, learn and discuss for free. Without the permission +* of the copyright owner or author, it shall not be merged, published, licensed or sold. +* The copyright owner or author has the right to pursue his responsibility. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "tmain.h" + +/************************************************************************************************* + statement + *************************************************************************************************/ +extern char **environ; +static char *g_Last = NULL; +static char **g_Argv = NULL; +static int g_eRun = 1; +Rowgrp *g_pstDomgrp = NULL, *g_pstTblgrp = NULL; + +extern char* pGetLog(); +extern long lGetBootType(); +extern void vSetBootType(long lType); +void* pParsePacket(SATvm *pstSavm, void *pstVoid, TFace *pstFace, void *pvBuffer, long lLen); +void* pProtocaJava(SATvm *pstSavm, void *pstVoid, TFace *pstFace, void *pvBuffer, long lLen); + +/************************************************************************************************* + macro + *************************************************************************************************/ +#define Tlog(...) vTraceLog(__FILE__, __LINE__, __VA_ARGS__) + +#define checkrequest(f,c,v,d,l) if(MAX(f->m_lRows, f->m_lDLen) > l) \ + { \ + if(MAX(f->m_lRows, f->m_lDLen) > DATA_MAX_LEN) \ + { \ + f->m_lErrno = RECD_TOO_LONG; \ + goto LISTEN_ERROR; \ + } \ + l = MAX(f->m_lRows, f->m_lDLen); \ + if(NULL == (c = (void *)realloc(c, l + sizeof(TFace)))) \ + { \ + f->m_lErrno = MALLC_MEM_ERR; \ + goto LISTEN_ERROR; \ + } \ + f = (TFace *)c; \ + d = c + sizeof(TFace); \ + if(NULL == (v = (void *)realloc(v, l + sizeof(TFace)))) \ + { \ + f->m_lErrno = MALLC_MEM_ERR; \ + goto LISTEN_ERROR; \ + } \ + } + +#define checkbuffer(p, r, n) if((p->lSize * n + r->m_lCurLine) > r->m_lRowSize) \ + { \ + if(r->m_lRowSize > DATA_MAX_LEN) \ + { \ + p->m_lErrno = RECD_TOO_LONG; \ + return RC_FAIL; \ + } \ + r->m_lRowSize = p->lSize + r->m_lCurLine; \ + if(NULL == (r->pstVoid = (void *)realloc(r->pstVoid, r->m_lRowSize))) \ + { \ + p->m_lErrno = MALLC_MEM_ERR; \ + return RC_FAIL; \ + } \ + } + +/************************************************************************************************* + function + *************************************************************************************************/ +/************************************************************************************************* + description:get root of domain list + parameters: + return: + void* --root + *************************************************************************************************/ +Rowgrp* pGetDomgrp() +{ + return g_pstDomgrp; +} + +/************************************************************************************************* + description:get root of table list + parameters: + return: + void* --root + *************************************************************************************************/ +Rowgrp* pGetTblgrp() +{ + return g_pstTblgrp; +} + +/************************************************************************************************* + description:checkt the child process is already started + parameters: + lPid --pid + return: + true --exist + false --disappear + *************************************************************************************************/ +bool bExistProcess(long lPid) +{ + errno = 0; + if(getpgid(lPid) == -1) + { + if(ESRCH == errno) return false; + else return true; + } + + return true; +} + +/************************************************************************************************* + description:trace log + parameters: + return: + *************************************************************************************************/ +void vTraceLog(const char *pszFile, int nLine, const char *fmt, ...) +{ + va_list ap; + FILE *fp = NULL; + char szMsg[5120]; + struct timeb tb; + struct tm *ptm = NULL; + + memset(szMsg, 0, sizeof(szMsg)); + va_start(ap, fmt); + vsnprintf(szMsg, sizeof(szMsg), fmt, ap); + va_end(ap); + + if(NULL == (fp = fopen(pGetLog(), "a+"))) + { + fprintf(stderr, "P(%d), open (%s) failed, err:%s,[%s]\n", getpid(), + pGetLog(), strerror(errno), szMsg); + return ; + } + + ftime(&tb); + ptm = localtime(&tb.time); + fprintf(fp, "F=%-8s L=%-5d P=%-7d T=%-7ld T=%04d%02d%02d %02d%02d%02d:%03d %s\n", + pszFile, nLine, getpid(), syscall(SYS_gettid), ptm->tm_year + 1900, ptm->tm_mon + 1, + ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec, tb.millitm, szMsg); + fclose(fp); + return ; +} + +/************************************************************************************************* + description:Show cloning progress + parameters: + nVaild --vaild + nMax --max + return: + *************************************************************************************************/ +void vPrintProgresss(int nValid, int nMax) +{ + double dPer; + int i, nPer; + static int len = 0; + char szPrint[64]; + + for(i = len + 50; i > 0 && nValid > 1; i --) + fprintf(stdout, "\b"); + + dPer = nValid * 100.0 / nMax; + nPer = nValid * 50 / nMax > 0 ? nValid * 50 / nMax : 1; + if(dPer < 60.00) + fprintf(stdout, "\033[42;32m"); + else if(dPer < 70.00) + fprintf(stdout, "\033[45;35m"); + else if(dPer < 80.00) + fprintf(stdout, "\033[46;36m"); + else if(dPer < 90.00) + fprintf(stdout, "\033[43;33m"); + else + fprintf(stdout, "\033[41;31m"); + + fflush(stdout); + for(i = 0; i < nPer; i ++) + fprintf(stdout, "|"); + + fprintf(stdout, "\033[0m"); + for(i; i < 50; i ++) + fprintf(stdout, " "); + + memset(szPrint, 0, sizeof(szPrint)); + len = snprintf(szPrint, sizeof(szPrint), "] %6.3f%%, (%d/%d)", dPer, nValid, nMax); + fprintf(stdout, "%s", szPrint); + fflush(stdout); +} + +/************************************************************************************************* + description:Initialize the startup process name + parameters: + argc + **argv + **envp + return: + *************************************************************************************************/ +void vInitTitle(int argc, char **argv, char **envp) +{ + int i = 0; + + for(i = 0; envp[i] != NULL; i++) // calc envp num + continue; + + environ = (char **) malloc(sizeof (char *) * (i + 1)); + for (i = 0; envp[i] != NULL; i++) + { + environ[i] = malloc(sizeof(char) * strlen(envp[i]) + 1); + memset(environ[i], 0, sizeof(char) * strlen(envp[i]) + 1); + strcpy(environ[i], envp[i]); + } + + environ[i] = NULL; + g_Argv = argv; + if (i > 0) + g_Last = envp[i - 1] + strlen(envp[i - 1]); + else + g_Last = argv[argc - 1] + strlen(argv[argc - 1]); +} + +/************************************************************************************************* + description:set current process name + parameters: + pname --process name + return: + *************************************************************************************************/ +void vSetTitile(const char *pname) +{ + int i; + char *p, name[16]; + extern char **g_Argv; + extern char *g_Last; + + strncpy(name, pname, 16); + i = strlen(name); + if (i > g_Last - g_Argv[0] - 2) + { + i = g_Last - g_Argv[0] - 2; + name[i] = '\0'; + } + + (void) strcpy(g_Argv[0], name); + p = &g_Argv[0][i]; + while (p < g_Last) + *p++ = '\0'; + g_Argv[1] = NULL; + prctl(PR_SET_NAME, name); +} + +/************************************************************************************************* + description:get tick time + parameters: + return: + uint64_t + *************************************************************************************************/ +uint64_t get_tick_time() +{ + struct timeval tval; + uint64_t tick; + + gettimeofday(&tval, NULL); + + tick = tval.tv_sec * 1000L + tval.tv_usec / 1000L; + + return tick; +} + +/************************************************************************************************* + description:Set non-blocking + parameters: + skSock --socket + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lSetUnBlock(BSock skSock) +{ + int nOpt = 0; + + if(fcntl(skSock, F_GETFL) < 0) + return RC_FAIL; + + nOpt = nOpt | O_NONBLOCK; + if(fcntl(skSock, F_SETFL, nOpt) < 0) + return RC_FAIL; + + return RC_SUCC; +} + +/************************************************************************************************* + description:Set blocking + parameters: + skSock --socket + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lSetBlock(BSock skSock) +{ + int nOpt = 0; + + if(fcntl(skSock, F_GETFL) < 0) + return RC_FAIL; + + nOpt &= ~O_NONBLOCK; + if(fcntl(skSock, F_SETFL, nOpt) < 0) + return RC_FAIL; + + return RC_SUCC; +} + +/************************************************************************************************* + description:connect server + parameters: + pstSavm --stvm handle + pszIp --ip + lPort --port + bf --blocking and no-blocking + lTime --time out + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +BSock skConnectServer(SATvm *pstSavm, char *pszIp, long lPort, BOOL bf, long lTime) +{ + fd_set set, exp; + struct timeval tv; + struct linger lin; + BSock skSock; + struct sockaddr_in stAdr; + int error = -1, len = sizeof(int); + + memset(&stAdr, 0, sizeof(struct sockaddr_in)); + stAdr.sin_family = AF_INET; + stAdr.sin_addr.s_addr = inet_addr(pszIp); + stAdr.sin_port = htons((u_short)lPort); + + if((skSock = socket(AF_INET, SOCK_STREAM, 0)) < 0) + { + pstSavm->m_lErrno = SOCK_ERR_CRTE; + return RC_FAIL; + } + + memset(&lin, 0, sizeof(lin)); + lin.l_onoff = TRUE; + lin.l_linger = 10; + if (0 > setsockopt(skSock, SOL_SOCKET, SO_LINGER, &lin, sizeof(lin))) + { + close(skSock); + return RC_FAIL; + } + + if(RC_SUCC != lSetUnBlock(skSock)) + { + close(skSock); + return RC_FAIL; + } + + if(RC_SUCC == connect(skSock, (struct sockaddr *)(&stAdr), sizeof(struct sockaddr_in))) + { + if(!bf) lSetBlock(skSock); + return skSock; + } + + if(errno != EINPROGRESS) + { + close(skSock); + pstSavm->m_lErrno = SOCK_CONN_ERR; + return RC_FAIL; + } + + FD_ZERO(&set); + FD_ZERO(&exp); + FD_SET(skSock, &set); + tv.tv_sec = lTime; + tv.tv_usec = 0; + errno = 0; + if(RC_SUCC >= select(skSock + 1, NULL, &set, &exp, &tv)) + { + close(skSock); + pstSavm->m_lErrno = SOCK_CONN_TMO; + return RC_FAIL; + } + + if(!FD_ISSET(skSock, &set) || FD_ISSET(skSock, &exp)) //异常套接字就绪 + { + close(skSock); + pstSavm->m_lErrno = SOCK_CONN_ERR; + return RC_FAIL; + } + +#ifdef HP_UX + getsockopt(skSock, SOL_SOCKET, SO_ERROR, &error, &len); +#else // linux + getsockopt(skSock, SOL_SOCKET, SO_ERROR, &error,(socklen_t*)&len); +#endif + if(!bf) lSetBlock(skSock); // set block + if(0 == error) return skSock; + + pstSavm->m_lErrno = SOCK_CONN_ERR; + close(skSock); + return RC_FAIL; +} + +/************************************************************************************************* + description:server initail + parameters: + pstSavm --stvm handle + lPort --port + return: + BSock --socket + *************************************************************************************************/ +BSock skServerInitail(SATvm *pstSavm, int lPort) +{ + int iret = -1; + int optval = 1; + BSock skSock = -1; + struct sockaddr_in serveraddr; + + memset(&serveraddr, 0, sizeof(struct sockaddr_in)); + if((skSock = socket(AF_INET, SOCK_STREAM, 0)) < 0) + { + pstSavm->m_lErrno = SOCK_ERR_CRTE; + return RC_FAIL; + } + + if(RC_SUCC != lSetUnBlock(skSock)) + { + close(skSock); + return RC_FAIL; + } + + if (0 > setsockopt(skSock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))) + { + close(skSock); + return RC_FAIL; + } + + serveraddr.sin_family = AF_INET; + serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); + serveraddr.sin_port = htons(lPort); + + if (0 > bind(skSock, (struct sockaddr *)&serveraddr, sizeof(struct sockaddr_in))) + { + close(skSock); + pstSavm->m_lErrno = SOCK_BIND_ERR; + return RC_FAIL; + } + + if (0 > listen(skSock, 1024)) + { + close(skSock); + pstSavm->m_lErrno = SOCK_LSEN_ERR; + return RC_FAIL; + } + + return skSock; +} + +/************************************************************************************************* + description:send buffer with no-blocking + parameters: + pstSavm --stvm handle + skSock --socket + ss --buffer + len --the length of buffer + return: + int --Number of bytes sent + *************************************************************************************************/ +int lSendUnblock(SATvm *pstSavm, int skSock, char *ss, int len) +{ + long lByte = 0, lLeft = len, lWrite = 0; + + while(lLeft > 0) + { + if((lWrite = send(skSock, ss + lByte, lLeft, MSG_DONTWAIT)) <= 0) + { + if(EWOULDBLOCK == errno|| EAGAIN == errno) + return lByte; + else + { + pstSavm->m_lErrno = SOCK_SEND_ERR; + return RC_FAIL; + } + } + else + { + lLeft -= lWrite; + lByte += lWrite; + } + } + + return lByte; +} + +/************************************************************************************************* + description:recv buffer with no-blocking + parameters: + pstSavm --stvm handle + skSock --socket + ss --buffer + len --the length of buffer + return: + int --Number of bytes recv + *************************************************************************************************/ +int lRecvUnblock(SATvm *pstSavm, int skSock, char *so, int read) +{ + int lByte = 0, lRecv = 0; + + while(read > lRecv) + { + lByte = recv(skSock, so + lRecv, read - lRecv, MSG_DONTWAIT); + if(lByte < 0) + { + if(EAGAIN == errno || EWOULDBLOCK == errno) + return lRecv; + else if(errno == ECONNRESET || ENETRESET == errno || ENETDOWN == errno || + EINTR == errno) + { + pstSavm->m_lErrno = SOCK_IO_RESET; + return RC_FAIL; + } + else + { + pstSavm->m_lErrno = SOCK_READ_ERR; + return RC_FAIL; + } + } + else if(lByte == 0) + { + pstSavm->m_lErrno = SOCK_IO_RESET; + return RC_FAIL; + } + + lRecv += lByte; + } + + return lRecv; +} + +/************************************************************************************************* + description:recv buffer with blocking + parameters: + skSock --socket + pszRecv --buffer + lRead --the byte of read + return: + int --Number of bytes recv + *************************************************************************************************/ +int lRecvBuffer(int skSock, char *pszRecv, int lRead) +{ + int lByte = 0, lRecv = 0; + + errno = 0; + while(lRead > lRecv) + { + lByte = recv(skSock, pszRecv + lRecv, lRead - lRecv, 0); + if(lByte < 0) + { + if(EAGAIN == errno || EWOULDBLOCK == errno) + return lRecv; + + // Connection reset by peer + if(errno == ECONNRESET || ENETRESET == errno || ENETDOWN == errno || + EINTR == errno) + return RC_FAIL; + else + return RC_FAIL; + } + else if(lByte == 0) + return RC_CLOSE; + + lRecv += lByte; + } + + return lRecv; +} + +/************************************************************************************************* + description:send buffer with blocking + parameters: + skSock --socket + pszSend --buffer + lSend --the byte of send + return: + int --Number of bytes send + *************************************************************************************************/ +int lSendBuffer(BSock skSock, void *pszSend, int lSend) +{ + long lByte = 0, lLeft = lSend, lWrite = 0; + + errno = 0; + while(lLeft > 0) + { + if((lWrite = send(skSock, pszSend + lByte, lLeft, 0)) <= 0) + return lByte; + else + { + lLeft -= lWrite; + lByte += lWrite; + } + } + + return lByte; +} + +/************************************************************************************************* + description:close socket of domain + parameters: + pstDom --domain + return: + *************************************************************************************************/ +void vCloseSocket(TDomain *pstDom) +{ + shutdown(pstDom->m_skSock, SHUT_RDWR); + close(pstDom->m_skSock); + pstDom->m_skSock = -1; +} + +/************************************************************************************************* + description:find table from table list + parameters: + t --table + return: + list --rowgrp node + *************************************************************************************************/ +Rowgrp* pGetTblNode(TABLE t) +{ + Rowgrp *list = NULL; + + for(list = pGetTblgrp(); list; list = list->pstNext) + { + if(!memcmp(&t, list->psvData, sizeof(TABLE))) + return list; + } + + return NULL; +} + +/************************************************************************************************* + description:update remote table perms + parameters: + pstDom --domain + pstIndex --retmote table + return: + *************************************************************************************************/ +void vUpdateDomPers(TDomain *pstDom, TIndex *pstIndex) +{ + TDomain *pvm; + Rowgrp *list, *node = NULL; + + for(list = pGetTblgrp(); list; list = list->pstNext) + { + if(memcmp(&pstIndex->m_table, list->psvData, sizeof(TABLE))) + continue; + + for(node = list->pstSSet; node; node = node->pstNext) + { + if(NULL == (pvm = (TDomain *)(list->pstFset->psvData))) + continue; + + if(strcmp(pvm->m_szIp, pstDom->m_szIp) || pvm->m_lPort != pstDom->m_lPort) + continue; + + pvm->m_lPers = pstIndex->m_lPers; + return ; + } + } +} + +/************************************************************************************************* + description:find domain from rowgrp + parameters: + pszIp --ip + lPort --port + return: + list --rowgrp node + *************************************************************************************************/ +Rowgrp* pGetDomnode(char *pszIp, long lPort) +{ + Rowgrp *list = NULL; + TDomain *pstDom = NULL; + + for(list = pGetDomgrp(); list; list = list->pstNext) + { + pstDom = (TDomain *)list->psvData; + if(!strcmp(pstDom->m_szIp, pszIp) && pstDom->m_lPort == lPort) + return list; + } + + return NULL; +} + +/************************************************************************************************* + description:find domain + parameters: + pszIp --ip + lPort --port + return: + domain --domain + *************************************************************************************************/ +TDomain* pGetDomain(char *pszIp, long lPort) +{ + Rowgrp *list = NULL; + TDomain *pstDom = NULL; + + for(list = pGetDomgrp(); list; list = list->pstNext) + { + pstDom = (TDomain *)list->psvData; + if(!strcmp(pstDom->m_szIp, pszIp) && pstDom->m_lPort == lPort) + return pstDom; + } + + return NULL; +} + +/************************************************************************************************* + description:Initialize the network connection table handle + parameters: + pstSavm --stvm handle + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lTvmBuffer(SATvm *pstSavm) +{ + RunTime *pstRun; + + if(!pstSavm) return RC_FAIL; + + pstRun = (RunTime *)pGetRunTime(pstSavm, 0); + if(pstRun->m_lRowSize > 0 && pstRun->pstVoid) + return RC_SUCC; + + pstRun->m_lCurLine = sizeof(pstSavm->stCond) + sizeof(pstSavm->stUpdt) + sizeof(TFace); + pstRun->m_lRowSize = READ_MAX_LEN > pstRun->m_lCurLine ? READ_MAX_LEN : pstRun->m_lCurLine; + if(NULL == (pstRun->pstVoid = (void *)calloc(pstRun->m_lRowSize, 1))) + { + pstSavm->m_lErrno = MALLC_MEM_ERR; + return RC_FAIL; + } + + return RC_SUCC; +} + +/************************************************************************************************* + description:Update local domain information + parameters: + pstSavm --stvm handle + pszId --ip + lPort --lPort + lStatus --status + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lUpdateDomain(SATvm *pstSavm, char *pszIp, long lPort, long lStatus) +{ + TDomain stUpdate, stDomain; + + if(RC_SUCC != lInitSATvm(pstSavm, SYS_TVM_DOMAIN)) + return RC_FAIL; + + updateinit(stUpdate); + conditinit(pstSavm, stDomain, SYS_TVM_DOMAIN); + numberset(pstSavm, stDomain, m_lPort, lPort) + stringset(pstSavm, stDomain, m_szIp, pszIp); + + numberupd(pstSavm, stUpdate, m_lStatus, lStatus); + if(RESOURCE_ABLE != lStatus) + numberupd(pstSavm, stUpdate, m_lPers, 0); + if(RC_SUCC != lUpdate(pstSavm, (void *)&stUpdate)) + { + Tlog("update domain (%s:%d) failure, %s\n", pszIp, lPort, sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; + } + + return RC_SUCC; +} + +/************************************************************************************************* + description:Update local resources based on remote tables + parameters: + pstSavm --stvm handle + pstFace --request head + pstDom --domain info + pstIndx --remote resource list + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lRemodeIndex(SATvm *pstSavm, TFace *pstFace, TDomain *pstDom, TIndex *pstIndex) +{ + long i; + TDomain stDomain, stRemote; + + pstFace->m_lRows = pstFace->m_lRows / pstFace->m_lDLen; + if(RC_SUCC != lInitSATvm(pstSavm, SYS_TVM_DOMAIN)) + return RC_FAIL; + + conditinit(pstSavm, stDomain, SYS_TVM_DOMAIN); + numberset(pstSavm, stDomain, m_lPort, pstDom->m_lPort); + stringset(pstSavm, stDomain, m_szIp, pstDom->m_szIp); + numberupd(pstSavm, stRemote, m_lStatus, RESOURCE_AUTH); + numberupd(pstSavm, stRemote, m_lPers, 0); + if(RC_SUCC != lUpdate(pstSavm, (void *)&stRemote)) + { + if(NO_DATA_FOUND != pstSavm->m_lErrno) + return RC_FAIL; + } + + conditinit(pstSavm, stDomain, SYS_TVM_DOMAIN); + for(i = 0; i < pstFace->m_lRows; i ++) + { + numberset(pstSavm, stDomain, m_lPort, pstDom->m_lPort); + numberset(pstSavm, stDomain, m_mtable, pstIndex[i].m_table); + stringset(pstSavm, stDomain, m_szIp, pstDom->m_szIp); + + updateinit(stRemote); + numberupd(pstSavm, stRemote, m_lLastTime, time(NULL)); + numberupd(pstSavm, stRemote, m_lTryTimes, 0); + numberupd(pstSavm, stRemote, m_lStatus, RESOURCE_ABLE); + numberupd(pstSavm, stRemote, m_skSock, pstDom->m_skSock); + numberupd(pstSavm, stRemote, m_lPers, pstIndex[i].m_lPers); + numberupd(pstSavm, stRemote, m_mtable, pstIndex[i].m_table); + numberupd(pstSavm, stRemote, m_lRowSize, pstIndex[i].m_lRowSize); + stringupd(pstSavm, stRemote, m_szPart, pstIndex[i].m_szPart); + stringupd(pstSavm, stRemote, m_szTable, pstIndex[i].m_szTable); + + if(RC_SUCC != lUpdate(pstSavm, (void *)&stRemote)) + { + Tlog("update local resource stat failed, %s, e(%d)", sGetTError(pstSavm->m_lErrno), + pstSavm->m_lEType); + if(NO_DATA_FOUND == pstSavm->m_lErrno) + continue; + return RC_FAIL; + } + + vUpdateDomPers(pstDom, &pstIndex[i]); + } + + return RC_SUCC; +} + +/************************************************************************************************* + description:Upload local resources + parameters: + pstSavm --stvm handle + pstFace --request head + skSock --domain info + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lLocalIndex(SATvm *pstSavm, TFace *pstFace, BSock skSock) +{ + size_t lWrite; + TIndex stIndex; + void *pvOut = NULL, *pvBuffer = NULL; + + pstFace->m_table = SYS_TVM_INDEX; + pstFace->m_lDLen = sizeof(TIndex); + + if(RC_SUCC != lInitSATvm(pstSavm, pstFace->m_table)) + return RC_FAIL; + + conditinit(pstSavm, stIndex, SYS_TVM_INDEX); + numberset(pstSavm, stIndex, m_lType, TYPE_CLIENT); + numberset(pstSavm, stIndex, m_lLocal, RES_LOCAL_SID); + if(RC_SUCC != lQuery(pstSavm, (size_t *)&pstFace->m_lRows, (void *)&pvOut)) + { + if(NO_DATA_FOUND != pstSavm->m_lErrno) + return RC_FAIL; + } + + if(pstFace->m_lRows == 0) + { + if(sizeof(TFace) != lSendBuffer(skSock, (void *)pstFace, sizeof(TFace))) + return RC_FAIL; + return RC_SUCC; + } + + pstFace->m_lRows = pstFace->m_lDLen * pstFace->m_lRows; + lWrite = pstFace->m_lRows + sizeof(TFace); + if(NULL == (pvBuffer = (void *)malloc(lWrite))) + { + pstSavm->m_lErrno = MALLC_MEM_ERR; + TFree(pvOut); + return RC_FAIL; + } + + memcpy(pvBuffer, (void *)pstFace, sizeof(TFace)); + memcpy(pvBuffer + sizeof(TFace), (void *)pvOut, pstFace->m_lRows); + lSendBuffer(skSock, pvBuffer, lWrite); + TFree(pvOut); + TFree(pvBuffer); + + return RC_SUCC; +} + +/************************************************************************************************* + description:Join in the domain + parameters: + pstSavm --stvm handle + pstFace --request head + lPort --local port + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lConnectDomain(SATvm *pstSavm, TDomain *pstDom, long lPort) +{ + TFace stFace; + TIndex *pstIndex = NULL; + + memset(&stFace, 0, sizeof(TFace)); + if(pstDom->m_skSock < 0) + { + pstDom->m_skSock = skConnectServer(pstSavm, pstDom->m_szIp, pstDom->m_lPort, + false, pstDom->m_lTimeOut); + if(RC_FAIL == pstDom->m_skSock) + { + pstDom->m_lStatus = RESOURCE_STOP; + Tlog("connect server:%s:%d failed, %s", pstDom->m_szIp, pstDom->m_lPort, + sGetTError(pstSavm->m_lErrno)); + goto EXCP_NOTIFY; + } + } + + stFace.m_lRows = 0; + stFace.m_lFind = lPort; + stFace.m_table = SYS_TVM_INDEX; + stFace.m_enum = OPERATE_DOMPUL; + stFace.m_lErrno = TVM_DONE_SUCC; + stFace.m_lDLen = sizeof(TIndex); + if(sizeof(TFace) != lSendBuffer(pstDom->m_skSock, (void *)&stFace, sizeof(TFace))) + { + pstDom->m_lStatus = RESOURCE_EXCP; + goto EXCP_NOTIFY; + } + + if(sizeof(TFace) != lRecvBuffer(pstDom->m_skSock, (char *)&stFace, sizeof(TFace))) + { + pstDom->m_lStatus = RESOURCE_EXCP; + goto EXCP_NOTIFY; + } + + if(DOM_NOT_REGST == stFace.m_lErrno) + { + pstDom->m_lStatus = RESOURCE_AUTH; + goto EXCP_NOTIFY; + } + else if(0 != stFace.m_lErrno && NO_DATA_FOUND != stFace.m_lErrno) + { + pstDom->m_lStatus = RESOURCE_EXCP; + goto EXCP_NOTIFY; + } + + if(NULL == (pstIndex = (TIndex *)malloc(stFace.m_lRows))) + { + pstSavm->m_lErrno = MALLC_MEM_ERR; + return RC_FAIL; + } + + if(stFace.m_lRows != lRecvBuffer(pstDom->m_skSock, (void *)pstIndex, stFace.m_lRows)) + { + TFree(pstIndex); + return RC_FAIL; + } + + if(RC_SUCC != _lRemodeIndex(pstSavm, &stFace, pstDom, pstIndex)) + { + TFree(pstIndex); + pstDom->m_lStatus = RESOURCE_EXCP; + goto EXCP_NOTIFY; + } + TFree(pstIndex); + + stFace.m_lFind = lPort; + stFace.m_enum = OPERATE_DOMPSH; + stFace.m_lErrno = TVM_DONE_SUCC; + if(RC_SUCC != _lLocalIndex(pstSavm, &stFace, pstDom->m_skSock)) + { + pstDom->m_lStatus = RESOURCE_EXCP; + goto EXCP_NOTIFY; + } + + pstDom->m_lStatus = RESOURCE_ABLE; + return RC_SUCC; + +EXCP_NOTIFY: + vCloseSocket(pstDom); + pstDom->m_lTryTimes = pstDom->m_lTryMax; + pstDom->m_lLastTime = (long)time(NULL); + lUpdateDomain(pstSavm, pstDom->m_szIp, pstDom->m_lPort, pstDom->m_lStatus); + return RC_FAIL; +} + +/************************************************************************************************* + description:Notifies the remote domain that the local will be offline + parameters: + pstSavm --stvm handle + pstFace --request head + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lLocalOffline(SATvm *pstSavm, TFace *pstFace) +{ + Rowgrp *list = NULL; + TDomain *pstDom = NULL; + + for(list = pGetDomgrp(); list; list = list->pstNext) + { + if(NULL == (pstDom = (TDomain *)list->psvData)) + continue; + + if(RESOURCE_ABLE != pstDom->m_lStatus) + { + vCloseSocket(pstDom); + continue; + } + + while(DATA_TRUCK_LOCK == pstDom->m_lLock) + usleep(10); + + pstDom->m_lLock = DATA_TRUCK_LOCK; + pstFace->m_lRows = 0; + pstFace->m_enum = OPERATE_DOMROFF; + if(sizeof(TFace) != lSendBuffer(pstDom->m_skSock, (void *)pstFace, sizeof(TFace))) + { + vCloseSocket(pstDom); + pstDom->m_lLock = DATA_TRUCK_NULL; + continue; + } + + lRecvBuffer(pstDom->m_skSock, (char *)pstFace, sizeof(TFace)); + vCloseSocket(pstDom); + pstDom->m_lLock = DATA_TRUCK_NULL; + } + + return RC_SUCC; +} + +/************************************************************************************************* + description:Set the remote domain offline + parameters: + pstSavm --stvm handle + pstCon --socket handle + pstFace --request head + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lRemoteOffline(SATvm *pstSavm, SKCon *pstCon, TFace *pstFace) +{ + TDomain *pstDom = NULL; + long lPort = pstFace->m_lFind; + + if(NULL == (pstDom = pGetDomain(pstCon->m_szCltIp, pstFace->m_lFind))) + { + Tlog("Unregistered client request: %s:%d", pstCon->m_szCltIp, pstFace->m_lFind); + return RC_FAIL; + } + + vCloseSocket(pstDom); + pstDom->m_lStatus = RESOURCE_ROFF; + pstDom->m_lTryTimes = pstDom->m_lTryMax; + return lUpdateDomain(pstSavm, pstDom->m_szIp, lPort, RESOURCE_STOP); +} + +/************************************************************************************************* + description:reconnect the remote domain + parameters: + pstSavm --stvm handle + pstCon --socket handle + pstFace --request head + pv --remote domain + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lReconnectDomain(SATvm *pstSavm, SKCon *pstCon, TFace *pstFace, TDomain *pv) +{ + TDomain *pstDom; + + if(NULL == (pstDom = pGetDomain(pv->m_szIp, pv->m_lPort))) + { + Tlog("Unregistered client request: %s:%d", pv->m_szIp, pv->m_lPort); + return RC_FAIL; + } + + pstDom->m_lTryTimes = 0; + pstDom->m_lLastTime = (long)time(NULL); + return lConnectDomain(pstSavm, pstDom, pstFace->m_lFind); +} + +/************************************************************************************************* + description:Receiving remote resources + parameters: + pstSavm --stvm handle + pstCon --socket handle + pstFace --request head + pvData --remote resource + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lDomainPull(SATvm *pstSavm, SKCon *pstCon, TFace *pstFace, void *pvData) +{ + TDomain *pstDom = NULL; + + if(NULL == (pstDom = pGetDomain(pstCon->m_szCltIp, pstFace->m_lFind))) + { + Tlog("Unregistered client request: %s:%d", pstCon->m_szCltIp, pstFace->m_lFind); + return RC_FAIL; + } + + pstDom->m_lTryTimes = 0; + pstDom->m_lLastTime = (long)time(NULL); + return _lRemodeIndex(pstSavm, pstFace, pstDom, (TIndex *)pvData); +} + +/************************************************************************************************* + description:Sending local resources + parameters: + pstSavm --stvm handle + pstCon --socket handle + pstFace --request head + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lDomainPush(SATvm *pstSavm, SKCon *pstCon, TFace *pstFace) +{ + TDomain *pstDom = NULL; + + if(NULL == (pstDom = pGetDomain(pstCon->m_szCltIp, pstFace->m_lFind))) + { + Tlog("Unregistered client request: %s:%d", pstCon->m_szCltIp, pstFace->m_lFind); + return RC_FAIL; + } + + pstDom->m_lTryTimes = 0; + pstDom->m_lStatus = RESOURCE_ABLE; + pstDom->m_lLastTime = (long)time(NULL); + return _lLocalIndex(pstSavm, pstFace, pstCon->m_skSock); +} + +/************************************************************************************************* + description:Sending local table data + parameters: + pstSavm --stvm handle + pstCon --socket handle + skSock --socket + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lPushTable(SATvm *pstSavm, TFace *pstFace, BSock skSock) +{ + long lWrite, lRow = 0, lRet; + void *pvData = NULL, *pvBuffer = NULL; + + pstFace->m_lRows = 1; + pstFace->m_lDLen = sizeof(TblDef); + if(pstFace->m_lDLen != lSendBuffer(skSock, (void *)pGetTblDef(pstFace->m_table), + pstFace->m_lDLen)) + return RC_FAIL; + + if(pstFace->m_lFind <= 0) + { + pstFace->m_lRows = 0; + lSendBuffer(skSock, (void *)pstFace, sizeof(TFace)); + return RC_SUCC; + } + + lWrite = lGetRowSize(pstFace->m_table) * pstFace->m_lFind + sizeof(TFace); + if(NULL == (pvBuffer = (char *)calloc(1, lWrite))) + { + pstSavm->m_lErrno = MALLC_MEM_ERR; + return RC_FAIL; + } + pvData = pvBuffer + sizeof(TFace); + + pstSavm->pstVoid = NULL; + pstSavm->tblName = pstFace->m_table; + pstSavm->lSize = lGetRowSize(pstFace->m_table); + if(RC_SUCC != lTableDeclare(pstSavm)) + { + TFree(pvBuffer); + return RC_FAIL; + } + + ((TFace *)pvBuffer)->m_table = pstFace->m_table; + ((TFace *)pvBuffer)->m_lRows = pstFace->m_lFind; + ((TFace *)pvBuffer)->m_lDLen = lGetRowSize(pstFace->m_table); + + while(1) + { + lRet = lTableFetch(pstSavm, (void *)pvData + lRow * pstFace->m_lDLen); + if(RC_FAIL == lRet) + { + TFree(pvBuffer); + vTableClose(pstSavm); + return RC_FAIL; + } + else if(RC_NOTFOUND == lRet) + break; + + if(pstFace->m_lFind != ++ lRow) + continue; + + lRow = 0; + if(lWrite != lSendBuffer(skSock, (void *)pvBuffer, lWrite)) + { + vTableClose(pstSavm); + return RC_FAIL; + } + } + vTableClose(pstSavm); + + if(0 == lRow) + { + TFree(pvBuffer); + pstFace->m_lRows = 0; + lSendBuffer(skSock, (void *)pstFace, sizeof(TFace)); + return RC_SUCC; + } + + ((TFace *)pvBuffer)->m_lRows = lRow; + lWrite = lGetRowSize(pstFace->m_table) * lRow + sizeof(TFace); + if(lWrite != lSendBuffer(skSock, (void *)pvBuffer, lWrite)) + { + TFree(pvBuffer); + return RC_FAIL; + } + + ((TFace *)pvBuffer)->m_lRows = 0; + if(sizeof(TFace) != lSendBuffer(skSock, (void *)pvBuffer, sizeof(TFace))) + { + TFree(pvBuffer); + return RC_FAIL; + } + + TFree(pvBuffer); + return RC_SUCC; +} + +/************************************************************************************************* + description:refresh remote domain + parameters: + pstSavm --stvm handle + pstFace --request head + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lRefreshDomain(SATvm *pstSavm, TFace *pstFace) +{ + Rowgrp *list = NULL; + TDomain *pstDom = NULL; + + for(list = pGetDomgrp(); list; list = list->pstNext) + { + if(NULL == (pstDom = (TDomain *)list->psvData)) + continue; + + while(DATA_TRUCK_LOCK == pstDom->m_lLock) + usleep(10); + + pstDom->m_lLock = DATA_TRUCK_LOCK; + lConnectDomain(pstSavm, pstDom, pstFace->m_lFind); + pstDom->m_lLock = DATA_TRUCK_NULL; + } + + return RC_SUCC; +} + +/************************************************************************************************* + description:Java API - event operation + parameters: + pstSavm --stvm handle + pstFace --request head + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lProcaOperate(SATvm *pstSavm, SKCon *pstCon, TFace *pstFace, char *pvData) +{ + + + + + + pstFace->m_lRows = 0; + pstFace->m_lErrno = RMT_NOT_SUPPT; + return RC_FAIL; +} + +/************************************************************************************************* + description:C/C++ API - event operation + parameters: + pstSavm --stvm handle + pstCon --socket handle + pstFace --request head + pvData --request data + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lEventOperate(SATvm *pstSavm, SKCon *pstCon, TFace *pstFace, char *pvData) +{ + size_t lData; + void *pvOut = NULL; + + switch(pstFace->m_enum) + { + case OPERATE_SELECT: + if(RC_SUCC != lSelect(pstSavm, (void *)pvData)) + { + pstFace->m_lErrno = pstSavm->m_lErrno; + lData = sizeof(TFace); + } + else + { + lData = pstFace->m_lDLen + sizeof(TFace); + pstFace->m_lRows = pstSavm->m_lEffect; + } + + lSendBuffer(pstCon->m_skSock, (void *)pstFace, lData); + return RC_SUCC; + case OPERATE_QUERY: + if(RC_SUCC != lQuery(pstSavm, (size_t *)&pstFace->m_lRows, (void *)&pvOut)) + pstFace->m_lErrno = pstSavm->m_lErrno; + + lData = pstFace->m_lDLen * pstFace->m_lRows; + if(sizeof(TFace) != lSendBuffer(pstCon->m_skSock, (void *)pstFace, sizeof(TFace))) + { + TFree(pvOut); + return RC_SUCC; + } + + lSendBuffer(pstCon->m_skSock, pvOut, lData); + TFree(pvOut); + return RC_SUCC; + case OPERATE_UPDATE: + pstSavm->m_bWork = pstCon->m_bWork; + pstSavm->m_pstWork = pstCon->m_pstWork; + if(RC_SUCC != lUpdate(pstSavm, pvData)) + pstFace->m_lErrno = pstSavm->m_lErrno; + else + pstFace->m_lRows = pstSavm->m_lEffect; + pstCon->m_pstWork = pstSavm->m_pstWork; + lSendBuffer(pstCon->m_skSock, (void *)pstFace, sizeof(TFace)); + return RC_SUCC; + case OPERATE_DELETE: + pstSavm->m_bWork = pstCon->m_bWork; + pstSavm->m_pstWork = pstCon->m_pstWork; + if(RC_SUCC != lDelete(pstSavm)) + pstFace->m_lErrno = pstSavm->m_lErrno; + pstCon->m_pstWork = pstSavm->m_pstWork; + pstFace->m_lRows = pstSavm->m_lEffect; + lSendBuffer(pstCon->m_skSock, (void *)pstFace, sizeof(TFace)); + return RC_SUCC; + case OPERATE_INSERT: + pstSavm->m_bWork = pstCon->m_bWork; + pstSavm->m_pstWork = pstCon->m_pstWork; + if(RC_SUCC != lInsert(pstSavm)) + pstFace->m_lErrno = pstSavm->m_lErrno; + else + pstFace->m_lRows = pstSavm->m_lEffect; + pstCon->m_pstWork = pstSavm->m_pstWork; + lSendBuffer(pstCon->m_skSock, (void *)pstFace, sizeof(TFace)); + return RC_SUCC; + case OPERATE_TRCATE: + if(RC_SUCC != lTruncate(pstSavm, pstFace->m_table)) + pstFace->m_lErrno = pstSavm->m_lErrno; + else + pstFace->m_lRows = pstSavm->m_lEffect; + lSendBuffer(pstCon->m_skSock, (void *)pstFace, sizeof(TFace)); + return RC_SUCC; + case OPERATE_COUNT: + if(RC_SUCC != lCount(pstSavm, (size_t *)&pstFace->m_lRows)) + pstFace->m_lErrno = pstSavm->m_lErrno; + + lSendBuffer(pstCon->m_skSock, (void *)pstFace, sizeof(TFace)); + return RC_SUCC; + case OPERATE_EXTREM: + memset(pvData, 0, pstSavm->lSize); + if(RC_SUCC != lExtreme(pstSavm, (void *)pvData)) + { + pstFace->m_lErrno = pstSavm->m_lErrno; + lData = sizeof(TFace); + } + else + { + lData = pstFace->m_lDLen + sizeof(TFace); + pstFace->m_lRows = pstSavm->m_lEffect; + } + lSendBuffer(pstCon->m_skSock, (void *)pstFace, lData); + return RC_SUCC; + case OPERATE_TBDROP: + if(RC_SUCC != lDropTable(pstSavm, pstFace->m_table)) + pstFace->m_lErrno = pstSavm->m_lErrno; + else + pstFace->m_lRows = pstSavm->m_lEffect; + lSendBuffer(pstCon->m_skSock, (void *)pstFace, sizeof(TFace)); + return RC_SUCC; + case OPERATE_RENAME: + if(RC_SUCC != lRenameTable(pstSavm, pstFace->m_table, (TABLE)pstFace->m_lDLen)) + pstFace->m_lErrno = pstSavm->m_lErrno; + + lSendBuffer(pstCon->m_skSock, (void *)pstFace, sizeof(TFace)); + return RC_SUCC; + case OPERATE_SELSEQ: + if(RC_SUCC != lSelectSeque(pstSavm, (char *)pvData, (ulong *)pvData)) + { + pstFace->m_lErrno = pstSavm->m_lErrno; + lData = sizeof(TFace); + } + else + lData = pstFace->m_lDLen + sizeof(ulong); + + lSendBuffer(pstCon->m_skSock, (void *)pstFace, lData); + return RC_SUCC; + case OPERATE_SETSEQ: + if(RC_SUCC != lSetSequence(pstSavm, (char *)pvData, *((ulong *)(pvData + MAX_INDEX_LEN)))) + pstFace->m_lErrno = pstSavm->m_lErrno; + + lSendBuffer(pstCon->m_skSock, (void *)pstFace, sizeof(TFace)); + return RC_SUCC; + case OPERATE_RBDIDX: + if(RC_SUCC != lRebuildIndex(pstSavm, pstFace->m_table)) + pstFace->m_lErrno = pstSavm->m_lErrno; + + lSendBuffer(pstCon->m_skSock, (void *)pstFace, sizeof(TFace)); + return RC_SUCC; + case OPERATE_RETLOK: + if(RC_SUCC != lResetLock(pstSavm, pstFace->m_table)) + pstFace->m_lErrno = pstSavm->m_lErrno; + lSendBuffer(pstCon->m_skSock, (void *)pstFace, sizeof(TFace)); + return RC_SUCC; + case OPERATE_GROUP: + if(RC_SUCC != lGroup(pstSavm, (size_t *)&pstFace->m_lRows, (void *)&pvOut)) + pstFace->m_lErrno = pstSavm->m_lErrno; + + lData = pstFace->m_lDLen * pstFace->m_lRows; + if(sizeof(TFace) != lSendBuffer(pstCon->m_skSock, (void *)pstFace, sizeof(TFace))) + { + TFree(pvOut); + return RC_SUCC; + } + + lSendBuffer(pstCon->m_skSock, pvOut, lData); + TFree(pvOut); + return RC_SUCC; + +/* work */ + case OPERATE_BEGWORK: + if(pstCon->m_bWork && pstCon->m_uWorker != pstFace->m_lDLen) + lRollbackWork(pstSavm); + if(!pstCon->m_bWork) + { + pstCon->m_bWork = true; + pstCon->m_uWorker = pstFace->m_lDLen; + } + lSendBuffer(pstCon->m_skSock, (void *)pstFace, sizeof(TFace)); + return RC_SUCC; + case OPERATE_ROLWORK: + if(pstCon->m_uWorker != pstFace->m_lDLen) + { + pstFace->m_lErrno = WORK_NOT_REGT; + lSendBuffer(pstCon->m_skSock, (void *)pstFace, sizeof(TFace)); + return RC_SUCC; + } + + pstSavm->m_bWork = pstCon->m_bWork; + pstSavm->m_pstWork = pstCon->m_pstWork; + lRollbackWork(pstSavm); + pstFace->m_lRows = pstSavm->m_lEffect; + pstCon->m_pstWork = NULL; + pstFace->m_lErrno = pstSavm->m_lErrno; + lSendBuffer(pstCon->m_skSock, (void *)pstFace, sizeof(TFace)); + return RC_SUCC; + case OPERATE_CMTWORK: + if(pstCon->m_uWorker != pstFace->m_lDLen) + { + pstFace->m_lErrno = WORK_NOT_REGT; + lSendBuffer(pstCon->m_skSock, (void *)pstFace, sizeof(TFace)); + return RC_SUCC; + } + + pstSavm->m_bWork = pstCon->m_bWork; + pstSavm->m_pstWork = pstCon->m_pstWork; + lCommitWork(pstSavm); + pstCon->m_pstWork = NULL; + lSendBuffer(pstCon->m_skSock, (void *)pstFace, sizeof(TFace)); + return RC_SUCC; + case OPERATE_ENDWORK: + if(pstCon->m_uWorker != pstFace->m_lDLen) + { + pstFace->m_lErrno = WORK_NOT_REGT; + lSendBuffer(pstCon->m_skSock, (void *)pstFace, sizeof(TFace)); + return RC_SUCC; + } + + pstSavm->m_bWork = pstCon->m_bWork; + pstSavm->m_pstWork = pstCon->m_pstWork; + lCommitWork(pstSavm); + pstCon->m_bWork = false; + pstCon->m_pstWork = NULL; + lSendBuffer(pstCon->m_skSock, (void *)pstFace, sizeof(TFace)); + return RC_SUCC; + + case OPERATE_DOMPUL: + if(RC_SUCC != lDomainPush(pstSavm, pstCon, pstFace)) + { + pstFace->m_lErrno = pstSavm->m_lErrno; + lSendBuffer(pstCon->m_skSock, (void *)pstFace, sizeof(TFace)); + } + + return RC_SUCC; + case OPERATE_DOMPSH: + lDomainPull(pstSavm, pstCon, pstFace, pvData); + return RC_SUCC; + + case OPERATE_DMRECN: + lSendBuffer(pstCon->m_skSock, (void *)pstFace, sizeof(TFace)); + lReconnectDomain(pstSavm, pstCon, pstFace, (TDomain *)pvData); + return RC_SUCC; + case OPERATE_REFRESH: + lSendBuffer(pstCon->m_skSock, (void *)pstFace, sizeof(TFace)); + lRefreshDomain(pstSavm, pstFace); + return RC_SUCC; + case OPERATE_DOMLOFF: + lLocalOffline(pstSavm, pstFace); + g_eRun = 0; + pstSavm->m_bWork = pstCon->m_bWork; + pstSavm->m_pstWork = pstCon->m_pstWork; + lCommitWork(pstSavm); + pstCon->m_bWork = false; + pstCon->m_pstWork = NULL; + lSendBuffer(pstCon->m_skSock, (void *)pstFace, sizeof(TFace)); + return RC_SUCC; + case OPERATE_DOMROFF: + lSendBuffer(pstCon->m_skSock, (void *)pstFace, sizeof(TFace)); + lRemoteOffline(pstSavm, pstCon, pstFace); + return RC_SUCC; + case OPERATE_PULTBL: + lSendBuffer(pstCon->m_skSock, (void *)pstFace, sizeof(TFace)); + lPushTable(pstSavm, pstFace, pstCon->m_skSock); + return RC_SUCC; + case OPERATE_EXEEXIT: + g_eRun = 0; + pstSavm->m_bWork = pstCon->m_bWork; + pstSavm->m_pstWork = pstCon->m_pstWork; + lCommitWork(pstSavm); + pstCon->m_bWork = false; + pstCon->m_pstWork = NULL; + lSendBuffer(pstCon->m_skSock, (void *)pstFace, sizeof(TFace)); + return RC_SUCC; + default: + pstFace->m_lRows = 0; + pstFace->m_lErrno = RMT_NOT_SUPPT; + Tlog("Unknown request:%d", pstFace->m_enum); + return RC_FAIL; + } + + return RC_SUCC; +} + +/************************************************************************************************* + description:accepte operation + parameters: + pstSavm --stvm handle + epdf --socket + pc --socket handle + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lEpollAccept(SATvm *pstSavm, BSock epfd, SKCon *pc) +{ + socklen_t kLen; + epollevt event; + BSock skAccept; + SKCon *pstCon = NULL; + struct sockaddr_in cAddr; + + while (1) + { + kLen = sizeof(struct sockaddr_in); + /* The phenomenon of "terrors" produced by multiple processes, There is only one + process returned to succ and other processes return errno=EAGAIN */ + if(0 > (skAccept = accept(pc->m_skSock, (struct sockaddr *)&cAddr, &kLen))) + break; + + if (RC_SUCC != lSetUnBlock(skAccept)) + { + close(skAccept); + continue; + } + + if(NULL == (pstCon = (SKCon *)calloc(sizeof(SKCon), 1))) + { + close(skAccept); + fprintf(stderr, "Create memory, err:(%d)(%s)", errno, strerror(errno)); + return RC_FAIL; + } + + pstCon->m_skSock = skAccept; + pstCon->m_lCltPort = ntohs(cAddr.sin_port); + strncpy(pstCon->m_szCltIp, inet_ntoa(cAddr.sin_addr), sizeof(pstCon->m_szCltIp)); + + memset(&event, 0, sizeof(event)); + event.data.ptr = pstCon; + event.events = EPOLLIN | EPOLLET; + if(0 != epoll_ctl(epfd, EPOLL_CTL_ADD, skAccept, &event)) + { + close(skAccept); + pstSavm->m_lErrno = EPOLL_ADD_ERR; + fprintf(stderr, "add socket (%d) error, err:(%d)(%s)", skAccept, + errno, strerror(errno)); + return RC_FAIL; + } + } + + return RC_SUCC; +} + +/************************************************************************************************* + description:reset remote domain + parameters: + pstSavm --stvm handle + pszIp --ip + lPort --lport + skSock --socket + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +void vResetRemote(SATvm *pstSavm, char *pszIp, long lPort, BSock skSock) +{ + TDomain *pv = NULL; + Rowgrp *list = NULL; + + for(list = pGetDomgrp(); list; list = list->pstNext) + { + pv = (TDomain *)list->psvData; + if(strcmp(pv->m_szIp, pszIp) || pv->m_lPort != lPort) + continue; + + pv->m_lTryTimes = 0; + pv->m_lStatus = RESOURCE_ABLE; + pv->m_lLastTime = (long)time(NULL); + } + + return ; +} + +/************************************************************************************************* + description:Get the event request + parameters: + pstSovm --stvm handle + pstCon --socket handle + pstFace --request head + pstVoid --request condition + pvData --decorate + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lPollRequest(SATvm *pstSovm, SKCon *pstCon, TFace *pstFace, void *pstVoid, char *pvData) +{ + long lRet; + RunTime *pstRun = NULL; + SATvm *pstSavm = (SATvm *)pGetSATvm(); + + if(OPERATE_DMKEEP == pstFace->m_enum) + { + lSendBuffer(pstCon->m_skSock, (void *)pstFace, sizeof(TFace)); + vResetRemote(pstSovm, pstCon->m_szCltIp, pstFace->m_lFind, pstCon->m_skSock); + return RC_SUCC; + } + + if(pstFace->m_lRows != lRecvBuffer(pstCon->m_skSock, pvData, pstFace->m_lRows)) + { + Tlog("recv %d byte, err:%s", lRet, strerror(errno)); + return RC_FAIL; + } + + pstRun = (RunTime *)pGetRunTime(pstSovm, pstFace->m_table); + pstRun->m_bAttch = pstSovm->stRunTime[pstFace->m_table].m_bAttch; + pstRun->m_pvAddr = pstSovm->stRunTime[pstFace->m_table].m_pvAddr; + if(!pstRun->m_bAttch || !pstRun->m_pvAddr) + { +//Tlog("initial table:%d, %d, %d", pstFace->m_table, pstFace->m_enum, pstRun->m_bAttch); + if(RC_SUCC != lInitSATvm(pstSovm, pstFace->m_table)) + { + pstFace->m_lRows = 0; + pstFace->m_lErrno = pstSovm->m_lErrno; + return lSendBuffer(pstCon->m_skSock, (void *)pstFace, sizeof(TFace)); + } + } + + if(PROT_JAVA & pstFace->m_enum) + { + pstFace->m_enum = pstFace->m_enum ^ PROT_JAVA; + pstFace->m_lDLen = pstRun->m_lRowSize; + if(NULL == (pvData = pProtocaJava(pstSovm, pstVoid, pstFace, pvData, pstFace->m_lRows))) + { + pstFace->m_lErrno = RESOU_DISABLE; + pvData = (void *)pstFace + sizeof(TFace); + return lSendBuffer(pstCon->m_skSock, (void *)pstFace, sizeof(TFace)); + } + + pstSovm->pstVoid = pstVoid; + pstSovm->lFind = pstFace->m_lFind; + pstSovm->tblName = pstFace->m_table; + pstSovm->lSize = pstFace->m_lDLen; + lRet = lProcaOperate(pstSovm, pstCon, pstFace, pvData); + pstSavm->stRunTime[pstFace->m_table].m_bAttch = pstRun->m_bAttch; + pstSavm->stRunTime[pstFace->m_table].m_pvAddr = pstRun->m_pvAddr; + if(RC_SUCC == lRet) return RC_SUCC; + + return lSendBuffer(pstCon->m_skSock, (void *)pstFace, sizeof(TFace)); + } + else + { + if(NULL == (pvData = pParsePacket(pstSovm, pstVoid, pstFace, pvData, pstFace->m_lRows))) + { + pstFace->m_lErrno = RESOU_DISABLE; + pvData = (void *)pstFace + sizeof(TFace); + return lSendBuffer(pstCon->m_skSock, (void *)pstFace, sizeof(TFace)); + } + + pstSovm->pstVoid = pstVoid; + pstSovm->lFind = pstFace->m_lFind; + pstSovm->tblName = pstFace->m_table; + pstSovm->lSize = pstFace->m_lDLen; + lRet = lEventOperate(pstSovm, pstCon, pstFace, pvData); + pstSavm->stRunTime[pstFace->m_table].m_bAttch = pstRun->m_bAttch; + pstSavm->stRunTime[pstFace->m_table].m_pvAddr = pstRun->m_pvAddr; + if(RC_SUCC == lRet) return RC_SUCC; + + return lSendBuffer(pstCon->m_skSock, (void *)pstFace, sizeof(TFace)); + } +} + +/************************************************************************************************* + description:server listen + parameters: + pvParam + return: + *************************************************************************************************/ +void* vEpollListen(void *pvParam) +{ + SKCon *pstCon = NULL; + TFace *pstFace = NULL; + epollevt events[MAX_EVENTS]; + BSock epfd = *((long *)pvParam); + long i, nWait, lBuffer = READ_MAX_LEN; + char *pvData, *pvFace = NULL, *pstVoid = NULL; + SATvm *pstSavm = (SATvm *)calloc(1, sizeof(SATvm)); + + pthread_detach(pthread_self()); + vHoldConnect(pstSavm); + if(!pstSavm || NULL == (pvFace = calloc(1, lBuffer + sizeof(TFace)))) + { + fprintf(stderr, "create process(%s) memory failed, (%s)", TVM_LOCAL_SERV, strerror(errno)); + return NULL; + } + + if(NULL == (pstVoid = (void *)calloc(1, lBuffer + sizeof(TFace)))) + return NULL; + + if(RC_SUCC != lTvmBuffer(pstSavm)) + return NULL; + + pstFace = (TFace *)pvFace; + pvData = pvFace + sizeof(TFace); + while(g_eRun) + { + nWait = epoll_wait(epfd, events, MAX_EVENTS, 1000); + for(i = 0; i < nWait; i++) + { + pstCon = (SKCon *)events[i].data.ptr; + if(pstCon->m_isListen) + lEpollAccept(pstSavm, epfd, pstCon); + else if(events[i].events & EPOLLIN) + { + if(sizeof(TFace) != lRecvBuffer(pstCon->m_skSock, pvFace, sizeof(TFace))) + { + if(pstCon->m_bWork) + { + pstSavm->m_bWork = pstCon->m_bWork; + pstSavm->m_pstWork = pstCon->m_pstWork; + lRollbackWork(pstSavm); + pstCon->m_bWork = false; + } + pstCon->m_pstWork = NULL; + epoll_ctl(epfd, EPOLL_CTL_DEL, pstCon->m_skSock, &events[i]); + close(pstCon->m_skSock); + continue; + } + + if(TVM_MAX_TABLE <= pstFace->m_table) + { + pstFace->m_lErrno = RESOU_DISABLE; + goto LISTEN_ERROR; + } + + checkrequest(pstFace, pvFace, pstVoid, pvData, lBuffer); + if(RC_FAIL == lPollRequest(pstSavm, pstCon, pstFace, pstVoid, pvData)) + { + if(pstCon->m_bWork) + { + pstSavm->m_bWork = pstCon->m_bWork; + pstSavm->m_pstWork = pstCon->m_pstWork; + lRollbackWork(pstSavm); + pstCon->m_bWork = false; + } + pstCon->m_pstWork = NULL; + epoll_ctl(epfd, EPOLL_CTL_DEL, pstCon->m_skSock, &events[i]); + close(pstCon->m_skSock); + } + } + } + continue; + +LISTEN_ERROR: + lSendBuffer(pstCon->m_skSock, pvFace, sizeof(TFace)); + continue; + } + + close(epfd); + TFree(pvFace); + TFree(pstVoid); + pstSavm->pstVoid = NULL; + vTvmDisconnect(pstSavm); + return NULL; +} + +/************************************************************************************************* + description:Get the event request + parameters: + pstSovm --stvm handle + epfg --socket + plMultListen --listen handle + return: + *************************************************************************************************/ +void vMultListen(SATvm *pstSavm, BSock epfd, FUNCEXEC plMultListen) +{ + long i, nWait = 0; + SKCon *pstCon = NULL; + epollevt events[MAX_EVENTS]; + + pthread_detach(pthread_self()); + vHoldConnect(pstSavm); + while(1) + { + nWait = epoll_wait(epfd, events, MAX_EVENTS, 5000); + for(i = 0; i < nWait; i++) + { + pstCon = (SKCon *)events[i].data.ptr; + if(pstCon->m_isListen) + lEpollAccept(pstSavm, epfd, pstCon); + else if(events[i].events & EPOLLIN) + { + if(RC_CLOSE == plMultListen(pstSavm, pstCon)) + { + epoll_ctl(epfd, EPOLL_CTL_DEL, pstCon->m_skSock, &events[i]); + close(pstCon->m_skSock); + } + } + } + } + + close(epfd); + vHoldRelease(pstSavm); + return ; +} + +/************************************************************************************************* + description:Fork multi-process listening + parameters: + pstSavm --stvm handle + lPort --socket handle + lProcess --request head + plMultInitail --init handle + arg --request condition + plMultListen --listen handle + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lMultListen(SATvm *pstSavm, long lPort, long lProcess, FUNCEXEC plMultInitail, void *arg, + FUNCEXEC plMultListen) +{ + int i; + pid_t lPid; + epollevt event; + BSock epfd = -1; + SKCon *pstCon = NULL; + + if(NULL == (pstCon = (SKCon *)calloc(sizeof(SKCon), 1))) + { + fprintf(stderr, "create memory, err:(%d)(%s)", errno, strerror(errno)); + return RC_FAIL; + } + + pstCon->m_isListen = 1; + if(0 > (pstCon->m_skSock = skServerInitail(pstSavm, lPort))) + return RC_FAIL; + + for(i = 0; i < lProcess; i ++) + { + if(0 > (lPid = fork())) + { + close(pstCon->m_skSock); + return RC_FAIL; + } + else if(lPid > 0) + continue; + + epfd = epoll_create(MAX_EVENTS); + + memset(&event, 0, sizeof(event)); + event.data.ptr = pstCon; + event.events = EPOLLIN | EPOLLET; + if(0 != epoll_ctl(epfd, EPOLL_CTL_ADD, pstCon->m_skSock, &event)) + { + pstSavm->m_lErrno = EPOLL_ADD_ERR; + return RC_FAIL; + } + + if(plMultInitail && RC_SUCC != plMultInitail(pstSavm, (void *)arg)) + { + pstSavm->m_lErrno = INI_ERR_CHLDP; + return RC_FAIL; + } + + vMultListen(pstSavm, epfd, plMultListen); + exit(0); + } + + return RC_SUCC; +} + +/************************************************************************************************* + description:break heart + parameters: + pstSovm --stvm handle + pstDom --remote domain + lPort --local port + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lBreakHeart(SATvm *pstSavm, TDomain *pstDom, long lPort) +{ + TFace stFace; + + if(pstDom->m_skSock < 0) + { + pstDom->m_skSock = skConnectServer(pstSavm, pstDom->m_szIp, pstDom->m_lPort, + false, pstDom->m_lTimeOut); + if(RC_FAIL == pstDom->m_skSock) + return RC_FAIL; + } + + stFace.m_lFind = lPort; + stFace.m_enum = OPERATE_DMKEEP; + if(sizeof(TFace) != lSendBuffer(pstDom->m_skSock, (void *)&stFace, sizeof(TFace))) + { + pstDom->m_lTryTimes ++; + return RC_FAIL; + } + + if(sizeof(TFace) != lRecvBuffer(pstDom->m_skSock, (void *)&stFace, sizeof(TFace))) + { + pstDom->m_lTryTimes ++; + return RC_FAIL; + } + + return RC_SUCC; +} + +/************************************************************************************************* + description:Domain activity detection + parameters: + pstSovm --stvm handle + lPort --socket handle + return: + *************************************************************************************************/ +void vDomainEvent(SATvm *pstSavm, long lPort) +{ + Rowgrp *list = NULL; + TDomain *pstDom = NULL; + + while(g_eRun) + { + for(sleep(1), list = pGetDomgrp(); list; list = list->pstNext) + { + if(NULL == (pstDom = (TDomain *)list->psvData)) + continue; + + if(RESOURCE_ROFF == pstDom->m_lStatus) + continue; + + if(pstDom->m_lKeepLive > ((long)time(NULL) - pstDom->m_lLastTime)) + continue; + + if(pstDom->m_lTryMax > 0 && pstDom->m_lTryMax <= pstDom->m_lTryTimes) + continue; + + if(pstDom->m_lStatus != RESOURCE_ABLE) + { + lConnectDomain(pstSavm, pstDom, lPort); + continue; + } + + if(0 != pthread_mutex_trylock(&list->lock)) + continue; + + pstDom->m_lLastTime = (long)time(NULL); + pstDom->m_lLock = DATA_TRUCK_LOCK; + if(RC_SUCC == lBreakHeart(pstSavm, pstDom, lPort)) + { + pthread_mutex_unlock(&list->lock); + pstDom->m_lTryTimes = 0; + pstDom->m_lLock = DATA_TRUCK_NULL; + pstDom->m_lStatus = RESOURCE_ABLE; + continue; + } + + pthread_mutex_unlock(&list->lock); + + vCloseSocket(pstDom); + pstDom->m_lLock = DATA_TRUCK_NULL; + if(pstDom->m_lTryMax > 0 && pstDom->m_lTryMax <= pstDom->m_lTryTimes) + { + pstDom->m_lStatus = RESOURCE_STOP; + lUpdateDomain(pstSavm, pstDom->m_szIp, pstDom->m_lPort, RESOURCE_STOP); + } + } + } + + return ; +} + +/************************************************************************************************* + description:close domain + parameters: + return: + *************************************************************************************************/ +void vCloseDomain() +{ + Rowgrp *list; + + for(list = g_pstDomgrp; list; list = list->pstNext) + { + pthread_mutex_destroy(&list->lock); + close(((TDomain *)list->psvData)->m_skSock); + ((TDomain *)list->psvData)->m_skSock = -1; + } + + TFgrp(g_pstDomgrp); + TFgrp(g_pstTblgrp); +} + +/************************************************************************************************* + description:Cache domain + parameters: + pstSavm --stvm handle + eMode --cache type + lPort --local port + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lCacheDomain(SATvm *pstSavm, Benum eMode, long lPort) +{ + size_t i, lOut = 0; + TDomain *pstDom = NULL, stDomain; + Rowgrp *list = NULL, *node = NULL; + + if(RC_SUCC != lInitSATvm(pstSavm, SYS_TVM_DOMAIN)) + { + fprintf(stderr, "init domain error, %s\n", sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; + } + + conditnull(pstSavm, TDomain, SYS_TVM_DOMAIN); + decorate(pstSavm, TDomain, m_szIp, GROUP_BY | ORDER_ASC); + decorate(pstSavm, TDomain, m_lPort, GROUP_BY | ORDER_ASC); + decorate(pstSavm, TDomain, m_lGroup, GROUP_BY); + decorate(pstSavm, TDomain, m_lTryMax, GROUP_BY); + decorate(pstSavm, TDomain, m_lTimeOut, GROUP_BY); + decorate(pstSavm, TDomain, m_lKeepLive, GROUP_BY); + if(RC_SUCC != lGroup(pstSavm, &lOut, (void *)&pstDom)) + { + if(NO_DATA_FOUND != pstSavm->m_lErrno) + { + fprintf(stderr, "get domain error, %s", sGetTError(pstSavm->m_lErrno)); + pthread_exit(NULL); + return ; + } + } + + for(i = 0; i < lOut; i ++) + { + pstDom[i].m_skSock = -1; + pstDom[i].m_lLastTime = time(NULL); + if(0 == eMode) lConnectDomain(pstSavm, &pstDom[i], lPort); + + if(NULL == (g_pstDomgrp = pInsertRowgrp(pstSavm, g_pstDomgrp, NULL, NULL, + (void *)&pstDom[i], sizeof(TDomain), 0))) + { + TFree(pstDom); + fprintf(stderr, "add domain list error, %s", strerror(errno)); + pthread_exit(NULL); + return ; + } + } + TFree(pstDom); + + conditnull(pstSavm, TDomain, SYS_TVM_DOMAIN); + decorate(pstSavm, TDomain, m_table, GROUP_BY | ORDER_ASC); + if(RC_SUCC != lGroup(pstSavm, &lOut, (void *)&pstDom)) + { + if(NO_DATA_FOUND == pstSavm->m_lErrno) + return RC_SUCC; + return RC_FAIL; + } + + for(i = 0; i < lOut; i ++) + { + if(NULL == (g_pstTblgrp = pInsertRowgrp(pstSavm, pGetTblgrp(), NULL, NULL, + (void *)&pstDom[i].m_table, sizeof(TABLE), 0))) + { + TFree(pstDom); + return RC_FAIL; + } + } + + TFree(pstDom); + + for(list = pGetTblgrp(); list; list = list->pstNext) + { + conditinit(pstSavm, stDomain, SYS_TVM_DOMAIN); + numberset(pstSavm, stDomain, m_table, *((TABLE *)list->psvData)); + if(RC_SUCC != lQuery(pstSavm, &lOut, (void *)&pstDom)) + return RC_FAIL; + + for(i = 0; i < lOut; i ++) + { + if(NULL == (list->pstSSet = pInsertRowgrp(pstSavm, list->pstSSet, list, NULL, + (void *)&pstDom[i], sizeof(TDomain), 0))) + { + TFree(pstDom); + return RC_FAIL; + } + } + + TFree(pstDom); + } + + for(list = pGetTblgrp(); list; list = list->pstNext) + { + for(node = list->pstSSet; node; node = node->pstNext) + { + if(NULL == (pstDom = (TDomain *)node->psvData)) + continue; + + node->pstFset = pGetDomnode(pstDom->m_szIp, pstDom->m_lPort); + pthread_mutex_init(&node->pstFset->lock, NULL); + } + } + + vSetBootType(TVM_BOOT_LOCAL); + return RC_SUCC; +} + +/************************************************************************************************* + description:Open domain as local mode + parameters: + pstSavm --stvm handle + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lOpenDomain(SATvm *pstSavm) +{ + return lCacheDomain(pstSavm, 1, 0); +} + +/************************************************************************************************* + description:load remote resourc3 + parameters: + pstSavm --stvm handle + eMode --cache type + lPort --local port + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +void vRemoteResouce(SATvm *pstSavm, Benum eMode, long lPort) +{ + TDomain *pstDom = NULL; + Rowgrp *list, *node = NULL; + long lType = lGetBootType(); + + if(RC_SUCC != lCacheDomain(pstSavm, eMode, lPort)) + return ; + + Tlog("=-=-=-=-=-=-=-=-=-=-=-=- Domain node announcement -=-=-=-=-=-=-=-=-=-=-=-=-="); + for(list = pGetDomgrp(); list; list = list->pstNext) + { + pstDom = (TDomain *)list->psvData; + Tlog("NODE:%X, %s:%d, Group:%d, Try:%d, Time:%d, Keep:%d", list, pstDom->m_szIp, + pstDom->m_lPort, pstDom->m_lGroup, pstDom->m_lTryMax, pstDom->m_lTimeOut, + pstDom->m_lKeepLive); + } + + Tlog("=-=-=-=-=-=-=-=-=-=- Remote table resource announcement -=-=-=-=-=-=-=-=-=-=-="); + for(list = pGetTblgrp(); list; list = list->pstNext) + { + Tlog("NODE:%X, TABLE:%d", list, *((TABLE *)list->psvData)); + for(node = list->pstSSet; node; node = node->pstNext) + { + pstDom = (TDomain *)node->psvData; + Tlog("\t>>TABLE:%s, PART:%s, OWNER:%s, pstFset:%X", pstDom->m_szTable, + pstDom->m_szPart, pstDom->m_szOwner, node->pstFset); + } + } + + vSetBootType(lType); + vDomainEvent(pstSavm, lPort); + return ; +} + +/************************************************************************************************* + description:boot local process + parameters: + pstSavm --stvm handle + pstBoot --boot parameter + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lBootLocal(SATvm *pstSavm, TBoot *pstBoot, Benum eMode) +{ + int i; + pid_t lPid; + epollevt event; + BSock epfd = -1; + pthread_t *tPid = NULL; + SKCon *pstCon = NULL; + + if(!pstBoot || pstBoot->m_lBootExec < 1) // 线程数量 + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + if(TVM_BOOT_SIMPLE == pstBoot->m_lBootType) + return RC_SUCC; + +/* + pthread_mutex_init(&mutex_thread_read, NULL); + pthread_cond_init(&cond_thread_read, NULL); +*/ + if(NULL == (pstCon = (SKCon *)calloc(sizeof(SKCon), 1))) + { + fprintf(stderr, "create memory, err:(%d)(%s)", errno, strerror(errno)); + return RC_FAIL; + } + + pstCon->m_isListen = 1; + if(0 > (pstCon->m_skSock = skServerInitail(pstSavm, pstBoot->m_lBootPort))) + return RC_FAIL; + + vSetTitile(TVM_LOCAL_SERV); + fprintf(stdout, "Boot process(%s), total %ld process\n", TVM_LOCAL_SERV, pstBoot->m_lBootExec); + if(0 > (lPid = fork())) + { + close(pstCon->m_skSock); + return RC_FAIL; + } + else if(lPid > 0) + { + usleep(500); + return RC_SUCC; + } + + epfd = epoll_create(MAX_EVENTS); + + memset(&event, 0, sizeof(event)); + event.data.ptr = pstCon; + event.events = EPOLLIN | EPOLLET; + if(0 != epoll_ctl(epfd, EPOLL_CTL_ADD, pstCon->m_skSock, &event)) + { + fprintf(stderr, "add socket (%d) error, err:(%d)(%s)", pstCon->m_skSock, + errno, strerror(errno)); + return -1; + } + + signal(SIGPIPE, SIG_IGN); + signal(SIGTRAP, SIG_IGN); + tPid = malloc(sizeof(pthread_t) * pstBoot->m_lBootExec); + vHoldConnect(pstSavm); + for(i = 0; i < pstBoot->m_lBootExec; i ++) + { + if(0 != pthread_create(&tPid[i], NULL, vEpollListen, (void*)&epfd)) + { + fprintf(stderr, "create thread error, %s\n", strerror(errno)); + exit(-1); + } + } + + fprintf(stdout, " process %s id=%d ... success\n", TVM_LOCAL_SERV, getpid()); + fflush(stdout); + + vRemoteResouce(pstSavm, eMode, pstBoot->m_lBootPort); + vTvmDisconnect(pstSavm); + for(i = 0; i < pstBoot->m_lBootExec; i ++) + { + for(usleep(1000);ESRCH != pthread_kill(tPid[i], 0); usleep(1000)); + } + + vCloseDomain(); + TFree(tPid); + Tlog("Service thread exits"); + exit(-1); +} + +/************************************************************************************************* + * Domain maintenance interface + *************************************************************************************************/ +/************************************************************************************************* + description:Notification reconnect the domain + parameters: + pstSavm --stvm handle + pstDom --remote domain + lPort --local port + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lConnectNotify(SATvm *pstSavm, TDomain *pstDom, long lPort) +{ + long lWrite; + void *pvData = NULL; + + lWrite = sizeof(TFace) + sizeof(TDomain); + if(NULL == (pvData = (char *)calloc(1, lWrite))) + { + pstSavm->m_lErrno = MALLC_MEM_ERR; + return RC_FAIL; + } + + pstDom->m_skSock = skConnectServer(pstSavm, LOCAL_HOST_IP, lPort, false, 5); + if(RC_FAIL == pstDom->m_skSock) + { + fprintf(stderr, "Connect server %s:%ld error, %s\n", LOCAL_HOST_IP, lPort, + sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; + } + + ((TFace *)pvData)->m_lFind = lPort; + ((TFace *)pvData)->m_enum = OPERATE_DMRECN; + ((TFace *)pvData)->m_table = SYS_TVM_INDEX; + ((TFace *)pvData)->m_lDLen = sizeof(TDomain); + ((TFace *)pvData)->m_lRows = sizeof(TDomain); + memcpy(pvData + sizeof(TFace), pstDom, sizeof(TDomain)); + if(lWrite != lSendBuffer(pstDom->m_skSock, (void *)pvData, lWrite)) + { + vCloseSocket(pstDom); + return RC_FAIL; + } + + if(sizeof(TFace) != lRecvBuffer(pstDom->m_skSock, (char *)pvData, sizeof(TFace))) + { + vCloseSocket(pstDom); + return RC_FAIL; + } + + vCloseSocket(pstDom); + pstSavm->m_lErrno = ((TFace *)pvData)->m_lErrno; + if(0 != pstSavm->m_lErrno) + return RC_FAIL; + return RC_SUCC; +} + +/************************************************************************************************* + description:Notification refresh the domain + parameters: + pstSavm --stvm handle + lPort --local port + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lRefreshNotify(SATvm *pstSavm, long lPort) +{ + BSock skSock; + TFace stFace; + + stFace.m_lRows = 0; + stFace.m_lDLen = 0; + stFace.m_lFind = lPort; + stFace.m_table = SYS_TVM_INDEX; + stFace.m_enum = OPERATE_REFRESH; + skSock = skConnectServer(pstSavm, LOCAL_HOST_IP, lPort, false, 5); + if(RC_FAIL == skSock) + { + fprintf(stderr, "Connect server %s:%ld error, %s\n", LOCAL_HOST_IP, lPort, + sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; + } + + if(sizeof(TFace) != lSendBuffer(skSock, (void *)&stFace, sizeof(TFace))) + { + close(skSock); + return RC_FAIL; + } + + if(sizeof(TFace) != lRecvBuffer(skSock, (char *)&stFace, sizeof(TFace))) + { + close(skSock); + return RC_FAIL; + } + close(skSock); + + pstSavm->m_lErrno = stFace.m_lErrno; + if(0 != pstSavm->m_lErrno) + return RC_FAIL; + + return RC_SUCC; +} + +/************************************************************************************************* + description:Notification offline + parameters: + pstSavm --stvm handle + lPort --local port + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lOfflineNotify(SATvm *pstSavm, long lPort) +{ + BSock skSock; + TFace stFace; + + stFace.m_lRows = 0; + stFace.m_lDLen = 0; + stFace.m_lFind = lPort; + stFace.m_table = SYS_TVM_INDEX; + stFace.m_enum = OPERATE_DOMLOFF; + if(RC_FAIL == (skSock = skConnectServer(pstSavm, LOCAL_HOST_IP, lPort, false, 5))) + { + fprintf(stderr, "Connect server %s:%ld error, %s\n", LOCAL_HOST_IP, lPort, + sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; + } + + if(sizeof(TFace) != lSendBuffer(skSock, (void *)&stFace, sizeof(TFace))) + { + close(skSock); + return RC_FAIL; + } + + if(sizeof(TFace) != lRecvBuffer(skSock, (char *)&stFace, sizeof(TFace))) + { + close(skSock); + return RC_FAIL; + } + close(skSock); + + pstSavm->m_lErrno = stFace.m_lErrno; + if(0 != pstSavm->m_lErrno) + return RC_FAIL; + + return RC_SUCC; +} + +/************************************************************************************************* + description:Notifies to clone remote table + parameters: + pstSavm --stvm handle + pstDom --remote domain + lCount --record + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lPullNotify(SATvm *pstSavm, TDomain *pstDom, size_t lCount) +{ + TblDef stDet; + TFace stFace; + void *pvData = NULL; + size_t lRecv, i, lRow = 0, lValid; + + memset(&stDet, 0, sizeof(TblDef)); + memset(&stFace, 0, sizeof(TFace)); + stFace.m_lRows = 0; + stFace.m_lFind = lCount; + stFace.m_enum = OPERATE_PULTBL; + stFace.m_table = pstDom->m_mtable; + if(RC_FAIL == (pstDom->m_skSock = skConnectServer(pstSavm, pstDom->m_szIp, pstDom->m_lPort, + false, pstDom->m_lTimeOut))) + { + fprintf(stderr, "Connect server %s:%ld error, %s\n", LOCAL_HOST_IP, pstDom->m_lPort, + sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; + } + + if(sizeof(TFace) != lSendBuffer(pstDom->m_skSock, (void *)&stFace, sizeof(TFace))) + goto ERR_PULLNOTIFY; + + if(sizeof(TFace) != lRecvBuffer(pstDom->m_skSock, (void *)&stFace, sizeof(TFace))) + goto ERR_PULLNOTIFY; + + pstSavm->m_lErrno = stFace.m_lErrno; + if(0 != pstSavm->m_lErrno) + goto ERR_PULLNOTIFY; + + fprintf(stdout, "\nCopying table(%s)(%d) define ..", pstDom->m_szTable, pstDom->m_table); + fflush(stdout); + usleep(5000); + if(sizeof(TblDef) != lRecvBuffer(pstDom->m_skSock, (void *)&stDet, sizeof(TblDef))) + goto ERR_PULLNOTIFY; + + lValid = stDet.m_lValid; + stDet.m_lValid = 0; + stDet.m_lGroup = 0; + if(RC_SUCC != lCustomTable(pstSavm, pstDom->m_table, stDet.m_lMaxRow, &stDet)) + { + fprintf(stderr, "Create table(%d) failed, err:(%d)(%s)\n", pstDom->m_table, + pstSavm->m_lErrno, sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; + } + + fprintf(stdout, "\b\bcompleted .\nCopy table(%s) success, table maxrow:%d, valid:%ld " + " completed .\n", stDet.m_szTable, stDet.m_lMaxRow, lValid); + fflush(stdout); + if(NULL == (pstSavm = (SATvm *)pInitSATvm(pstDom->m_table))) + { + fprintf(stderr, "initial table(%s) error, err:(%d)(%s)\n", pstDom->m_szTable, + pstSavm->m_lErrno, sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; + } + + fprintf(stdout, "Start Copy table(%s)(%s)rows:[", pstDom->m_szTable, pstDom->m_szPart); + fprintf(stdout, "\033[?25l"); + + if(NULL == (pvData = (char *)malloc(lCount * stDet.m_lReSize))) + goto ERR_PULLNOTIFY; + + pstSavm->lSize = stDet.m_lReSize; + while(1) + { + if(sizeof(TFace) != lRecvBuffer(pstDom->m_skSock, (void *)&stFace, sizeof(TFace))) + goto ERR_PULLNOTIFY; + + if(0 == stFace.m_lRows) + break; + + lRecv = stDet.m_lReSize * stFace.m_lRows; + if(lRecv != lRecvBuffer(pstDom->m_skSock, (char *)pvData, lRecv)) + goto ERR_PULLNOTIFY; + + for(i = 0; i < stFace.m_lRows; i ++) + { + pstSavm->pstVoid = (void *)pvData + i * stDet.m_lReSize; + if(RC_SUCC != lInsert(pstSavm)) + goto ERR_PULLNOTIFY; + + ++ lRow; + vPrintProgresss(lRow, lValid); + } + } + TFree(pvData); + fprintf(stdout, "\n"); + fprintf(stdout, "\033[?25h"); + fprintf(stdout, "Copy (%s)(%s) success,rows(%ld), completed successfully!!!\n", + pstDom->m_szTable, pstDom->m_szPart, lRow); + fflush(stdout); + + vCloseSocket(pstDom); + return RC_SUCC; + +ERR_PULLNOTIFY: + fprintf(stdout, "\n"); + fprintf(stdout, "\033[?25h"); + fflush(stdout); + TFree(pvData); + vCloseSocket(pstDom); + return RC_FAIL; +} + + +/************************************************************************************************* + Remote table access + *************************************************************************************************/ +/************************************************************************************************* + description:remote - Select + parameters: + pstSavm --stvm handle + psvOut --out of data + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lSelectByRt(SATvm *pstSavm, void *psvOut) +{ + long lRet; + TDomain *pvm, *pnoe; + Rowgrp *list = NULL, *node = NULL; + + if(NULL == (node = pGetTblNode(pstSavm->tblName))) + { + pstSavm->m_lErrno = DOM_NOT_INITL; + return RC_FAIL; + } + + pstSavm->m_lErrno = RESOU_DISABLE; + switch(lGetBootType()) + { + case TVM_BOOT_CLUSTER: + for(list = node->pstSSet; list; list = list->pstNext) + { + if(!list->pstFset) + continue; + + if(NULL == (pvm = (TDomain *)(list->pstFset->psvData))) + continue; + + pnoe = (TDomain *)list->psvData; + if(0 == (OPERATE_SELECT & pnoe->m_lPers) || RESOURCE_ABLE != pvm->m_lStatus || + pnoe->m_lRelia < 0) + continue; + + pstSavm->m_skSock = pvm->m_skSock; + pstSavm->tblName = pnoe->m_mtable; + pthread_mutex_lock(&list->pstFset->lock); + lRet = lTvmSelect(pstSavm, psvOut); + if(RC_SUCC == lRet || SOCK_COM_EXCP != pstSavm->m_lErrno) + { + pvm->m_lTryTimes = 0; + pvm->m_lLastTime = time(NULL); + } + + pthread_mutex_unlock(&list->pstFset->lock); + return lRet; + } + return RC_FAIL; + default: + for(list = node->pstSSet; list; list = list->pstNext) + { + if(NULL == (pvm = (TDomain *)(list->psvData))) + continue; + + if(0 == (OPERATE_SELECT & pvm->m_lPers)) + continue; + + if(RC_SUCC != lTvmConnect(pstSavm, pvm->m_szIp, pvm->m_lPort, pvm->m_lTimeOut)) + continue; + + pstSavm->tblName = pvm->m_mtable; + lRet = lTvmSelect(pstSavm, psvOut); + if(RC_SUCC == lRet || SOCK_COM_EXCP != pstSavm->m_lErrno) + { + close(pstSavm->m_skSock); + ((RunTime *)pGetRunTime(pstSavm, 0))->m_lRowSize = 0; + TFree(((RunTime *)pGetRunTime(pstSavm, 0))->pstVoid); + return lRet; + } + + close(pstSavm->m_skSock); + } + + ((RunTime *)pGetRunTime(pstSavm, 0))->m_lRowSize = 0; + TFree(((RunTime *)pGetRunTime(pstSavm, 0))->pstVoid); + return RC_FAIL; + } +} + +/************************************************************************************************* + description:remote - Query + parameters: + pstSavm --stvm handle + plOut --number + psvOut --out of data + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lQueryByRt(SATvm *pstSavm, size_t *plOut, void **ppsvOut) +{ + long lRet; + TDomain *pvm, *pnoe; + Rowgrp *list = NULL, *node = NULL; + + if(NULL == (node = pGetTblNode(pstSavm->tblName))) + { + pstSavm->m_lErrno = DOM_NOT_INITL; + return RC_FAIL; + } + + pstSavm->m_lErrno = RESOU_DISABLE; + switch(lGetBootType()) + { + case TVM_BOOT_CLUSTER: + for(list = node->pstSSet; list; list = list->pstNext) + { + if(!list->pstFset) + continue; + + if(NULL == (pvm = (TDomain *)(list->pstFset->psvData))) + continue; + + pnoe = (TDomain *)list->psvData; + if(0 == (OPERATE_SELECT & pnoe->m_lPers) || RESOURCE_ABLE != pvm->m_lStatus || + pnoe->m_lRelia < 0) + continue; + + pstSavm->m_skSock = pvm->m_skSock; + pstSavm->tblName = pnoe->m_mtable; + pthread_mutex_lock(&list->pstFset->lock); + lRet = lTvmQuery(pstSavm, plOut, ppsvOut); + if(RC_SUCC == lRet || SOCK_COM_EXCP != pstSavm->m_lErrno) + { + pvm->m_lTryTimes = 0; + pvm->m_lLastTime = time(NULL); + } + + pthread_mutex_unlock(&list->pstFset->lock); + return lRet; + } + + return RC_FAIL; + default: + for(list = node->pstSSet; list; list = list->pstNext) + { + if(NULL == (pvm = (TDomain *)(list->psvData))) + continue; + + if(0 == (OPERATE_SELECT & pvm->m_lPers)) + continue; + + if(RC_SUCC != lTvmConnect(pstSavm, pvm->m_szIp, pvm->m_lPort, pvm->m_lTimeOut)) + continue; + + pstSavm->tblName = pvm->m_mtable; + lRet = lTvmQuery(pstSavm, plOut, ppsvOut); + if(RC_SUCC == lRet || SOCK_COM_EXCP != pstSavm->m_lErrno) + { + close(pstSavm->m_skSock); + ((RunTime *)pGetRunTime(pstSavm, 0))->m_lRowSize = 0; + TFree(((RunTime *)pGetRunTime(pstSavm, 0))->pstVoid); + return lRet; + } + + close(pstSavm->m_skSock); + } + + ((RunTime *)pGetRunTime(pstSavm, 0))->m_lRowSize = 0; + TFree(((RunTime *)pGetRunTime(pstSavm, 0))->pstVoid); + return RC_FAIL; + } +} + +/************************************************************************************************* + description:remote - Delete + parameters: + pstSavm --stvm handle + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lDeleteByRt(SATvm *pstSavm) +{ + TDomain *pvm, *pnoe; + long lRet = RC_FAIL; + Rowgrp *list = NULL, *node = NULL; + + if(NULL == (node = pGetTblNode(pstSavm->tblName))) + { + pstSavm->m_lErrno = DOM_NOT_INITL; + return RC_FAIL; + } + + pstSavm->m_lErrno = RESOU_DISABLE; + switch(lGetBootType()) + { + case TVM_BOOT_CLUSTER: + for(list = node->pstSSet; list; list = list->pstNext) + { + if(!list->pstFset) + continue; + + if(NULL == (pvm = (TDomain *)(list->pstFset->psvData))) + continue; + + pnoe = (TDomain *)list->psvData; + if(0 == (OPERATE_DELETE & pnoe->m_lPers) || RESOURCE_ABLE != pvm->m_lStatus) + continue; + + pstSavm->m_skSock = pvm->m_skSock; + pstSavm->tblName = pnoe->m_mtable; + pthread_mutex_lock(&list->pstFset->lock); + if(RC_SUCC == lTvmDelete(pstSavm)) + { + lRet = RC_SUCC; + pvm->m_lTryTimes = 0; + pvm->m_lLastTime = time(NULL); + } + else if(SOCK_COM_EXCP == pstSavm->m_lErrno) + { + pnoe->m_lRelia --; + Tlog("Delete err: %s, T(%d), F(%s:%d), R(%d)", sGetTError(pstSavm->m_lErrno), + pstSavm->tblName, pvm->m_szIp, pvm->m_lPort, pnoe->m_lRelia); + } + + pthread_mutex_unlock(&list->pstFset->lock); + } + return lRet; + default: + for(list = node->pstSSet; list; list = list->pstNext) + { + if(NULL == (pvm = (TDomain *)(list->psvData))) + continue; + + if(0 == (OPERATE_DELETE & pvm->m_lPers)) + continue; + + if(RC_SUCC != lTvmConnect(pstSavm, pvm->m_szIp, pvm->m_lPort, pvm->m_lTimeOut)) + continue; + + pstSavm->tblName = pvm->m_mtable; + lRet = lTvmDelete(pstSavm); + if(RC_SUCC == lRet || SOCK_COM_EXCP != pstSavm->m_lErrno) + { + close(pstSavm->m_skSock); + ((RunTime *)pGetRunTime(pstSavm, 0))->m_lRowSize = 0; + TFree(((RunTime *)pGetRunTime(pstSavm, 0))->pstVoid); + return lRet; + } + + close(pstSavm->m_skSock); + } + + ((RunTime *)pGetRunTime(pstSavm, 0))->m_lRowSize = 0; + TFree(((RunTime *)pGetRunTime(pstSavm, 0))->pstVoid); + return lRet; + } +} + +/************************************************************************************************* + description:remote - Truncate + parameters: + pstSavm --stvm handle + t --table + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lTruncateByRt(SATvm *pstSavm, TABLE t) +{ + TDomain *pvm, *pnoe; + long lRet = RC_FAIL; + Rowgrp *list = NULL, *node = NULL; + + if(NULL == (node = pGetTblNode(t))) + { + pstSavm->m_lErrno = DOM_NOT_INITL; + return RC_FAIL; + } + + pstSavm->m_lErrno = RESOU_DISABLE; + switch(lGetBootType()) + { + case TVM_BOOT_CLUSTER: + for(list = node->pstSSet; list; list = list->pstNext) + { + if(!list->pstFset) + continue; + + if(NULL == (pvm = (TDomain *)(list->pstFset->psvData))) + continue; + + pnoe = (TDomain *)list->psvData; + if(0 == (OPERATE_DELETE & pnoe->m_lPers) || RESOURCE_ABLE != pvm->m_lStatus) + continue; + + pstSavm->m_skSock = pvm->m_skSock; + pstSavm->tblName = pnoe->m_mtable; + pthread_mutex_lock(&list->pstFset->lock); + if(RC_SUCC == lTvmTruncate(pstSavm, pstSavm->tblName)) + { + lRet = RC_SUCC; + pvm->m_lTryTimes = 0; + pvm->m_lLastTime = time(NULL); + } + else if(SOCK_COM_EXCP == pstSavm->m_lErrno) + { + pnoe->m_lRelia --; + Tlog("Truncate err: %s, T(%d), F(%s:%d), R(%d)", sGetTError(pstSavm->m_lErrno), + pstSavm->tblName, pvm->m_szIp, pvm->m_lPort, pnoe->m_lRelia); + } + + pthread_mutex_unlock(&list->pstFset->lock); + } + return lRet; + default: + for(list = node->pstSSet; list; list = list->pstNext) + { + if(NULL == (pvm = (TDomain *)(list->psvData))) + continue; + + if(0 == (OPERATE_DELETE & pvm->m_lPers)) + continue; + + if(RC_SUCC != lTvmConnect(pstSavm, pvm->m_szIp, pvm->m_lPort, pvm->m_lTimeOut)) + continue; + + pstSavm->tblName = pvm->m_mtable; + lRet = lTvmTruncate(pstSavm, pstSavm->tblName); + if(RC_SUCC == lRet || SOCK_COM_EXCP != pstSavm->m_lErrno) + { + close(pstSavm->m_skSock); + ((RunTime *)pGetRunTime(pstSavm, 0))->m_lRowSize = 0; + TFree(((RunTime *)pGetRunTime(pstSavm, 0))->pstVoid); + return lRet; + } + + close(pstSavm->m_skSock); + } + + ((RunTime *)pGetRunTime(pstSavm, 0))->m_lRowSize = 0; + TFree(((RunTime *)pGetRunTime(pstSavm, 0))->pstVoid); + + return lRet; + } +} + +/************************************************************************************************* + description:remote - Insert + parameters: + pstSavm --stvm handle + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lInsertByRt(SATvm *pstSavm) +{ + TDomain *pvm, *pnoe; + long lRet = RC_FAIL; + Rowgrp *list = NULL, *node = NULL; + + if(NULL == (node = pGetTblNode(pstSavm->tblName))) + { + pstSavm->m_lErrno = DOM_NOT_INITL; + return RC_FAIL; + } + + pstSavm->m_lErrno = RESOU_DISABLE; + switch(lGetBootType()) + { + case TVM_BOOT_CLUSTER: + for(list = node->pstSSet; list; list = list->pstNext) + { + if(!list->pstFset) + continue; + if(NULL == (pvm = (TDomain *)(list->pstFset->psvData))) + continue; + + pnoe = (TDomain *)list->psvData; + if(0 == (OPERATE_INSERT & pnoe->m_lPers) || RESOURCE_ABLE != pvm->m_lStatus) + continue; + + pstSavm->m_skSock = pvm->m_skSock; + pstSavm->tblName = pnoe->m_mtable; + pthread_mutex_lock(&list->pstFset->lock); + if(RC_SUCC == lTvmInsert(pstSavm)) + { + lRet = RC_SUCC; + pvm->m_lTryTimes = 0; + pvm->m_lLastTime = time(NULL); + } + else if(SOCK_COM_EXCP == pstSavm->m_lErrno) + { + pnoe->m_lRelia --; + Tlog("Insert err: %s, T(%d), F(%s:%d), R(%d)", sGetTError(pstSavm->m_lErrno), + pstSavm->tblName, pvm->m_szIp, pvm->m_lPort, pnoe->m_lRelia); + } + + pthread_mutex_unlock(&list->pstFset->lock); + } + return lRet; + default: + for(list = node->pstSSet; list; list = list->pstNext) + { + if(NULL == (pvm = (TDomain *)(list->psvData))) + continue; + + if(0 == (OPERATE_INSERT & pvm->m_lPers)) + continue; + + if(RC_SUCC != lTvmConnect(pstSavm, pvm->m_szIp, pvm->m_lPort, pvm->m_lTimeOut)) + continue; + + pstSavm->tblName = pvm->m_mtable; + lRet = lTvmInsert(pstSavm); + if(RC_SUCC == lRet || SOCK_COM_EXCP != pstSavm->m_lErrno) + { + close(pstSavm->m_skSock); + ((RunTime *)pGetRunTime(pstSavm, 0))->m_lRowSize = 0; + TFree(((RunTime *)pGetRunTime(pstSavm, 0))->pstVoid); + return lRet; + } + + close(pstSavm->m_skSock); + } + + ((RunTime *)pGetRunTime(pstSavm, 0))->m_lRowSize = 0; + TFree(((RunTime *)pGetRunTime(pstSavm, 0))->pstVoid); + return lRet; + } +} + +/************************************************************************************************* + description:remote - Update + parameters: + pstSavm --stvm handle + psvUpdate --update + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lUpdateByRt(SATvm *pstSavm, void *pvUpdate) +{ + TDomain *pvm, *pnoe; + long lRet = RC_FAIL; + Rowgrp *list = NULL, *node = NULL; + + if(NULL == (node = pGetTblNode(pstSavm->tblName))) + { + pstSavm->m_lErrno = DOM_NOT_INITL; + return RC_FAIL; + } + + pstSavm->m_lErrno = RESOU_DISABLE; + switch(lGetBootType()) + { + case TVM_BOOT_CLUSTER: + for(list = node->pstSSet; list; list = list->pstNext) + { + if(!list->pstFset) + continue; + + if(NULL == (pvm = (TDomain *)(list->pstFset->psvData))) + continue; + + pnoe = (TDomain *)list->psvData; + if(0 == (OPERATE_UPDATE & pnoe->m_lPers) || RESOURCE_ABLE != pvm->m_lStatus) + continue; + + pstSavm->m_skSock = pvm->m_skSock; + pstSavm->tblName = pnoe->m_mtable; + pthread_mutex_lock(&list->pstFset->lock); + if(RC_SUCC == lTvmUpdate(pstSavm, pvUpdate)) + { + lRet = RC_SUCC; + pvm->m_lTryTimes = 0; + pvm->m_lLastTime = time(NULL); + } + else if(SOCK_COM_EXCP == pstSavm->m_lErrno) + { + pnoe->m_lRelia --; + Tlog("Update err: %s, T(%d), F(%s:%d), R(%d)", sGetTError(pstSavm->m_lErrno), + pstSavm->tblName, pvm->m_szIp, pvm->m_lPort, pnoe->m_lRelia); + } + + pthread_mutex_unlock(&list->pstFset->lock); + } + return lRet; + default: + for(list = node->pstSSet; list; list = list->pstNext) + { + if(NULL == (pvm = (TDomain *)(list->psvData))) + continue; + + if(0 == (OPERATE_UPDATE & pvm->m_lPers)) + continue; + + if(RC_SUCC != lTvmConnect(pstSavm, pvm->m_szIp, pvm->m_lPort, pvm->m_lTimeOut)) + continue; + + pstSavm->tblName = pvm->m_mtable; + lRet = lTvmUpdate(pstSavm, pvUpdate); + if(RC_SUCC == lRet || SOCK_COM_EXCP != pstSavm->m_lErrno) + { + close(pstSavm->m_skSock); + ((RunTime *)pGetRunTime(pstSavm, 0))->m_lRowSize = 0; + TFree(((RunTime *)pGetRunTime(pstSavm, 0))->pstVoid); + return lRet; + } + + close(pstSavm->m_skSock); + } + + ((RunTime *)pGetRunTime(pstSavm, 0))->m_lRowSize = 0; + TFree(((RunTime *)pGetRunTime(pstSavm, 0))->pstVoid); + return lRet; + } +} + +/************************************************************************************************* + description:remote - Group + parameters: + pstSavm --stvm handle + plOut --number + psvOut --out of data + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lGroupByRt(SATvm *pstSavm, size_t *plOut, void **ppvOut) +{ + long lRet; + TDomain *pvm, *pnoe; + Rowgrp *list = NULL, *node = NULL; + + if(NULL == (node = pGetTblNode(pstSavm->tblName))) + { + pstSavm->m_lErrno = DOM_NOT_INITL; + return RC_FAIL; + } + + pstSavm->m_lErrno = RESOU_DISABLE; + switch(lGetBootType()) + { + case TVM_BOOT_CLUSTER: + for(list = node->pstSSet; list; list = list->pstNext) + { + if(!list->pstFset) + continue; + + if(NULL == (pvm = (TDomain *)(list->pstFset->psvData))) + continue; + + pnoe = (TDomain *)list->psvData; + if(0 == (OPERATE_SELECT & pnoe->m_lPers) || RESOURCE_ABLE != pvm->m_lStatus || + pnoe->m_lRelia < 0) + continue; + + pstSavm->m_skSock = pvm->m_skSock; + pstSavm->tblName = pnoe->m_mtable; + pthread_mutex_lock(&list->pstFset->lock); + lRet = lTvmGroup(pstSavm, plOut, ppvOut); + if(RC_SUCC == lRet || SOCK_COM_EXCP != pstSavm->m_lErrno) + { + pvm->m_lTryTimes = 0; + pvm->m_lLastTime = time(NULL); + } + + pthread_mutex_unlock(&list->pstFset->lock); + return lRet; + } + return RC_FAIL; + default: + for(list = node->pstSSet; list; list = list->pstNext) + { + if(NULL == (pvm = (TDomain *)(list->psvData))) + continue; + + if(0 == (OPERATE_SELECT & pvm->m_lPers)) + continue; + + if(RC_SUCC != lTvmConnect(pstSavm, pvm->m_szIp, pvm->m_lPort, pvm->m_lTimeOut)) + continue; + + pstSavm->tblName = pvm->m_mtable; + lRet = lTvmGroup(pstSavm, plOut, ppvOut); + if(RC_SUCC == lRet || SOCK_COM_EXCP != pstSavm->m_lErrno) + { + close(pstSavm->m_skSock); + ((RunTime *)pGetRunTime(pstSavm, 0))->m_lRowSize = 0; + TFree(((RunTime *)pGetRunTime(pstSavm, 0))->pstVoid); + return lRet; + } + + close(pstSavm->m_skSock); + } + + ((RunTime *)pGetRunTime(pstSavm, 0))->m_lRowSize = 0; + TFree(((RunTime *)pGetRunTime(pstSavm, 0))->pstVoid); + return RC_FAIL; + } +} + +/************************************************************************************************* + description:remote - Count + parameters: + pstSavm --stvm handle + plOut --count + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lCountByRt(SATvm *pstSavm, size_t *plCount) +{ + long lRet; + TDomain *pvm, *pnoe; + Rowgrp *list = NULL, *node = NULL; + + if(NULL == (node = pGetTblNode(pstSavm->tblName))) + { + pstSavm->m_lErrno = DOM_NOT_INITL; + return RC_FAIL; + } + + pstSavm->m_lErrno = RESOU_DISABLE; + switch(lGetBootType()) + { + case TVM_BOOT_CLUSTER: + for(list = node->pstSSet; list; list = list->pstNext) + { + if(!list->pstFset) + continue; + + if(NULL == (pvm = (TDomain *)(list->pstFset->psvData))) + continue; + + pnoe = (TDomain *)list->psvData; + if(0 == (OPERATE_SELECT & pnoe->m_lPers) || RESOURCE_ABLE != pvm->m_lStatus || + pnoe->m_lRelia < 0) + continue; + + pstSavm->m_skSock = pvm->m_skSock; + pstSavm->tblName = pnoe->m_mtable; + pthread_mutex_lock(&list->pstFset->lock); + lRet = lTvmCount(pstSavm, plCount); + if(RC_SUCC == lRet || SOCK_COM_EXCP != pstSavm->m_lErrno) + { + pvm->m_lTryTimes = 0; + pvm->m_lLastTime = time(NULL); + } + + pthread_mutex_unlock(&list->pstFset->lock); + return lRet; + } + return RC_FAIL; + default: + for(list = node->pstSSet; list; list = list->pstNext) + { + if(NULL == (pvm = (TDomain *)(list->psvData))) + continue; + + if(0 == (OPERATE_SELECT & pvm->m_lPers)) + continue; + + if(RC_SUCC != lTvmConnect(pstSavm, pvm->m_szIp, pvm->m_lPort, pvm->m_lTimeOut)) + continue; + + pstSavm->tblName = pvm->m_mtable; + lRet = lTvmCount(pstSavm, plCount); + if(RC_SUCC == lRet || SOCK_COM_EXCP != pstSavm->m_lErrno) + { + close(pstSavm->m_skSock); + ((RunTime *)pGetRunTime(pstSavm, 0))->m_lRowSize = 0; + TFree(((RunTime *)pGetRunTime(pstSavm, 0))->pstVoid); + return lRet; + } + + close(pstSavm->m_skSock); + } + + ((RunTime *)pGetRunTime(pstSavm, 0))->m_lRowSize = 0; + TFree(((RunTime *)pGetRunTime(pstSavm, 0))->pstVoid); + return RC_FAIL; + } +} + +/************************************************************************************************* + description:remote - Extreme + parameters: + pstSavm --stvm handle + psvOut --out of data + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lExtremeByRt(SATvm *pstSavm, void *psvOut) +{ + long lRet; + TDomain *pvm, *pnoe; + Rowgrp *list = NULL, *node = NULL; + + if(NULL == (node = pGetTblNode(pstSavm->tblName))) + { + pstSavm->m_lErrno = DOM_NOT_INITL; + return RC_FAIL; + } + + pstSavm->m_lErrno = RESOU_DISABLE; + switch(lGetBootType()) + { + case TVM_BOOT_CLUSTER: + for(list = node->pstSSet; list; list = list->pstNext) + { + if(!list->pstFset) + continue; + + if(NULL == (pvm = (TDomain *)(list->pstFset->psvData))) + continue; + + pnoe = (TDomain *)list->psvData; + if(0 == (OPERATE_SELECT & pnoe->m_lPers) || RESOURCE_ABLE != pvm->m_lStatus || + pnoe->m_lRelia < 0) + continue; + + pstSavm->m_skSock = pvm->m_skSock; + pstSavm->tblName = pnoe->m_mtable; + pthread_mutex_lock(&list->pstFset->lock); + lRet = lTvmExtreme(pstSavm, psvOut); + if(RC_SUCC == lRet || SOCK_COM_EXCP != pstSavm->m_lErrno) + { + pvm->m_lTryTimes = 0; + pvm->m_lLastTime = time(NULL); + } + + pthread_mutex_unlock(&list->pstFset->lock); + return lRet; + } + return RC_FAIL; + default: + for(list = node->pstSSet; list; list = list->pstNext) + { + if(NULL == (pvm = (TDomain *)(list->psvData))) + continue; + + if(0 == (OPERATE_SELECT & pvm->m_lPers)) + continue; + + if(RC_SUCC != lTvmConnect(pstSavm, pvm->m_szIp, pvm->m_lPort, pvm->m_lTimeOut)) + continue; + + pstSavm->tblName = pvm->m_mtable; + lRet = lTvmExtreme(pstSavm, psvOut); + if(RC_SUCC == lRet || SOCK_COM_EXCP != pstSavm->m_lErrno) + { + close(pstSavm->m_skSock); + ((RunTime *)pGetRunTime(pstSavm, 0))->m_lRowSize = 0; + TFree(((RunTime *)pGetRunTime(pstSavm, 0))->pstVoid); + return lRet; + } + + close(pstSavm->m_skSock); + } + + ((RunTime *)pGetRunTime(pstSavm, 0))->m_lRowSize = 0; + TFree(((RunTime *)pGetRunTime(pstSavm, 0))->pstVoid); + return RC_FAIL; + } +} + +/************************************************************************************************* + description:remote - Droptable + parameters: + pstSavm --stvm handle + t --table + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +void _vDropTableByRt(SATvm *pstSavm, TABLE t) +{ + Rowgrp *node = NULL; + + if(NULL == (node = pGetTblNode(t))) + return ; + + memset(node->psvData, 0, sizeof(TABLE)); +// vDropNodegrp(&g_pstTblgrp, node); +} + +/************************************************************************************************* + description:remote - Rename + parameters: + pstSavm --stvm handle + to --from table + tn --to table + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lRenameTableByRt(SATvm *pstSavm, TABLE to, TABLE tn) +{ + TDomain stDom, stUpd; + Rowgrp *node = NULL; + + if(NULL == (node = pGetTblNode(to))) + return RC_SUCC; + + if(RC_SUCC != lInitSATvm(pstSavm, SYS_TVM_DOMAIN)) + return RC_FAIL; + + updateinit(stUpd); + conditinit(pstSavm, stDom, SYS_TVM_DOMAIN); + numberset(pstSavm, stDom, m_table, to) + numberupd(pstSavm, stUpd, m_table, tn); + + if(RC_SUCC != lUpdate(pstSavm, &stUpd)) + return RC_FAIL; + + memcpy(node->psvData, &tn, sizeof(TABLE)); + return RC_SUCC; +} + +/************************************************************************************************* + description:disconnect server + parameters: + pstSavm --stvm handle + return: + *************************************************************************************************/ +void vTvmDisconnect(SATvm *pstSavm) +{ + RunTime *pstRun; + + if(!pstSavm) return ; + + pstRun = (RunTime *)pGetRunTime(pstSavm, 0); + pstRun->m_lRowSize = 0; + close(pstSavm->m_skSock); + TFree(pstRun->pstVoid); + + vHoldRelease(pstSavm); +} + +/************************************************************************************************* + description:connect server + parameters: + pstSavm --stvm handle + pszIp --server ip + lPort --server port + times --time out + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lTvmConnect(SATvm *pstSavm, char *pszIp, long lPort, int times) +{ + RunTime *pstRun; + + if(!pstSavm || !pszIp) + return RC_FAIL; + + pstSavm->m_lTimes = times; + pstRun = (RunTime *)pGetRunTime(pstSavm, 0); + pstSavm->m_skSock = skConnectServer(pstSavm, pszIp, lPort, false, times); + if(RC_FAIL == pstSavm->m_skSock) + { + Tlog("Connect server %s:%d failed, %s", pszIp, lPort, sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; + } + + return lTvmBuffer(pstSavm); +} + +/************************************************************************************************* + description:parse Java packed + parameters: + pstSavm --stvm handle + pstVoid --conditon + pstFace --request head + pvBuffer --recv buffer + lLen --the length of buffer + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +void* pProtocaJava(SATvm *pstSavm, void *pstVoid, TFace *pstFace, void *pvBuffer, long lLen) +{ + void *pvData, *q; + int i, len, n, m, k; + FdCond *pstCond = &pstSavm->stCond; + char szLen[5] = {0}, szField[MAX_FIELD_LEN]; + TblKey *pstKey, *pv = pGetTblKey(pstFace->m_table); + + if(pstFace->m_lRows == 0) + return pvBuffer; + +// pstFace->m_lDLen +// szName[256]="020020tx_date=201708120016tx_name=DefPuzzL"; + pstCond->uFldcmp = 0; + memcpy(szLen, pvBuffer, 2); + for(i = 0, lLen -= 2, pvData = pvBuffer + 2, k = atol(szLen); i < k; i ++) + { + memcpy(szLen, pvData, 4); + pvData += 4; + + if(lLen < (len = strlen(szLen))) return NULL; + lLen -= (len + 4); + + if(NULL == (q = strstr(pvData, "="))) + return NULL; + + n = q - pvData; + m = MIN(n, MAX_FIELD_LEN); + memcpy(szField, pvData, m); + szField[m] = 0x00; + if(NULL == (pstKey = pFindField(pv, lGetIdxNum(pstFace->m_table), szField))) + return NULL; + + vSetCodField(pstCond, pstKey->m_lLen, pstKey->m_lFrom); + memcpy(pstVoid + pstKey->m_lFrom, pvData + n + 1, m); + pvData += len; + } + + switch(pstFace->m_enum) + { + case OPERATE_INSERT: + return pvBuffer; + case OPERATE_UPDATE: + pstCond = &pstSavm->stUpdt; + pstCond->uFldcmp = 0; + memset(szLen, 0, sizeof(szLen)); + memcpy(szLen, pvBuffer, 2); + pstVoid += pstFace->m_lDLen; + for(i = 0, lLen -= 2, pvData += 2, k = atol(szLen); i < k; i ++) + { + memcpy(szLen, pvData, 4); + pvData += 4; + + if(lLen < (len = strlen(szLen))) return NULL; + lLen -= (len + 4); + + if(NULL == (q = strstr(pvData, "="))) + return NULL; + + n = q - pvData; + m = MIN(n, MAX_FIELD_LEN); + memcpy(szField, pvData, m); + szField[m] = 0x00; + if(NULL == (pstKey = pFindField(pv, lGetIdxNum(pstFace->m_table), szField))) + return NULL; + + vSetCodField(pstCond, pstKey->m_lLen, pstKey->m_lFrom); + memcpy(pstVoid + pstKey->m_lFrom, pvData + n + 1, m); + pvData += len; + } + if(lLen < 0) return NULL; + + return memcpy(pvBuffer, pstVoid, pstFace->m_lDLen); + case OPERATE_SELECT: + case OPERATE_QUERY: + case OPERATE_DELETE: + case OPERATE_TRCATE: + case OPERATE_GROUP: + case OPERATE_EXTREM: + if(lLen < 0) return NULL; + + pstCond = &pstSavm->stUpdt; + pstCond->uFldcmp = 0; + memset(szLen, 0, sizeof(szLen)); + memcpy(szLen, pvBuffer, 2); + for(i = 0, lLen -= 2, pvData += 2, k = atol(szLen); i < k; i ++) + { + memcpy(szLen, pvData, 4); + pvData += 4; + + if(lLen < (len = strlen(szLen))) return NULL; + lLen -= (len + 4); + + if(NULL == (q = strstr(pvData, "="))) + return NULL; + + n = q - pvData; + m = MIN(n, MAX_FIELD_LEN); + memcpy(szField, pvData, m); + szField[m] = 0x00; + if(NULL == (pstKey = pFindField(pv, lGetIdxNum(pstFace->m_table), szField))) + return NULL; + + m = ((char *)pvData)[n + 1]; + vSetDecorate(pstCond, pstKey->m_lLen, pstKey->m_lFrom, (Uenum)m); + pstSavm->lFind = m & FIRST_ROW; + pvData += len; + } + + return pvBuffer; + default: + return pvBuffer; + } + + return NULL; +} + +/************************************************************************************************* + description:parse packed + parameters: + pstSavm --stvm handle + pstVoid --conditon + pstFace --request head + pvBuffer --recv buffer + lLen --the length of buffer + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +void* pParsePacket(SATvm *pstSavm, void *pstVoid, TFace *pstFace, void *pvBuffer, long lLen) +{ + register uint i; + FdKey *pstFld; + void *pvData = pvBuffer; + FdCond *pstCond = &pstSavm->stCond; + + if(pstFace->m_lRows == 0) + return pvBuffer; + + switch(pstFace->m_enum) + { + case OPERATE_INSERT: + return memcpy(pstVoid, pvData, pstFace->m_lDLen); + case OPERATE_UPDATE: + memcpy(&pstCond->uFldcmp, pvData, sizeof(uint)); + for(i = 0, pvData += sizeof(uint); i < pstCond->uFldcmp; i ++) + { + pstFld = &pstCond->stFdKey[i]; + memcpy(pstFld, pvData, sizeof(FdKey)); + pvData += sizeof(FdKey); + memcpy(pstVoid + pstFld->uFldpos, pvData, pstFld->uFldlen); + pvData += pstFld->uFldlen; + } + + pstCond = &pstSavm->stUpdt; + memcpy(&pstCond->uFldcmp, pvData, sizeof(uint)); + if(0 == pstCond->uFldcmp) return pvBuffer; + + for(i = 0, pvData += sizeof(uint), pstVoid += pstFace->m_lDLen; i < pstCond->uFldcmp; i ++) + { + pstFld = &pstCond->stFdKey[i]; + memcpy(pstFld, pvData, sizeof(FdKey)); + pvData += sizeof(FdKey); + memcpy(pstVoid + pstFld->uFldpos, pvData, pstFld->uFldlen); + pvData += pstFld->uFldlen; + } + + return memcpy(pvBuffer, pstVoid, pstFace->m_lDLen); + case OPERATE_SELECT: + case OPERATE_QUERY: + case OPERATE_DELETE: + case OPERATE_TRCATE: + case OPERATE_GROUP: + case OPERATE_COUNT: + case OPERATE_EXTREM: + memcpy(&pstCond->uFldcmp, pvData, sizeof(uint)); + for(i = 0, pvData += sizeof(uint); i < pstCond->uFldcmp; i ++) + { + pstFld = &pstCond->stFdKey[i]; + memcpy(pstFld, pvData, sizeof(FdKey)); + pvData += sizeof(FdKey); + memcpy(pstVoid + pstFld->uFldpos, pvData, pstFld->uFldlen); + pvData += pstFld->uFldlen; + } + + pstCond = &pstSavm->stUpdt; + memcpy(&pstCond->uFldcmp, pvData, sizeof(uint)); + if(0 == pstCond->uFldcmp) return pvBuffer; + + pvData += sizeof(uint); + memcpy(pstCond->stFdKey, pvData, sizeof(FdKey) * pstCond->uFldcmp); + return pvBuffer; +/* + case OPERATE_TBDROP: + case OPERATE_RENAME: + case OPERATE_SELSEQ: + case OPERATE_SETSEQ: + case OPERATE_RETLOK: + case OPERATE_RBDIDX: + case OPERATE_DOMPSH: + case OPERATE_DOMPUL: + .... +*/ + default: + return pvBuffer; + } + + return NULL; +} + +/************************************************************************************************* + description:build condition packed + parameters: + pvData --send buffer + pvBuffer --condition + pstCond --cond field + plRows --length + return: + *************************************************************************************************/ +void vBuildPacket(void *pvData, void *pvBuffer, FdCond *pstCond, uint *plRows) +{ + uint i; + FdKey *pstFld; + + if(!pvBuffer) + { + memset(pvData + (*plRows), 0, sizeof(uint)); + (*plRows) += sizeof(uint); + return; + } + + memcpy(pvData + (*plRows), (void *)&pstCond->uFldcmp, sizeof(uint)); + for(i = 0, (*plRows) += sizeof(uint); i < pstCond->uFldcmp; i ++) + { + pstFld = &pstCond->stFdKey[i]; + memcpy(pvData + (*plRows), (void *)pstFld, sizeof(FdKey)); + (*plRows) += sizeof(FdKey); + memcpy(pvData + (*plRows), pvBuffer + pstFld->uFldpos, pstFld->uFldlen); + (*plRows) += pstFld->uFldlen; + } + + return ; +} + +/************************************************************************************************* + description:parse decorate packed + parameters: + pvData --send buffer + pstCond --decorate field + plRows --length + return: + *************************************************************************************************/ +void vAppendCond(void *pvData, FdCond *pstCond, uint *plRows) +{ + memcpy(pvData + (*plRows), (void *)&pstCond->uFldcmp, sizeof(uint)); + (*plRows) += sizeof(uint); + if(pstCond->uFldcmp <= 0) + return ; + + memcpy(pvData + (*plRows), (void *)&pstCond->stFdKey, pstCond->uFldcmp * sizeof(FdKey)); + (*plRows) += sizeof(FdKey) * pstCond->uFldcmp; + return ; +} + +/************************************************************************************************* + description:API - select + parameters: + pstSavm --stvm handle + pvOut --out data + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lTvmSelect(SATvm *pstSavm, void *pvOut) +{ + RunTime *pstRun; + TFace *pstFace; + uint lWrite = sizeof(TFace); + + if(!pstSavm || !pstSavm->pstVoid) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + pstRun = (RunTime *)pGetRunTime(pstSavm, 0); + if(!pstRun->pstVoid) + { + pstSavm->m_lErrno = DOM_NOT_INITL; + return RC_FAIL; + } + + pstFace = (TFace *)pstRun->pstVoid; + pstFace->m_lFind = pstSavm->lFind; + pstFace->m_lDLen = pstSavm->lSize; + pstFace->m_lErrno = TVM_DONE_SUCC; + pstFace->m_enum = OPERATE_SELECT; + pstFace->m_table = pstSavm->tblName; + + checkbuffer(pstSavm, pstRun, 1); + vBuildPacket(pstRun->pstVoid, pstSavm->pstVoid, &pstSavm->stCond, &lWrite); + vAppendCond(pstRun->pstVoid, &pstSavm->stUpdt, &lWrite); + pstFace->m_lRows = lWrite - sizeof(TFace); + + if(lWrite != lSendBuffer(pstSavm->m_skSock, (char *)pstRun->pstVoid, lWrite)) + { + pstSavm->m_lErrno = SOCK_COM_EXCP; + return RC_FAIL; + } + + if(sizeof(TFace) != lRecvBuffer(pstSavm->m_skSock, (char *)pstRun->pstVoid, sizeof(TFace))) + { + pstSavm->m_lErrno = SOCK_COM_EXCP; + return RC_FAIL; + } + + pstSavm->m_lErrno = pstFace->m_lErrno; + if(0 != pstSavm->m_lErrno) + return RC_FAIL; + + pstSavm->m_lEffect = pstFace->m_lRows; + if(pstSavm->lSize != lRecvBuffer(pstSavm->m_skSock, (char *)pvOut, pstSavm->lSize)) + { + pstSavm->m_lErrno = SOCK_COM_EXCP; + return RC_FAIL; + } + + return RC_SUCC; +} + +/************************************************************************************************* + description:API - query + parameters: + pstSavm --stvm handle + plOut --number + ppvOut --out data list + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lTvmQuery(SATvm *pstSavm, size_t *plOut, void **ppvOut) +{ + RunTime *pstRun; + TFace *pstFace; + uint lWrite = sizeof(TFace); + + if(!pstSavm) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + pstRun = (RunTime *)pGetRunTime(pstSavm, 0); + if(!pstRun->pstVoid) + { + pstSavm->m_lErrno = DOM_NOT_INITL; + return RC_FAIL; + } + + pstFace = (TFace *)pstRun->pstVoid; + pstFace->m_lFind = pstSavm->lFind; + pstFace->m_lDLen = pstSavm->lSize; + pstFace->m_lErrno = TVM_DONE_SUCC; + pstFace->m_enum = OPERATE_QUERY; + pstFace->m_table = pstSavm->tblName; + + checkbuffer(pstSavm, pstRun, 1); + vBuildPacket(pstRun->pstVoid, pstSavm->pstVoid, &pstSavm->stCond, &lWrite); + vAppendCond(pstRun->pstVoid, &pstSavm->stUpdt, &lWrite); + pstFace->m_lRows = lWrite - sizeof(TFace); + + if(lWrite != lSendBuffer(pstSavm->m_skSock, (char *)pstRun->pstVoid, lWrite)) + { + pstSavm->m_lErrno = SOCK_COM_EXCP; + return RC_FAIL; + } + + if(sizeof(TFace) != lRecvBuffer(pstSavm->m_skSock, (char *)pstRun->pstVoid, sizeof(TFace))) + { + pstSavm->m_lErrno = SOCK_COM_EXCP; + return RC_FAIL; + } + + pstSavm->m_lErrno = pstFace->m_lErrno; + if(0 != pstSavm->m_lErrno) + return RC_FAIL; + + pstRun->m_lRowSize = pstSavm->lSize * pstFace->m_lRows; + if(NULL == (*ppvOut = (void *)malloc(pstRun->m_lRowSize))) + { + pstSavm->m_lErrno = MALLC_MEM_ERR; + return RC_FAIL; + } + + if(pstRun->m_lRowSize != lRecvBuffer(pstSavm->m_skSock, (char *)*ppvOut, pstRun->m_lRowSize)) + { + pstSavm->m_lErrno = SOCK_COM_EXCP; + return RC_FAIL; + } + + *plOut = pstFace->m_lRows; + pstSavm->m_lEffect = pstFace->m_lRows; + return RC_SUCC; +} + +/************************************************************************************************* + description:API - insert + parameters: + pstSavm --stvm handle + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lTvmInsert(SATvm *pstSavm) +{ + RunTime *pstRun; + TFace *pstFace; + uint lWrite = sizeof(TFace); + + if(!pstSavm || !pstSavm->pstVoid) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + pstRun = (RunTime *)pGetRunTime(pstSavm, 0); + if(!pstRun->pstVoid) + { + pstSavm->m_lErrno = DOM_NOT_INITL; + return RC_FAIL; + } + + pstFace = (TFace *)pstRun->pstVoid; + pstFace->m_lFind = pstSavm->lFind; + pstFace->m_lDLen = pstSavm->lSize; + pstFace->m_lErrno = TVM_DONE_SUCC; + pstFace->m_enum = OPERATE_INSERT; + pstFace->m_table = pstSavm->tblName; + + pstFace->m_lRows = pstSavm->lSize; + lWrite = pstFace->m_lRows + sizeof(TFace); + + checkbuffer(pstSavm, pstRun, 1); + memcpy(pstRun->pstVoid + sizeof(TFace), pstSavm->pstVoid, pstSavm->lSize); + if(lWrite != lSendBuffer(pstSavm->m_skSock, (void *)pstRun->pstVoid, lWrite)) + { + pstSavm->m_lErrno = SOCK_COM_EXCP; + return RC_FAIL; + } + + if(sizeof(TFace) != lRecvBuffer(pstSavm->m_skSock, (char *)pstRun->pstVoid, sizeof(TFace))) + { + pstSavm->m_lErrno = SOCK_COM_EXCP; + return RC_FAIL; + } + + pstSavm->m_lErrno = pstFace->m_lErrno; + if(0 != pstSavm->m_lErrno) + return RC_FAIL; + + pstSavm->m_lEffect = pstFace->m_lRows; + return RC_SUCC; +} + +/************************************************************************************************* + description:API - delete + parameters: + pstSavm --stvm handle + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lTvmDelete(SATvm *pstSavm) +{ + RunTime *pstRun; + TFace *pstFace; + uint lWrite = sizeof(TFace); + + if(!pstSavm) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + pstRun = (RunTime *)pGetRunTime(pstSavm, 0); + if(!pstRun->pstVoid) + { + pstSavm->m_lErrno = DOM_NOT_INITL; + return RC_FAIL; + } + + pstFace = (TFace *)pstRun->pstVoid; + pstFace->m_lFind = pstSavm->lFind; + pstFace->m_lDLen = pstSavm->lSize; + pstFace->m_lErrno = TVM_DONE_SUCC; + pstFace->m_enum = OPERATE_DELETE; + pstFace->m_table = pstSavm->tblName; + + checkbuffer(pstSavm, pstRun, 1); + vBuildPacket(pstRun->pstVoid, pstSavm->pstVoid, &pstSavm->stCond, &lWrite); + vAppendCond(pstRun->pstVoid, &pstSavm->stUpdt, &lWrite); + pstFace->m_lRows = lWrite - sizeof(TFace); + + if(lWrite != lSendBuffer(pstSavm->m_skSock, (void *)pstRun->pstVoid, lWrite)) + { + pstSavm->m_lErrno = SOCK_COM_EXCP; + return RC_FAIL; + } + + if(sizeof(TFace) != lRecvBuffer(pstSavm->m_skSock, (char *)pstRun->pstVoid, sizeof(TFace))) + { + pstSavm->m_lErrno = SOCK_COM_EXCP; + return RC_FAIL; + } + + pstSavm->m_lErrno = ((TFace *)pstRun->pstVoid)->m_lErrno; + if(0 != pstSavm->m_lErrno) + return RC_FAIL; + + pstSavm->m_lEffect = ((TFace *)pstRun->pstVoid)->m_lRows; + return RC_SUCC; +} + +/************************************************************************************************* + description:API - update + parameters: + pstSavm --stvm handle + pvData --update data + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lTvmUpdate(SATvm *pstSavm, void *pvData) +{ + RunTime *pstRun; + FdCond *pstCond; + TFace *pstFace; + uint lWrite = sizeof(TFace); + + if(!pstSavm || !pvData) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + pstRun = (RunTime *)pGetRunTime(pstSavm, 0); + if(!pstRun->pstVoid) + { + pstSavm->m_lErrno = DOM_NOT_INITL; + return RC_FAIL; + } + + pstFace = (TFace *)pstRun->pstVoid; + pstFace->m_lFind = pstSavm->lFind; + pstFace->m_lDLen = pstSavm->lSize; + pstFace->m_lErrno = TVM_DONE_SUCC; + pstFace->m_enum = OPERATE_UPDATE; + pstFace->m_table = pstSavm->tblName; + + checkbuffer(pstSavm, pstRun, 2); + pstCond = &pstSavm->stUpdt; + if(0 == pstCond->uFldcmp) + { + pstSavm->m_lErrno = UPDFD_NOT_SET; + return RC_FAIL; + } + + vBuildPacket(pstRun->pstVoid, pstSavm->pstVoid, &pstSavm->stCond, &lWrite); + vBuildPacket(pstRun->pstVoid, pvData, pstCond, &lWrite); + pstFace->m_lRows = lWrite - sizeof(TFace); + + if(lWrite != lSendBuffer(pstSavm->m_skSock, (void *)pstRun->pstVoid, lWrite)) + { + pstSavm->m_lErrno = SOCK_COM_EXCP; + return RC_FAIL; + } + + if(sizeof(TFace) != lRecvBuffer(pstSavm->m_skSock, (char *)pstRun->pstVoid, sizeof(TFace))) + { + pstSavm->m_lErrno = SOCK_COM_EXCP; + return RC_FAIL; + } + + pstSavm->m_lErrno = ((TFace *)pstRun->pstVoid)->m_lErrno; + if(0 != pstSavm->m_lErrno) + return RC_FAIL; + + pstSavm->m_lEffect = ((TFace *)pstRun->pstVoid)->m_lRows; + return RC_SUCC; +} + +/************************************************************************************************* + description:API - truncate + parameters: + pstSavm --stvm handle + t --t + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lTvmTruncate(SATvm *pstSavm, TABLE t) +{ + RunTime *pstRun; + TFace *pstFace; + + if(!pstSavm) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + pstRun = (RunTime *)pGetRunTime(pstSavm, 0); + if(!pstRun->pstVoid) + { + pstSavm->m_lErrno = DOM_NOT_INITL; + return RC_FAIL; + } + + pstFace = (TFace *)pstRun->pstVoid; + pstFace->m_table = t; + pstFace->m_lRows = 0; + pstFace->m_lErrno = TVM_DONE_SUCC; + pstFace->m_enum = OPERATE_TRCATE; + + if(sizeof(TFace) != lSendBuffer(pstSavm->m_skSock, (void *)pstFace, sizeof(TFace))) + { + pstSavm->m_lErrno = SOCK_COM_EXCP; + return RC_FAIL; + } + + if(sizeof(TFace) != lRecvBuffer(pstSavm->m_skSock, (void *)pstFace, sizeof(TFace))) + { + pstSavm->m_lErrno = SOCK_COM_EXCP; + return RC_FAIL; + } + + pstSavm->m_lErrno = pstFace->m_lErrno; + if(0 != pstSavm->m_lErrno) + return RC_FAIL; + + pstSavm->m_lEffect = pstFace->m_lRows; + return RC_SUCC; +} + +/************************************************************************************************* + description:API - group + parameters: + pstSavm --stvm handle + plOut --number + ppvOut --out data list + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lTvmGroup(SATvm *pstSavm, size_t *plOut, void **ppvOut) +{ + RunTime *pstRun; + TFace *pstFace; + FdCond *pstCond; + uint lWrite = sizeof(TFace); + + if(!pstSavm || !ppvOut) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + pstRun = (RunTime *)pGetRunTime(pstSavm, 0); + if(!pstRun->pstVoid) + { + pstSavm->m_lErrno = DOM_NOT_INITL; + return RC_FAIL; + } + + pstFace = (TFace *)pstRun->pstVoid; + pstFace->m_lFind = pstSavm->lFind; + pstFace->m_lDLen = pstSavm->lSize; + pstFace->m_lErrno = TVM_DONE_SUCC; + pstFace->m_enum = OPERATE_GROUP; + pstFace->m_table = pstSavm->tblName; + + checkbuffer(pstSavm, pstRun, 1); + pstCond = &pstSavm->stUpdt; + if(0 == pstCond->uFldcmp) + { + pstSavm->m_lErrno = GROUP_SET_ERR; + return RC_FAIL; + } + + vBuildPacket(pstRun->pstVoid, pstSavm->pstVoid, &pstSavm->stCond, &lWrite); + vAppendCond(pstRun->pstVoid, &pstSavm->stUpdt, &lWrite); + pstFace->m_lRows = lWrite - sizeof(TFace); + if(lWrite != lSendBuffer(pstSavm->m_skSock, (char *)pstRun->pstVoid, lWrite)) + { + pstSavm->m_lErrno = SOCK_COM_EXCP; + return RC_FAIL; + } + + if(sizeof(TFace) != lRecvBuffer(pstSavm->m_skSock, (char *)pstRun->pstVoid, sizeof(TFace))) + { + pstSavm->m_lErrno = SOCK_COM_EXCP; + return RC_FAIL; + } + + pstSavm->m_lErrno = pstFace->m_lErrno; + if(0 != pstSavm->m_lErrno) + return RC_FAIL; + + pstRun->m_lRowSize = pstSavm->lSize * pstFace->m_lRows; + if(NULL == (*ppvOut = (void *)malloc(pstRun->m_lRowSize))) + { + pstSavm->m_lErrno = MALLC_MEM_ERR; + return RC_FAIL; + } + + if(pstRun->m_lRowSize != lRecvBuffer(pstSavm->m_skSock, (char *)*ppvOut, pstRun->m_lRowSize)) + { + pstSavm->m_lErrno = SOCK_COM_EXCP; + return RC_FAIL; + } + + *plOut = pstFace->m_lRows; + pstSavm->m_lEffect = pstFace->m_lRows; + return RC_SUCC; +} + +/************************************************************************************************* + description:API - count + parameters: + pstSavm --stvm handle + plcount --count + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lTvmCount(SATvm *pstSavm, size_t *plCount) +{ + RunTime *pstRun; + TFace *pstFace; + uint lWrite = sizeof(TFace); + + if(!pstSavm || !plCount) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + pstRun = (RunTime *)pGetRunTime(pstSavm, 0); + if(!pstRun->pstVoid) + { + pstSavm->m_lErrno = DOM_NOT_INITL; + return RC_FAIL; + } + + pstFace = (TFace *)pstRun->pstVoid; + pstFace->m_lFind = pstSavm->lFind; + pstFace->m_lDLen = pstSavm->lSize; + pstFace->m_lErrno = TVM_DONE_SUCC; + pstFace->m_enum = OPERATE_COUNT; + pstFace->m_table = pstSavm->tblName; + + checkbuffer(pstSavm, pstRun, 1); + vBuildPacket(pstRun->pstVoid, pstSavm->pstVoid, &pstSavm->stCond, &lWrite); + vAppendCond(pstRun->pstVoid, &pstSavm->stUpdt, &lWrite); + pstFace->m_lRows = lWrite - sizeof(TFace); + + if(lWrite != lSendBuffer(pstSavm->m_skSock, (char *)pstRun->pstVoid, lWrite)) + { + pstSavm->m_lErrno = SOCK_COM_EXCP; + return RC_FAIL; + } + + if(sizeof(TFace) != lRecvBuffer(pstSavm->m_skSock, (char *)pstRun->pstVoid, sizeof(TFace))) + { + pstSavm->m_lErrno = SOCK_COM_EXCP; + return RC_FAIL; + } + + pstSavm->m_lErrno = pstFace->m_lErrno; + if(0 != pstSavm->m_lErrno) + return RC_FAIL; + + *plCount = pstFace->m_lRows; + return RC_SUCC; +} + +/************************************************************************************************* + description:API - extreme + parameters: + pstSavm --stvm handle + pvOut --out data + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lTvmExtreme(SATvm *pstSavm, void *pvOut) +{ + RunTime *pstRun; + TFace *pstFace; + FdCond *pstCond; + uint lWrite = sizeof(TFace); + + if(!pstSavm || !pvOut) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + pstRun = (RunTime *)pGetRunTime(pstSavm, 0); + if(!pstRun->pstVoid) + { + pstSavm->m_lErrno = DOM_NOT_INITL; + return RC_FAIL; + } + + pstFace = (TFace *)pstRun->pstVoid; + pstFace->m_lFind = pstSavm->lFind; + pstFace->m_lDLen = pstSavm->lSize; + pstFace->m_lErrno = TVM_DONE_SUCC; + pstFace->m_enum = OPERATE_EXTREM; + pstFace->m_table = pstSavm->tblName; + + checkbuffer(pstSavm, pstRun, 1); + pstCond = &pstSavm->stUpdt; + if(0 == pstCond->uFldcmp) + { + pstSavm->m_lErrno = GROUP_SET_ERR; + return RC_FAIL; + } + + vBuildPacket(pstRun->pstVoid, pstSavm->pstVoid, &pstSavm->stCond, &lWrite); + vAppendCond(pstRun->pstVoid, pstCond, &lWrite); + pstFace->m_lRows = lWrite - sizeof(TFace); + + if(lWrite != lSendBuffer(pstSavm->m_skSock, (char *)pstRun->pstVoid, lWrite)) + { + pstSavm->m_lErrno = SOCK_COM_EXCP; + return RC_FAIL; + } + + if(sizeof(TFace) != lRecvBuffer(pstSavm->m_skSock, (char *)pstRun->pstVoid, sizeof(TFace))) + { + pstSavm->m_lErrno = SOCK_COM_EXCP; + return RC_FAIL; + } + + pstSavm->m_lErrno = pstFace->m_lErrno; + if(0 != pstSavm->m_lErrno) + return RC_FAIL; + + if(pstSavm->lSize != lRecvBuffer(pstSavm->m_skSock, (char *)pvOut, pstSavm->lSize)) + { + pstSavm->m_lErrno = SOCK_COM_EXCP; + return RC_FAIL; + } + + return RC_SUCC; +} + +/************************************************************************************************* + description:API - droptable + parameters: + pstSavm --stvm handle + t --table + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lTvmDropTable(SATvm *pstSavm, TABLE t) +{ + RunTime *pstRun; + TFace *pstFace; + + if(!pstSavm) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + pstRun = (RunTime *)pGetRunTime(pstSavm, 0); + if(!pstRun->pstVoid) + { + pstSavm->m_lErrno = DOM_NOT_INITL; + return RC_FAIL; + } + + pstFace = (TFace *)pstRun->pstVoid; + pstFace->m_lRows = 0; + pstFace->m_table = t; + pstFace->m_lErrno = TVM_DONE_SUCC; + pstFace->m_enum = OPERATE_TBDROP; + + if(sizeof(TFace) != lSendBuffer(pstSavm->m_skSock, (void *)pstRun->pstVoid, sizeof(TFace))) + { + pstSavm->m_lErrno = SOCK_COM_EXCP; + return RC_FAIL; + } + + if(sizeof(TFace) != lRecvBuffer(pstSavm->m_skSock, (char *)pstRun->pstVoid, sizeof(TFace))) + { + pstSavm->m_lErrno = SOCK_COM_EXCP; + return RC_FAIL; + } + + pstSavm->m_lErrno = pstFace->m_lErrno; + if(0 != pstSavm->m_lErrno) + return RC_FAIL; + + pstSavm->m_lEffect = pstFace->m_lRows; + return RC_SUCC; +} + +/************************************************************************************************* + description:API - renametable + parameters: + pstSavm --stvm handle + to --from + tn --to table + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lTvmRenameTable(SATvm *pstSavm, TABLE to, TABLE tn) +{ + RunTime *pstRun; + TFace *pstFace; + + if(!pstSavm) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + pstRun = (RunTime *)pGetRunTime(pstSavm, 0); + if(!pstRun->pstVoid) + { + pstSavm->m_lErrno = DOM_NOT_INITL; + return RC_FAIL; + } + + pstFace = (TFace *)pstRun->pstVoid; + pstFace->m_lRows = 0; + pstFace->m_table = to; + pstFace->m_lDLen = tn; + pstFace->m_lErrno = TVM_DONE_SUCC; + pstFace->m_enum = OPERATE_RENAME; + + if(sizeof(TFace) != lSendBuffer(pstSavm->m_skSock, (void *)pstRun->pstVoid, sizeof(TFace))) + { + pstSavm->m_lErrno = SOCK_COM_EXCP; + return RC_FAIL; + } + + if(sizeof(TFace) != lRecvBuffer(pstSavm->m_skSock, (char *)pstRun->pstVoid, sizeof(TFace))) + { + pstSavm->m_lErrno = SOCK_COM_EXCP; + return RC_FAIL; + } + + pstSavm->m_lErrno = ((TFace *)pstRun->pstVoid)->m_lErrno; + if(0 != pstSavm->m_lErrno) + return RC_FAIL; + + pstSavm->m_lEffect = ((TFace *)pstRun->pstVoid)->m_lRows; + return RC_SUCC; +} + +/************************************************************************************************* + description:API - selectseque + parameters: + pstSavm --stvm handle + pszSQName --seque name + pulNumber --oout seque + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lTvmSelectSeque(SATvm *pstSavm, char *pszSQName, ulong *pulNumber) +{ + RunTime *pstRun; + TFace *pstFace; + uint lWrite = sizeof(TFace) + MAX_INDEX_LEN; + + if(!pstSavm) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + pstRun = (RunTime *)pGetRunTime(pstSavm, 0); + if(!pstRun->pstVoid) + { + pstSavm->m_lErrno = DOM_NOT_INITL; + return RC_FAIL; + } + + pstFace = (TFace *)pstRun->pstVoid; + pstFace->m_table = SYS_TVM_SEQUE; + pstFace->m_lDLen = MAX_INDEX_LEN; + pstFace->m_lErrno = TVM_DONE_SUCC; + pstFace->m_enum = OPERATE_SELSEQ; + pstFace->m_lRows = MAX_INDEX_LEN; + + strncpy(pstRun->pstVoid + sizeof(TFace), pszSQName, MAX_INDEX_LEN); + if(lWrite != lSendBuffer(pstSavm->m_skSock, (char *)pstRun->pstVoid, lWrite)) + { + pstSavm->m_lErrno = SOCK_COM_EXCP; + return RC_FAIL; + } + + if(sizeof(TFace) != lRecvBuffer(pstSavm->m_skSock, (char *)pstRun->pstVoid, sizeof(TFace))) + { + pstSavm->m_lErrno = SOCK_COM_EXCP; + return RC_FAIL; + } + + pstSavm->m_lErrno = pstFace->m_lErrno; + if(0 != pstSavm->m_lErrno) + return RC_FAIL; + + if(sizeof(ulong) != lRecvBuffer(pstSavm->m_skSock, (void *)pstRun->pstVoid, sizeof(ulong))) + { + pstSavm->m_lErrno = SOCK_COM_EXCP; + return RC_FAIL; + } + + memcpy((void *)pulNumber, pstRun->pstVoid, sizeof(ulong)); + return RC_SUCC; +} + +/************************************************************************************************* + description:API - setsequence + parameters: + pstSavm --stvm handle + pszSQName --seque name + uStart --out seque + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lTvmSetSequence(SATvm *pstSavm, char *pszSQName, ulong uStart) +{ + RunTime *pstRun; + TFace *pstFace; + uint lWrite = sizeof(TFace) + MAX_INDEX_LEN; + + if(!pstSavm) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + pstRun = (RunTime *)pGetRunTime(pstSavm, 0); + if(!pstRun->pstVoid) + { + pstSavm->m_lErrno = DOM_NOT_INITL; + return RC_FAIL; + } + + pstFace = (TFace *)pstRun->pstVoid; + pstFace->m_table = SYS_TVM_SEQUE; + pstFace->m_lDLen = MAX_INDEX_LEN; + pstFace->m_lErrno = TVM_DONE_SUCC; + pstFace->m_enum = OPERATE_SETSEQ; + + strncpy(pstRun->pstVoid + sizeof(TFace), pszSQName, MAX_INDEX_LEN); + *((ulong *)(pstRun->pstVoid + lWrite)) = uStart; + lWrite += sizeof(ulong); + pstFace->m_lRows = lWrite - sizeof(TFace); + if(lWrite != lSendBuffer(pstSavm->m_skSock, (void *)pstRun->pstVoid, lWrite)) + { + pstSavm->m_lErrno = SOCK_COM_EXCP; + return RC_FAIL; + } + + if(sizeof(TFace) != lRecvBuffer(pstSavm->m_skSock, (char *)pstRun->pstVoid, sizeof(TFace))) + { + pstSavm->m_lErrno = SOCK_COM_EXCP; + return RC_FAIL; + } + + pstSavm->m_lErrno = ((TFace *)pstRun->pstVoid)->m_lErrno; + if(0 != pstSavm->m_lErrno) + return RC_FAIL; + + return RC_SUCC; +} + +/************************************************************************************************* + description:API - rebuildindex + parameters: + pstSavm --stvm handle + t --table + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lTvmRebuildIndex(SATvm *pstSavm, TABLE t) +{ + RunTime *pstRun; + TFace *pstFace; + + if(!pstSavm) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + pstRun = (RunTime *)pGetRunTime(pstSavm, 0); + if(!pstRun->pstVoid) + { + pstSavm->m_lErrno = DOM_NOT_INITL; + return RC_FAIL; + } + + pstFace = (TFace *)pstRun->pstVoid; + pstFace->m_lRows = 0; + pstFace->m_table = t; + pstFace->m_lErrno = TVM_DONE_SUCC; + pstFace->m_enum = OPERATE_RBDIDX; + + if(sizeof(TFace) != lSendBuffer(pstSavm->m_skSock, (void *)pstRun->pstVoid, sizeof(TFace))) + { + pstSavm->m_lErrno = SOCK_COM_EXCP; + return RC_FAIL; + } + + if(sizeof(TFace) != lRecvBuffer(pstSavm->m_skSock, (char *)pstRun->pstVoid, sizeof(TFace))) + { + pstSavm->m_lErrno = SOCK_COM_EXCP; + return RC_FAIL; + } + + pstSavm->m_lErrno = ((TFace *)pstRun->pstVoid)->m_lErrno; + if(0 != pstSavm->m_lErrno) + return RC_FAIL; + + return RC_SUCC; +} + +/************************************************************************************************* + description:API - Relock + parameters: + pstSavm --stvm handle + t --table + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lTvmResetLock(SATvm *pstSavm, TABLE t) +{ + RunTime *pstRun; + TFace *pstFace; + + if(!pstSavm) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + pstRun = (RunTime *)pGetRunTime(pstSavm, 0); + if(!pstRun->pstVoid) + { + pstSavm->m_lErrno = DOM_NOT_INITL; + return RC_FAIL; + } + + pstFace = (TFace *)pstRun->pstVoid; + pstFace->m_lRows = 0; + pstFace->m_table = t; + pstFace->m_lErrno = TVM_DONE_SUCC; + pstFace->m_enum = OPERATE_RETLOK; + + if(sizeof(TFace) != lSendBuffer(pstSavm->m_skSock, (void *)pstFace, sizeof(TFace))) + { + pstSavm->m_lErrno = SOCK_COM_EXCP; + return RC_FAIL; + } + + if(sizeof(TFace) != lRecvBuffer(pstSavm->m_skSock, (char *)pstFace, sizeof(TFace))) + { + pstSavm->m_lErrno = SOCK_COM_EXCP; + return RC_FAIL; + } + + pstSavm->m_lErrno = ((TFace *)pstRun->pstVoid)->m_lErrno; + if(0 != pstSavm->m_lErrno) + return RC_FAIL; + + return RC_SUCC; +} + +/************************************************************************************************* + description:API - work + parameters: + pstSavm --stvm handle + eWork --ework + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lTvmWork(SATvm *pstSavm, Benum eWork) +{ + RunTime *pstRun; + TFace *pstFace; + + if(!pstSavm) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + pstRun = (RunTime *)pGetRunTime(pstSavm, 0); + if(!pstRun->pstVoid) + { + pstSavm->m_lErrno = DOM_NOT_INITL; + return RC_FAIL; + } + + pstFace = (TFace *)pstRun->pstVoid; + pstFace->m_lRows = 0; + pstFace->m_enum = eWork; + pstFace->m_table = SYS_TVM_INDEX; + pstFace->m_lErrno = TVM_DONE_SUCC; +//#ifdef __linux__ + pstFace->m_lDLen = syscall(SYS_gettid); +//#endif + + if(sizeof(TFace) != lSendBuffer(pstSavm->m_skSock, (void *)pstFace, sizeof(TFace))) + { + pstSavm->m_lErrno = SOCK_COM_EXCP; + return RC_FAIL; + } + + if(sizeof(TFace) != lRecvBuffer(pstSavm->m_skSock, (char *)pstFace, sizeof(TFace))) + { + pstSavm->m_lErrno = SOCK_COM_EXCP; + return RC_FAIL; + } + + pstSavm->m_lErrno = pstFace->m_lErrno; + pstSavm->m_lEffect = pstFace->m_lRows; + if(0 != pstSavm->m_lErrno) + return RC_FAIL; + + return RC_SUCC; +} + +/************************************************************************************************* + description:API - begin work + parameters: + pstSavm --stvm handle + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lTvmBeginWork(SATvm *pstSavm) +{ + return _lTvmWork(pstSavm, OPERATE_BEGWORK); +} + +/************************************************************************************************* + description:API - rollback work + parameters: + pstSavm --stvm handle + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lTvmRollbackWork(SATvm *pstSavm) +{ + return _lTvmWork(pstSavm, OPERATE_ROLWORK); +} + +/************************************************************************************************* + description:API - commit work + parameters: + pstSavm --stvm handle + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lTvmCommitWork(SATvm *pstSavm) +{ + return _lTvmWork(pstSavm, OPERATE_CMTWORK); +} + +/************************************************************************************************* + description:API - end work + parameters: + pstSavm --stvm handle + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lTvmEndWork(SATvm *pstSavm) +{ + return _lTvmWork(pstSavm, OPERATE_ENDWORK); +} + +/************************************************************************************************* + description:API - exit + parameters: + pstSavm --stvm handle + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lTvmExit(SATvm *pstSavm) +{ + return _lTvmWork(pstSavm, OPERATE_EXEEXIT); +} + +/************************************************************************************************* + description:Gets the remote table index, user STVM-SQL + parameters: + pstSavm --stvm handle + pszTable --table name + pszPart --part + pstIndex --table index + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lTvmGetTblIndex(SATvm *pstSavm, char *pszTable, char *pszPart, TIndex *pstIndex) +{ + TIndex stIndex; + + if(!pszTable || !pstSavm) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + pstSavm->bSearch = TYPE_SYSTEM; + conditinit(pstSavm, stIndex, SYS_TVM_INDEX); + stringset(pstSavm, stIndex, m_szPart, pszPart); + stringset(pstSavm, stIndex, m_szTable, pszTable); + numberset(pstSavm, stIndex, m_lLocal, RES_LOCAL_SID); + if(RC_SUCC != lTvmSelect(pstSavm, (void *)pstIndex)) + { + if(NO_DATA_FOUND == pstSavm->m_lErrno) + pstSavm->m_lErrno = TBL_NOT_FOUND; + return RC_FAIL; + } + + return RC_SUCC; +} + +/************************************************************************************************* + description:Gets the remote table field, user STVM-SQL + parameters: + pstSavm --stvm handle + t --t + plOut --number + ppstField --table field + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lTvmGetTblField(SATvm *pstSavm, TABLE t, size_t *plOut, TField **ppstField) +{ + TField stField; + + conditinit(pstSavm, stField, SYS_TVM_FIELD) + numberset(pstSavm, stField, m_table, t); + + return lTvmQuery(pstSavm, plOut, (void **)ppstField); +} + +/************************************************************************************************* + * code end + *************************************************************************************************/ diff --git a/src/tree.c b/src/tree.c new file mode 100644 index 0000000..3060907 --- /dev/null +++ b/src/tree.c @@ -0,0 +1,9511 @@ +/* +* Copyright (c) 2018 Savens Liu +* +* The original has been patented, Open source is not equal to open rights. +* Anyone can clone, download, learn and discuss for free. Without the permission +* of the copyright owner or author, it shall not be merged, published, licensed or sold. +* The copyright owner or author has the right to pursue his responsibility. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "tvm.h" +#include "tmain.h" + +/************************************************************************************************* + globle + *************************************************************************************************/ +SATvm g_stSavm = {0}; +TblDef g_stTblDef[TVM_MAX_TABLE] = {0}; + +extern long _lInsertByRt(SATvm *pstSavm); +extern long _lGroupByRt(SATvm *pstSavm, size_t *plOut, void **ppvOut); +extern long _lSelectByRt(SATvm *pstSavm, void *psvOut); +extern long _lCountByRt(SATvm *pstSavm, size_t *plCount); +extern long _lDeleteByRt(SATvm *pstSavm); +extern long _lUpdateByRt(SATvm *pstSavm, void *pvUpdate); +extern long _lTruncateByRt(SATvm *pstSavm, TABLE t); +extern long _lQueryByRt(SATvm *pstSavm, size_t *plOut, void **ppsvOut); +extern long _lExtremeByRt(SATvm *pstSavm, void *psvOut); +extern void _vDropTableByRt(SATvm *pstSavm, TABLE t); +extern long _lRenameTableByRt(SATvm *pstSavm, TABLE to, TABLE tn); +/************************************************************************************************* + macro + *************************************************************************************************/ +#define Tremohold(p,r) if(p->m_bHold) r->m_lState = RESOURCE_ABLE; + +/************************************************************************************************* + Error message definition + *************************************************************************************************/ +static char tvmerr[100][MAX_INDEX_LEN] = { + "completed successfully", + "sever exception", + "index field values is null", + "condition is null", + "no space for insert data", + "generate shm key failure", + "Invalid parameter or shm has disappeared", + "shared memory already exists", + "shared memory has been deleted", + "Permission denied .shm", + "Insufficient core memory .shm", + "data truck version mismatch", + "size is error to creat data block", + "unique index definition overflow", + "unique index length overflow", + "normal index definition overflow", + "normal index length overflow", + "index type not define", + "field define overflow", + "index data mismatch", + "field type not define", + "memory has not been initialized", + "unique index repeat", + "no space for create index", + "no data be found", + "more then one records be selected", + "malloc memory error", + "cursor invalid", + "table not define", + "file not exist", + "semget condition is null", + "Invalid parameter or sem has disappeared", + "semaphore already exists", + "semaphore has been deleted", + "Permission denied .sem", + "Insufficient core memory .sem", + "Semaphore value out of limit", + "SQL syntax is error", + "SQL syntax not be supported", + "SQL no table name be inputted", + "SQL field is not selected", + "SQL conditional syntax error", + "SQL field syntax error", + "SQL where syntax error", + "table not found", + "SQL fields does not match the value", + "set the read lock failure", + "unlock read lock failure", + "set the write lock failure", + "unlock write lock failure", + "socket connect failure", + "socket connect timeout", + "create socket failure", + "socket recv failure", + "socket send failure", + "socket bind failure", + "socket listen failure", + "socket send timeout", + "socket read timeout", + "socket reset by peer", + "socket communication anomaly", + "epoll add fd error", + "create epoll fd failure", + "delete epoll fd failure", + "socket accept failure", + "SQL remote does not support", + "file not found", + "boot parameters error", + "parameters table related error", + "Incompatible version", + "domain not register", + "domain work does not support", + "sequence does not exist", + "file is not set", + "record data too long", + "Resource unavailable", + "message queue already exists", + "Permission denied .msg", + "Insufficient(msg) core memory", + "Invalid parameter or msg has disappeared", + "message Invalid address", + "message queue has been deleted", + "message text length is greater than msgsz", + "Interrupted by signal", + "msgsnd queue overrun", + "initial child process failed", + "field not exist", + "table already exist", + "The transaction has not been opened yet", + "The transaction has not been register", + "domain not initail", + "table field not define", + "set field value error", + "update field not set", + "extreme set decorate error", + "group set decorate error", + "", +}; + +/************************************************************************************************* + description:error message customization + parameters: + return: + *************************************************************************************************/ +void vRedeError(long err, char *s) +{ + if(100 <= err || !s) + return ; + strncpy(tvmerr[err], s, MAX_INDEX_LEN - 1); +} + +/************************************************************************************************* + description:output hexadecimal + parameters: + return: + *************************************************************************************************/ +void vPrintHex(char *s, long lIdx, bool bf) +{ + int i = 0; + FILE *fp = NULL; + + if(!bf) + { + for(i = 0; i < lIdx; i ++) + { + if((ushar)s[i] > 0x80 && (ushar)s[i + 1] >= 0x40) + { + fprintf(stdout, "\033[0;35m%c%c\033[0m", s[i], s[i + 1]); + ++ i; + continue; + } + + if(s[i] > 40 && s[i] < 126) + fprintf(stdout, "\033[0;35m%C\033[0m", s[i]); + else + fprintf(stdout, "/x%0X ", (ushar)s[i]); + } + } + else + { + fp = fopen("log.txt", "a"); + fwrite(s, 1, lIdx, fp); + fclose(fp); + } + + fprintf(stdout, "\n"); + fflush(stdout); +} + +/************************************************************************************************* + description:System table creation + parameters: + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +CREATE lCreateTvmIndex() +{ + DEFINE(SYS_TVM_INDEX, "SYS_TVM_INDEX", "", TIndex) + FIELD(TIndex, m_table, "m_table", FIELD_LONG) + FIELD(TIndex, m_lType, "m_lType", FIELD_LONG) + FIELD(TIndex, m_szTable, "m_szTable", FIELD_CHAR) + FIELD(TIndex, m_szPart, "m_szPart", FIELD_CHAR) + FIELD(TIndex, m_szOwner, "m_szOwner", FIELD_CHAR) + FIELD(TIndex, m_yKey, "m_yKey", FIELD_LONG) + FIELD(TIndex, m_shmID, "m_shmID", FIELD_LONG) + FIELD(TIndex, m_semID, "m_semID", FIELD_LONG) + FIELD(TIndex, m_lPid, "m_lPid", FIELD_LONG) + FIELD(TIndex, m_lValid, "m_lValid", FIELD_LONG) + FIELD(TIndex, m_lMaxRows, "m_lMaxRows", FIELD_LONG) + FIELD(TIndex, m_lRowSize, "m_lRowSize", FIELD_LONG) + FIELD(TIndex, m_lLocal, "m_lLocal", FIELD_LONG) + FIELD(TIndex, m_lState, "m_lState", FIELD_LONG) + FIELD(TIndex, m_lPers, "m_lPers", FIELD_LONG) + FIELR(TIndex, m_szTime, "m_szTime", FIELD_LONG) + + CREATE_IDX(NORMAL) + IDX_FIELD(TIndex, m_szTable, FIELD_CHAR); + IDX_FIELD(TIndex, m_szPart, FIELD_CHAR); + + CREATE_IDX(UNQIUE) + IDX_FIELD(TIndex, m_table, FIELD_LONG); + FINISH +} + +/************************************************************************************************* + description:field table creation + parameters: + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +CREATE lCreateTvmField() +{ + DEFINE(SYS_TVM_FIELD, "SYS_TVM_FIELD", "", TField) + FIELD(TField, m_table, "m_table", FIELD_LONG) + FIELD(TField, m_szOwner, "m_szOwner", FIELD_CHAR) + FIELD(TField, m_szTable, "m_szTable", FIELD_CHAR) + FIELD(TField, m_szField, "m_szField", FIELD_CHAR) + FIELD(TField, m_lSeq, "m_lSeq", FIELD_LONG) + FIELD(TField, m_lAttr, "m_lAttr", FIELD_LONG) + FIELD(TField, m_lFrom, "m_lFrom", FIELD_LONG) + FIELD(TField, m_lLen, "m_lLen", FIELD_LONG) + FIELD(TField, m_lIsPk, "m_lIsPk", FIELD_LONG) + + CREATE_IDX(NORMAL) + IDX_FIELD(TField, m_table, FIELD_LONG); + + CREATE_IDX(UNQIUE) + IDX_FIELD(TField, m_table, FIELD_LONG); + IDX_FIELD(TField, m_lSeq, FIELD_LONG); + FINISH +} + +/************************************************************************************************* + description:domain table creation + parameters: + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +CREATE lCreateTvmDomain() +{ + DEFINE(SYS_TVM_DOMAIN, "SYS_TVM_DOMAIN", "", TDomain) + FIELD(TDomain, m_skSock, "m_skSock", FIELD_LONG) + FIELD(TDomain, m_table, "m_table", FIELD_LONG) + FIELD(TDomain, m_mtable, "m_mtable", FIELD_LONG) + FIELD(TDomain, m_lLock, "m_lLock", FIELD_LONG) + FIELD(TDomain, m_lGroup, "m_lGroup", FIELD_LONG) + FIELD(TDomain, m_lKeepLive, "m_lKeepLive", FIELD_LONG) + FIELD(TDomain, m_lLastTime, "m_lLastTime", FIELD_LONG) + FIELD(TDomain, m_lTimeOut, "m_lTimeOut", FIELD_LONG) + FIELD(TDomain, m_lTryMax, "m_lTryMax", FIELD_LONG) + FIELD(TDomain, m_lTryTimes, "m_lTryTimes", FIELD_LONG) + FIELD(TDomain, m_lRowSize, "m_lRowSize", FIELD_LONG) + FIELD(TDomain, m_lStatus, "m_lStatus", FIELD_LONG) + FIELD(TDomain, m_lPers, "m_lPers", FIELD_LONG) + FIELD(TDomain, m_lPort, "m_lPort", FIELD_LONG) + FIELD(TDomain, m_szIp, "m_szIp", FIELD_CHAR) + FIELD(TDomain, m_szTable, "m_szTable", FIELD_CHAR) + FIELD(TDomain, m_szPart, "m_szPart", FIELD_CHAR) + FIELD(TDomain, m_szOwner, "m_szOwner", FIELD_CHAR) + + CREATE_IDX(NORMAL) + IDX_FIELD(TDomain, m_szTable, FIELD_CHAR) + IDX_FIELD(TDomain, m_szPart, FIELD_CHAR) + + CREATE_IDX(UNQIUE) + IDX_FIELD(TDomain, m_mtable, FIELD_LONG) + IDX_FIELD(TDomain, m_lPort, FIELD_LONG) + IDX_FIELD(TDomain, m_szIp, FIELD_CHAR) + + FINISH +} + +/************************************************************************************************* + description:seque table creation + parameters: + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +CREATE lCreateTvmSeque() +{ + DEFINE(SYS_TVM_SEQUE, "SYS_TVM_SEQUE", "", TSeque) + FIELD(TSeque, m_szSQName, "m_szSQName", FIELD_CHAR) + FIELD(TSeque, m_uIncrement, "m_uIncrement", FIELD_LONG) + + CREATE_IDX(UNQIUE) + IDX_FIELD(TSeque, m_szSQName, FIELD_CHAR) + + FINISH +} + +/************************************************************************************************* + description:timestamp string + parameters: + return: + char* + *************************************************************************************************/ +char* sGetUpdTime() +{ + time_t current; + struct tm *tm = NULL; + static char szTime[20]; + + tzset(); + time(¤t); + tm = localtime(¤t); + + memset(szTime, 0, sizeof(szTime)); + snprintf(szTime, sizeof(szTime), "%4d/%02d/%02d %02d:%02d:%02d", tm->tm_year + 1900, + tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); + + return szTime; +} + +/************************************************************************************************* + description:Conditional field setting + parameters: + return: + *************************************************************************************************/ +void vSetCodField(FdCond *pstCond, uint ulen, uint uPos) +{ + register int i = 0; + + for(i; i < pstCond->uFldcmp; i ++) + { + if(pstCond->stFdKey[i].uFldpos == uPos) + return ; + } + + pstCond->stFdKey[pstCond->uFldcmp].uFldlen = ulen; + pstCond->stFdKey[pstCond->uFldcmp].uFldpos = uPos; + pstCond->uFldcmp ++; + return ; +} + +/************************************************************************************************* + description:decorate field setting + parameters: + return: + *************************************************************************************************/ +void vSetDecorate(FdCond *pstCond, uint ulen, uint uPos, Uenum em) +{ + register int i = 0; + + for(i; i < pstCond->uFldcmp; i ++) + { + if(pstCond->stFdKey[i].uFldpos == uPos) + return ; + } + + pstCond->stFdKey[pstCond->uFldcmp].uFldlen = ulen; + pstCond->stFdKey[pstCond->uFldcmp].uFldpos = uPos; + pstCond->stFdKey[pstCond->uFldcmp].uDecorate = em; + pstCond->uFldcmp ++; + + return ; +} + +/************************************************************************************************* + description:pick index from data + parameters: + return: + char* + *************************************************************************************************/ +char* pPickIndex(long lIdx, TblKey *pstKey, void *psvData, char *pszIdx) +{ + register int i, j, m = 0; + static char szZore[MAX_INDEX_LEN] = {0}; + + if(!psvData) return NULL; + + for(i = 0, j = 0; i < lIdx; i ++) + { + if(FIELD_CHAR != pstKey[i].m_lAttr) + m ++; + memcpy(pszIdx + j, psvData + pstKey[i].m_lFrom, pstKey[i].m_lLen); + j += pstKey[i].m_lLen; + } + + if(0 != m) return pszIdx; + + if(!memcmp(pszIdx, szZore, j)) + return NULL; + + return pszIdx; +} + +/************************************************************************************************* + description:get index from data + parameters: + return: + char* + *************************************************************************************************/ +char* pGetIndex(FdCond *pstCond, long lIdx, TblKey *pstKey, void *psvData, char *pszIdx) +{ + register int i, j, m; + + if(!psvData || 0 == pstCond->uFldcmp) + return NULL; + + for(i = 0, m = 0; i < lIdx; i ++) + { + for(j = 0; j < pstCond->uFldcmp; j ++) + { + if(pstKey[i].m_lFrom == pstCond->stFdKey[j].uFldpos) + { + memcpy(pszIdx + m, psvData + pstKey[i].m_lFrom, pstKey[i].m_lLen); + m += pstKey[i].m_lLen; + break; + } + } + + if(j == pstCond->uFldcmp) + return NULL; + } + + return pszIdx; +} + +/************************************************************************************************* + description:get stvm handle + parameters: + return: + void* + *************************************************************************************************/ +void* pGetSATvm() +{ + return &g_stSavm; +} + +/************************************************************************************************* + description:initial stvm handle + parameters: + return: + *************************************************************************************************/ +void vInitSATvm(SATvm *pstSavm) +{ + memset(pstSavm, 0, sizeof(SATvm)); +} + +/************************************************************************************************* + description:User custom error message + parameters: + return: + *************************************************************************************************/ +void vSetTvmMsg(SATvm *pstSamo, char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vsnprintf(pstSamo->m_szMsg, sizeof(pstSamo->m_szMsg), fmt, ap); + va_end(ap); +} + +/************************************************************************************************* + description:get custom error message + parameters: + return: + char* + *************************************************************************************************/ +char* sGetTvmMsg(SATvm *pstSamo) +{ + return pstSamo->m_szMsg; +} + +/************************************************************************************************* + description:Gets the operation error code + parameters: + return: + long --errno code + *************************************************************************************************/ +long lGetTErrno() +{ + return g_stSavm.m_lErrno; +} + +/************************************************************************************************* + description:set operation error code index from data + parameters: + error --errno + return: + *************************************************************************************************/ +void vSetTErrno(long err) +{ + g_stSavm.m_lErrno = err; +} + +/************************************************************************************************* + description:Gets the operation error message + parameters: + error --errno + return: + char* + *************************************************************************************************/ +char* sGetTError(long err) +{ + return tvmerr[(uint)err]; +} + +/************************************************************************************************* + description:Operation STVM affects the number of records. + parameters: + return: + size_t + *************************************************************************************************/ +size_t lGetEffect() +{ + return g_stSavm.m_lEffect; +} + +/************************************************************************************************* + description:Get the table run handle + parameters: + return: + RunTime* + *************************************************************************************************/ +RunTime* pGetRunTime(SATvm *pstSavm, TABLE t) +{ + return &pstSavm->stRunTime[t]; +} + +/************************************************************************************************* + description:get table starting address + parameters: + return: + void* + *************************************************************************************************/ +void* pGetAddr(SATvm *pstSavm, TABLE t) +{ + return ((RunTime *)pGetRunTime(pstSavm, t))->m_pvAddr; +} + +/************************************************************************************************* + description:Gets the table structure information + parameters: + t --table + return: + TblDef* + *************************************************************************************************/ +TblDef* pGetTblDef(TABLE t) +{ + return &g_stTblDef[t]; +} + +/************************************************************************************************* + description:Gets the table structure information + parameters: + pvAddr --address + return: + RWLock* + *************************************************************************************************/ +RWLock* pGetRWLock(char* pvAddr) +{ + return &((TblDef *)pvAddr)->m_rwlock; +} + +/************************************************************************************************* + description:initial the table structure information + parameters: + pvAddr --address + return: + RWLock* + *************************************************************************************************/ +void vInitTblDef(TABLE t) +{ + memset(&g_stTblDef[t], 0, sizeof(TblDef)); +} + +/************************************************************************************************* + description:Get the number of query index groups + parameters: + t --table + return: + long + *************************************************************************************************/ +long lGetTblGroup(TABLE t) +{ + return g_stTblDef[t].m_lGroup; +} + +/************************************************************************************************* + description:Get the maximum number of table support records + parameters: + t --table + return: + size_t + *************************************************************************************************/ +size_t lGetTblRow(TABLE t) +{ + return g_stTblDef[t].m_lMaxRow; +} + +/************************************************************************************************* + description:Get the current record number of valid records + parameters: + t --table + return: + size_t + *************************************************************************************************/ +size_t lGetTblValid(TABLE t) +{ + return g_stTblDef[t].m_lValid; +} + +/************************************************************************************************* + description:Get the table's unique index length + parameters: + t --table + return: + long + *************************************************************************************************/ +long lGetIdxLen(TABLE t) +{ + return g_stTblDef[t].m_lIdxLen; +} + +/************************************************************************************************* + description:Get the location of the table index + parameters: + t --table + return: + size_t + *************************************************************************************************/ +size_t lGetIdxPos(TABLE t) +{ + return g_stTblDef[t].m_lTreePos; +} + +/************************************************************************************************* + description:Gets the unique index of the table Root position + parameters: + t --table + return: + size_t + *************************************************************************************************/ +size_t lGetIdxRoot(TABLE t) +{ + return g_stTblDef[t].m_lTreeRoot; +} + +/************************************************************************************************* + description:Get NIL position of the table + parameters: + t --table + return: + size_t + *************************************************************************************************/ +size_t lGetNodeNil(TABLE t) +{ + return g_stTblDef[t].m_lNodeNil; +} + +/************************************************************************************************* + description:Get the index of the table query group length + parameters: + t --table + return: + long + *************************************************************************************************/ +long lGetGrpLen(TABLE t) +{ + return g_stTblDef[t].m_lGrpLen; +} + +/************************************************************************************************* + description:Get the location of the index group for the table + parameters: + t --table + return: + size_t + *************************************************************************************************/ +size_t lGetGrpPos(TABLE t) +{ + return g_stTblDef[t].m_lGroupPos; +} + +/************************************************************************************************* + description:Get the root position of the table + parameters: + t --table + return: + size_t + *************************************************************************************************/ +size_t lGetGrpRoot(TABLE t) +{ + return g_stTblDef[t].m_lGroupRoot; +} + +/************************************************************************************************* + description:Gets the offset of the index list + parameters: + t --table + return: + size_t + *************************************************************************************************/ +size_t lGetListOfs(TABLE t) +{ + return g_stTblDef[t].m_lListOfs; +} + +/************************************************************************************************* + description:Gets the position of the index list + parameters: + t --table + return: + size_t + *************************************************************************************************/ +size_t lGetListPos(TABLE t) +{ + return g_stTblDef[t].m_lListPos; +} + +/************************************************************************************************* + description:Get table data area location + parameters: + t --table + return: + size_t + *************************************************************************************************/ +size_t lGetTblData(TABLE t) +{ + return g_stTblDef[t].m_lData; +} + +/************************************************************************************************* + description:Get the number of unique index combinations + parameters: + t --table + return: + uint + *************************************************************************************************/ +uint lGetIdxNum(TABLE t) +{ + return g_stTblDef[t].m_lIdxUp; +} + +/************************************************************************************************* + description:Get unique index field list + parameters: + t --table + return: + TblKey + size_t + *************************************************************************************************/ +TblKey* pGetTblIdx(TABLE t) +{ + return g_stTblDef[t].m_stIdxUp; +} + +/************************************************************************************************* + description:Get the number of index combinations + parameters: + t --table + return: + uint + *************************************************************************************************/ +uint lGetGrpNum(TABLE t) +{ + return g_stTblDef[t].m_lGrpUp; +} + +/************************************************************************************************* + description:Get index field list + parameters: + t --table + return: + TblKey + *************************************************************************************************/ +TblKey* pGetTblGrp(TABLE t) +{ + return g_stTblDef[t].m_stGrpUp; +} + +/************************************************************************************************* + description:Get the entire table size + parameters: + t --table + return: + size_t + *************************************************************************************************/ +size_t lGetTableSize(TABLE t) +{ + return g_stTblDef[t].m_lTable; +} + +/************************************************************************************************* + description:Get a table to define a single record size + parameters: + t --table + return: + long + *************************************************************************************************/ +long lGetRowSize(TABLE t) +{ + return g_stTblDef[t].m_lReSize; +} + +/************************************************************************************************* + description:Get Table Defines a single data block size + parameters: + t --table + return: + size_t + *************************************************************************************************/ +size_t lGetRowTruck(TABLE t) +{ + return g_stTblDef[t].m_lTruck; +} + +/************************************************************************************************* + description:Get the number of table fields + parameters: + t --table + return: + long + *************************************************************************************************/ +long lGetFldNum(TABLE t) +{ + return g_stTblDef[t].m_lIdxNum; +} + +/************************************************************************************************* + description:Get the table fields + parameters: + t --table + return: + TblKey + *************************************************************************************************/ +TblKey* pGetTblKey(TABLE t) +{ + return g_stTblDef[t].m_stKey; +} + +/************************************************************************************************* + description:Get the field by offset + parameters: + t --table + return: + TblKey + *************************************************************************************************/ +TblKey* pGetFldKey(TABLE t, uint uFrom, uint uLen) +{ + long i = 0; + TblKey *pstKey = (TblKey *)pGetTblKey(t); + + for(i = 0; i < lGetFldNum(t); i ++) + { + if(pstKey[i].m_lFrom == uFrom && pstKey[i].m_lLen == uLen) + return &pstKey[i]; + } + + return NULL; +} + +/************************************************************************************************* + description:initial field condition + parameters: + t --table + return: + *************************************************************************************************/ +void vCondInsInit(FdCond *pstCond, TABLE t) +{ + long i = 0; + TblKey *pstKey = (TblKey *)pGetTblKey(t); + + for(pstCond->uFldcmp = lGetFldNum(t); i < pstCond->uFldcmp; i ++) + { + pstCond->stFdKey[i].uFldpos = pstKey[i].m_lFrom; + pstCond->stFdKey[i].uFldlen = pstKey[i].m_lLen; + } + + return ; +} + +/************************************************************************************************* + description:Set the field properties + parameters: + pstCond --condion field + t --table + return: + true + *************************************************************************************************/ +bool bSetCondAttr(FdCond *pstCond, TABLE t, Uenum eCheck) +{ + FdKey *pstFd; + register int i, j; + bool bCheck = false; + TblKey *pstKey = (TblKey *)pGetTblKey(t); + + for(j = 0; j < pstCond->uFldcmp; j ++) + { + pstFd = &pstCond->stFdKey[j]; + for(i = 0; i < lGetFldNum(t); i ++) + { + if(pstKey[i].m_lFrom == pstFd->uFldpos) + { + pstFd->uDecorate |= pstKey[i].m_lAttr; + break; + } + } + + if(pstFd->uDecorate & eCheck) + bCheck = true; + } + + return bCheck; +} + +/************************************************************************************************* + description:Check to see if it is an index field. + parameters: + t --table + pstRrp --field list + return: + true --yes + false --no + *************************************************************************************************/ +bool bIsGroupFld(TABLE t, FdCond *pstRrp) +{ + long i, j; + FdKey *pstFd; + TblKey *pstKey = (TblKey *)pGetTblGrp(t); + + if(pstRrp->uFldcmp != lGetGrpNum(t)) + return false; + + for(i = 0; i < pstRrp->uFldcmp; i ++) + { + pstFd = &pstRrp->stFdKey[i]; + for(j = 0; j < lGetGrpNum(t); j ++) + { + if(pstKey[j].m_lFrom == pstFd->uFldpos) + break; + } + + if(j == lGetGrpNum(t)) + return false; + } + + return true; +} + +/************************************************************************************************* + description:Get table name + parameters: + t --table + return: + char* + *************************************************************************************************/ +char* sGetTableName(TABLE t) +{ + return g_stTblDef[t].m_szTable; +} + +/************************************************************************************************* + description:Gets the table partition + parameters: + t --table + return: + char* + *************************************************************************************************/ +char* sGetTablePart(TABLE t, char *pszNode) +{ + if(0x00 == g_stTblDef[t].m_szPart[0]) + strncpy(g_stTblDef[t].m_szPart, pszNode, MAX_FIELD_LEN); + return g_stTblDef[t].m_szPart; +} + +/************************************************************************************************* + description:Stand-alone mode, let stvm keep links improve efficiency + parameters: + pstSavm --stvm handle + return: + *************************************************************************************************/ +void vHoldConnect(SATvm *pstSavm) +{ + pstSavm->m_bHold = TRUE; +} + +/************************************************************************************************* + description:Stand-alone mode, disconnect STVM + parameters: + pstSavm --stvm handle + return: + *************************************************************************************************/ +void vHoldRelease(SATvm *pstSavm) +{ + TABLE t; + RunTime *pstRun = NULL; + + pstSavm->m_bHold = FALSE; + for(t = 0; t < TVM_MAX_TABLE; t ++) + { + pstRun = (RunTime *)pGetRunTime(pstSavm, t); + if(RES_REMOT_SID == pstRun->m_lLocal) + { + pstRun->m_lState = RESOURCE_INIT; + continue; + } + + pstRun->m_lCurType = 0; + pstRun->m_lCurLine = 0; + pstRun->m_pvCurAddr = NULL; + TFree(pstRun->pstVoid); + + if(pstRun->m_pvAddr) + shmdt(pstRun->m_pvAddr); + pstRun->m_pvAddr = NULL; + pstRun->m_bAttch = FALSE; + } + + return ; +} + +/************************************************************************************************* + description:Release the table resources + parameters: + pstSavm --stvm handle + t --table + bHold + return: + *************************************************************************************************/ +void _vTblRelease(SATvm *pstSavm, TABLE t, bool bHold) +{ + RunTime *pstRun = (RunTime *)pGetRunTime(pstSavm, t); + + TFree(pstRun->pstVoid); + if(bHold) return ; + + if(RES_REMOT_SID == pstRun->m_lLocal) + { + pstRun->m_lState = RESOURCE_INIT; + return ; + } + + pstRun->m_lCurType = 0; + pstRun->m_lCurLine = 0; + pstRun->m_pvCurAddr = NULL; + + if(pstRun->m_pvAddr) + shmdt(pstRun->m_pvAddr); + pstRun->m_pvAddr = NULL; + pstRun->m_bAttch = FALSE; +} + +/************************************************************************************************* + description:Close the table resources + parameters: + pstSavm --stvm handle + t --table + return: + *************************************************************************************************/ +void vTblDisconnect(SATvm *pstSavm, TABLE t) +{ + _vTblRelease(pstSavm, t, pstSavm->m_bHold); +} + +/************************************************************************************************* + description:Forced to close the table resources + parameters: + pstSavm --stvm handle + t --table + return: + *************************************************************************************************/ +void vForceDisconnect(SATvm *pstSavm, TABLE t) +{ + _vTblRelease(pstSavm, t, false); +} + +/************************************************************************************************* + description:API - begin work + parameters: + pstSavm --stvm handle + return: + *************************************************************************************************/ +void vBeginWork(SATvm *pstSavm) +{ + if(!pstSavm) return ; + + pstSavm->m_lErrno = 0; + pstSavm->m_lEffect = 0; + pstSavm->m_bWork = true; +} + +/************************************************************************************************* + description:API - end work + parameters: + pstSavm --stvm handle + return: + *************************************************************************************************/ +void vEndWork(SATvm *pstSavm) +{ + if(!pstSavm) return ; + + pstSavm->m_lErrno = 0; + pstSavm->m_lEffect = 0; + pstSavm->m_bWork = false; + lCommitWork(pstSavm); +} + +/************************************************************************************************* + description:Save abnormal transaction data + parameters: + pstWork --work + return: + *************************************************************************************************/ +void vBackupWork(TWork *pstWork) +{ + FILE *fp = NULL; + char szPath[512]; + + memset(szPath, 0, sizeof(szPath)); + snprintf(szPath, sizeof(szPath), "%s/%s", getenv("TVMDBD"), WORK_ERROR_LOG); + + if(NULL == (fp = fopen(szPath, "ab"))) + return ; + + fwrite(pstWork, FPOS(TWork, m_lOperate) + FLEN(TWork, m_lOperate), 1, fp); + if(OPERATE_UPDATE == pstWork->m_lOperate) + fwrite(pstWork->m_pvNew, pstWork->m_lRowSize, 1, fp); + fwrite(pstWork->m_pvData, pstWork->m_lRowSize, 1, fp); + fclose(fp); +} + +/************************************************************************************************* + description:API - rollback work + parameters: + pstSavm --stvm handle + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lRollbackWork(SATvm *pstSavm) +{ + TWork *pstWork = NULL; + size_t lRow = 0, lErrno = 0; + CMList *pstNode = NULL, *pstList = NULL; + + pstSavm->m_lEffect = 0; + if(!pstSavm || !pstSavm->m_bWork) + { + pstSavm->m_lErrno = WORK_NOT_OPEN; + return RC_FAIL; + } + + // In order to roll back from the tail to the front + for(pstNode = pGetCMTail(pstSavm->m_pstWork); pstNode; ) + { + if(NULL == (pstWork = (TWork *)pstNode->m_psvData)) + { + pstNode = pstNode->pstLast; + continue; + } + + if(RC_SUCC != lInitSATvm(pstSavm, pstWork->m_table)) + { + lErrno = pstSavm->m_lErrno; + vBackupWork(pstWork); + if(pstNode->pstLast) + pstNode->pstLast->pstNext = pstNode->pstNext; + else + pstSavm->m_pstWork = pstNode->pstNext; + + if(pstNode->pstNext) + pstNode->pstNext->pstLast = pstNode->pstLast; + pstList = pstNode; + pstNode = pstNode->pstLast; + if(pstWork) + { + TFree(pstWork->m_pvNew); + TFree(pstWork->m_pvData); + } + TFree(pstList->m_psvData); + TFree(pstList); + continue; + } + + pstSavm->m_bPrew = true; // Transaction is turned on + pstSavm->lSize = pstWork->m_lRowSize; + if(OPERATE_UPDATE == pstWork->m_lOperate) + { + pstSavm->lFind = FIRST_ROW; + pstSavm->pstVoid = (void *)pstWork->m_pvNew; + memcpy(&pstSavm->stCond, &pstWork->m_stUpdt, sizeof(FdCond)); + memcpy(&pstSavm->stUpdt, &pstWork->m_stCond, sizeof(FdCond)); + if(RC_SUCC != lUpdate(pstSavm, (void *)pstWork->m_pvData)) + { + vBackupWork(pstWork); + lErrno = pstSavm->m_lErrno; + } + else + lRow += pstSavm->m_lEffect; + } + else if(OPERATE_DELETE == pstWork->m_lOperate) + { + pstSavm->lFind = FIRST_ROW; + pstSavm->pstVoid = (void *)pstWork->m_pvData; + memcpy(&pstSavm->stCond, &pstWork->m_stCond, sizeof(FdCond)); + if(RC_SUCC != lInsert(pstSavm)) + { + vBackupWork(pstWork); + lErrno = pstSavm->m_lErrno; + } + else + lRow += pstSavm->m_lEffect; + } + else if(OPERATE_INSERT == pstWork->m_lOperate) + { + pstSavm->pstVoid = (void *)pstWork->m_pvData; + memcpy(&pstSavm->stCond, &pstWork->m_stCond, sizeof(FdCond)); + if(RC_SUCC != lDelete(pstSavm)) + { + vBackupWork(pstWork); + lErrno = pstSavm->m_lErrno; + } + else + lRow += pstSavm->m_lEffect; + } + + // delete this node + if(pstNode->pstLast) + pstNode->pstLast->pstNext = pstNode->pstNext; + else + pstSavm->m_pstWork = pstNode->pstNext; + + if(pstNode->pstNext) + pstNode->pstNext->pstLast = pstNode->pstLast; + pstList = pstNode; + pstNode = pstNode->pstLast; + if(pstWork) + { + TFree(pstWork->m_pvNew); + TFree(pstWork->m_pvData); + pstSavm->pstVoid = NULL; + } + TFree(pstList->m_psvData); + TFree(pstList); + } + + pstSavm->lFind = 0; + pstSavm->m_lEffect = lRow; +// pstSavm->m_pstWork = NULL; + pstSavm->m_bPrew = false; // Transaction is turned off + pstSavm->m_lErrno = lErrno; + + return RC_SUCC; +} + +/************************************************************************************************* + description:API - commit work + parameters: + pstSavm --stvm handle + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lCommitWork(SATvm *pstSavm) +{ + TWork *pstWork = NULL; + CMList *pstNode = NULL, *pstList = NULL; + + if(!pstSavm) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + for(pstNode = pstSavm->m_pstWork; pstNode; ) + { + if(NULL == (pstWork = (TWork *)pstNode->m_psvData)) + { + pstNode = pstNode->pstNext; + continue; + } + + if(pstNode->pstLast) + pstNode->pstLast->pstNext = pstNode->pstNext; + else + pstSavm->m_pstWork = pstNode->pstNext; + + if(pstNode->pstNext) + pstNode->pstNext->pstLast = pstNode->pstLast; + pstList = pstNode; + pstNode = pstNode->pstNext; + if(pstWork) + { + TFree(pstWork->m_pvNew); + TFree(pstWork->m_pvData); + } + TFree(pstList->m_psvData); + TFree(pstList); + } +// pstSavm->m_bPrew = false; + + return RC_SUCC; +} + +/************************************************************************************************* + description:Record the transaction + parameters: + pstSavm --stvm handle + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lRecordWork(SATvm *pstSavm, void *pvoData, long lOperate) +{ + TWork stWork; + + // where transaction is on, do not record the transaction itself + if(!pstSavm->m_bWork || pstSavm->m_bPrew) + return RC_SUCC; + + memset(&stWork, 0, sizeof(TWork)); + stWork.m_lOperate = lOperate; + stWork.m_lRowSize = pstSavm->lSize; + stWork.m_table = pstSavm->tblName; + if(NULL == (stWork.m_pvData = (void *)malloc(pstSavm->lSize))) + { + pstSavm->m_lErrno = MALLC_MEM_ERR; + return RC_FAIL; + } + + if(OPERATE_UPDATE == lOperate) + { + if(NULL == (stWork.m_pvNew = (void *)malloc(pstSavm->lSize))) + { + pstSavm->m_lErrno = MALLC_MEM_ERR; + return RC_FAIL; + } + + memcpy(stWork.m_pvNew, pstSavm->pstVoid, pstSavm->lSize); + vCondInsInit(&stWork.m_stUpdt, pstSavm->tblName); + + memcpy(stWork.m_pvData, pvoData, pstSavm->lSize); + memcpy(&stWork.m_stCond, &pstSavm->stUpdt, sizeof(FdCond)); + } + else if(OPERATE_INSERT == lOperate) + { + memcpy(stWork.m_pvData, pvoData, pstSavm->lSize); + vCondInsInit(&stWork.m_stCond, pstSavm->tblName); + } + else + { + memcpy(stWork.m_pvData, pvoData, pstSavm->lSize); + memcpy(&stWork.m_stCond, &pstSavm->stCond, sizeof(FdCond)); + } + + if(NULL == (pstSavm->m_pstWork = pInsertList(pstSavm->m_pstWork, &stWork, sizeof(TWork)))) + return RC_FAIL; + + return RC_SUCC; +} + +/************************************************************************************************* + description:Initialize the second level cache + parameters: + pstSavm --stvm handle + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lInitSvCache(SATvm *pstSavm) +{ + size_t lOut = 0, i; + RunTime *pstRun = NULL; + TIndex *pstIndex = NULL; + + if(!pstSavm) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + if(RC_SUCC != lExportTable(SYS_TVM_INDEX, &lOut, (void *)&pstIndex)) + return RC_FAIL; + + for(i = 0; i < lOut; i ++) + { + pstRun = (RunTime *)pGetRunTime(pstSavm, pstIndex[i].m_table); + pstRun->m_lState = RESOURCE_ABLE; + pstRun->m_shmID = pstIndex[i].m_shmID; + pstRun->m_semID = pstIndex[i].m_semID; + pstRun->m_lLocal = pstIndex[i].m_lLocal; + } + + pstSavm->m_bCache = TRUE; + TFree(pstIndex); + + return RC_SUCC; +} + +/************************************************************************************************* + description:Gets the STVM handle by partition + parameters: + pstSavm --stvm handle + pstTable --table name + pstPart --table part + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +void* pPartSATvm(SATvm *pstSavm, char *pszTable, char *pszPart) +{ + TABLE i; + TIndex stIndex; + RunTime *pstRun = NULL; + + if(!pstSavm) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return NULL; + } + + memset(&stIndex, 0, sizeof(TIndex)); + strncpy(stIndex.m_szPart, pszPart, sizeof(stIndex.m_szPart)); + strncpy(stIndex.m_szTable, pszTable, sizeof(stIndex.m_szTable)); + + pstSavm->bSearch = TYPE_SYSTEM; + conditinit(pstSavm, stIndex, SYS_TVM_INDEX) + stringset(pstSavm, stIndex, m_szPart, pszPart); + stringset(pstSavm, stIndex, m_szTable, pszTable); + if(RC_SUCC != lSelect(pstSavm, (void *)&stIndex)) + { + if(NO_DATA_FOUND == pstSavm->m_lErrno) + pstSavm->m_lErrno = TBL_NOT_FOUND; + return NULL; + } + + pstSavm->pstVoid = NULL; + pstSavm->tblName = stIndex.m_table; + + pstRun = (RunTime *)pGetRunTime(pstSavm, pstSavm->tblName); + pstRun->m_shmID = stIndex.m_shmID; + pstRun->m_semID = stIndex.m_semID; + pstRun->m_lLocal = stIndex.m_lLocal; + return pstSavm; +} + +/************************************************************************************************* + description:Gets the table STVM handle. + parameters: + pstSavm --stvm handle + t --table + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lInitSATvm(SATvm *pstSavm, TABLE t) +{ + TIndex stIndex; + RunTime *pstRun = NULL; + + pstSavm->tblName = t; + pstRun = (RunTime *)pGetRunTime(pstSavm, t); + if(pstRun->m_bAttch && pstRun->m_pvAddr) + return RC_SUCC; + + if(RESOURCE_ABLE == pstRun->m_lState) + { + pstSavm->pstVoid = NULL; + pstSavm->bSearch = TYPE_CLIENT; + return RC_SUCC; + } + + pstSavm->bSearch = TYPE_SYSTEM; + conditinit(pstSavm, stIndex, SYS_TVM_INDEX) + numberset(pstSavm, stIndex, m_table, t) + if(RC_SUCC != lSelect(pstSavm, (void *)&stIndex)) + { + if(NO_DATA_FOUND == pstSavm->m_lErrno) + pstSavm->m_lErrno = TBL_NOT_FOUND; + return RC_FAIL; + } + + pstSavm->tblName = t; + pstSavm->pstVoid = NULL; + strcpy(pstSavm->m_szNode, stIndex.m_szOwner); + + pstRun->m_shmID = stIndex.m_shmID; + pstRun->m_semID = stIndex.m_semID; + pstRun->m_lLocal = stIndex.m_lLocal; + pstRun->m_lRowSize = stIndex.m_lRowSize; + return RC_SUCC; +} + +/************************************************************************************************* + description:Gets the table STVM handle. + parameters: + pstSavm --stvm handle + return: + void* --success + *************************************************************************************************/ +void* pInitSATvm(TABLE t) +{ + SATvm *pstSavm = (SATvm *)pGetSATvm(); + + if(RC_SUCC != lInitSATvm(pstSavm, t)) + return NULL; + + return pstSavm; +} + +/************************************************************************************************* + description:Gets the KEY value for the connection to create the Shared memory + parameters: + pstSavm --stvm handle + return: + tKey + *************************************************************************************************/ +key_t yGetIPCPath(SATvm *pstSavm, Benum em) +{ + key_t tKey = 0; + char szPath[512]; + + memset(szPath, 0, sizeof(szPath)); + snprintf(szPath, sizeof(szPath), "%s", getenv("TVMDBD")); + + if(-1 == (tKey = ftok(szPath, em))) + { + pstSavm->m_lErrno = GENER_KEY_ERR; + return RC_FAIL; + } + + return tKey; +} + +/************************************************************************************************* + description:Connect to Shared memory click test + parameters: + pstSavm --stvm handle + t --table + return: + void* --success + *************************************************************************************************/ +void* pInitHitTest(SATvm *pstSavm, TABLE t) +{ + RunTime *pstRun = (RunTime *)pGetRunTime(pstSavm, t); + + if(RES_REMOT_SID == pstRun->m_lLocal || (pstRun->m_bAttch && pstRun->m_pvAddr)) + return pstRun; + + pstRun->m_pvAddr = (void* )shmat(pstRun->m_shmID, NULL, 0); + if(NULL == pstRun->m_pvAddr || (void *)(-1) == (void *)pstRun->m_pvAddr) + { + if(EACCES == errno) + pstSavm->m_lErrno = SHM_ERR_ACCES; + else if(ENOMEM == errno) + pstSavm->m_lErrno = SHM_ERR_NOMEM; + else + pstSavm->m_lErrno = SHM_ERR_INVAL; + return NULL; + } + + pstSavm->m_lErrno = 0; + pstSavm->m_lEffect= 0; + pstRun->m_bAttch = TRUE; + pstSavm->lSize = lGetRowSize(t); + memcpy((void *)pGetTblDef(t), pstRun->m_pvAddr, sizeof(TblDef)); + + return pstRun; +} + +/************************************************************************************************* + description:Connect to Shared memory + parameters: + pstSavm --stvm handle + t --table + return: + void* --success + *************************************************************************************************/ +void* pInitMemTable(SATvm *pstSavm, TABLE t) +{ + RunTime *pstRun = (RunTime *)pGetRunTime(pstSavm, t); + + if(RES_REMOT_SID == pstRun->m_lLocal) // remote + return pstRun; + + pstSavm->m_lErrno = 0; + pstSavm->m_lEffect = 0; + if(pstRun->m_bAttch && pstRun->m_pvAddr) + { + pstSavm->bSearch = TYPE_CLIENT; + return pstRun; + } + + if(TYPE_SYSTEM == pstSavm->bSearch) + { + pstSavm->bSearch = TYPE_CLIENT; + if(RC_FAIL == (pstSavm->m_yKey = yGetIPCPath(pstSavm, IPC_SHM))) + return NULL; + pstRun->m_shmID = shmget(pstSavm->m_yKey, 0, IPC_CREAT|0600); + + if(pstRun->m_shmID < 0) + { + switch(errno) + { + case EEXIST: + pstSavm->m_lErrno = SHM_ERR_EXIST; + break; + case EIDRM: + pstSavm->m_lErrno = SHM_ERR_EIDRM; + break; + case EACCES: + pstSavm->m_lErrno = SHM_ERR_ACCES; + break; + case ENOMEM: + pstSavm->m_lErrno = SHM_ERR_NOMEM; + break; + default: + pstSavm->m_lErrno = SHM_ERR_INVAL; + break; + } + return NULL; + } + } + + pstRun->m_pvAddr = (void* )shmat(pstRun->m_shmID, NULL, 0); + if(NULL == pstRun->m_pvAddr || (void *)(-1) == (void *)pstRun->m_pvAddr) + { + if(EACCES == errno) + pstSavm->m_lErrno = SHM_ERR_ACCES; + else if(ENOMEM == errno) + pstSavm->m_lErrno = SHM_ERR_NOMEM; + else + pstSavm->m_lErrno = SHM_ERR_INVAL; + return NULL; + } + + pstRun->m_bAttch = TRUE; + + memcpy((void *)pGetTblDef(t), pstRun->m_pvAddr, sizeof(TblDef)); + + if(pstSavm->lSize != lGetRowSize(t)) + { + vTblDisconnect(pstSavm, t); + pstSavm->m_lErrno = VER_NOT_MATCH; + return NULL; + } + + return pstRun; +} + +/************************************************************************************************* + description:Create a memory table space + parameters: + pstSavm --stvm handle + t --table + lSize --The block size + bCreate + return: + void* --success + *************************************************************************************************/ +void* pCreateBlock(SATvm *pstSavm, TABLE t, size_t lSize, bool bCreate) +{ + RunTime *pstRun = NULL; + + if(!pstSavm || lSize <= 0) + { + pstSavm->m_lErrno = BLCK_SIZE_ERR; + return NULL; + } + + pstRun = (RunTime *)pGetRunTime(pstSavm, t); + memset(pstRun, 0, sizeof(RunTime)); + + if(!bCreate) + { + pstSavm->m_yKey = IPC_PRIVATE; + pstSavm->m_ySey = IPC_PRIVATE; + } + else + { + if(RC_FAIL == (pstSavm->m_yKey = yGetIPCPath(pstSavm, IPC_SHM))) + return NULL; + + if(RC_FAIL == (pstSavm->m_ySey = yGetIPCPath(pstSavm, IPC_SEM))) + return NULL; + } + + pstRun->m_shmID = shmget(pstSavm->m_yKey, lSize, IPC_CREAT|IPC_EXCL|0600); + if(pstRun->m_shmID < 0) + { + switch(errno) + { + case EEXIST: + pstSavm->m_lErrno = SHM_ERR_EXIST; + break; + case EIDRM: + pstSavm->m_lErrno = SHM_ERR_EIDRM; + break; + case EACCES: + pstSavm->m_lErrno = SHM_ERR_ACCES; + break; + case ENOMEM: + pstSavm->m_lErrno = SHM_ERR_NOMEM; + break; + default: + pstSavm->m_lErrno = SHM_ERR_INVAL; + break; + } + return NULL; + } + + pstRun->m_pvAddr = (void* )shmat(pstRun->m_shmID, NULL, 0); + if(NULL == pstRun->m_pvAddr || (void *)(-1) == (void *)pstRun->m_pvAddr) + { + if(EACCES == errno) + pstSavm->m_lErrno = SHM_ERR_ACCES; + else if(ENOMEM == errno) + pstSavm->m_lErrno = SHM_ERR_NOMEM; + else + pstSavm->m_lErrno = SHM_ERR_INVAL; + return NULL; + } + +// memset(pstRun->m_pvAddr, 0, lSize); + pstRun->m_bAttch = TRUE; + + return pstRun; +} + +/************************************************************************************************* + description:add New index field + parameters: + t --table + type --type + from --from position + len --length + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lAddIdxField(TABLE t, long type, long lFrom, long lLen, long lAttr) +{ + long lIdx = 0; + TblKey *pstKey = NULL; + SATvm *pstSavm = (SATvm *)pGetSATvm(); + + if(UNQIUE == type) + { + for(lIdx = 0, pstKey = pGetTblIdx(t); lIdx < lGetIdxNum(t); lIdx++) + { + if((pstKey[lIdx].m_lFrom == lFrom) && pstKey[lIdx].m_lLen == lLen) + return RC_SUCC; + } + + if(MAX_FILED_IDX <= lGetIdxNum(t)) + { + pstSavm->m_lErrno = IDX_DEF_SPILL; + return RC_FAIL; + } + + ((TblDef *)pGetTblDef(t))->m_lIdxLen += lLen; + if(MAX_INDEX_LEN < (((TblDef *)pGetTblDef(t))->m_lIdxLen)) + { + pstSavm->m_lErrno = IDX_LEN_SPILL; + return RC_FAIL; + } + + pstKey[lGetIdxNum(t)].m_lFrom = lFrom; + pstKey[lGetIdxNum(t)].m_lLen = lLen; + pstKey[lGetIdxNum(t)].m_lAttr = lAttr; + ((TblDef *)pGetTblDef(t))->m_lIdxUp ++; + ((TblDef *)pGetTblDef(t))->m_lIType |= type; + + return RC_SUCC; + } + else if(NORMAL == type || HASHID == type) + { + for(lIdx = 0, pstKey = pGetTblGrp(t); lIdx < lGetGrpNum(t); lIdx++) + { + if((pstKey[lIdx].m_lFrom == lFrom) && pstKey[lIdx].m_lLen == lLen) + return RC_SUCC; + } + + if(MAX_FILED_IDX <= lGetGrpNum(t)) + { + pstSavm->m_lErrno = GRP_DEF_SPILL; + return RC_FAIL; + } + + ((TblDef *)pGetTblDef(t))->m_lGrpLen += lLen; + if(MAX_INDEX_LEN < (((TblDef *)pGetTblDef(t))->m_lGrpLen)) + { + pstSavm->m_lErrno = GRP_LEN_SPILL; + return RC_FAIL; + } + + pstKey[lGetGrpNum(t)].m_lFrom = lFrom; + pstKey[lGetGrpNum(t)].m_lLen = lLen; + pstKey[lGetGrpNum(t)].m_lAttr = lAttr; + ((TblDef *)pGetTblDef(t))->m_lGrpUp ++; + ((TblDef *)pGetTblDef(t))->m_lIType |= type; + + return RC_SUCC; + } + + pstSavm->m_lErrno = IDX_TYP_NODEF; + + return RC_FAIL; +} + +/************************************************************************************************* + description:set index field + parameters: + t --table + type --type + from --from position + len --length + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lSetTableIdx(TABLE t, long lFrom, long lLen, char *pszDesc, long lAttr, long lType) +{ + long lIdx = 0; + SATvm *pstSavm = (SATvm *)pGetSATvm(); + TblKey *pstKey = (TblKey *)pGetTblKey(t); + + for(lIdx = 0; lIdx < lGetFldNum(t); lIdx ++) + { + if((pstKey[lIdx].m_lFrom == lFrom) && pstKey[lIdx].m_lLen == lLen) + return RC_SUCC; + } + + if(MAX_FILED_NUM <= lGetFldNum(t)) + { + pstSavm->m_lErrno = FLD_DEF_SPILL; + return RC_FAIL; + } + + pstKey[lGetFldNum(t)].m_lFrom = lFrom; + pstKey[lGetFldNum(t)].m_lLen = lLen; + pstKey[lGetFldNum(t)].m_lAttr = lAttr; + pstKey[lGetFldNum(t)].m_lIsPk = lType; + strncpy(pstKey[lGetFldNum(t)].m_szField, pszDesc, sizeof(pstKey[lGetFldNum(t)].m_szField)); + ((TblDef *)pGetTblDef(t))->m_lIdxNum ++; + + return RC_SUCC; +} + +/************************************************************************************************* + description:find filed key + parameters: + pstIdx --field list + lNum --number + pszField --field name + return: + TblKey* + *************************************************************************************************/ +TblKey* pFindField(TblKey *pstIdx, long lNum, char *pszField) +{ + register int i; + + for(i = 0; i < lNum; i ++) + { + if(!strcmp(pstIdx[i].m_szField, pszField)) + return &pstIdx[i]; + } + + return NULL; +} + +/************************************************************************************************* + description:insert table field + parameters: + pstSavm --stvm handle + t --table + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lInsertField(SATvm *pstSavm, TABLE t) +{ + TField stField; + long i, lIdx = lGetFldNum(t); + TblKey *pstIdx = pGetTblKey(t); + + if(NULL == (pstSavm = (SATvm *)pInitSATvm(SYS_TVM_FIELD))) + return RC_FAIL; + + insertinit(pstSavm, stField, SYS_TVM_FIELD) + for(i = 0; i < lIdx; i ++) + { + memset(&stField, 0, sizeof(TField)); + stField.m_table = t; + stField.m_lSeq = i + 1; + stField.m_lAttr = pstIdx[i].m_lAttr; + stField.m_lFrom = pstIdx[i].m_lFrom; + stField.m_lLen = pstIdx[i].m_lLen; + stField.m_lIsPk = pstIdx[i].m_lIsPk; + strncpy(stField.m_szOwner, TVM_NODE_INFO, sizeof(stField.m_szOwner)); + strncpy(stField.m_szTable, sGetTableName(t), sizeof(stField.m_szTable)); + strncpy(stField.m_szField, pstIdx[i].m_szField, sizeof(stField.m_szField)); + + if(RC_SUCC != lInsert(pstSavm)) + return RC_FAIL; + } + + return RC_SUCC; +} + +/************************************************************************************************* + description:Merge valid data to update fields + parameters: + pstSavm --stvm handle + s + p + eType + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lMergeTruck(SATvm *pstSavm, FdCond *pstCond, char *p, char *pvData) +{ + register int i = 0; + FdKey *pFdKey; + + if(0 == pstCond->uFldcmp) + { + pstSavm->m_lErrno = UPDFD_NOT_SET; + return RC_FAIL; + } + + for(i = 0; i < pstCond->uFldcmp; i ++) + { + pFdKey = &pstCond->stFdKey[i]; + memcpy(pvData + pFdKey->uFldpos, p + pFdKey->uFldpos, pFdKey->uFldlen); + } +} + +/************************************************************************************************* + description:Returns the record of the extremum field + parameters: + s --original date + p --records to be compared + pstKey --field key + eType --MATCH_MAX or MATCH_MIN + return: + void* + *************************************************************************************************/ +void* pvCompExtrem(void *s, void *p, TblKey *pstKey, Uenum eType) +{ + if(!p) return s; + + if(eType & MATCH_MAX) + { + switch(pstKey->m_lAttr) + { + case FIELD_DOUB: + switch(pstKey->m_lLen) + { + case 4: + if(*((float *)(p + pstKey->m_lFrom)) < *((float *)(s + pstKey->m_lFrom))) + return s; + return p; + case 8: + if(*((double *)(p + pstKey->m_lFrom)) < *((double *)(s + pstKey->m_lFrom))) + return s; + return p; + default: + return p; + } + return p; + case FIELD_LONG: + switch(pstKey->m_lLen) + { + case 2: + if(*((sint *)(p + pstKey->m_lFrom)) < *((sint *)(s + pstKey->m_lFrom))) + return s; + return p; + case 4: + if(*((int *)(p + pstKey->m_lFrom)) < *((int *)(s + pstKey->m_lFrom))) + return s; + return p; + case 8: + if(*((llong *)(p + pstKey->m_lFrom)) < *((llong *)(s + pstKey->m_lFrom))) + return s; + return p; + default: + return p; + } + return p; + case FIELD_CHAR: + if(0 < memcmp(s + pstKey->m_lFrom, p + pstKey->m_lFrom, pstKey->m_lLen)) + return s; + return p; + default: + return p; + } + } + else + { + switch(pstKey->m_lAttr) + { + case FIELD_DOUB: + switch(pstKey->m_lLen) + { + case 4: + if(*((float *)(p + pstKey->m_lFrom)) < *((float *)(s + pstKey->m_lFrom))) + return p; + return s; + case 8: + if(*((double *)(p + pstKey->m_lFrom)) < *((double *)(s + pstKey->m_lFrom))) + return p; + return s; + default: + return p; + } + return p; + case FIELD_LONG: + switch(pstKey->m_lLen) + { + case 2: + if(*((sint *)(p + pstKey->m_lFrom)) < *((sint *)(s + pstKey->m_lFrom))) + return p; + return s; + case 4: + if(*((int *)(p + pstKey->m_lFrom)) < *((int *)(s + pstKey->m_lFrom))) + return p; + return s; + case 8: + if(*((llong *)(p + pstKey->m_lFrom)) < *((llong *)(s + pstKey->m_lFrom))) + return p; + return s; + default: + return p; + } + return p; + case FIELD_CHAR: + if(0 < memcmp(s + pstKey->m_lFrom, p + pstKey->m_lFrom, pstKey->m_lLen)) + return p; + return s; + default: + return p; + } + } + + return p; +} + +/************************************************************************************************* + description:Match table field values + parameters: + pstCon --condit field + s --original date + p --records to be compared + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lFeildMatch(FdCond *pstCond, void *s, void *p) +{ + register int i; + FdKey *pFdKey; + + if(!p) return RC_MATCH; + + for(i = 0; i < pstCond->uFldcmp; i ++) + { + pFdKey = &pstCond->stFdKey[i]; + if(memcmp(s + pFdKey->uFldpos, p + pFdKey->uFldpos, pFdKey->uFldlen)) + return RC_MISMA; + } + + return RC_MATCH; +} + +/************************************************************************************************* + description:Gets the index group space size + parameters: + lRow --rows + return: + size_t + *************************************************************************************************/ +size_t lGetGroupTruck(size_t lRow, size_t *plOfs) +{ + *plOfs = sizeof(SHTree) * lRow; + return (sizeof(SHTree) + sizeof(SHList)) * lRow; +} + +/************************************************************************************************* + description:Gets the tree node space size + parameters: + rows + return: + size_t + *************************************************************************************************/ +size_t lGetTreeTruck(size_t lRow) +{ + return sizeof(SHTree) * lRow; +} + +/************************************************************************************************* + description:insert table field + parameters: + pstSavm --stvm handle + row --row + return: + size_t + *************************************************************************************************/ +size_t lInitialTable(TABLE t, size_t lRow) +{ + size_t lSize = sizeof(TblDef), lIdxOfs = 0; + + g_stTblDef[t].m_lMaxRow = lRow; + + // set NIL + g_stTblDef[t].m_lNodeNil = FPOS(TblDef, m_stNil); + memset(&g_stTblDef[t].m_stNil, 0, sizeof(SHTree)); + g_stTblDef[t].m_stNil.m_eColor = COLOR_BLK; + g_stTblDef[t].m_stNil.m_lSePos = g_stTblDef[t].m_lNodeNil; + + if(HAVE_UNIQ_IDX(t)) + { + g_stTblDef[t].m_lTreePos = lSize; + g_stTblDef[t].m_lTreeRoot = lSize; + lSize += lGetTreeTruck(lRow); + } + else + { + g_stTblDef[t].m_lTreePos = 0; + g_stTblDef[t].m_lTreeRoot = 0; + } + + if(HAVE_NORL_IDX(t) || HAVE_HASH_IDX(t)) + { + g_stTblDef[t].m_lGroupPos = lSize; + g_stTblDef[t].m_lGroupRoot = lSize; + lSize += lGetGroupTruck(lRow, &g_stTblDef[t].m_lListPos); + g_stTblDef[t].m_lListOfs = g_stTblDef[t].m_lGroupPos + g_stTblDef[t].m_lListPos; + } + else + { + g_stTblDef[t].m_lListPos = 0; + g_stTblDef[t].m_lListOfs = 0; + g_stTblDef[t].m_lGroupPos = 0; + g_stTblDef[t].m_lGroupRoot= 0; + } + + g_stTblDef[t].m_lData = lSize; + lSize += g_stTblDef[t].m_lTruck * lRow; + + return lSize; +} + +/************************************************************************************************* + description:count list + parameters: + pvAddr --Adress + pstList --SHList + return: + size_t + *************************************************************************************************/ +size_t lGetListCount(void *pvAddr, SHList *pstList) +{ + size_t lCount; + + if(!pstList || SELF_POS_UNUSE == pstList->m_lPos) + return 0; + + for(lCount = 1; SELF_POS_UNUSE != pstList->m_lNext; + pstList = (SHList *)pGetNode(pvAddr, pstList->m_lNext)) + ++ lCount; + + return lCount; +} + +/************************************************************************************************* + description:Initialize the index group + parameters: + pvData --address + t --table + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lInitailGroup(SATvm *pstSavm, void *pvData, TABLE t) +{ + long lRow = 0; + void *psData = NULL; + SHTree *pstTree = NULL; + SHList *pstList = NULL; + + if(!pvData) + { + pstSavm->m_lErrno = SHMT_NOT_INIT; + return RC_FAIL; + } + + if(lGetGrpNum(t) <= 0) return RC_SUCC; + + for(psData = pvData + lGetListPos(t); lRow < lGetTblRow(t); lRow ++) + { + pstTree = (SHTree *)(pvData + lRow * sizeof(SHTree)); + memset(pstTree, 0, sizeof(SHTree)); + pstTree->m_lSePos = SELF_POS_UNUSE; + pstTree->m_lData = SELF_POS_UNUSE; + + pstList = (SHList *)(psData + lRow * sizeof(SHList)); + pstList->m_lPos = SELF_POS_UNUSE; + pstList->m_lNode = SELF_POS_UNUSE; + pstList->m_lData = lGetTblData(t) + lGetRowTruck(t) * lRow; + pstList->m_lNext = SELF_POS_UNUSE; + pstList->m_lLast = SELF_POS_UNUSE; + } + ((TblDef *)pGetTblDef(t))->m_lGroupRoot = lGetGrpPos(t); + + return RC_SUCC; +} + +/************************************************************************************************* + description:Initialize the index tree + parameters: + pstSavm --stvm handle + pvData --address + t --table + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lInitailTree(SATvm *pstSavm, void *pvData, TABLE t) +{ + long lRow = 0; + SHTree *pstTree = NULL; + + if(!pvData) + { + pstSavm->m_lErrno = SHMT_NOT_INIT; + return RC_FAIL; + } + + if(lGetIdxNum(t) <= 0) return RC_SUCC; + + for(lRow = 0; lRow < lGetTblRow(t); lRow ++) + { + pstTree = (SHTree *)(pvData + lRow * sizeof(SHTree)); + memset(pstTree, 0, sizeof(SHTree)); + pstTree->m_lSePos = SELF_POS_UNUSE; + pstTree->m_lData = lGetTblData(t) + lGetRowTruck(t) * lRow; + } + ((TblDef *)pGetTblDef(t))->m_lTreeRoot = lGetIdxPos(t); + + return RC_SUCC; +} + +/************************************************************************************************* + description:Calculate the hash value + parameters: + s --key + n --length + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +uint uGetHash(char *s, long n) +{ + uint hash = 0; + static uint i, seed = 131; + + for(i = 0; i < n; i ++) + hash = hash * seed + (*s++); + + return (hash & 0x7FFFFFFF); +} + +/************************************************************************************************* + description:Gets the address of the offset + parameters: + lOffset --key + return: + void* + *************************************************************************************************/ +void* pGetNode(void *pvData, size_t lOffset) +{ + return (void *)(pvData + lOffset); +} + +/************************************************************************************************* + description:Create node + parameters: + pvData --address + t --length + lOffset --offset address + return: + SHTree* + *************************************************************************************************/ +SHTree* pCreateNode(void *pvData, TABLE t, size_t lOffset) +{ + return (SHTree *)(pvData + lOffset); +} + +/************************************************************************************************* + description:Create index node + parameters: + pvData --address memory + t --table + pstGroup --tree node + lGroup --Group offset + ppstTruck --Data truck + return: + SHTree* + *************************************************************************************************/ +SHTree* pCreateGroup(void *pvData, TABLE t, SHTree *pstGroup, size_t lGroup, SHTruck **ppstTruck) +{ + size_t lOffset = 0; + SHList *pstList = NULL, *pstNode = NULL; + + if(!pstGroup) pstGroup = (SHTree *)(pvData + lGroup); + lOffset = lGetListOfs(t) + sizeof(SHList) * ((TblDef *)pvData)->m_lValid; + pstList = (SHList *)pGetNode(pvData, lOffset); + pstList->m_lPos = lOffset; + *ppstTruck = (PSHTruck)pGetNode(pvData, pstList->m_lData); + + if(pstGroup->m_lData == SELF_POS_UNUSE) + { + pstList->m_lNode = lGroup; + pstGroup->m_lData = pstList->m_lPos; + } + else + { + pstNode = (SHList *)pGetNode(pvData, pstGroup->m_lData); + +#if 0 + pstList->m_lNext = pstNode->m_lNext; + pstList->m_lLast = pstNode->m_lPos; + if(SELF_POS_UNUSE != pstNode->m_lNext) + ((SHList *)pGetNode(pvData, pstNode->m_lNext))->m_lLast = pstList->m_lPos; + pstNode->m_lNext = pstList->m_lPos; +#else + pstGroup->m_lData = pstList->m_lPos; + pstList->m_lNode = pstGroup->m_lSePos; + pstList->m_lNext = pstNode->m_lPos; + pstNode->m_lLast = pstList->m_lPos; +#endif + } + + return pstGroup; +} + +/************************************************************************************************* + description:reset data list + parameters: + pvData --address memory + t --table + pstTree --tree node + plOut + return: + *************************************************************************************************/ +void vResetList(void *pvData, TABLE t, SHTree *pstTree, long *plOut) +{ + size_t lOffset, lNext; + SHList *pstList = NULL, *pstTail = NULL; + + + return ; +#if 0 + if(pstTree->m_lData <= SELF_POS_UNUSE) + return ; + +fprintf(stderr, "vResetList error \n"); +exit(-1); + + lOffset = lGetListOfs(t) + lGetTblValid(t) * sizeof(SHList); + // 将链表中的数据向前移动,将后面空间释放出来待下次使用, 同时 g_lTreeNode 个数减一 + for(pstList = (SHList *)pGetNode(pvData, pstTree->m_lData); SELF_POS_UNUSE != pstList->m_lPos; + (*plOut) ++, pstList = (SHList *)pGetNode(pvData, lNext)) + { + lNext = pstList->m_lNext; + + lOffset -= sizeof(SHList); + pstTail = (SHList *)pGetNode(pvData, lOffset); + if(pstList == pstTail) + { + pstTail->m_lPos = SELF_POS_UNUSE; + pstTail->m_lNode = SELF_POS_UNUSE; + pstTail->m_lNext = SELF_POS_UNUSE; + pstTail->m_lLast = SELF_POS_UNUSE; + if(SELF_POS_UNUSE == lNext) break; + continue; + } + + if(SELF_POS_UNUSE != pstTail->m_lLast) + ((SHList *)pGetNode(pvData, pstTail->m_lLast))->m_lNext = pstList->m_lPos; + memcpy(pstList, pstTail, sizeof(SHList)); + pstTail->m_lPos = SELF_POS_UNUSE; + pstTail->m_lNode = SELF_POS_UNUSE; + pstTail->m_lNext = SELF_POS_UNUSE; + pstTail->m_lLast = SELF_POS_UNUSE; + if(SELF_POS_UNUSE == lNext) break; + } +#endif + + pstTree->m_lData = SELF_POS_UNUSE; +} + +/************************************************************************************************* + description:Release the deleted node + parameters: + pstSavm --stvm handle + pvData --address memory + pstRoot --tree root + pstTree --tree node + pstSon --child node + return: + SHTree* + *************************************************************************************************/ +SHTree* pReleaseNode(void *pvData, TABLE t, SHTree *pstRoot, SHTree *pstTree, SHTree **ppstSon) +{ + size_t lSePos = 0, lData, lVaild; + SHTree *pstTail = NULL, *pstNode = NULL; + + if(!pstTree || ((TblDef *)pvData)->m_lValid < 1) + return pstRoot; + + lData = pstTree->m_lData; // backup lData + lVaild = ((TblDef *)pvData)->m_lValid - 1; + pstTail = (SHTree *)(pvData + lGetIdxPos(t) + lVaild * sizeof(SHTree)); + if(pstTail == pstTree) // The tail node is exactly deleted + { + memset(pstTail, 0, sizeof(SHTree)); + pstTail->m_lData = lData; + return pstRoot; + } + + if(ppstSon) + { + if(*ppstSon == pstTail) // move Son(tail) node + *ppstSon = pstTree; + else if(pstTree->m_lParent == pstTail->m_lSePos) + ((SHTree *)*ppstSon)->m_lParent = pstTree->m_lSePos; + } + + lSePos = pstTail->m_lSePos; // backup lSePos + pstTail->m_lSePos = pstTree->m_lSePos; + memcpy((void *)pstTree, (void *)pstTail, sizeof(SHTree)); + memset(pstTail, 0, sizeof(SHTree)); + pstTail->m_lData = lData; + + // modify parent and child node + if(NODE_NULL != pstTree->m_lParent) + { + pstNode = (SHTree *)pGetNode(pvData, pstTree->m_lParent); + if(lSePos == pstNode->m_lLeft) + pstNode->m_lLeft = pstTree->m_lSePos; + else + pstNode->m_lRight = pstTree->m_lSePos; + } + else // May be the tail of the root moved + { + pstRoot = pstTree; + } + + if(NODE_NULL != pstTree->m_lLeft) + { + pstNode = (SHTree *)pGetNode(pvData, pstTree->m_lLeft); + pstNode->m_lParent = pstTree->m_lSePos; + } + + if(NODE_NULL != pstTree->m_lRight) + { + pstNode = (SHTree *)pGetNode(pvData, pstTree->m_lRight); + pstNode->m_lParent = pstTree->m_lSePos; + } + + return pstRoot; +} + +/************************************************************************************************* + description:Release deleted data block space + parameters: + pvAddr --address memory + t --table + pstTruck --Data truck + bErase --erase + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lReleaseTruck(void *pvAddr, TABLE t, SHTruck *pstTruck, bool bErase) +{ + size_t lOffset = 0; + SHTruck *pstTail = NULL; + + if(bErase) + { + memset(pstTruck, 0, lGetRowTruck(t)); + return RC_SUCC; + } + + if(((TblDef *)pvAddr)->m_lValid < 1) + return RC_SUCC; + + lOffset = lGetTblData(t) + lGetRowTruck(t) * (((TblDef *)pvAddr)->m_lValid - 1); + pstTail = (PSHTruck)pGetNode(pvAddr, lOffset); + if(pstTruck == pstTail) + { + memset(pstTail, 0, lGetRowTruck(t)); + return RC_SUCC; + } + + memcpy(pstTruck, pstTail, lGetRowTruck(t)); + memset(pstTail, 0, lGetRowTruck(t)); + + return RC_SUCC; +} + +/************************************************************************************************* + description:Release index node + parameters: + pvData --address memory + t --table + pstRoot --tree root + pstTree --tree node + pstSon --child node + plOut + return: + SHTree* + *************************************************************************************************/ +SHTree* pReleaseGroup(void *pvData, TABLE t, SHTree *pstRoot, SHTree *pstTree, SHTree **ppstSon, + long *plOut) +{ + size_t lSePos = 0, lVaild; + SHTree *pstTail = NULL, *pstNode = NULL; + + if(!pstTree || ((TblDef *)pvData)->m_lGroup < 1) + return pstRoot; + +// vResetList(pvData, t, pstTree, plOut); + + lVaild = -- ((TblDef *)pvData)->m_lGroup; + pstTail = (SHTree *)(pvData + lGetGrpPos(t) + lVaild * sizeof(SHTree)); + if(pstTail == pstTree) + { + memset(pstTail, 0, sizeof(SHTree)); + return pstRoot; + } + + if(ppstSon) + { + if(*ppstSon == pstTail) // move Son(tail) node + *ppstSon = pstTree; + else if(pstTree->m_lParent == pstTail->m_lSePos) + ((SHTree *)*ppstSon)->m_lParent = pstTree->m_lSePos; + } + + lSePos = pstTail->m_lSePos; // backup SePos + pstTail->m_lSePos = pstTree->m_lSePos; + memcpy((void *)pstTree, (void *)pstTail, sizeof(SHTree)); + memset(pstTail, 0, sizeof(SHTree)); + ((SHList *)pGetNode(pvData, pstTree->m_lData))->m_lNode = pstTree->m_lSePos; + + if(NODE_NULL != pstTree->m_lParent) + { + pstNode = (SHTree *)pGetNode(pvData, pstTree->m_lParent); + if(lSePos == pstNode->m_lLeft) + pstNode->m_lLeft = pstTree->m_lSePos; + else + pstNode->m_lRight = pstTree->m_lSePos; + } + else + { + pstRoot = pstTree; + } + + if(NODE_NULL != pstTree->m_lLeft) + { + pstNode = (SHTree *)pGetNode(pvData, pstTree->m_lLeft); + pstNode->m_lParent = pstTree->m_lSePos; + } + + if(NODE_NULL != pstTree->m_lRight) + { + pstNode = (SHTree *)pGetNode(pvData, pstTree->m_lRight); + pstNode->m_lParent = pstTree->m_lSePos; + } + + return pstRoot; +} + +/************************************************************************************************* + description:Release list node + parameters: + pvData --address memory + t --table + pstTree --tree node + pstList --data list + lOffset --Data offset + plNext --lNext offset + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lReleaseList(void *pvData, TABLE t, SHTree *pstTree, SHList *pstList, size_t lOffset, + size_t *plNext) +{ + size_t lData; + SHList *pstTail = NULL; + + pstTail = (SHList *)pGetNode(pvData, lOffset); + if(SELF_POS_UNUSE == pstTail->m_lPos) + return RC_FAIL; + + if(pstTree->m_lData == pstList->m_lPos) + { + pstTree->m_lData = pstList->m_lNext; + if(SELF_POS_UNUSE != pstList->m_lNext) + { + ((SHList *)pGetNode(pvData, pstList->m_lNext))->m_lLast = SELF_POS_UNUSE; + ((SHList *)pGetNode(pvData, pstList->m_lNext))->m_lNode = pstTree->m_lSePos; + } + } + else + { + ((SHList *)pGetNode(pvData, pstList->m_lLast))->m_lNext = pstList->m_lNext; + if(SELF_POS_UNUSE != pstList->m_lNext) + ((SHList *)pGetNode(pvData, pstList->m_lNext))->m_lLast = pstList->m_lLast; + } + + if(pstTail == pstList) + { + // save lData + pstList->m_lPos = SELF_POS_UNUSE; + pstList->m_lNode = SELF_POS_UNUSE; + pstList->m_lNext = SELF_POS_UNUSE; + pstList->m_lLast = SELF_POS_UNUSE; + return RC_SUCC; + } + + // If the pstTail node is the next scan node + if(pstTail->m_lPos == pstList->m_lNext) + *plNext = pstList->m_lPos; + + lData = pstList->m_lData; + if(pstTail->m_lPos == pstTree->m_lData) + pstTree->m_lData = pstList->m_lPos; + else + { + if(SELF_POS_UNUSE == pstTail->m_lLast) + ((SHTree *)pGetNode(pvData, pstTail->m_lNode))->m_lData = pstList->m_lPos; + } + + if(SELF_POS_UNUSE != pstTail->m_lLast) + ((SHList *)pGetNode(pvData, pstTail->m_lLast))->m_lNext = pstList->m_lPos; + if(SELF_POS_UNUSE != pstTail->m_lNext) + ((SHList *)pGetNode(pvData, pstTail->m_lNext))->m_lLast = pstList->m_lPos; + + pstList->m_lNode = pstTail->m_lNode; + pstList->m_lNext = pstTail->m_lNext; + pstList->m_lData = pstTail->m_lData; + pstList->m_lLast = pstTail->m_lLast; + + pstTail->m_lData = lData; + pstTail->m_lPos = SELF_POS_UNUSE; + pstTail->m_lNode = SELF_POS_UNUSE; + pstTail->m_lNext = SELF_POS_UNUSE; + pstTail->m_lLast = SELF_POS_UNUSE; + + return RC_SUCC; +} + +/************************************************************************************************* + description:Left-Rotate the red-black tree node (pstTree) + parameters: + pvData --address memory + pstRoot --tree root + pstTree --tree node + return: + SHTree* + + Schematic: + root root + / / + tree node + / \ --(L--R)--> / \ # + lA node tree rC + / \ / \ + lB rC lA lB + *************************************************************************************************/ +SHTree* _pLeftRotation(void *pvData, SHTree *pstRoot, SHTree *pstTree) +{ + SHTree *pstCur = NULL, *pstNode = (SHTree *)pGetNode(pvData, pstTree->m_lRight); + + // set "pstNode's left child" as "pstTree's right child" + // if the "pstNode's left is not null", set "pstTree" as father of the left child of pstNode + pstTree->m_lRight = pstNode->m_lLeft; + if(NODE_NULL != pstNode->m_lLeft) + { + pstCur = (SHTree *)pGetNode(pvData, pstNode->m_lLeft); + pstCur->m_lParent = pstTree->m_lSePos; + } + + // Set "pstTree's father" as "pstNode's father" + pstNode->m_lParent = pstTree->m_lParent; + + if(NODE_NULL == pstTree->m_lParent) + pstRoot = pstNode; // create new Root + else + { + pstCur = (SHTree *)pGetNode(pvData, pstTree->m_lParent); + if(pstCur->m_lLeft == pstTree->m_lSePos) + pstCur->m_lLeft = pstNode->m_lSePos; + else + pstCur->m_lRight = pstNode->m_lSePos; + } + + // set "pstTree" as "pstNode's left child" + pstNode->m_lLeft = pstTree->m_lSePos; + + // set "pstTree's father" as "pstNode” + pstTree->m_lParent = pstNode->m_lSePos; + + return pstRoot; +} + +/************************************************************************************************* + description:Right-Rotate the red-black tree node (pstTree) + parameters: + pvData --address memory + pstRoot --tree root + pstTree --tree node + return: + SHTree* + + Schematic: + root root + / / + tree node + / \ --(R--R)--> / \ # + node rC lA tree + / \ / \ # + lA rB rB rC + *************************************************************************************************/ +SHTree* _pRightRotation(void *pvData, SHTree *pstRoot, SHTree *pstTree) +{ + SHTree *pstCur = NULL, *pstNode = (SHTree *)pGetNode(pvData, pstTree->m_lLeft); + + // set "pstNode's right child" as "pstTree's left child" + // if the "pstNode's right is not null, set "pstTree" as father of the right child of pstNode + pstTree->m_lLeft = pstNode->m_lRight; + if(NODE_NULL != pstNode->m_lRight) + { + pstCur = (SHTree *)pGetNode(pvData, pstNode->m_lRight); + pstCur->m_lParent = pstTree->m_lSePos; + } + + // set "pstTree's parent" as "pstNode's parent" + pstNode->m_lParent = pstTree->m_lParent; + if(NODE_NULL == pstTree->m_lParent) + pstRoot = pstNode; + else + { + pstCur = (SHTree *)pGetNode(pvData, pstTree->m_lParent); + if(pstCur->m_lLeft == pstTree->m_lSePos) + pstCur->m_lLeft = pstNode->m_lSePos; + else + pstCur->m_lRight = pstNode->m_lSePos; + } + + // set "pstTree" as "pstNode's right child" + pstNode->m_lRight = pstTree->m_lSePos; + // set "pstTree's parent as "pstNode" + pstTree->m_lParent = pstNode->m_lSePos; + + return pstRoot; +} + +/************************************************************************************************* + description:Get extreme values in RBTree traversal + parameters: + uEnum + pvData --addree memory + pstTree --tree node + return: + SHTree* + *************************************************************************************************/ +SHTree* pExtremeTree(Uenum uEnum, void *pvData, SHTree *pstTree) +{ + if(SELF_POS_UNUSE == pstTree->m_lSePos || NODE_NULL == pstTree->m_lSePos) + return NULL; + + if(uEnum & MATCH_MAX) + { + while(SELF_POS_UNUSE != pstTree->m_lRight && NODE_NULL != pstTree->m_lRight) + pstTree = (SHTree *)pGetNode(pvData, pstTree->m_lRight); + } + else + { + while(SELF_POS_UNUSE != pstTree->m_lLeft && NODE_NULL != pstTree->m_lLeft) + pstTree = (SHTree *)pGetNode(pvData, pstTree->m_lLeft); + } + + if(SELF_POS_UNUSE == pstTree->m_lSePos && NODE_NULL == pstTree->m_lSePos) + pstTree = NULL; + + return pstTree; +} + +/************************************************************************************************* + description:Specify the KEY value in the RBTree traversal + parameters: + pvData --addree memory + psTree --tree node + psvIdx --index value + lIdx --value length + return: + SHTree* + *************************************************************************************************/ +SHTree* pSearchTree(void *pvData, SHTree *pstTree, void *psvIdx, long lIdx) +{ + if(SELF_POS_UNUSE == pstTree->m_lSePos || NODE_NULL == pstTree->m_lSePos) + return NULL; + + if(!memcmp(pstTree->m_szIdx, psvIdx, lIdx)) + return pstTree; + + if(0 < memcmp(pstTree->m_szIdx, psvIdx, lIdx)) + return pSearchTree(pvData, (SHTree *)pGetNode(pvData, pstTree->m_lLeft), psvIdx, lIdx); + else + return pSearchTree(pvData, (SHTree *)pGetNode(pvData, pstTree->m_lRight), psvIdx, lIdx); +} + +/************************************************************************************************* + description:Gets a list of data sets + parameters: + pvData --addree memory + psTree --tree node + psvIdx --index value + lIdx --value length + return: + SHList* + *************************************************************************************************/ +SHList *pSearchGroup(void *pvData, SHTree *pstTree, void *psvIdx, long lIdx) +{ + if(NULL == (pstTree = pSearchTree(pvData, pstTree, psvIdx, lIdx))) + return NULL; + + // If the group information exists in an abnormal situation, + // but there are numerous references, then the group should be deleted. + if(SELF_POS_UNUSE == pstTree->m_lData) + return NULL; + + return (SHList *)pGetNode(pvData, pstTree->m_lData); +} + +/************************************************************************************************* + description:Restore the new RBTree imbalance problem + parameters: + pvData --addree memory + pstRoot --root node + pstCur --tree node + return: + SHTree* + *************************************************************************************************/ +SHTree* _pFixupInsert(void *pvData, SHTree *pstRoot, SHTree *pstCur) +{ + SHTree *pstParent = NULL, *pstUncle = NULL, *pstGrand = NULL; + + while((pstParent = (SHTree *)pGetNode(pvData, pstCur->m_lParent)) && IS_RED(pstParent)) + { + pstGrand = (SHTree *)pGetNode(pvData, pstParent->m_lParent); + if(pstParent->m_lSePos == pstGrand->m_lLeft) + { + pstUncle = (SHTree *)pGetNode(pvData, pstGrand->m_lRight); + if((NODE_NULL != pstUncle->m_lSePos) && IS_RED(pstUncle)) + { + pstUncle->m_eColor = COLOR_BLK; + pstParent->m_eColor = COLOR_BLK; + pstGrand->m_eColor = COLOR_RED; + pstCur = pstGrand; + continue; + } + + if(pstCur->m_lSePos == pstParent->m_lRight) + { + pstRoot = _pLeftRotation(pvData, pstRoot, pstParent); + pstParent = pstCur; + } + + pstParent->m_eColor = COLOR_BLK; + pstGrand->m_eColor = COLOR_RED; + pstRoot = _pRightRotation(pvData, pstRoot, pstGrand); + } + else + { + pstUncle = (SHTree *)pGetNode(pvData, pstGrand->m_lLeft); + if((NODE_NULL != pstUncle->m_lSePos) && IS_RED(pstUncle)) + { + pstUncle->m_eColor = COLOR_BLK; + pstParent->m_eColor = COLOR_BLK; + pstGrand->m_eColor = COLOR_RED; + pstCur = pstGrand; + continue; + } + + if(pstCur->m_lSePos == pstParent->m_lLeft) + { + pstRoot = _pRightRotation(pvData, pstRoot, pstParent); + pstParent = pstCur; + } + + pstParent->m_eColor = COLOR_BLK; + pstGrand->m_eColor = COLOR_RED; + pstRoot = _pLeftRotation(pvData, pstRoot, pstGrand); + } + } + + pstRoot->m_eColor = COLOR_BLK; // set root is black + + return pstRoot; +} + +/************************************************************************************************* + description:Insert the new node into r-btree and return the root node + parameters: + pstSavm --stvm handle + pstRoot --tree Root + psvIdx --index value + lIdx --value length + ppstTruck --data truck + return: + SHTree* + *************************************************************************************************/ +SHTree* pInsertTree(SATvm *pstSavm, SHTree *pstRoot, void *psvIdx, long lIdx, SHTruck **ppstTruck) +{ + int nRet = 0; + size_t lOffset; + SHTree *pstNode = NULL, *pstCur = NULL, *pstTree = pstRoot; + void *pvData = NULL, *pvAddr = pGetAddr(pstSavm, pstSavm->tblName); + + while(SELF_POS_UNUSE != pstTree->m_lSePos && NODE_NULL != pstTree->m_lSePos) + { + pstNode = pstTree; + nRet = memcmp(pstTree->m_szIdx, psvIdx, lIdx); + if(0 < nRet) + { + if(NODE_NULL == pstTree->m_lLeft) + break; + pstTree = (SHTree *)pGetNode(pvAddr, pstTree->m_lLeft); + } + else if(0 > nRet) + { + if(NODE_NULL == pstTree->m_lRight) + break; + pstTree = (SHTree *)pGetNode(pvAddr, pstTree->m_lRight); + } + else + { + pstSavm->m_lErrno = UNIQ_IDX_REPT; + return NULL; + } + } + + lOffset = sizeof(SHTree) * ((TblDef *)pvAddr)->m_lValid + lGetIdxPos(pstSavm->tblName); + if(NULL == (pstCur = pCreateNode(pvAddr, pstSavm->tblName, lOffset))) + { + pstSavm->m_lErrno = IDX_SPC_SPILL; + return NULL; + } + + if(*ppstTruck && (*ppstTruck != (PSHTruck)pGetNode(pvAddr, pstCur->m_lData))) + { + pstSavm->m_lErrno = SVR_EXCEPTION; + return NULL; + } + else + { + *ppstTruck = (PSHTruck)pGetNode(pvAddr, pstCur->m_lData); + if(!IS_TRUCK_NULL(*ppstTruck)) + { + pstSavm->m_lErrno = SVR_EXCEPTION; + return NULL; + } + } + + pstCur->m_lIdx = lIdx; + pstCur->m_lSePos = lOffset; + pstCur->m_lParent = NODE_NULL; + memcpy(pstCur->m_szIdx, psvIdx, pstCur->m_lIdx); + // set parent node and left -right node is NIL + pstCur->m_lLeft = pstCur->m_lRight = NODE_NULL; + + if(pstNode != NULL) + { + pstCur->m_eColor = COLOR_RED; + pstCur->m_lParent = pstNode->m_lSePos; + if(0 < memcmp(pstNode->m_szIdx, pstCur->m_szIdx, pstCur->m_lIdx)) + pstNode->m_lLeft = pstCur->m_lSePos; + else + pstNode->m_lRight = pstCur->m_lSePos; + } + else + { + pstRoot = pstCur; + pstCur->m_eColor = COLOR_BLK; + return pstRoot; + } + + return _pFixupInsert(pvAddr, pstRoot, pstCur); +} + +/************************************************************************************************* + description:Insert values and handle collisions according to the hash table + parameters: + pstSavm --stvm handle + pvAddr --address memory + t --table + pstTree --tree node + lGroup --group offset + ppstTruck --data truck + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long __lInsertHash(SATvm *pstSavm, void *pvAddr, TABLE t, SHTree *pstTree, size_t lGroup, + SHTruck **ppstTruck) +{ + size_t lOffset; + SHTruck *pstTruck = NULL; + SHList *pstList = NULL, *pstNode = NULL; + + lOffset = lGetListOfs(t) + sizeof(SHList) * ((TblDef *)pvAddr)->m_lValid; + pstList = (SHList *)pGetNode(pvAddr, lOffset); + pstList->m_lPos = lOffset; + pstTruck = (PSHTruck)pGetNode(pvAddr, pstList->m_lData); + + // If the data space has been found in the previous only index creation, recheck it + if(!IS_TRUCK_NULL(pstTruck) || ((*ppstTruck) && (*ppstTruck != pstTruck))) + { + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + *ppstTruck = pstTruck; + if(SELF_POS_UNUSE == pstTree->m_lSePos || NODE_NULL == pstTree->m_lSePos) + { + pstTree->m_lSePos= lGroup; + pstTree->m_lData = pstList->m_lPos; + pstList->m_lNode = pstTree->m_lSePos; + } + else + { + pstNode = (SHList *)pGetNode(pvAddr, pstTree->m_lData); + + pstList->m_lNext = pstNode->m_lNext; + pstList->m_lLast = pstNode->m_lPos; + if(SELF_POS_UNUSE != pstNode->m_lNext) + ((SHList *)pGetNode(pvAddr, pstNode->m_lNext))->m_lLast = pstList->m_lPos; + pstNode->m_lNext = pstList->m_lPos; + } + + return RC_SUCC; +} + +/************************************************************************************************* + description:Insert the group node into r-btree and return the root node + parameters: + pstSavm --stvm handle + pstRoot --tree Root + psvIdx --index value + lIdx --value length + ppstTruck --data truck + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +SHTree* pInsertGroup(SATvm *pstSavm, SHTree *pstRoot, void *psvIdx, long lIdx, SHTruck **ppstTruck) +{ + int nRet = 0; + size_t lOffset; + SHTruck *pstTruck = NULL; + void *pvData = pGetAddr(pstSavm, pstSavm->tblName); + SHTree *pstNode = NULL, *pstCur = NULL, *pstTree = pstRoot; + + while(SELF_POS_UNUSE != pstTree->m_lSePos && NODE_NULL != pstTree->m_lSePos) + { + pstNode = pstTree; + nRet = memcmp(pstTree->m_szIdx, psvIdx, lIdx); + if(0 < nRet) + { + if(NODE_NULL == pstTree->m_lLeft) + break; + pstTree = (SHTree *)pGetNode(pvData, pstTree->m_lLeft); + } + else if(0 > nRet) + { + if(NODE_NULL == pstTree->m_lRight) + break; + pstTree = (SHTree *)pGetNode(pvData, pstTree->m_lRight); + } + else + { + pCreateGroup(pvData, pstSavm->tblName, pstTree, 0, &pstTruck); + if(!IS_TRUCK_NULL(pstTruck) || ((*ppstTruck) && (*ppstTruck != pstTruck))) + { + pstSavm->m_lErrno = SVR_EXCEPTION; + return NULL; + } + + return pstRoot; + } + } + + lOffset = sizeof(SHTree) * ((TblDef *)pvData)->m_lGroup + lGetGrpPos(pstSavm->tblName); + if(NULL == (pstCur = pCreateGroup(pvData, pstSavm->tblName, NULL, lOffset, &pstTruck))) + { + pstSavm->m_lErrno = SVR_EXCEPTION; + return pstRoot; + } + + // If the data space has been found in the previous only index creation, recheck it + if(!IS_TRUCK_NULL(pstTruck) || ((*ppstTruck) && (*ppstTruck != pstTruck))) + { + pstSavm->m_lErrno = SVR_EXCEPTION; + return NULL; + } + + ((TblDef *)pvData)->m_lGroup ++; + *ppstTruck = pstTruck; + + pstCur->m_lIdx = lIdx; + pstCur->m_lSePos = lOffset; + pstCur->m_lParent = NODE_NULL; + memcpy(pstCur->m_szIdx, psvIdx, pstCur->m_lIdx); + pstCur->m_lLeft = pstCur->m_lRight = NODE_NULL; + if(pstNode != NULL) + { + pstCur->m_eColor = COLOR_RED; + pstCur->m_lParent = pstNode->m_lSePos; + if(0 < memcmp(pstNode->m_szIdx, pstCur->m_szIdx, pstCur->m_lIdx)) + pstNode->m_lLeft = pstCur->m_lSePos; + else + pstNode->m_lRight = pstCur->m_lSePos; + } + else + { + pstRoot = pstCur; + pstCur->m_eColor = COLOR_BLK; + return pstRoot; + } + + return _pFixupInsert(pvData, pstRoot, pstCur); +} + +/************************************************************************************************* + description:Repair deletion causes RBTree imbalance + parameters: + pvData --stvm handle + pstRoot --tree Root + psTree --tree node + return: + SHTree* + *************************************************************************************************/ +SHTree* _pFixupDelete(void *pvData, SHTree *pstRoot, SHTree *pstTree) +{ + SHTree *pstParent = NULL, *pstBrother = NULL, *pstLeft = NULL, *pstRight = NULL; + + while(COLOR_BLK == pstTree->m_eColor && (pstRoot != pstTree)) + { + pstParent = (SHTree *)pGetNode(pvData, pstTree->m_lParent); + + if(pstTree->m_lSePos == pstParent->m_lLeft) + { + pstBrother = (SHTree *)pGetNode(pvData, pstParent->m_lRight); + + if(COLOR_RED == pstBrother->m_eColor) + { + pstParent->m_eColor = COLOR_RED; + pstBrother->m_eColor = COLOR_BLK; + pstRoot = _pLeftRotation(pvData, pstRoot, pstParent); + + // New sibling nodes. That's what it looks like + pstBrother = (SHTree *)pGetNode(pvData, pstParent->m_lRight); + } + if(NODE_NULL == pstBrother->m_lSePos) + return pstRoot; + + pstLeft = (SHTree *)pGetNode(pvData, pstBrother->m_lLeft); + pstRight = (SHTree *)pGetNode(pvData, pstBrother->m_lRight); + if(COLOR_BLK == pstLeft->m_eColor && COLOR_BLK == pstRight->m_eColor) + { + pstBrother->m_eColor = COLOR_RED; + pstTree = pstParent; + } + else + { + /* 3: Brothers node is black (default), the left node of the brother + node is red, the right child node is black: to the brother as the + fulcrum, right-Rotate*/ + if(COLOR_BLK == pstRight->m_eColor) + { + pstLeft->m_eColor = COLOR_BLK; + pstBrother->m_eColor = COLOR_RED; + pstRoot = _pRightRotation(pvData, pstRoot, pstBrother); + + /* The changed right child of the parent node serves as a new + brother node*/ + pstBrother = (SHTree *)pGetNode(pvData, pstParent->m_lRight); + pstRight = (SHTree *)pGetNode(pvData, pstBrother->m_lRight); + } + + /* 4: Brothers node is black (default), brother node right child + node is red: parent as a fulcrum, left-Rotate */ + pstBrother->m_eColor = pstParent->m_eColor; + pstParent->m_eColor = COLOR_BLK; + pstRight->m_eColor = COLOR_BLK; + pstRoot = _pLeftRotation(pvData, pstRoot, pstParent); + pstTree = pstRoot; + } + } + else // pstTree is pstParent right child + { + pstBrother = (SHTree *)pGetNode(pvData, pstParent->m_lLeft); + if(COLOR_RED == pstBrother->m_eColor) + { + pstParent->m_eColor = COLOR_RED; + pstBrother->m_eColor = COLOR_BLK; + pstRoot = _pRightRotation(pvData, pstRoot, pstParent); + + // New Brothers node. In fact, the effect is left-handed + pstBrother = (SHTree *)pGetNode(pvData, pstParent->m_lLeft); + } + if(NODE_NULL == pstBrother->m_lSePos) + return pstRoot; + + /* Brothers node is black (default), and the two nodes of the + brother node are black */ + pstLeft = (SHTree *)pGetNode(pvData, pstBrother->m_lLeft); + pstRight = (SHTree *)pGetNode(pvData, pstBrother->m_lRight); + if(COLOR_BLK == pstLeft->m_eColor && COLOR_BLK == pstRight->m_eColor) + { + pstBrother->m_eColor = COLOR_RED; + pstTree = pstParent; + } + else + { + /* Brothers node is black (default), the right node of the brother + node is red, the left child node is black: + the brother as a fulcrum, left-rotate*/ + if(COLOR_BLK == pstLeft->m_eColor) + { + pstRight->m_eColor = COLOR_BLK; + pstBrother->m_eColor = COLOR_RED; + pstRoot = _pLeftRotation(pvData, pstRoot, pstBrother); + + // The changed right child of the parent node serves as a new brother node + pstBrother = (SHTree *)pGetNode(pvData, pstParent->m_lLeft); + pstLeft = (SHTree *)pGetNode(pvData, pstBrother->m_lLeft); + } + + /* Brothers node is black (default), brother node left child node is red: + parent as the fulcrum, right-handed processing */ + pstBrother->m_eColor = pstParent->m_eColor; + pstParent->m_eColor = COLOR_BLK; + pstLeft->m_eColor = COLOR_BLK; + pstRoot = _pRightRotation(pvData, pstRoot, pstParent); + pstTree = pstRoot; + } + } + } + + pstTree->m_eColor = COLOR_BLK; + + return pstRoot; +} + +/************************************************************************************************* + description:Remove the execution index from RBTree + parameters: + pvData --addree memory + t --table + pstRoot --tree root + pstTree --tree node + return: + SHTree* + *************************************************************************************************/ +SHTree* _pDeleteTree(void *pvData, TABLE t, SHTree *pstRoot, SHTree *pstTree) +{ + size_t lData; + SHTree *pstChild = NULL, *pstParent = NULL, *pstNext = NULL; + + // If there is a left node or a right node, notice that no node defaults to NIL + // for right node processing + if(NODE_NULL == pstTree->m_lLeft || NODE_NULL == pstTree->m_lRight) + { + if(NODE_NULL == pstTree->m_lLeft) + pstNext = (SHTree *)pGetNode(pvData, pstTree->m_lRight); + else + pstNext = (SHTree *)pGetNode(pvData, pstTree->m_lLeft); + + // The child node points to the parent of the node to be deleted + pstNext->m_lParent = pstTree->m_lParent; + if(NODE_NULL == pstTree->m_lParent) + pstRoot = pstNext; + else + { + pstParent = (SHTree *)pGetNode(pvData, pstTree->m_lParent); + if(pstParent->m_lLeft == pstTree->m_lSePos) + pstParent->m_lLeft = pstNext->m_lSePos; + else + pstParent->m_lRight = pstNext->m_lSePos; + } + + // If you delete the red node, it does not affect the tree structure + if(pstTree->m_eColor == COLOR_RED) + return pReleaseNode(pvData, t, pstRoot, pstTree, NULL); + + pstRoot = pReleaseNode(pvData, t, pstRoot, pstTree, &pstNext); + + return _pFixupDelete(pvData, pstRoot, pstNext); + } + + pstNext = (SHTree *)pGetNode(pvData, pstTree->m_lRight); + // Left and right children of deleted node D are not leaf nodes + while(NODE_NULL != pstNext->m_lLeft) + pstNext = (SHTree *)pGetNode(pvData, pstNext->m_lLeft); + + pstChild = (SHTree *)pGetNode(pvData, pstNext->m_lRight); + pstParent = (SHTree *)pGetNode(pvData, pstNext->m_lParent); + + pstChild->m_lParent = pstParent->m_lSePos; + if(pstNext->m_lSePos == pstParent->m_lLeft) + pstParent->m_lLeft = pstChild->m_lSePos; + else + pstParent->m_lRight = pstChild->m_lSePos; + + lData = pstTree->m_lData; + pstTree->m_lData = pstNext->m_lData; + pstNext->m_lData = lData; + memcpy(pstTree->m_szIdx, pstNext->m_szIdx, pstNext->m_lIdx); + + if(pstNext->m_eColor == COLOR_RED) + return pReleaseNode(pvData, t, pstRoot, pstNext, NULL); + + pstRoot = pReleaseNode(pvData, t, pstRoot, pstNext, &pstChild); + + return _pFixupDelete(pvData, pstRoot, pstChild); +} + +/************************************************************************************************* + description:Remove the query index from RBTree + parameters: + pvData --address memory + t --table + pstRoot --tree Root + pstTree --tree node + lOut + return: + SHTree* + *************************************************************************************************/ +SHTree* _pDeleteGroup(void *pvData, TABLE t, SHTree *pstRoot, SHTree *pstTree, long *plOut) +{ + size_t lData = 0; + SHTree *pstChild = NULL, *pstParent = NULL, *pstNext = NULL; + + // If there is a left node or a right node, notice that no node defaults to NIL + // for right node processing + if(NODE_NULL == pstTree->m_lLeft || NODE_NULL == pstTree->m_lRight) + { + if(NODE_NULL == pstTree->m_lLeft) + pstNext = (SHTree *)pGetNode(pvData, pstTree->m_lRight); + else + pstNext = (SHTree *)pGetNode(pvData, pstTree->m_lLeft); + + // The child node points to the parent of the node to be deleted + pstNext->m_lParent = pstTree->m_lParent; + if(NODE_NULL == pstTree->m_lParent) + pstRoot = pstNext; + else + { + pstParent = (SHTree *)pGetNode(pvData, pstTree->m_lParent); + if(pstParent->m_lLeft == pstTree->m_lSePos) + pstParent->m_lLeft = pstNext->m_lSePos; + else + pstParent->m_lRight = pstNext->m_lSePos; + } + + if(pstTree->m_eColor == COLOR_RED) + return pReleaseGroup(pvData, t, pstRoot, pstTree, NULL, plOut); + + pstRoot = pReleaseGroup(pvData, t, pstRoot, pstTree, &pstNext, plOut); + return _pFixupDelete(pvData, pstRoot, pstNext); + } + + pstNext = (SHTree *)pGetNode(pvData, pstTree->m_lRight); + while(NODE_NULL != pstNext->m_lLeft) + pstNext = (SHTree *)pGetNode(pvData, pstNext->m_lLeft); + + pstChild = (SHTree *)pGetNode(pvData, pstNext->m_lRight); + pstParent = (SHTree *)pGetNode(pvData, pstNext->m_lParent); + + pstChild->m_lParent = pstParent->m_lSePos; + if(pstNext->m_lSePos == pstParent->m_lLeft) + pstParent->m_lLeft = pstChild->m_lSePos; + else + pstParent->m_lRight = pstChild->m_lSePos; + + lData = pstTree->m_lData; + pstTree->m_lData = pstNext->m_lData; + pstNext->m_lData = lData; // set lData to the Release the node + memcpy(pstTree->m_szIdx, pstNext->m_szIdx, pstNext->m_lIdx); + ((SHList *)pGetNode(pvData, pstTree->m_lData))->m_lNode = pstTree->m_lSePos; + + if(pstNext->m_eColor == COLOR_RED) + return pReleaseGroup(pvData, t, pstRoot, pstNext, NULL, plOut); + + pstRoot = pReleaseGroup(pvData, t, pstRoot, pstNext, &pstChild, plOut); + + return _pFixupDelete(pvData, pstRoot, pstChild); +} + +/************************************************************************************************* + description:Remove the execution index from RBTree + parameters: + pstSavm --stvm handle + pstRoot --tree Root + psvIdx --index value + lIdx --value length + *plData --data offset + return: + SHTree* + *************************************************************************************************/ +SHTree* pDeleteTree(SATvm *pstSavm, SHTree *pstRoot, void *psvIdx, long lIdx, size_t *plData) +{ + SHTree *pstTree = NULL; + void *pvData = pGetAddr(pstSavm, pstSavm->tblName); + + if(NULL == (pstTree = pSearchTree(pvData, pstRoot, psvIdx, lIdx))) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + return NULL; + } + + *plData = pstTree->m_lData; + + return _pDeleteTree(pvData, pstSavm->tblName, pstRoot, pstTree); +} + +/************************************************************************************************* + description:Remove the index from the hash table + parameters: + pstSavm --stvm handle + pvAddr --memory address + pstTree --tree node + lData --data offset + pvData --data truck + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lPurgedHash(SATvm *pstSavm, void *pvAddr, SHTree *pstTree, void *pvData) +{ + SHList *pstList = NULL; + SHTruck *pstTruck = NULL; + size_t lNext = 0, lOffset; + + pstList = (SHList *)pGetNode(pvAddr, pstTree->m_lData); + lOffset = lGetListOfs(pstSavm->tblName) + ((TblDef *)pvAddr)->m_lValid * sizeof(SHList); + for(;SELF_POS_UNUSE != pstList->m_lPos; pstList = (SHList *)pGetNode(pvAddr, lNext)) + { + lNext = pstList->m_lNext; + pstTruck = (PSHTruck)pGetNode(pvAddr, pstList->m_lData); + if(memcmp(pstTruck->m_pvData, pvData, pstSavm->lSize)) + { + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + lOffset -= sizeof(SHList); + if(RC_SUCC != lReleaseList(pvAddr, pstSavm->tblName, pstTree, pstList, lOffset, &lNext)) + { + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + if(SELF_POS_UNUSE == pstTree->m_lData) + pstTree->m_lSePos = SELF_POS_UNUSE; + + return RC_SUCC; + } + + return RC_FAIL; +} + +/************************************************************************************************* + description:Remove the execution index from RBTree + parameters: + pstSavm --stvm handle + pstRoot --tree Root + psvIdx --index value + lIdx --value length + pvData --data truck + plOut --lOffset + eType + return: + SHTree* + *************************************************************************************************/ +SHTree* _pRemoveGroup(SATvm *pstSavm, SHTree *pstRoot, void *psvIdx, long lIdx, void *pvData, + long *plOut, long eType) +{ + SHList *pstList = NULL; + SHTree *pstTree = NULL; + SHTruck *pstTruck = NULL; + size_t lNext = 0, lOffset; + void *pvAddr = pGetAddr(pstSavm, pstSavm->tblName); + + if(NULL == (pstTree = pSearchTree(pvAddr, pstRoot, psvIdx, lIdx))) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + return NULL; + } + + if(SELF_POS_UNUSE == pstTree->m_lData) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + return _pDeleteGroup(pvAddr, pstSavm->tblName, pstRoot, pstTree, plOut); + } + + pstList = (SHList *)pGetNode(pvAddr, pstTree->m_lData); + + lOffset = lGetListOfs(pstSavm->tblName) + ((TblDef *)pvAddr)->m_lValid * sizeof(SHList); + for(*plOut = 0; SELF_POS_UNUSE != pstList->m_lPos; pstList = (SHList *)pGetNode(pvAddr, lNext)) + { + lNext = pstList->m_lNext; + pstTruck = (PSHTruck)pGetNode(pvAddr, pstList->m_lData); + if(0 == eType) + { + if(memcmp(pvData, (void *)&pstList->m_lData, sizeof(pstList->m_lData))) + { + if(SELF_POS_UNUSE == lNext) break; + continue; + } + } + else + { + if(RC_MISMA == lFeildMatch(&pstSavm->stCond, pstTruck->m_pvData, pvData)) + { + if(SELF_POS_UNUSE == lNext) break; + continue; + } + } + + (*plOut) ++; + lOffset -= sizeof(SHList); + + // lNext may be tail node, just moved, here need to update lNext + if(RC_SUCC != lReleaseList(pvAddr, pstSavm->tblName, pstTree, pstList, lOffset, &lNext)) + { + pstSavm->m_lErrno = SVR_EXCEPTION; + return pstRoot; + } + + if(SELF_POS_UNUSE == lNext || 0 == eType) break; + } + + if(SELF_POS_UNUSE != pstTree->m_lData) + return pstRoot; + else + return _pDeleteGroup(pvAddr, pstSavm->tblName, pstRoot, pstTree, plOut); +} + +/************************************************************************************************* + description:Remove the execution index from RBTree by Offset + parameters: + pstSavm --stvm handle + pstRoot --tree Root + psvIdx --index value + lIdx --value length + pvData --data truck + plOut --lOffset + eType + return: + SHTree* + *************************************************************************************************/ +SHTree* pDeleteGroup(SATvm *pstSavm, SHTree *pstRoot, void *psvIdx, long lIdx, void *pvData, + long *plOut) +{ + return _pRemoveGroup(pstSavm, pstRoot, psvIdx, lIdx, pvData, plOut, 0); +} + +/************************************************************************************************* + description:Remove the index from RBTree + parameters: + pstSavm --stvm handle + pstRoot --tree Root + psvIdx --index value + lIdx --value length + pvData --data truck + plOut --lOffset + eType + return: + SHTree* + *************************************************************************************************/ +SHTree* pRemoveGroup(SATvm *pstSavm, SHTree *pstRoot, void *psvIdx, long lIdx, void *pvData, + long *plOut) +{ + return _pRemoveGroup(pstSavm, pstRoot, psvIdx, lIdx, pvData, plOut, 1); +} + +/************************************************************************************************* + description:Remove the corresponding data from Hash + parameters: + pstSavm --stvm handle + pvAddr --memory address + pstTree --tree node + t --table + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long __lDeleteHash(SATvm *pstSavm, void *pvAddr, SHTree *pstTree, TABLE t) +{ + SHTree *pstRoot = NULL; + SHList *pstList = NULL; + SHTruck *pstTruck = NULL; + char szIdx[MAX_INDEX_LEN]; + size_t lNext = 0, lOffset, lData = 0; + RWLock *prwLock = (RWLock *)pGetRWLock(pvAddr); + + pstSavm->m_lEType = EXE_PLAN_GRP; + if(RC_SUCC != pthread_rwlock_wrlock(prwLock)) + { + pstSavm->m_lErrno = LOCK_DOWR_ERR; + return RC_FAIL; + } + + pstList = (SHList *)pGetNode(pvAddr, pstTree->m_lData); + lOffset = lGetListOfs(t) + ((TblDef *)pvAddr)->m_lValid * sizeof(SHList); + for(pstSavm->m_lEffect = 0; SELF_POS_UNUSE != pstList->m_lPos; + pstList = (SHList *)pGetNode(pvAddr, lNext)) + { + lNext = pstList->m_lNext; + pstTruck = (PSHTruck)pGetNode(pvAddr, pstList->m_lData); + if(RC_MISMA == lFeildMatch(&pstSavm->stCond, pstTruck->m_pvData, pstSavm->pstVoid)) + { + if(SELF_POS_UNUSE == pstList->m_lNext) break; + continue; + } + + if(HAVE_UNIQ_IDX(t)) + { + memset(szIdx, 0, sizeof(szIdx)); + if(NULL == pPickIndex(lGetIdxNum(t), pGetTblIdx(t), pstTruck->m_pvData, szIdx)) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + if(NULL == (pstRoot = (SHTree *)pGetNode(pvAddr, ((TblDef *)pvAddr)->m_lTreeRoot))) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + pstRoot = pDeleteTree(pstSavm, pstRoot, szIdx, lGetIdxLen(t), &lData); + if(!pstRoot || pstList->m_lData != lData) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + ((TblDef *)pvAddr)->m_lTreeRoot = pstRoot->m_lSePos; + } + + pstSavm->m_lEffect ++; + lOffset -= sizeof(SHList); + if(RC_SUCC != lReleaseList(pvAddr, t, pstTree, pstList, lOffset, &lNext)) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + if(SELF_POS_UNUSE == pstTree->m_lData) + pstTree->m_lSePos = SELF_POS_UNUSE; + + if(RC_SUCC != lRecordWork(pstSavm, pstTruck->m_pvData, OPERATE_DELETE)) + { + pthread_rwlock_unlock(prwLock); + return RC_FAIL; + } + + lReleaseTruck(pvAddr, t, pstTruck, TRUE); + ((TblDef *)pvAddr)->m_lValid --; + + if(SELF_POS_UNUSE == lNext) break; + if(FIRST_ROW & pstSavm->lFind) break; + } + + pthread_rwlock_unlock(prwLock); + + return RC_SUCC; +} + +/************************************************************************************************* + description:Delete Hash table points to the data + parameters: + pstSavm --stvm handle + pvAddr --memory address + t --table + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lDeleteHash(SATvm *pstSavm, void *pvAddr, TABLE t) +{ + size_t lIdx; + SHTree *pstTree = NULL; + char szIdx[MAX_INDEX_LEN]; + + memset(szIdx, 0, sizeof(szIdx)); + if(NULL == pGetIndex(&pstSavm->stCond, lGetGrpNum(t), pGetTblGrp(t), pstSavm->pstVoid, szIdx)) + return RC_CONTU; + + lIdx = uGetHash(szIdx, lGetGrpLen(t)) % ((TblDef *)pvAddr)->m_lMaxRow; + pstTree = pvAddr + ((TblDef *)pvAddr)->m_lGroupRoot + lIdx * sizeof(SHTree); + if(NULL == pstTree || SELF_POS_UNUSE == pstTree->m_lData) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_FAIL; + } + + return __lDeleteHash(pstSavm, pvAddr, pstTree, t); +} + +/************************************************************************************************* + description:For the unique index traversal of data deleted + parameters: + pstSavm --stvm handle + pvAddr --memory address + t --table + psvIdx --index value + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long __lDeleteIndex(SATvm *pstSavm, void *pvAddr, TABLE t, void *psvIdx) +{ + long lRow = 0; + size_t lData, lIdx; + SHTruck *pstTruck = NULL; + char szIdx[MAX_INDEX_LEN]; + SHTree *pstRoot = NULL, *pstTree = NULL; + RWLock *prwLock = (RWLock *)pGetRWLock(pvAddr); + + if(RC_SUCC != pthread_rwlock_wrlock(prwLock)) + { + pstSavm->m_lErrno = LOCK_DOWR_ERR; + return RC_FAIL; + } + + pstSavm->m_lEType = EXE_PLAN_IDX; + if(NULL == (pstRoot = pGetNode(pvAddr, ((TblDef *)pvAddr)->m_lTreeRoot))) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + if(NULL == (pstTree = pSearchTree(pvAddr, pstRoot, psvIdx, lGetIdxLen(t)))) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_FAIL; + } + + lData = pstTree->m_lData; + pstTruck = (PSHTruck)pGetNode(pvAddr, pstTree->m_lData); + if(RC_MISMA == lFeildMatch(&pstSavm->stCond, pstTruck->m_pvData, pstSavm->pstVoid)) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_FAIL; + } + + if(NULL == (pstRoot = _pDeleteTree(pvAddr, pstSavm->tblName, pstRoot, pstTree))) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + ((TblDef *)pvAddr)->m_lTreeRoot = pstRoot->m_lSePos; + + if(HAVE_NORL_IDX(t)) + { + memset(szIdx, 0, sizeof(szIdx)); + if(NULL == pPickIndex(lGetGrpNum(t), pGetTblGrp(t), pstTruck->m_pvData, szIdx)) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + if(NULL == (pstRoot = (SHTree *)pGetNode(pvAddr, ((TblDef *)pvAddr)->m_lGroupRoot))) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + if(NULL == (pstRoot = pDeleteGroup(pstSavm, pstRoot, szIdx, lGetGrpLen(t), &lData, &lRow))) + { + pthread_rwlock_unlock(prwLock); + return RC_FAIL; + } + + if(1 != lRow) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + ((TblDef *)pvAddr)->m_lGroupRoot = pstRoot->m_lSePos; + } + else if(HAVE_HASH_IDX(t)) + { + memset(szIdx, 0, sizeof(szIdx)); + if(NULL == pPickIndex(lGetGrpNum(t), pGetTblGrp(t), pstTruck->m_pvData, szIdx)) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + lIdx = uGetHash(szIdx, lGetGrpLen(t)) % ((TblDef *)pvAddr)->m_lMaxRow; + pstRoot = pvAddr + ((TblDef *)pvAddr)->m_lGroupRoot + lIdx * sizeof(SHTree); + if(NULL == pstRoot || SELF_POS_UNUSE == pstRoot->m_lData) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + if(RC_SUCC != _lPurgedHash(pstSavm, pvAddr, pstRoot, pstTruck->m_pvData)) + { + pthread_rwlock_unlock(prwLock); + return RC_FAIL; + } + } + + if(RC_SUCC != lRecordWork(pstSavm, pstTruck->m_pvData, OPERATE_DELETE)) + { + pthread_rwlock_unlock(prwLock); + return RC_FAIL; + } + + lReleaseTruck(pvAddr, t, pstTruck, TRUE); + pthread_rwlock_unlock(prwLock); + + pstSavm->m_lEffect = 1; + ((TblDef *)pvAddr)->m_lValid --; + + return RC_SUCC; +} + +/************************************************************************************************* + description:delete The unique index truck data + parameters: + pstSavm --stvm handle + pvAddr --memory address + t --table + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lDeleteIndex(SATvm *pstSavm, void *pvAddr, TABLE t) +{ + char szIdx[MAX_INDEX_LEN]; + + memset(szIdx, 0, sizeof(szIdx)); + if(NULL == pGetIndex(&pstSavm->stCond, lGetIdxNum(t), pGetTblIdx(t), pstSavm->pstVoid, szIdx)) + return RC_CONTU; + + return __lDeleteIndex(pstSavm, pvAddr, t, (void *)szIdx); +} + +/************************************************************************************************* + description:Delete the data that matches conditions + parameters: + pstSavm --stvm handle + pvAddr --memory address + pstTree --tree node + t --table + psvIdx --index value + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long __lDeleteGroup(SATvm *pstSavm, void *pvAddr, TABLE t, void *psvIdx) +{ + SHList *pstList = NULL; + SHTruck *pstTruck = NULL; + char szIdx[MAX_INDEX_LEN]; + size_t lNext = 0, lOffset, lData = 0; + RWLock *prwLock = (RWLock *)pGetRWLock(pvAddr); + SHTree *pstRoot = NULL, *pstTree = NULL, *pstIRoot = NULL; + + pstSavm->m_lEType = EXE_PLAN_GRP; + if(RC_SUCC != pthread_rwlock_wrlock(prwLock)) + { + pstSavm->m_lErrno = LOCK_DOWR_ERR; + return RC_FAIL; + } + + if(NULL == (pstRoot = (SHTree *)pGetNode(pvAddr, ((TblDef *)pvAddr)->m_lGroupRoot))) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + if(NULL == (pstTree = pSearchTree(pvAddr, pstRoot, psvIdx, lGetGrpLen(t)))) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_FAIL; + } + + if(SELF_POS_UNUSE == pstTree->m_lData) + { + pstRoot = _pDeleteGroup(pvAddr, t, pstRoot, pstTree, &pstSavm->m_lEffect); + ((TblDef *)pvAddr)->m_lGroupRoot = pstRoot->m_lSePos; + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_SUCC; + } + + pstList = (SHList *)pGetNode(pvAddr, pstTree->m_lData); + lOffset = lGetListOfs(t) + ((TblDef *)pvAddr)->m_lValid * sizeof(SHList); + for(pstSavm->m_lEffect = 0; SELF_POS_UNUSE != pstList->m_lPos; + pstList = (SHList *)pGetNode(pvAddr, lNext)) + { + lNext = pstList->m_lNext; + pstTruck = (PSHTruck)pGetNode(pvAddr, pstList->m_lData); + if(RC_MISMA == lFeildMatch(&pstSavm->stCond, pstTruck->m_pvData, pstSavm->pstVoid)) + { + if(SELF_POS_UNUSE == pstList->m_lNext) break; + continue; + } + + if(HAVE_UNIQ_IDX(t)) + { + memset(szIdx, 0, sizeof(szIdx)); + if(NULL == pPickIndex(lGetIdxNum(t), pGetTblIdx(t), pstTruck->m_pvData, szIdx)) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + if(NULL == (pstIRoot = pGetNode(pvAddr, ((TblDef *)pvAddr)->m_lTreeRoot))) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + pstIRoot = pDeleteTree(pstSavm, pstIRoot, szIdx, lGetIdxLen(t), &lData); + if(!pstIRoot || pstList->m_lData != lData) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + ((TblDef *)pvAddr)->m_lTreeRoot = pstIRoot->m_lSePos; + } + + pstSavm->m_lEffect ++; + lOffset -= sizeof(SHList); + if(RC_SUCC != lReleaseList(pvAddr, t, pstTree, pstList, lOffset, &lNext)) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + if(RC_SUCC != lRecordWork(pstSavm, pstTruck->m_pvData, OPERATE_DELETE)) + { + pthread_rwlock_unlock(prwLock); + return RC_FAIL; + } + + lReleaseTruck(pvAddr, t, pstTruck, TRUE); + ((TblDef *)pvAddr)->m_lValid --; + + if(SELF_POS_UNUSE == lNext) break; + if(FIRST_ROW & pstSavm->lFind) break; + } + + if(SELF_POS_UNUSE == pstTree->m_lData) + { + pstRoot = _pDeleteGroup(pvAddr, pstSavm->tblName, pstRoot, pstTree, &pstSavm->m_lEffect); + ((TblDef *)pvAddr)->m_lGroupRoot = pstRoot->m_lSePos; + } + + pthread_rwlock_unlock(prwLock); + + return RC_SUCC; +} + +/************************************************************************************************* + description:Delete the data that matches conditions + parameters: + pstSavm --stvm handle + pvAddr --memory address + t --table + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lDeleteGroup(SATvm *pstSavm, void *pvAddr, TABLE t) +{ + char szIdx[MAX_INDEX_LEN]; + + memset(szIdx, 0, sizeof(szIdx)); + if(NULL == pGetIndex(&pstSavm->stCond, lGetGrpNum(t), pGetTblGrp(t), pstSavm->pstVoid, szIdx)) + return RC_CONTU; + + return __lDeleteGroup(pstSavm, pvAddr, t, (void *)szIdx); +} + +/************************************************************************************************* + description:Delete the truck that matches conditions + parameters: + pstSavm --stvm handle + pvAddr --memory address + t --table + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lDeleteTruck(SATvm *pstSavm, void *pvAddr, TABLE t) +{ + bool bIsIdx = FALSE; + SHTree *pstRoot = NULL; + SHTruck *pstTruck = NULL; + char szIdx[MAX_INDEX_LEN]; + RWLock *prwLock = (RWLock *)pGetRWLock(pvAddr); + size_t lData = 0, lOffset = lGetTblData(t), lIdx; + long lRow, lValid = ((TblDef *)pvAddr)->m_lValid; + + if(HAVE_INDEX(t)) bIsIdx = TRUE; + + if(RC_SUCC != pthread_rwlock_wrlock(prwLock)) + { + pstSavm->m_lErrno = LOCK_DOWR_ERR; + return RC_FAIL; + } + + pstSavm->m_lEType = EXE_PLAN_ALL; + for(lRow = 0, pstSavm->m_lEffect = 0, pstTruck = (PSHTruck)pGetNode(pvAddr, lOffset); + (lRow < lValid) && (lOffset < lGetTableSize(t)); pstTruck = (PSHTruck)pGetNode(pvAddr, lOffset)) + { + if(IS_TRUCK_NULL(pstTruck)) + { + lOffset += lGetRowTruck(t); + continue; + } + + ++ lRow; + if(RC_MISMA == lFeildMatch(&pstSavm->stCond, pstTruck->m_pvData, pstSavm->pstVoid)) + { + lOffset += lGetRowTruck(t); + continue; + } + + pstSavm->m_lEffect ++; + if(HAVE_UNIQ_IDX(t)) + { + memset(szIdx, 0, sizeof(szIdx)); + if(NULL == pPickIndex(lGetIdxNum(t), pGetTblIdx(t), pstTruck->m_pvData, szIdx)) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + if(NULL == (pstRoot = pGetNode(pvAddr, ((TblDef *)pvAddr)->m_lTreeRoot))) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + pstRoot = pDeleteTree(pstSavm, pstRoot, szIdx, lGetIdxLen(t), &lData); + if(!pstRoot || lOffset != lData) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + ((TblDef *)pvAddr)->m_lTreeRoot = pstRoot->m_lSePos; + } + + if(HAVE_NORL_IDX(t)) + { + memset(szIdx, 0, sizeof(szIdx)); + if(NULL == pPickIndex(lGetGrpNum(t), pGetTblGrp(t), pstTruck->m_pvData, szIdx)) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + if(NULL == (pstRoot = (SHTree *)pGetNode(pvAddr, ((TblDef *)pvAddr)->m_lGroupRoot))) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + pstRoot = pDeleteGroup(pstSavm, pstRoot, szIdx, lGetGrpLen(t), &lOffset, (long *)&lData); + if(!pstRoot) return RC_FAIL; + if(1 != lData) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + ((TblDef *)pvAddr)->m_lGroupRoot = pstRoot->m_lSePos; + } + else if(HAVE_HASH_IDX(t)) + { + memset(szIdx, 0, sizeof(szIdx)); + if(NULL == pPickIndex(lGetGrpNum(t), pGetTblGrp(t), pstTruck->m_pvData, szIdx)) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + lIdx = uGetHash(szIdx, lGetGrpLen(t)) % ((TblDef *)pvAddr)->m_lMaxRow; + pstRoot = pvAddr + ((TblDef *)pvAddr)->m_lGroupRoot + lIdx * sizeof(SHTree); + if(NULL == pstRoot || SELF_POS_UNUSE == pstRoot->m_lData) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + if(RC_SUCC != _lPurgedHash(pstSavm, pvAddr, pstRoot, pstTruck->m_pvData)) + { + pthread_rwlock_unlock(prwLock); + return RC_FAIL; + } + } + + if(bIsIdx) lOffset += lGetRowTruck(t); + + if(RC_SUCC != lRecordWork(pstSavm, pstTruck->m_pvData, OPERATE_DELETE)) + { + pthread_rwlock_unlock(prwLock); + return RC_FAIL; + } + + lReleaseTruck(pvAddr, t, pstTruck, bIsIdx); + ((TblDef *)pvAddr)->m_lValid --; + if(FIRST_ROW & pstSavm->lFind) break; + } + pthread_rwlock_unlock(prwLock); + + if(0 == pstSavm->m_lEffect) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_FAIL; + } + + return RC_SUCC; +} + +/************************************************************************************************* + description:API - delete + parameters: + pstSavm --stvm handle + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lDelete(SATvm *pstSavm) +{ + long lRet; + RunTime *pstRun = NULL; + + if(!pstSavm) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + if(NULL == (pstRun = (RunTime *)pInitMemTable(pstSavm, pstSavm->tblName))) + return RC_FAIL; + + if(RES_REMOT_SID == pstRun->m_lLocal) + { + Tremohold(pstSavm, pstRun); + return _lDeleteByRt(pstSavm); + } + + if(((TblDef *)pstRun->m_pvAddr)->m_lValid <= 0) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + vTblDisconnect(pstSavm, pstSavm->tblName); + return RC_FAIL; + } + + if(!pstSavm->pstVoid) + { + lRet = _lDeleteTruck(pstSavm, pstRun->m_pvAddr, pstSavm->tblName); + vTblDisconnect(pstSavm, pstSavm->tblName); + return lRet; + } + + if(HAVE_UNIQ_IDX(pstSavm->tblName)) + { + lRet = _lDeleteIndex(pstSavm, pstRun->m_pvAddr, pstSavm->tblName); + if(RC_CONTU != lRet) + { + vTblDisconnect(pstSavm, pstSavm->tblName); + return lRet; + } + } + + if(HAVE_NORL_IDX(pstSavm->tblName)) + { + lRet = _lDeleteGroup(pstSavm, pstRun->m_pvAddr, pstSavm->tblName); + if(RC_CONTU != lRet) + { + vTblDisconnect(pstSavm, pstSavm->tblName); + return lRet; + } + } + else if(HAVE_HASH_IDX(pstSavm->tblName)) + { + lRet = _lDeleteHash(pstSavm, pstRun->m_pvAddr, pstSavm->tblName); + if(RC_CONTU != lRet) + { + vTblDisconnect(pstSavm, pstSavm->tblName); + return lRet; + } + } + + lRet = _lDeleteTruck(pstSavm, pstRun->m_pvAddr, pstSavm->tblName); + vTblDisconnect(pstSavm, pstSavm->tblName); + return lRet; +} + +/************************************************************************************************* + description:Statistical compliance record + parameters: + pstSavm --stvm handle + pvAddr --memory address + t --table + plCount --index value + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lCountIndex(SATvm *pstSavm, void *pvAddr, TABLE t, size_t *plCount) +{ + SHTree *pstTree = NULL; + SHTruck *pstTruck = NULL; + char szIdx[MAX_INDEX_LEN]; + + memset(szIdx, 0, sizeof(szIdx)); + if(NULL == pGetIndex(&pstSavm->stCond, lGetIdxNum(t), pGetTblIdx(t), pstSavm->pstVoid, szIdx)) + return RC_CONTU; + + pstSavm->m_lEType = EXE_PLAN_IDX; + if(NULL == (pstTree = pGetNode(pvAddr, ((TblDef *)pvAddr)->m_lTreeRoot))) + { + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + if(NULL == (pstTree = pSearchTree(pvAddr, pstTree, szIdx, lGetIdxLen(t)))) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_FAIL; + } + + pstTruck = (PSHTruck)pGetNode(pvAddr, pstTree->m_lData); + if(RC_MISMA == lFeildMatch(&pstSavm->stCond, pstTruck->m_pvData, pstSavm->pstVoid)) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_FAIL; + } + + pstSavm->m_lEffect = *plCount = 1; + return RC_SUCC; +} + +/************************************************************************************************* + description:The statistics matches the index record + parameters: + pstSavm --stvm handle + pvAddr --memory address + t --table + plCount + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lCountGroup(SATvm *pstSavm, void *pvAddr, TABLE t, size_t *plCount) +{ + size_t lNext; + SHList *pstList = NULL; + SHTruck *pstTruck = NULL; + char szIdx[MAX_INDEX_LEN]; + SHTree *pstRoot = NULL, *pstTree = NULL; + + memset(szIdx, 0, sizeof(szIdx)); + if(NULL == pGetIndex(&pstSavm->stCond, lGetGrpNum(t), pGetTblGrp(t), pstSavm->pstVoid, szIdx)) + return RC_CONTU; + + *plCount = 0; + if(NULL == (pstRoot = (SHTree *)pGetNode(pvAddr, ((TblDef *)pvAddr)->m_lGroupRoot))) + { + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + if(NULL == (pstTree = pSearchTree(pvAddr, pstRoot, szIdx, lGetGrpLen(t)))) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_SUCC; + } + + pstList = (SHList *)pGetNode(pvAddr, pstTree->m_lData); + if(lGetGrpNum(t) == pstSavm->stCond.uFldcmp) + { + *plCount = lGetListCount(pvAddr, pstList); + pstSavm->m_lEffect = *plCount; + return RC_SUCC; + } + + for(; SELF_POS_UNUSE != pstList->m_lPos; pstList = (SHList *)pGetNode(pvAddr, lNext)) + { + lNext = pstList->m_lNext; + pstTruck = (PSHTruck)pGetNode(pvAddr, pstList->m_lData); + if(RC_MISMA == lFeildMatch(&pstSavm->stCond, pstTruck->m_pvData, pstSavm->pstVoid)) + { + if(SELF_POS_UNUSE == pstList->m_lNext) break; + continue; + } + + (*plCount) ++; + if(SELF_POS_UNUSE == lNext) break; + } + + if(0 == (pstSavm->m_lEffect = *plCount)) + pstSavm->m_lErrno = NO_DATA_FOUND; + + return RC_SUCC; +} + +/************************************************************************************************* + description:The statistics matches the hash record + parameters: + pstSavm --stvm handle + pvAddr --memory address + pstTree --tree node + t --table + psvIdx --index value + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lCountHash(SATvm *pstSavm, void *pvAddr, TABLE t, size_t *plCount) +{ + size_t lIdx, lNext; + SHList *pstList = NULL; + SHTruck *pstTruck = NULL; + SHTree *pstTree = NULL; + char szIdx[MAX_INDEX_LEN]; + + memset(szIdx, 0, sizeof(szIdx)); + if(NULL == pGetIndex(&pstSavm->stCond, lGetGrpNum(t), pGetTblGrp(t), pstSavm->pstVoid, szIdx)) + return RC_CONTU; + + *plCount = 0; + lIdx = uGetHash(szIdx, lGetGrpLen(t)) % ((TblDef *)pvAddr)->m_lMaxRow; + pstTree = pvAddr + ((TblDef *)pvAddr)->m_lGroupRoot + lIdx * sizeof(SHTree); + if(NULL == pstTree || SELF_POS_UNUSE == pstTree->m_lData) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_SUCC; + } + + for(pstList = (SHList *)pGetNode(pvAddr, pstTree->m_lData); + SELF_POS_UNUSE != pstList->m_lPos; pstList = (SHList *)pGetNode(pvAddr, lNext)) + { + lNext = pstList->m_lNext; + pstTruck = (PSHTruck)pGetNode(pvAddr, pstList->m_lData); + if(RC_MISMA == lFeildMatch(&pstSavm->stCond, pstTruck->m_pvData, pstSavm->pstVoid)) + { + if(SELF_POS_UNUSE == pstList->m_lNext) break; + continue; + } + + (*plCount) ++; + if(SELF_POS_UNUSE == lNext) break; + } + + if(0 == (pstSavm->m_lEffect = *plCount)) + pstSavm->m_lErrno = NO_DATA_FOUND; + + return RC_SUCC; +} + +/************************************************************************************************* + description:The statistics matches the truck record + parameters: + pstSavm --stvm handle + pvAddr --memory address + t --table + plCount --count + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lCountTruck(SATvm *pstSavm, void *pvAddr, TABLE t, size_t *plCount) +{ + SHTruck *pstTruck = NULL; + FdCond *pstCond = &pstSavm->stCond; + size_t lRow = 0, lOffset = lGetTblData(t); + + for(*plCount = 0; (lRow < ((TblDef *)pvAddr)->m_lValid) && (lOffset < lGetTableSize(t)); + lOffset += lGetRowTruck(t)) + { + pstTruck = (PSHTruck)pGetNode(pvAddr, lOffset); + if(IS_TRUCK_NULL(pstTruck)) + continue; + + ++ lRow; + if(RC_MISMA == lFeildMatch(pstCond, pstTruck->m_pvData, pstSavm->pstVoid)) + continue; + + (*plCount) ++; + } + + if(0 == (pstSavm->m_lEffect = *plCount)) + pstSavm->m_lErrno = NO_DATA_FOUND; + + return RC_SUCC; +} + +/************************************************************************************************* + description:API - lCount + parameters: + pstSavm --stvm handle + plCount --count + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lCount(SATvm *pstSavm, size_t *plCount) +{ + long lRet; + RunTime *pstRun = NULL; + RWLock *prwLock = NULL; + + if(!pstSavm || !plCount) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + if(NULL == (pstRun = (RunTime *)pInitMemTable(pstSavm, pstSavm->tblName))) + return RC_FAIL; + + if(RES_REMOT_SID == pstRun->m_lLocal) + { + Tremohold(pstSavm, pstRun); + return _lCountByRt(pstSavm, plCount); + } + + if(((TblDef *)pstRun->m_pvAddr)->m_lValid <= 0) + { + *plCount = 0; + vTblDisconnect(pstSavm, pstSavm->tblName); + return RC_SUCC; + } + + if(!pstSavm->pstVoid || pstSavm->stCond.uFldcmp == 0) + { + *plCount = ((TblDef *)pstRun->m_pvAddr)->m_lValid; + pstSavm->m_lEffect = *plCount; + vTblDisconnect(pstSavm, pstSavm->tblName); + return RC_SUCC; + } + + if(HAVE_UNIQ_IDX(pstSavm->tblName)) + { + lRet = _lCountIndex(pstSavm, pstRun->m_pvAddr, pstSavm->tblName, plCount); + if(RC_CONTU != lRet) + { + pstSavm->m_lEType = EXE_PLAN_IDX; + vTblDisconnect(pstSavm, pstSavm->tblName); + return lRet; + } + } + + if(HAVE_NORL_IDX(pstSavm->tblName)) + { + lRet = _lCountGroup(pstSavm, pstRun->m_pvAddr, pstSavm->tblName, plCount); + if(RC_CONTU != lRet) + { + pstSavm->m_lEType = EXE_PLAN_GRP; + vTblDisconnect(pstSavm, pstSavm->tblName); + return lRet; + } + } + else if(HAVE_HASH_IDX(pstSavm->tblName)) + { + lRet = _lCountHash(pstSavm, pstRun->m_pvAddr, pstSavm->tblName, plCount); + if(RC_CONTU != lRet) + { + pstSavm->m_lEType = EXE_PLAN_GRP; + vTblDisconnect(pstSavm, pstSavm->tblName); + return lRet; + } + } + + pstSavm->m_lEType = EXE_PLAN_ALL; + lRet = _lCountTruck(pstSavm, pstRun->m_pvAddr, pstSavm->tblName, plCount); + vTblDisconnect(pstSavm, pstSavm->tblName); + return lRet; +} + +/************************************************************************************************* + description:Rebuild unique index + parameters: + pstSavm --stvm handle + pstRoot --tree root + psvIdx --index value + lIdx --index length + lRow --rows + lData --data offset + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +SHTree* pRebuildTree(SATvm *pstSavm, SHTree *pstRoot, void *psvIdx, long lIdx, long lRow, size_t lData) +{ + int nRet = 0; + size_t lOffset, lPos = 0, lNext = 0; + void *pvData = NULL, *pvAddr = pGetAddr(pstSavm, pstSavm->tblName); + SHTree *pstNode = NULL, *pstCur = NULL, *pstNext = NULL, *pstTree = pstRoot; + + while(SELF_POS_UNUSE != pstTree->m_lSePos && NODE_NULL != pstTree->m_lSePos) + { + pstNode = pstTree; + nRet = memcmp(pstTree->m_szIdx, psvIdx, lIdx); + if(0 < nRet) + { + if(NODE_NULL == pstTree->m_lLeft) + break; + pstTree = (SHTree *)pGetNode(pvAddr, pstTree->m_lLeft); + } + else if(0 > nRet) + { + if(NODE_NULL == pstTree->m_lRight) + break; + pstTree = (SHTree *)pGetNode(pvAddr, pstTree->m_lRight); + } + else + { + pstSavm->m_lErrno = UNIQ_IDX_REPT; + return NULL; + } + } + + lOffset = sizeof(SHTree) * lRow + lGetIdxPos(pstSavm->tblName); + if(NULL == (pstCur = pCreateNode(pvAddr, pstSavm->tblName, lOffset))) + { + pstSavm->m_lErrno = SVR_EXCEPTION; + return NULL; + } + + lPos = pstCur->m_lData; + pstCur->m_lIdx = lIdx; + pstCur->m_lSePos = lOffset; + pstCur->m_lData = lData; + pstCur->m_lParent = NODE_NULL; + memcpy(pstCur->m_szIdx, psvIdx, pstCur->m_lIdx); + pstCur->m_lLeft = pstCur->m_lRight = NODE_NULL; + + if(lData != lPos) + { + lNext = (lData - lGetTblData(pstSavm->tblName)) / lGetRowTruck(pstSavm->tblName); + pstNext = (SHTree *)pGetNode(pvAddr, lNext * sizeof(SHTree) + lGetIdxPos(pstSavm->tblName)); + pstNext->m_lData = lPos; + } + + if(pstNode != NULL) + { + pstCur->m_eColor = COLOR_RED; + pstCur->m_lParent = pstNode->m_lSePos; + if(0 < memcmp(pstNode->m_szIdx, pstCur->m_szIdx, pstCur->m_lIdx)) + pstNode->m_lLeft = pstCur->m_lSePos; + else + pstNode->m_lRight = pstCur->m_lSePos; + } + else + { + pstRoot = pstCur; + pstCur->m_eColor = COLOR_BLK; + return pstRoot; + } + + return _pFixupInsert(pvAddr, pstRoot, pstCur); +} + +/************************************************************************************************* + description:Rebuild the index node + parameters: + pvAddr --memory address + t --table + pstGroup --group node + lGroup --group offset + lRow --rows + lData --data offset + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +SHTree* _pRebuildGroup(void *pvAddr, TABLE t, SHTree *pstGroup, long lGroup, long lRow, size_t lData) +{ + size_t lOffset = 0, lPos = 0, lNext = 0; + SHList *pstList = NULL, *pstNode = NULL, *pstNext = NULL; + + if(!pstGroup) pstGroup = (SHTree *)(pvAddr + lGroup); + lOffset = lGetListOfs(t) + sizeof(SHList) * lRow; + pstList = (SHList *)pGetNode(pvAddr, lOffset); + pstList->m_lPos = lOffset; + lPos = pstList->m_lData; + pstList->m_lData= lData; + + if(lData != lPos) + { + lNext = (lData - lGetTblData(t)) / lGetRowTruck(t); + pstNext = (SHList *)pGetNode(pvAddr, lNext * sizeof(SHList) + lGetListOfs(t)); + pstNext->m_lData = lPos; + } + + if(pstGroup->m_lData == SELF_POS_UNUSE) + { + pstList->m_lNode = lGroup; + pstGroup->m_lData = pstList->m_lPos; + } + else + { + pstNode = (SHList *)pGetNode(pvAddr, pstGroup->m_lData); + + pstList->m_lNext = pstNode->m_lNext; + pstList->m_lLast = pstNode->m_lPos; + if(SELF_POS_UNUSE != pstNode->m_lNext) + ((SHList *)pGetNode(pvAddr, pstNode->m_lNext))->m_lLast = pstList->m_lPos; + pstNode->m_lNext = pstList->m_lPos; + } + + return pstGroup; +} + +/************************************************************************************************* + description:Rebuild the hash index node + parameters: + pstSavm --stvm handle + t --table + pvAddr --Memory address + pstTree --tree node + lRow --rows + lData --data offset + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lRebuildHash(SATvm *pstSavm, TABLE t, void *pvAddr, SHTree *pstTree, size_t lRow, size_t lData) +{ + size_t lOffset = 0, lPos, lNext; + SHList *pstList = NULL, *pstNode = NULL, *pstNext = NULL; + + lOffset = lGetListOfs(t) + sizeof(SHList) * lRow; + pstList = (SHList *)pGetNode(pvAddr, lOffset); + pstList->m_lPos = lOffset; + lPos = pstList->m_lData; + pstList->m_lData= lData; + + if(lData != lPos) + { + lNext = (lData - lGetTblData(t)) / lGetRowTruck(t); + pstNext = (SHList *)pGetNode(pvAddr, lNext * sizeof(SHList) + lGetListOfs(t)); + pstNext->m_lData = lPos; + } + + if(SELF_POS_UNUSE == pstTree->m_lSePos || NODE_NULL == pstTree->m_lSePos) + { + pstTree->m_lSePos= (void *)pstTree - pvAddr; + pstList->m_lNode = pstTree->m_lSePos; + pstTree->m_lData = pstList->m_lPos; + } + else + { + pstNode = (SHList *)pGetNode(pvAddr, pstTree->m_lData); + + pstList->m_lNext = pstNode->m_lNext; + pstList->m_lLast = pstNode->m_lPos; + if(SELF_POS_UNUSE != pstNode->m_lNext) + ((SHList *)pGetNode(pvAddr, pstNode->m_lNext))->m_lLast = pstList->m_lPos; + pstNode->m_lNext = pstList->m_lPos; + } + + return RC_SUCC; +} + +/************************************************************************************************* + description:Rebuild the index + parameters: + pstSavm --stvm handle + pstRoot --root node + psvIdx --index values + lRow --rows + lData --data offset + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +SHTree* pRebuildGroup(SATvm *pstSavm, SHTree *pstRoot, char *psvIdx, long lIdx, long lRow, size_t lData) +{ + int nRet; + size_t lOffset; + SHTruck *pstTruck = NULL; + void *pvAddr = pGetAddr(pstSavm, pstSavm->tblName); + SHTree *pstNode = NULL, *pstCur = NULL, *pstTree = pstRoot; + + while(SELF_POS_UNUSE != pstTree->m_lSePos && NODE_NULL != pstTree->m_lSePos) + { + pstNode = pstTree; + nRet = memcmp(pstTree->m_szIdx, psvIdx, lIdx); + if(0 < nRet) + { + if(NODE_NULL == pstTree->m_lLeft) + break; + pstTree = (SHTree *)pGetNode(pvAddr, pstTree->m_lLeft); + } + else if(0 > nRet) + { + if(NODE_NULL == pstTree->m_lRight) + break; + pstTree = (SHTree *)pGetNode(pvAddr, pstTree->m_lRight); + } + else + { + _pRebuildGroup(pvAddr, pstSavm->tblName, pstTree, 0, lRow, lData); + return pstRoot; + } + } + + lOffset = sizeof(SHTree) * ((TblDef *)pvAddr)->m_lGroup + lGetGrpPos(pstSavm->tblName); + if(NULL == (pstCur = _pRebuildGroup(pvAddr, pstSavm->tblName, NULL, lOffset, lRow, lData))) + { + pstSavm->m_lErrno = SVR_EXCEPTION; + return pstRoot; + } + + pstCur->m_lIdx = lIdx; + pstCur->m_lSePos = lOffset; + pstCur->m_lParent = NODE_NULL; + memcpy(pstCur->m_szIdx, psvIdx, pstCur->m_lIdx); + pstCur->m_lLeft = pstCur->m_lRight = NODE_NULL; + ((TblDef *)pvAddr)->m_lGroup ++; + + if(pstNode != NULL) + { + pstCur->m_eColor = COLOR_RED; + pstCur->m_lParent = pstNode->m_lSePos; + if(0 < memcmp(pstNode->m_szIdx, pstCur->m_szIdx, pstCur->m_lIdx)) + pstNode->m_lLeft = pstCur->m_lSePos; + else + pstNode->m_lRight = pstCur->m_lSePos; + } + else + { + pstRoot = pstCur; + pstCur->m_eColor = COLOR_BLK; + return pstRoot; + } + + return _pFixupInsert(pvAddr, pstRoot, pstCur); +} + +/************************************************************************************************* + description:API - truncate (without transactions) + parameters: + pstSavm --stvm handle + t --table + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lTruncate(SATvm *pstSavm, TABLE t) +{ + void *pvData = NULL; + RunTime *pstRun = NULL; + RWLock *prwLock = NULL; + + if(!pstSavm) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + if(NULL == (pstRun = (RunTime *)pInitHitTest(pstSavm, t))) + return RC_FAIL; + + if(RES_REMOT_SID == pstRun->m_lLocal) + { + Tremohold(pstSavm, pstRun); + return _lTruncateByRt(pstSavm, t); + } + + prwLock = (RWLock *)pGetRWLock(pstRun->m_pvAddr); + if(RC_SUCC != pthread_rwlock_wrlock(prwLock)) + { + pstSavm->m_lErrno = LOCK_DOWR_ERR; + vTblDisconnect(pstSavm, pstSavm->tblName); + return RC_FAIL; + } + + if(RC_SUCC != lInitailTree(pstSavm, (void *)pGetNode(pstRun->m_pvAddr, lGetIdxPos(t)), t)) + { + pthread_rwlock_unlock(prwLock); + vTblDisconnect(pstSavm, t); + return RC_FAIL; + } + + if(RC_SUCC != lInitailGroup(pstSavm, (void *)pGetNode(pstRun->m_pvAddr, lGetGrpPos(t)), t)) + { + pthread_rwlock_unlock(prwLock); + vTblDisconnect(pstSavm, t); + return RC_FAIL; + } + + pstSavm->m_lEffect = ((TblDef *)pstRun->m_pvAddr)->m_lValid; + pvData = (void *)pGetNode(pstRun->m_pvAddr, lGetTblData(t)); + memset(pvData, 0, lGetTableSize(t) - lGetTblData(t)); + ((TblDef *)pstRun->m_pvAddr)->m_lGroup = 0; + ((TblDef *)pstRun->m_pvAddr)->m_lValid = 0; + + pthread_rwlock_unlock(prwLock); + vTblDisconnect(pstSavm, t); + + return RC_SUCC; +} + +/************************************************************************************************* + description:Index reconstruction based on data area data + parameters: + pstSavm --stvm handle + pvAddr --memory address + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lRebuildIndex(SATvm *pstSavm, void *pvAddr) +{ + SHTruck *pstTruck = NULL; + char szIdx[MAX_INDEX_LEN]; + TABLE t = pstSavm->tblName; + SHTree *pstIRoot = NULL, *pstGRoot = NULL; + size_t lRow = 0, lOffset = lGetTblData(t), lIdx; + + if(RC_SUCC != lInitailTree(pstSavm, (void *)pGetNode(pvAddr, lGetIdxPos(t)), t)) + return RC_FAIL; + + if(RC_SUCC != lInitailGroup(pstSavm, (void *)pGetNode(pvAddr, lGetGrpPos(t)), t)) + return RC_FAIL; + + ((TblDef *)pvAddr)->m_lGroup = 0; + ((TblDef *)pvAddr)->m_lGroupRoot = ((TblDef *)pvAddr)->m_lGroupPos; + pstTruck = (PSHTruck)pGetNode(pvAddr, lOffset); + for(lRow = 0; (lRow < ((TblDef *)pvAddr)->m_lValid) && (lOffset < lGetTableSize(t)); + lOffset += lGetRowTruck(t), pstTruck = (PSHTruck)pGetNode(pvAddr, lOffset)) + { + if(IS_TRUCK_NULL(pstTruck)) + continue; + + if(HAVE_UNIQ_IDX(t)) + { + memset(szIdx, 0, sizeof(szIdx)); + if(NULL == pPickIndex(lGetIdxNum(t), pGetTblIdx(t), pstTruck->m_pvData, szIdx)) + { + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + pstIRoot = (SHTree *)pGetNode(pvAddr, ((TblDef *)pvAddr)->m_lTreeRoot); + pstIRoot = pRebuildTree(pstSavm, pstIRoot, szIdx, lGetIdxLen(t), lRow, lOffset); + if(!pstIRoot) return RC_FAIL; + + ((TblDef *)pvAddr)->m_lTreeRoot = pstIRoot->m_lSePos; + } + + if(HAVE_NORL_IDX(t)) + { + memset(szIdx, 0, sizeof(szIdx)); + if(NULL == pPickIndex(lGetGrpNum(t), pGetTblGrp(t), pstTruck->m_pvData, szIdx)) + { + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + pstGRoot = (SHTree *)pGetNode(pvAddr, ((TblDef *)pvAddr)->m_lGroupRoot); + pstGRoot = pRebuildGroup(pstSavm, pstGRoot, szIdx, lGetGrpLen(t), lRow, lOffset); + if(!pstGRoot) return RC_FAIL; + + ((TblDef *)pvAddr)->m_lGroupRoot = pstGRoot->m_lSePos; + } + else if(HAVE_HASH_IDX(t)) + { + memset(szIdx, 0, sizeof(szIdx)); + if(NULL == pPickIndex(lGetGrpNum(t), pGetTblGrp(t), pstTruck->m_pvData, szIdx)) + { + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + lIdx = uGetHash(szIdx, lGetGrpLen(t)) % ((TblDef *)pvAddr)->m_lMaxRow; + pstGRoot = pvAddr + ((TblDef *)pvAddr)->m_lGroupPos + lIdx * sizeof(SHTree); + if(NULL == pstGRoot) return RC_FAIL; + + if(RC_SUCC != lRebuildHash(pstSavm, t, pvAddr, pstGRoot, lRow, lOffset)) + return RC_FAIL; + } + + lRow ++; + } + + return RC_SUCC; +} + +/************************************************************************************************* + description:The index rebuild + parameters: + pstSavm --stvm handle + t --table + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lRebuildIndex(SATvm *pstSavm, TABLE t) +{ + long lRet; + RunTime *pstRun = NULL; + RWLock *prwLock = NULL; + + if(!pstSavm) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + if(RC_SUCC != lInitSATvm(pstSavm, t)) + return RC_FAIL; + + if(NULL == (pstRun = (RunTime *)pInitHitTest(pstSavm, pstSavm->tblName))) + return RC_FAIL; + + if(RES_REMOT_SID == pstRun->m_lLocal) + { + pstSavm->m_lErrno = RMT_NOT_SUPPT; + return RC_FAIL; + } + + if(!HAVE_INDEX(pstSavm->tblName)) + { + vTblDisconnect(pstSavm, pstSavm->tblName); + return RC_SUCC; + } + + prwLock = (RWLock *)pGetRWLock(pstRun->m_pvAddr); + if(RC_SUCC != pthread_rwlock_wrlock(prwLock)) + { + pstSavm->m_lErrno = LOCK_DOWR_ERR; + vTblDisconnect(pstSavm, pstSavm->tblName); + return RC_FAIL; + } + + pstSavm->lSize = lGetRowSize(t); + lRet = _lRebuildIndex(pstSavm, pstRun->m_pvAddr); + pthread_rwlock_unlock(prwLock); + vTblDisconnect(pstSavm, pstSavm->tblName); + + return lRet; +} + +/************************************************************************************************* + description:Select the table data according to the hash + parameters: + pstSavm --stvm handle + pvAddr --memory address + t --table + psvOut --result data + plData --offset + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lSelectHash(SATvm *pstSavm, void *pvAddr, TABLE t, void *psvOut, size_t *plData) +{ + size_t lData, lIdx; + SHTree *pstTree = NULL; + SHList *pstList = NULL; + SHTruck *pstTruck = NULL; + char szIdx[MAX_INDEX_LEN], *pvData = NULL; + RWLock *prwLock = (RWLock *)pGetRWLock(pvAddr); + + memset(szIdx, 0, sizeof(szIdx)); + if(NULL == pGetIndex(&pstSavm->stCond, lGetGrpNum(t), pGetTblGrp(t), pstSavm->pstVoid, szIdx)) + return RC_CONTU; + + lIdx = uGetHash(szIdx, lGetGrpLen(t)) % ((TblDef *)pvAddr)->m_lMaxRow; + pstTree = pvAddr + ((TblDef *)pvAddr)->m_lGroupRoot + lIdx * sizeof(SHTree); + if(NULL == pstTree || SELF_POS_UNUSE == pstTree->m_lData) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_FAIL; + } + + if(RC_SUCC != pthread_rwlock_rdlock(prwLock)) + { + pstSavm->m_lErrno = LOCK_DORD_ERR; + return RC_FAIL; + } + + pstList = (SHList *)pGetNode(pvAddr, pstTree->m_lData); + for(pstSavm->m_lEType = EXE_PLAN_GRP; SELF_POS_UNUSE != pstList->m_lPos; + pstList = (SHList *)pGetNode(pvAddr, pstList->m_lNext)) + { + pstTruck = (PSHTruck)pGetNode(pvAddr, pstList->m_lData); + if(RC_MATCH == lFeildMatch(&pstSavm->stCond, pstTruck->m_pvData, pstSavm->pstVoid)) + { + if(1 < (++ pstSavm->m_lEffect)) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = MORE_ROWS_SEL; + return RC_FAIL; + } + + *plData = pstList->m_lData; + pvData = pstTruck->m_pvData; + if(FIRST_ROW & pstSavm->lFind) break; + } + + if(SELF_POS_UNUSE == pstList->m_lNext) break; + } + + if(0 == pstSavm->m_lEffect) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_FAIL; + } + + memcpy(psvOut, pvData, lGetRowSize(pstSavm->tblName)); + pthread_rwlock_unlock(prwLock); + pstTruck->m_lTimes ++; + return RC_SUCC; +} + +/************************************************************************************************* + description:Select the table data according to the index + parameters: + pstSavm --stvm handle + pvAddr --memory address + t --table + psvOut --result data + plData --offset + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lSelectGroup(SATvm *pstSavm, void *pvAddr, TABLE t, void *psvOut, size_t *plData) +{ + void *pvData = NULL; + SHList *pstList = NULL; + SHTree *pstTree = NULL; + SHTruck *pstTruck = NULL; + char szIdx[MAX_INDEX_LEN]; + RWLock *prwLock = (RWLock *)pGetRWLock(pvAddr); + + memset(szIdx, 0, sizeof(szIdx)); + if(NULL == pGetIndex(&pstSavm->stCond, lGetGrpNum(t), pGetTblGrp(t), pstSavm->pstVoid, szIdx)) + return RC_CONTU; + + if(RC_SUCC != pthread_rwlock_rdlock(prwLock)) + { + pstSavm->m_lErrno = LOCK_DORD_ERR; + return RC_FAIL; + } + + if(NULL == (pstTree = (SHTree *)pGetNode(pvAddr, ((TblDef *)pvAddr)->m_lGroupRoot))) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + if(NULL == (pstList = pSearchGroup(pvAddr, pstTree, szIdx, lGetGrpLen(t)))) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_CONTU; + } + + for(pstSavm->m_lEType = EXE_PLAN_GRP; SELF_POS_UNUSE != pstList->m_lPos; + pstList = (SHList *)pGetNode(pvAddr, pstList->m_lNext)) + { + pstTruck = (PSHTruck)pGetNode(pvAddr, pstList->m_lData); + if(RC_MATCH == lFeildMatch(&pstSavm->stCond, pstTruck->m_pvData, pstSavm->pstVoid)) + { + if(1 < (++ pstSavm->m_lEffect)) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = MORE_ROWS_SEL; + return RC_FAIL; + } + + *plData = pstList->m_lData; + pvData = pstTruck->m_pvData; + if(FIRST_ROW & pstSavm->lFind) break; + } + + if(SELF_POS_UNUSE == pstList->m_lNext) break; + } + + if(0 == pstSavm->m_lEffect) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_FAIL; + } + + memcpy(psvOut, pvData, lGetRowSize(pstSavm->tblName)); + pthread_rwlock_unlock(prwLock); + pstTruck->m_lTimes ++; + + return RC_SUCC; +} + +/************************************************************************************************* + description:Select the table data according to the truck + parameters: + pstSavm --stvm handle + pvAddr --memory address + t --table + psvOut --result data + plData --offset + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lSelectTruck(SATvm *pstSavm, void *pvAddr, TABLE t, void *psvOut, size_t *plData) +{ + void *pvData = NULL; + SHTruck *pstTruck = NULL; + size_t lRow = 0, lOffset = lGetTblData(t); + RWLock *prwLock = (RWLock *)pGetRWLock(pvAddr); + + if(RC_SUCC != pthread_rwlock_rdlock(prwLock)) + { + pstSavm->m_lErrno = LOCK_DORD_ERR; + return RC_FAIL; + } + + pstSavm->m_lEType = EXE_PLAN_ALL; + pstTruck = (PSHTruck)pGetNode(pvAddr, lOffset); + for(lRow = 0; (lRow < ((TblDef *)pvAddr)->m_lValid) && (lOffset < lGetTableSize(t)); + pstTruck = (PSHTruck)pGetNode(pvAddr, lOffset)) + { + if(IS_TRUCK_NULL(pstTruck)) + { + lOffset += lGetRowTruck(t); + continue; + } + + lRow ++; + if(RC_MISMA == lFeildMatch(&pstSavm->stCond, pstTruck->m_pvData, pstSavm->pstVoid)) + { + lOffset += lGetRowTruck(t); + continue; + } + + if(1 < (++ pstSavm->m_lEffect)) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = MORE_ROWS_SEL; + return RC_FAIL; + } + + *plData = lOffset; + lOffset+= lGetRowTruck(t); + pvData = pstTruck->m_pvData; + if(FIRST_ROW & pstSavm->lFind) break; + } + + if(0 == pstSavm->m_lEffect) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_FAIL; + } + + memcpy(psvOut, pvData, lGetRowSize(pstSavm->tblName)); + pthread_rwlock_unlock(prwLock); + pstTruck->m_lTimes ++; + return RC_SUCC; +} + +/************************************************************************************************* + description:Select the table data according to the Unique index + parameters: + pstSavm --stvm handle + pvAddr --memory address + t --table + psvOut --result data + plData --offset + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lSelectIndex(SATvm *pstSavm, void *pvAddr, TABLE t, void *psvOut, size_t *plData) +{ + SHTree *pstTree = NULL; + SHTruck *pstTruck = NULL; + char szIdx[MAX_INDEX_LEN]; + RWLock *prwLock = (RWLock *)pGetRWLock(pvAddr); + + memset(szIdx, 0, sizeof(szIdx)); + if(NULL == pGetIndex(&pstSavm->stCond, lGetIdxNum(t), pGetTblIdx(t), pstSavm->pstVoid, szIdx)) + return RC_CONTU; + + if(RC_SUCC != pthread_rwlock_rdlock(prwLock)) + { + pstSavm->m_lErrno = LOCK_DORD_ERR; + return RC_FAIL; + } + + pstSavm->m_lEType = EXE_PLAN_IDX; + if(NULL == (pstTree = (SHTree *)pGetNode(pvAddr, ((TblDef *)pvAddr)->m_lTreeRoot))) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + pstTree = (SHTree *)pSearchTree(pvAddr, pstTree, szIdx, lGetIdxLen(pstSavm->tblName)); + if(!pstTree) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_FAIL; + } + + pstTruck = (PSHTruck)pGetNode(pvAddr, pstTree->m_lData); + if(RC_MISMA == lFeildMatch(&pstSavm->stCond, pstTruck->m_pvData, pstSavm->pstVoid)) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + memcpy(psvOut, pstTruck->m_pvData, lGetRowSize(pstSavm->tblName)); + pthread_rwlock_unlock(prwLock); + pstTruck->m_lTimes ++; + pstSavm->m_lEffect = 1; + *plData = pstTree->m_lData; + + return RC_SUCC; +} + +/************************************************************************************************* + description:Group the table data according to the index + parameters: + pstSavm --stvm handle + pvAddr --memory address + t --table + plData --offset + ppsvOut --result data list + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lGroupIndex(SATvm *pstSavm, void *pvAddr, TABLE t, size_t *plOut, void **ppsvOut) +{ + SHTree *pstTree = NULL; + SHTruck *pstTruck = NULL; + char szIdx[MAX_INDEX_LEN]; + + memset(szIdx, 0, sizeof(szIdx)); + if(NULL == pGetIndex(&pstSavm->stCond, lGetIdxNum(t), pGetTblIdx(t), pstSavm->pstVoid, szIdx)) + return RC_CONTU; + + if(NULL == (pstTree = (SHTree *)pGetNode(pvAddr, ((TblDef *)pvAddr)->m_lTreeRoot))) + { + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + pstTree = (SHTree *)pSearchTree(pvAddr, pstTree, szIdx, lGetIdxLen(pstSavm->tblName)); + if(!pstTree) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_FAIL; + } + + pstTruck = (PSHTruck)pGetNode(pvAddr, pstTree->m_lData); + if(RC_MISMA == lFeildMatch(&pstSavm->stCond, pstTruck->m_pvData, pstSavm->pstVoid)) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_FAIL; + } + + *plOut = 0; + return lInsertLstgrp(pstSavm, &pstSavm->stUpdt, pstTruck->m_pvData, t, plOut, ppsvOut); +} + +/************************************************************************************************* + description:Group the group tree + parameters: + pstSavm --stvm handle + pvAddr --memory address + pstree --tree node + plData --offset + ppsvOut --result data list + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lGroupTree(SATvm *pstSavm, void *pvAddr, SHTree *pstTree, FdCond *pstRrp, size_t *plOut, + void **ppsvOut) +{ + size_t lCount; + SHList *pstList = NULL; + SHTruck *pstTruck = NULL; + + if(SELF_POS_UNUSE == pstTree->m_lSePos || NODE_NULL == pstTree->m_lSePos) + return RC_SUCC; + + pstList = (SHList *)pGetNode(pvAddr, pstTree->m_lData); + pstTruck = (PSHTruck)pGetNode(pvAddr, pstList->m_lData); + lCount = lGetListCount(pvAddr, pstList); + + if(!bRepeatLstgrp(pstRrp, pstTruck->m_pvData, pstSavm->tblName, *plOut, *ppsvOut)) + { + if(RC_SUCC != lInsertLstgrp(pstSavm, &pstSavm->stUpdt, pstTruck->m_pvData, + pstSavm->tblName, plOut, ppsvOut)) + return RC_FAIL; + } + + if(RC_SUCC != _lGroupTree(pstSavm, pvAddr, (SHTree *)pGetNode(pvAddr, pstTree->m_lLeft), + pstRrp, plOut, ppsvOut)) + return RC_FAIL; + + return _lGroupTree(pstSavm, pvAddr, (SHTree *)pGetNode(pvAddr, pstTree->m_lRight), pstRrp, + plOut, ppsvOut); +} + +/************************************************************************************************* + description:Group the table data according to the group tree + parameters: + pstSavm --stvm handle + pvAddr --memory address + t --table + plData --offset + ppsvOut --result data list + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lGroupGroup(SATvm *pstSavm, void *pvAddr, TABLE t, size_t *plOut, void **ppsvOut) +{ + SHList *pstList = NULL; + SHTree *pstTree = NULL; + SHTruck *pstTruck = NULL; + FdCond *pstRrp = &pstSavm->stUpdt; + char *pszIdx, szIdx[MAX_INDEX_LEN]; + + if(NULL == (pstTree = (SHTree *)pGetNode(pvAddr, ((TblDef *)pvAddr)->m_lGroupRoot))) + { + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + if(bIsGroupFld(t, pstRrp) && NULL == pstSavm->pstVoid) + return _lGroupTree(pstSavm, pvAddr, pstTree, pstRrp, plOut, ppsvOut); + + memset(szIdx, 0, sizeof(szIdx)); + pszIdx = pGetIndex(&pstSavm->stCond, lGetGrpNum(t), pGetTblGrp(t), pstSavm->pstVoid, szIdx); + if(!pszIdx) return RC_CONTU; + + if(NULL == (pstList = pSearchGroup(pvAddr, pstTree, szIdx, lGetGrpLen(t)))) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_CONTU; + } + + for(*plOut = 0; SELF_POS_UNUSE != pstList->m_lPos; + pstList = (SHList *)pGetNode(pvAddr, pstList->m_lNext)) + { + pstTruck = (PSHTruck)pGetNode(pvAddr, pstList->m_lData); + if(RC_MISMA == lFeildMatch(&pstSavm->stCond, pstTruck->m_pvData, pstSavm->pstVoid)) + { + if(SELF_POS_UNUSE == pstList->m_lNext) break; + continue; + } + + if(bRepeatLstgrp(pstRrp, pstTruck->m_pvData, t, *plOut, *ppsvOut)) + { + if(SELF_POS_UNUSE == pstList->m_lNext) break; + continue; + } + + if(RC_SUCC != lInsertLstgrp(pstSavm, &pstSavm->stUpdt, pstTruck->m_pvData, t, + plOut, ppsvOut)) + return RC_FAIL; + + pstSavm->m_lEffect ++; + if(SELF_POS_UNUSE == pstList->m_lNext) break; + } + + if(0 == pstSavm->m_lEffect) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_FAIL; + } + + return RC_SUCC; +} + +/************************************************************************************************* + description:Group the table data according to the hash + parameters: + pstSavm --stvm handle + pvAddr --memory address + t --table + plData --offset + ppsvOut --result data list + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lGroupHash(SATvm *pstSavm, void *pvAddr, TABLE t, size_t *plOut, void **ppsvOut) +{ + size_t lIdx; + SHTree *pstTree = NULL; + SHList *pstList = NULL; + SHTruck *pstTruck = NULL; + char szIdx[MAX_INDEX_LEN]; + FdCond *pstRrp = &pstSavm->stUpdt; + + memset(szIdx, 0, sizeof(szIdx)); + if(NULL == pGetIndex(&pstSavm->stCond, lGetGrpNum(t), pGetTblGrp(t), pstSavm->pstVoid, szIdx)) + return RC_CONTU; + + lIdx = uGetHash(szIdx, lGetGrpLen(t)) % ((TblDef *)pvAddr)->m_lMaxRow; + pstTree = pvAddr + ((TblDef *)pvAddr)->m_lGroupRoot + lIdx * sizeof(SHTree); + if(NULL == pstTree || SELF_POS_UNUSE == pstTree->m_lData) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_FAIL; + } + + for(*plOut = 0, pstList = (SHList *)pGetNode(pvAddr, pstTree->m_lData); + SELF_POS_UNUSE != pstList->m_lPos; pstList = (SHList *)pGetNode(pvAddr, pstList->m_lNext)) + { + pstTruck = (PSHTruck)pGetNode(pvAddr, pstList->m_lData); + if(RC_MISMA == lFeildMatch(&pstSavm->stCond, pstTruck->m_pvData, pstSavm->pstVoid)) + { + if(SELF_POS_UNUSE == pstList->m_lNext) break; + continue; + } + + if(bRepeatLstgrp(pstRrp, pstTruck->m_pvData, t, *plOut, *ppsvOut)) + { + if(SELF_POS_UNUSE == pstList->m_lNext) break; + continue; + } + + if(RC_SUCC != lInsertLstgrp(pstSavm, &pstSavm->stUpdt, pstTruck->m_pvData, t, + plOut, ppsvOut)) + return RC_FAIL; + + pstSavm->m_lEffect ++; + if(SELF_POS_UNUSE == pstList->m_lNext) break; + } + + if(0 == pstSavm->m_lEffect) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_FAIL; + } + + return RC_SUCC; +} + +/************************************************************************************************* + description:Group the table data according to the truck + parameters: + pstSavm --stvm handle + pvAddr --memory address + t --table + plData --offset + ppsvOut --result data list + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lGroupTruck(SATvm *pstSavm, void *pvAddr, TABLE t, size_t *plOut, void **ppsvOut) +{ + SHTruck *pstTruck = NULL; + FdCond *pstRrp = &pstSavm->stUpdt; + size_t lRow = 0, lOffset = lGetTblData(t); + + pstTruck = (PSHTruck)pGetNode(pvAddr, lOffset); + for(*plOut = 0; (lRow < ((TblDef *)pvAddr)->m_lValid) && (lOffset < lGetTableSize(t)); + pstTruck = (PSHTruck)pGetNode(pvAddr, lOffset)) + { + if(IS_TRUCK_NULL(pstTruck)) + { + lOffset += lGetRowTruck(t); + continue; + } + + lRow ++; + if(RC_MISMA == lFeildMatch(&pstSavm->stCond, pstTruck->m_pvData, pstSavm->pstVoid)) + { + lOffset += lGetRowTruck(t); + continue; + } + + if(bRepeatLstgrp(pstRrp, pstTruck->m_pvData, t, *plOut, *ppsvOut)) + { + lOffset += lGetRowTruck(t); + continue; + } + + if(RC_FAIL == lInsertLstgrp(pstSavm, pstRrp, pstTruck->m_pvData, t, plOut, ppsvOut)) + return RC_FAIL; + + lOffset += lGetRowTruck(t); + } + + if(0 == (pstSavm->m_lEffect = *plOut)) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_FAIL; + } + + return RC_SUCC; +} + +/************************************************************************************************* + description:Group the table data according to the index + parameters: + pstSavm --stvm handle + t --table + plData --offset + ppsvOut --result data list + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lGroup(SATvm *pstSavm, RunTime *pstRun, size_t *plOut, void **ppsvOut) +{ + long lRet; + RWLock *prwLock = (RWLock *)pGetRWLock(pstRun->m_pvAddr); + + if(RC_SUCC != pthread_rwlock_rdlock(prwLock)) + { + pstSavm->m_lErrno = LOCK_DORD_ERR; + return RC_FAIL; + } + + if(HAVE_UNIQ_IDX(pstSavm->tblName)) + { + lRet = _lGroupIndex(pstSavm, pstRun->m_pvAddr, pstSavm->tblName, plOut, ppsvOut); + if(RC_CONTU != lRet) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lEType = EXE_PLAN_IDX; + return lRet; + } + } + + if(HAVE_NORL_IDX(pstSavm->tblName)) + { + lRet = _lGroupGroup(pstSavm, pstRun->m_pvAddr, pstSavm->tblName, plOut, ppsvOut); + if(RC_CONTU != lRet) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lEType = EXE_PLAN_GRP; + return lRet; + } + } + else if(HAVE_HASH_IDX(pstSavm->tblName)) + { + lRet = _lGroupHash(pstSavm, pstRun->m_pvAddr, pstSavm->tblName, plOut, ppsvOut); + if(RC_CONTU != lRet) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lEType = EXE_PLAN_GRP; + return lRet; + } + } + + pstSavm->m_lEType = EXE_PLAN_ALL; + lRet = _lGroupTruck(pstSavm, pstRun->m_pvAddr, pstSavm->tblName, plOut, ppsvOut); + pthread_rwlock_unlock(prwLock); + return lRet; +} + +/************************************************************************************************* + description:Group the table data according to the index + parameters: + pstSavm --stvm handle + plOut --number + ppsvOut --result data list + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lGroup(SATvm *pstSavm, size_t *plOut, void **ppsvOut) +{ + RunTime *pstRun = NULL; + + if(!pstSavm) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + if(NULL == (pstRun = (RunTime *)pInitMemTable(pstSavm, pstSavm->tblName))) + return RC_FAIL; + + if(RES_REMOT_SID == pstRun->m_lLocal) + { + Tremohold(pstSavm, pstRun); + return _lGroupByRt(pstSavm, plOut, ppsvOut); + } + + if(RC_FAIL == _lGroup(pstSavm, pstRun, plOut, ppsvOut)) + { + vTblDisconnect(pstSavm, pstSavm->tblName); + return RC_FAIL; + } + + vTblDisconnect(pstSavm, pstSavm->tblName); + return lSortRowList(pstSavm, *plOut, *ppsvOut, lGetRowSize(pstSavm->tblName)); +} + +/************************************************************************************************* + description:Query the table data according to the Unique index + parameters: + pstSavm --stvm handle + pvAddr --memory address + t --table + plData --offset + ppsvOut --result data list + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lQueryIndex(SATvm *pstSavm, void *pvAddr, TABLE t, size_t *plOut, void **ppsvOut) +{ + SHTree *pstTree = NULL; + SHTruck *pstTruck = NULL; + char szIdx[MAX_INDEX_LEN]; + + memset(szIdx, 0, sizeof(szIdx)); + if(NULL == pGetIndex(&pstSavm->stCond, lGetIdxNum(t), pGetTblIdx(t), pstSavm->pstVoid, szIdx)) + return RC_CONTU; + + if(NULL == (pstTree = (SHTree *)pGetNode(pvAddr, ((TblDef *)pvAddr)->m_lTreeRoot))) + { + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + pstTree = (SHTree *)pSearchTree(pvAddr, pstTree, szIdx, lGetIdxLen(pstSavm->tblName)); + if(!pstTree) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_FAIL; + } + + pstTruck = (PSHTruck)pGetNode(pvAddr, pstTree->m_lData); + if(RC_MISMA == lFeildMatch(&pstSavm->stCond, pstTruck->m_pvData, pstSavm->pstVoid)) + { + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + if(NULL == (*ppsvOut = (char *)realloc(*ppsvOut, lGetRowSize(pstSavm->tblName)))) + { + pstSavm->m_lErrno = MALLC_MEM_ERR; + return RC_FAIL; + } + + pstTruck->m_lTimes ++; + *plOut = pstSavm->m_lEffect = 1; + memcpy(*ppsvOut, pstTruck->m_pvData, lGetRowSize(pstSavm->tblName)); + + return RC_SUCC; +} + +/************************************************************************************************* + description:Query the table data according to the hash + parameters: + pstSavm --stvm handle + pvAddr --memory address + t --table + plOut --number + ppsvOut --result data list + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lQueryHash(SATvm *pstSavm, void *pvAddr, TABLE t, size_t *plOut, void **ppsvOut) +{ + SHTree *pstTree = NULL; + SHList *pstList = NULL; + SHTruck *pstTruck = NULL; + size_t lData, lIdx, lPos; + char szIdx[MAX_INDEX_LEN]; + + memset(szIdx, 0, sizeof(szIdx)); + if(NULL == pGetIndex(&pstSavm->stCond, lGetGrpNum(t), pGetTblGrp(t), pstSavm->pstVoid, szIdx)) + return RC_CONTU; + + lIdx = uGetHash(szIdx, lGetGrpLen(t)) % ((TblDef *)pvAddr)->m_lMaxRow; + pstTree = pvAddr + ((TblDef *)pvAddr)->m_lGroupRoot + lIdx * sizeof(SHTree); + if(NULL == pstTree || SELF_POS_UNUSE == pstTree->m_lData) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_FAIL; + } + + pstList = (SHList *)pGetNode(pvAddr, pstTree->m_lData); + for(*plOut = 0, lPos = 0; SELF_POS_UNUSE != pstList->m_lPos; + pstList = (SHList *)pGetNode(pvAddr, pstList->m_lNext)) + { + pstTruck = (PSHTruck)pGetNode(pvAddr, pstList->m_lData); + if(RC_MISMA == lFeildMatch(&pstSavm->stCond, pstTruck->m_pvData, pstSavm->pstVoid)) + { + if(SELF_POS_UNUSE == pstList->m_lNext) break; + continue; + } + + pstTruck->m_lTimes ++; + lPos = (++ (*plOut)) * lGetRowSize(t); + if(NULL == (*ppsvOut = (char *)realloc(*ppsvOut, lPos))) + { + pstSavm->m_lErrno = MALLC_MEM_ERR; + return RC_FAIL; + } + + memcpy(*ppsvOut + (lPos - lGetRowSize(t)), pstTruck->m_pvData, lGetRowSize(t)); + if(SELF_POS_UNUSE == pstList->m_lNext) break; + } + + if(0 == (pstSavm->m_lEffect = *plOut)) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_FAIL; + } + + return RC_SUCC; +} + +/************************************************************************************************* + description:Query the table data according to the group + parameters: + pstSavm --stvm handle + pvAddr --memory address + t --table + plOut --number + ppsvOut --result data list + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lQueryGroup(SATvm *pstSavm, void *pvAddr, TABLE t, size_t *plOut, void **ppsvOut) +{ + size_t lPos; + TblKey *pstIdx = NULL; + SHList *pstList = NULL; + SHTree *pstTree = NULL; + SHTruck *pstTruck = NULL; + char szIdx[MAX_INDEX_LEN]; + + memset(szIdx, 0, sizeof(szIdx)); + if(NULL == pGetIndex(&pstSavm->stCond, lGetGrpNum(t), pGetTblGrp(t), pstSavm->pstVoid, szIdx)) + return RC_CONTU; + + if(NULL == (pstTree = (SHTree *)pGetNode(pvAddr, ((TblDef *)pvAddr)->m_lGroupRoot))) + { + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + if(NULL == (pstList = pSearchGroup(pvAddr, pstTree, szIdx, lGetGrpLen(t)))) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_CONTU; + } + + for(*plOut = 0, lPos = 0; SELF_POS_UNUSE != pstList->m_lPos; + pstList = (SHList *)pGetNode(pvAddr, pstList->m_lNext)) + { + pstTruck = (PSHTruck)pGetNode(pvAddr, pstList->m_lData); + if(RC_MISMA == lFeildMatch(&pstSavm->stCond, pstTruck->m_pvData, pstSavm->pstVoid)) + { + if(SELF_POS_UNUSE == pstList->m_lNext) break; + continue; + } + + pstTruck->m_lTimes ++; + lPos = (++ (*plOut)) * lGetRowSize(t); + if(NULL == (*ppsvOut = (char *)realloc(*ppsvOut, lPos))) + { + pstSavm->m_lErrno = MALLC_MEM_ERR; + return RC_FAIL; + } + + memcpy(*ppsvOut + (lPos - lGetRowSize(t)), pstTruck->m_pvData, lGetRowSize(t)); + if(SELF_POS_UNUSE == pstList->m_lNext) break; + } + + if(0 == (pstSavm->m_lEffect = *plOut)) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_FAIL; + } + + return RC_SUCC; +} + +/************************************************************************************************* + description:Query the table data according to the truck + parameters: + pstSavm --stvm handle + pvAddr --memory address + t --table + plOut --number + ppsvOut --result data list + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lQueryTruck(SATvm *pstSavm, void *pvAddr, TABLE t, size_t *plOut, void **ppsvOut) +{ + SHTruck *pstTruck = NULL; + size_t lRow = 0, lOffset = lGetTblData(t), lPos = 0; + + pstTruck = (PSHTruck)pGetNode(pvAddr, lOffset); + for(lRow = 0, *plOut = 0; (lRow < ((TblDef *)pvAddr)->m_lValid) && (lOffset < lGetTableSize(t)); + pstTruck = (PSHTruck)pGetNode(pvAddr, lOffset)) + { + if(IS_TRUCK_NULL(pstTruck)) + { + lOffset += lGetRowTruck(t); + continue; + } + + lRow ++; + if(RC_MISMA == lFeildMatch(&pstSavm->stCond, pstTruck->m_pvData, pstSavm->pstVoid)) + { + lOffset += lGetRowTruck(t); + continue; + } + + lPos = (++ (*plOut)) * lGetRowSize(t); + if(NULL == (*ppsvOut = (char *)realloc(*ppsvOut, lPos))) + { + pstSavm->m_lErrno = MALLC_MEM_ERR; + return RC_FAIL; + } + + memcpy(*ppsvOut + (lPos - lGetRowSize(t)), pstTruck->m_pvData, lGetRowSize(t)); + lOffset += lGetRowTruck(t); + } + + if(0 == (pstSavm->m_lEffect = *plOut)) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_FAIL; + } + + return RC_SUCC; +} + +/************************************************************************************************* + description:Query the table data + parameters: + pstSavm --stvm handle + pstRun --table handle + plOut --number + ppsvOut --result data list + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lQuery(SATvm *pstSavm, RunTime *pstRun, size_t *plOut, void **ppsvOut) +{ + long lRet; + RWLock *prwLock = (RWLock *)pGetRWLock(pstRun->m_pvAddr); + + if(RC_SUCC != pthread_rwlock_rdlock(prwLock)) + { + pstSavm->m_lErrno = LOCK_DORD_ERR; + return RC_FAIL; + } + + if(HAVE_UNIQ_IDX(pstSavm->tblName)) + { + lRet = _lQueryIndex(pstSavm, pstRun->m_pvAddr, pstSavm->tblName, plOut, ppsvOut); + if(RC_CONTU != lRet) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lEType = EXE_PLAN_IDX; + return lRet; + } + } + + if(HAVE_NORL_IDX(pstSavm->tblName)) + { + lRet = _lQueryGroup(pstSavm, pstRun->m_pvAddr, pstSavm->tblName, plOut, ppsvOut); + if(RC_CONTU != lRet) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lEType = EXE_PLAN_GRP; + return lRet; + } + } + else if(HAVE_HASH_IDX(pstSavm->tblName)) + { + lRet = _lQueryHash(pstSavm, pstRun->m_pvAddr, pstSavm->tblName, plOut, ppsvOut); + if(RC_CONTU != lRet) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lEType = EXE_PLAN_GRP; + return lRet; + } + } + + pstSavm->m_lEType = EXE_PLAN_ALL; + lRet = _lQueryTruck(pstSavm, pstRun->m_pvAddr, pstSavm->tblName, plOut, ppsvOut); + pthread_rwlock_unlock(prwLock); + + return lRet; +} + +/************************************************************************************************* + description:API - Query + parameters: + pstSavm --stvm handle + plOut --number + ppsvOut --result data list + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lQuery(SATvm *pstSavm, size_t *plOut, void **ppsvOut) +{ + long lRet; + RunTime *pstRun = NULL; + TblKey *pstIdx = NULL; + + if(!pstSavm) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + if(NULL == (pstRun = (RunTime *)pInitMemTable(pstSavm, pstSavm->tblName))) + return RC_FAIL; + + if(RES_REMOT_SID == pstRun->m_lLocal) + { + Tremohold(pstSavm, pstRun); + return _lQueryByRt(pstSavm, plOut, ppsvOut); + } + + if(RC_SUCC != _lQuery(pstSavm, pstRun, plOut, ppsvOut)) + { + vTblDisconnect(pstSavm, pstSavm->tblName); + return RC_FAIL; + } + + vTblDisconnect(pstSavm, pstSavm->tblName); + return lSortRowList(pstSavm, *plOut, *ppsvOut, lGetRowSize(pstSavm->tblName)); +} + +/************************************************************************************************* + description:Select the table data + parameters: + pstSavm --stvm handle + pstRun --table handle + t --table + ppsvOut --result data list + plData --Offset + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lSelect(SATvm *pstSavm, RunTime *pstRun, TABLE t, void *psvOut, size_t *plData) +{ + long lRet; + + if(HAVE_UNIQ_IDX(pstSavm->tblName)) + { + lRet = _lSelectIndex(pstSavm, pstRun->m_pvAddr, pstSavm->tblName, psvOut, plData); + if(RC_CONTU != lRet) return lRet; + } + + if(HAVE_NORL_IDX(pstSavm->tblName)) + { + lRet = _lSelectGroup(pstSavm, pstRun->m_pvAddr, pstSavm->tblName, psvOut, plData); + if(RC_CONTU != lRet) return lRet; + } + else if(HAVE_HASH_IDX(t)) + { + lRet = _lSelectHash(pstSavm, pstRun->m_pvAddr, pstSavm->tblName, psvOut, plData); + if(RC_CONTU != lRet) return lRet; + } + + return _lSelectTruck(pstSavm, pstRun->m_pvAddr, pstSavm->tblName, psvOut, plData); +} + +/************************************************************************************************* + description:API - Select + parameters: + pstSavm --stvm handle + ppsvOut --result data list + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lSelect(SATvm *pstSavm, void *psvOut) +{ + long lRet; + size_t lData = 0; + RunTime *pstRun = NULL; + + if(!pstSavm || !pstSavm->pstVoid) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + if(NULL == (pstRun = (RunTime *)pInitMemTable(pstSavm, pstSavm->tblName))) + return RC_FAIL; + + if(RES_REMOT_SID == pstRun->m_lLocal) + { + Tremohold(pstSavm, pstRun); + return _lSelectByRt(pstSavm, psvOut); + } + + lRet = _lSelect(pstSavm, pstRun, pstSavm->tblName, psvOut, &lData); + vTblDisconnect(pstSavm, pstSavm->tblName); + return lRet; +} + +/************************************************************************************************* + description:Add a unique index + parameters: + pstSavm --stvm handle + pvAddr --memory address + t --table + ppstTruck --data truck + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lInsertIndex(SATvm *pstSavm, void *pvAddr, TABLE t, SHTruck **ppstTruck) +{ + SHTree *pstRoot = NULL; + char szIdx[MAX_INDEX_LEN]; + + memset(szIdx, 0, sizeof(szIdx)); + if(NULL == (pstRoot = pGetNode(pvAddr, ((TblDef *)pvAddr)->m_lTreeRoot))) + { + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + if(NULL == pPickIndex(lGetIdxNum(t), pGetTblIdx(t), pstSavm->pstVoid, szIdx)) + { + pstSavm->m_lErrno = IDX_FIELD_NIL; + return RC_FAIL; + } + + pstRoot = pInsertTree(pstSavm, pstRoot, szIdx, lGetIdxLen(t), ppstTruck); + if(!pstRoot) return RC_FAIL; + + ((TblDef *)pvAddr)->m_lTreeRoot = pstRoot->m_lSePos; + + return RC_SUCC; +} + +/************************************************************************************************* + description:Add a hash index + parameters: + pstSavm --stvm handle + pvAddr --memory address + t --table + ppstTruck --data truck + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lInsertHash(SATvm *pstSavm, void *pvAddr, TABLE t, SHTruck **ppstTruck) +{ + size_t lIdx, lOffset; + SHTree *pstTree = NULL; + char szIdx[MAX_INDEX_LEN]; + + memset(szIdx, 0, sizeof(szIdx)); + if(NULL == pPickIndex(lGetGrpNum(t), pGetTblGrp(t), pstSavm->pstVoid, szIdx)) + { + pstSavm->m_lErrno = IDX_FIELD_NIL; + return RC_FAIL; + } + + lIdx = uGetHash(szIdx, lGetGrpLen(t)) % ((TblDef *)pvAddr)->m_lMaxRow; + lOffset = ((TblDef *)pvAddr)->m_lGroupPos + lIdx * sizeof(SHTree); + if(NULL == (pstTree = (SHTree *)(pvAddr + lOffset))) + { + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + return __lInsertHash(pstSavm, pvAddr, t, pstTree, lOffset, ppstTruck); +} + +/************************************************************************************************* + description:Add a index + parameters: + pstSavm --stvm handle + pvAddr --memory address + t --table + ppstTruck --data truck + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lInsertGroup(SATvm *pstSavm, void *pvAddr, TABLE t, SHTruck **ppstTruck) +{ + SHTree *pstRoot = NULL; + char szIdx[MAX_INDEX_LEN]; + + memset(szIdx, 0, sizeof(szIdx)); + if(NULL == (pstRoot = pGetNode(pvAddr, ((TblDef *)pvAddr)->m_lGroupRoot))) + { + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + if(NULL == pPickIndex(lGetGrpNum(t), pGetTblGrp(t), pstSavm->pstVoid, szIdx)) + { + pstSavm->m_lErrno = IDX_FIELD_NIL; + return RC_FAIL; + } + + pstRoot = pInsertGroup(pstSavm, pstRoot, szIdx, lGetGrpLen(t), ppstTruck); + if(!pstRoot) return RC_FAIL; + + ((TblDef *)pvAddr)->m_lGroupRoot = pstRoot->m_lSePos; + + return RC_SUCC; +} + +/************************************************************************************************* + description:Add one data + parameters: + pstSavm --stvm handle + pvAddr --memory address + t --table + ppstTruck --data truck + uTimes --Click volume + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lInsertTruck(SATvm *pstSavm, void *pvAddr, TABLE t, SHTruck *pstTruck, ulong uTimes) +{ + SHTruck *pvTruck = pstTruck; + + if(!pvTruck) // 说明无索引 + pvTruck = pGetNode(pvAddr, lGetTblData(t) + lGetRowTruck(t) * ((TblDef *)pvAddr)->m_lValid); + + SET_DATA_TRUCK(pvTruck, DATA_TRUCK_NRML); + pvTruck->m_lTimes = uTimes; + memcpy(pvTruck->m_pvData, pstSavm->pstVoid, lGetRowSize(t)); + + ((TblDef *)pvAddr)->m_lValid ++; + pstSavm->m_lEffect = 1; + + return RC_SUCC; +} + +/************************************************************************************************* + description:insert data to table + parameters: + pstSavm --stvm handle + pvAddr --memory address + t --table + uTimes --Click volume + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long __lInsert(SATvm *pstSavm, void *pvAddr, TABLE t, ulong uTimes) +{ + SHTruck *pstTruck = NULL; + + if(HAVE_UNIQ_IDX(t)) + { + if(RC_SUCC != _lInsertIndex(pstSavm, pvAddr, t, &pstTruck)) + return RC_FAIL; + } + + if(HAVE_NORL_IDX(t)) + { + if(RC_SUCC != _lInsertGroup(pstSavm, pvAddr, t, &pstTruck)) + return RC_FAIL; + } + else if(HAVE_HASH_IDX(t)) + { + if(RC_SUCC != _lInsertHash(pstSavm, pvAddr, t, &pstTruck)) + return RC_FAIL; + } + + return _lInsertTruck(pstSavm, pvAddr, t, pstTruck, uTimes); +} + +/************************************************************************************************* + description:Reset the table lock + parameters: + pstSavm --stvm handle + t --table + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lResetLock(SATvm *pstSavm, TABLE t) +{ + RWAttr attr; + RunTime *pstRun = NULL; + RWLock *prwLock = NULL; + + if(RC_SUCC != lInitSATvm(pstSavm, t)) + return RC_FAIL; + + if(NULL == (pstRun = (RunTime *)pInitHitTest(pstSavm, t))) + return RC_FAIL; + + if(RES_REMOT_SID == pstRun->m_lLocal) + { + pstSavm->m_lErrno = RMT_NOT_SUPPT; + return RC_FAIL; + } + + prwLock = (RWLock *)pGetRWLock(pstRun->m_pvAddr); + pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); + pthread_rwlock_init(prwLock, &attr); + vTblDisconnect(pstSavm, t); + + return RC_SUCC; +} + +/************************************************************************************************* + description:API - Insert + parameters: + pstSavm --stvm handle + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lInsert(SATvm *pstSavm) +{ + long lRet; + RunTime *pstRun = NULL; + RWLock *prwLock = NULL; + + if(!pstSavm || !pstSavm->pstVoid) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + if(NULL == (pstRun = (RunTime *)pInitMemTable(pstSavm, pstSavm->tblName))) + return RC_FAIL; + + if(RES_REMOT_SID == pstRun->m_lLocal) + { + Tremohold(pstSavm, pstRun); + return _lInsertByRt(pstSavm); + } + + if(lGetTblRow(pstSavm->tblName) <= ((TblDef *)pstRun->m_pvAddr)->m_lValid) + { + pstSavm->m_lErrno = DATA_SPC_FULL; + vTblDisconnect(pstSavm, pstSavm->tblName); + return RC_FAIL; + } + + prwLock = (RWLock *)pGetRWLock(pstRun->m_pvAddr); + if(RC_SUCC != pthread_rwlock_wrlock(prwLock)) + { + pstSavm->m_lErrno = LOCK_DOWR_ERR; + vTblDisconnect(pstSavm, pstSavm->tblName); + return RC_FAIL; + } + + lRet = __lInsert(pstSavm, pstRun->m_pvAddr, pstSavm->tblName, 0); + pthread_rwlock_unlock(prwLock); + vTblDisconnect(pstSavm, pstSavm->tblName); + if(RC_SUCC != lRet) return RC_FAIL; + + return lRecordWork(pstSavm, pstSavm->pstVoid, OPERATE_INSERT); +} + +/************************************************************************************************* + description:Transaction Flow Add record + parameters: + pstSavm --stvm handle + plOffset --memory address + pllSeq --seqno + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lInsertTrans(SATvm *pstSavm, size_t *plOffset, llSEQ *pllSeq) +{ + size_t lOffset; + RunTime *pstRun = NULL; + RWLock *prwLock = NULL; + SHTruck *pstTruck = NULL; + + if(!pstSavm || !pstSavm->pstVoid) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + if(NULL == (pstRun = (RunTime *)pInitMemTable(pstSavm, pstSavm->tblName))) + return RC_FAIL; + + if(lGetTblRow(pstSavm->tblName) <= ((TblDef *)pstRun->m_pvAddr)->m_lValid) + { + pstSavm->m_lErrno = DATA_SPC_FULL; + vTblDisconnect(pstSavm, pstSavm->tblName); + return RC_FAIL; + } + + prwLock = (RWLock *)pGetRWLock(pstRun->m_pvAddr); + if(RC_SUCC != pthread_rwlock_wrlock(prwLock)) + { + pstSavm->m_lErrno = LOCK_DOWR_ERR; + vTblDisconnect(pstSavm, pstSavm->tblName); + return RC_FAIL; + } + + if(HAVE_UNIQ_IDX(pstSavm->tblName)) + { + if(RC_SUCC != _lInsertIndex(pstSavm, pstRun->m_pvAddr, pstSavm->tblName, &pstTruck)) + goto ErrInsert; + } + + if(HAVE_NORL_IDX(pstSavm->tblName)) + { + if(RC_SUCC != _lInsertGroup(pstSavm, pstRun->m_pvAddr, pstSavm->tblName, &pstTruck)) + goto ErrInsert; + } + else if(HAVE_HASH_IDX(pstSavm->tblName)) + { + if(RC_SUCC != _lInsertHash(pstSavm, pstRun->m_pvAddr, pstSavm->tblName, &pstTruck)) + goto ErrInsert; + } + + if(!pstTruck) + { + lOffset = lGetTblData(pstSavm->tblName) + + lGetRowTruck(pstSavm->tblName) * ((TblDef *)pstRun->m_pvAddr)->m_lValid; + pstTruck = pGetNode(pstRun->m_pvAddr, lOffset); + } + + lOffset = (void *)pstTruck->m_pvData - (void *)pstRun->m_pvAddr; + SET_DATA_TRUCK(pstTruck, DATA_TRUCK_NRML); + pstTruck->m_lTimes = 0; + memcpy(pstTruck->m_pvData, pstSavm->pstVoid, lGetRowSize(pstSavm->tblName)); + ((TblDef *)pstRun->m_pvAddr)->m_lValid ++; + ((TblDef *)pstRun->m_pvAddr)->m_lExSeQ ++; + if(pllSeq) *pllSeq = ((TblDef *)pstRun->m_pvAddr)->m_lExSeQ; + + pthread_rwlock_unlock(prwLock); + vTblDisconnect(pstSavm, pstSavm->tblName); + pstSavm->m_lEffect = 1; + if(plOffset) *plOffset = lOffset; + + return RC_SUCC; + +ErrInsert: + pthread_rwlock_unlock(prwLock); + vTblDisconnect(pstSavm, pstSavm->tblName); + return RC_FAIL; +} + +/************************************************************************************************* + description:Cursor-fetch the data as unique index + parameters: + pstSavm --stvm handle + pstRun --table handle + t --table + psvout --result data + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _llFetchIndex(SATvm *pstSavm, RunTime *pstRun, TABLE t, void *psvOut) +{ + SHTree *pstTree = NULL; + SHTruck *pstTruck = NULL; + char szIdx[MAX_INDEX_LEN]; + void *pvAddr = pGetAddr(pstSavm, t); + + memset(szIdx, 0, sizeof(szIdx)); + if(NULL == pPickIndex(lGetIdxNum(t), pGetTblIdx(t), pstRun->pstVoid, szIdx)) + { + pstSavm->m_lErrno = IDX_FIELD_NIL; + return RC_FAIL; + } + + if(NULL == (pstTree = (SHTree *)pGetNode(pvAddr, ((TblDef *)pvAddr)->m_lTreeRoot))) + { + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + pstTree = (SHTree *)pSearchTree(pvAddr, pstTree, szIdx, lGetIdxLen(t)); + if(!pstTree) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_NOTFOUND; + } + + pstTruck = (PSHTruck)pGetNode(pvAddr, pstTree->m_lData); + if(RC_MISMA == lFeildMatch(&pstSavm->stCond, pstTruck->m_pvData, pstRun->pstVoid)) + { + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + pstRun->m_lCurLine ++; + pstRun->m_pvCurAddr = NULL; + memcpy(psvOut, pstTruck->m_pvData, lGetRowSize(t)); + + return RC_SUCC; +} + +/************************************************************************************************* + description:Cursor-fetch the data as index + parameters: + pstSavm --stvm handle + pstRun --table handle + t --table + psvout --result data + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _llFetchGroup(SATvm *pstSavm, RunTime *pstRun, TABLE t, void *psvOut) +{ + SHList *pstList = NULL; + SHTruck *pstTruck = NULL; + char szIdx[MAX_INDEX_LEN]; + void *pvAddr = pGetAddr(pstSavm, t); + + for(pstList = (SHList *)pstRun->m_pvCurAddr; pstList && (SELF_POS_UNUSE != pstList->m_lPos); + pstList = (SHList *)pGetNode(pvAddr, pstList->m_lNext)) + { + pstTruck = (PSHTruck)pGetNode(pvAddr, pstList->m_lData); + if(IS_TRUCK_NULL(pstTruck)) + { + if(SELF_POS_UNUSE == pstList->m_lNext) break; + continue; + } + + if(RC_MISMA == lFeildMatch(&pstSavm->stCond, pstTruck->m_pvData, pstRun->pstVoid)) + { + if(SELF_POS_UNUSE == pstList->m_lNext) break; + continue; + } + + pstRun->m_lCurLine ++; + memcpy(psvOut, pstTruck->m_pvData, lGetRowSize(t)); + if(SELF_POS_UNUSE == pstList->m_lNext) + pstRun->m_pvCurAddr = NULL; + else + pstRun->m_pvCurAddr = (void *)pGetNode(pvAddr, pstList->m_lNext); + + return RC_SUCC; + } + + return RC_NOTFOUND; +} + +/************************************************************************************************* + description:Cursor-fetch the data as truck + parameters: + pstSavm --stvm handle + pstRun --table handle + t --table + psvout --result data + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _llFetchTruck(SATvm *pstSavm, RunTime *pstRun, TABLE t, void *psvOut) +{ + SHTruck *pstTruck = NULL; + long lRow = 0, lOffset; + void *pvAddr = pGetAddr(pstSavm, t); + + if(1 == pstRun->m_lCurLine) + { + lOffset = lGetTblData(t); + pstTruck = (PSHTruck)pGetNode(pvAddr, lOffset); + } + else + { + lOffset = pstRun->m_pvCurAddr - pvAddr; + pstTruck = (PSHTruck)pstRun->m_pvCurAddr; + } + + for(lRow = 0; (lRow < ((TblDef *)pvAddr)->m_lValid) && (lOffset < lGetTableSize(t)); + pstTruck = (PSHTruck)pGetNode(pvAddr, lOffset)) + { + if(IS_TRUCK_NULL(pstTruck)) + { + lOffset += lGetRowTruck(t); + continue; + } + + lRow ++; + if(RC_MISMA == lFeildMatch(&pstSavm->stCond, pstTruck->m_pvData, pstRun->pstVoid)) + { + lOffset += lGetRowTruck(t); + continue; + } + + pstRun->m_lCurLine ++; + lOffset += lGetRowTruck(t); + pstRun->m_pvCurAddr = pGetNode(pvAddr, lOffset); + memcpy(psvOut, pstTruck->m_pvData, lGetRowSize(t)); + return RC_SUCC; + } + + return RC_NOTFOUND; +} + +/************************************************************************************************* + description:Define the cursor + parameters: + pstSavm --stvm handle + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lTableDeclare(SATvm *pstSavm) +{ + long lIdx; + SHTree *pstTree = NULL; + RunTime *pstRun = NULL; + char szIdx[MAX_INDEX_LEN]; + + if(!pstSavm) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + if(NULL == (pstRun = (RunTime *)pInitMemTable(pstSavm, pstSavm->tblName))) + return RC_FAIL; + + if(RES_REMOT_SID == pstRun->m_lLocal) + { + pstSavm->m_lErrno = RMT_NOT_SUPPT; + return RC_FAIL; + } + + pstRun->m_lCurLine = 1; + pstRun->m_lCurType = EXE_PLAN_ALL; + pstRun->m_lRowSize = pstSavm->lSize; + pstRun->m_pvCurAddr= pstRun->m_pvAddr; + pstSavm->m_lEType = pstRun->m_lCurType; + + if(!pstSavm->pstVoid) return RC_SUCC; + + pstRun->pstVoid = (char *)malloc(pstSavm->lSize); + memcpy(pstRun->pstVoid, pstSavm->pstVoid, pstSavm->lSize); + if(HAVE_UNIQ_IDX(pstSavm->tblName)) + { + memset(szIdx, 0, sizeof(szIdx)); + if(NULL != pGetIndex(&pstSavm->stCond, lGetIdxNum(pstSavm->tblName), + pGetTblIdx(pstSavm->tblName), pstSavm->pstVoid, szIdx)) + { + pstRun->m_lCurType = EXE_PLAN_IDX; + pstSavm->m_lEType = pstRun->m_lCurType; + return RC_SUCC; + } + } + + if(HAVE_NORL_IDX(pstSavm->tblName)) + { + memset(szIdx, 0, sizeof(szIdx)); + if(NULL == pGetIndex(&pstSavm->stCond, lGetGrpNum(pstSavm->tblName), + pGetTblGrp(pstSavm->tblName), pstSavm->pstVoid, szIdx)) + return RC_SUCC; + + pstRun->m_lCurType = EXE_PLAN_GRP; + pstSavm->m_lEType = pstRun->m_lCurType; + pstRun->m_pvCurAddr = pSearchGroup(pstRun->m_pvAddr, (SHTree *)pGetNode(pstRun->m_pvAddr, + ((TblDef *)pstRun->m_pvAddr)->m_lGroupRoot), szIdx, lGetGrpLen(pstSavm->tblName)); + + return RC_SUCC; + } + else if(HAVE_HASH_IDX(pstSavm->tblName)) + { + memset(szIdx, 0, sizeof(szIdx)); + if(NULL == pGetIndex(&pstSavm->stCond, lGetGrpNum(pstSavm->tblName), + pGetTblGrp(pstSavm->tblName), pstSavm->pstVoid, szIdx)) + return RC_SUCC; + + pstRun->m_lCurType = EXE_PLAN_GRP; + pstSavm->m_lEType = pstRun->m_lCurType; + lIdx = uGetHash(szIdx, lGetGrpLen(pstSavm->tblName)) % ((TblDef *)pstRun->m_pvAddr)->m_lMaxRow; + pstTree = pstRun->m_pvAddr + ((TblDef *)pstRun->m_pvAddr)->m_lGroupRoot + lIdx * sizeof(SHTree); + if(NULL == pstTree || SELF_POS_UNUSE == pstTree->m_lData) + { + pstRun->m_pvCurAddr = NULL; + return RC_SUCC; + } + + pstRun->m_pvCurAddr = (SHList *)pGetNode(pstRun->m_pvAddr, pstTree->m_lData); + return RC_SUCC; + } + + return RC_SUCC; +} + +/************************************************************************************************* + description:Cursor-fetch the data + parameters: + pstSavm --stvm handle + psvout --result data + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lTableFetch(SATvm *pstSavm, void *psvOut) +{ + long lRet; + RunTime *pstRun = NULL; + + if(!pstSavm) + { + pstSavm->m_lErrno = CURS_IS_INVAL; + return RC_FAIL; + } + + pstRun = (RunTime *)pGetRunTime(pstSavm, pstSavm->tblName); + if(NULL == pstRun->m_pvCurAddr) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_NOTFOUND; + } + + if(RES_REMOT_SID == pstRun->m_lLocal) + { + pstSavm->m_lErrno = RMT_NOT_SUPPT; + return RC_FAIL; + } + + if(EXE_PLAN_IDX == pstRun->m_lCurType) + lRet = _llFetchIndex(pstSavm, pstRun, pstSavm->tblName, psvOut); + else if(EXE_PLAN_GRP == pstRun->m_lCurType) + lRet = _llFetchGroup(pstSavm, pstRun, pstSavm->tblName, psvOut); + else + lRet = _llFetchTruck(pstSavm, pstRun, pstSavm->tblName, psvOut); + if(RC_NOTFOUND == lRet) + { + pstRun->m_pvCurAddr = NULL; + pstSavm->m_lErrno = NO_DATA_FOUND; + } + + return lRet; +} + +/************************************************************************************************* + description:Cursor-next truck data + parameters: + pstSavm --stvm handle + pstRun --table handle + t --table + psvout --result data + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lNextTruck(SATvm *pstSavm, RunTime *pstRun, TABLE t, void **ppvOAddr) +{ + SHTruck *pstTruck = NULL; + long lRow = 0, lOffset; + void *pvAddr = pGetAddr(pstSavm, t); + + if(1 == pstRun->m_lCurLine) + { + lOffset = lGetTblData(t); + pstTruck = (PSHTruck)pGetNode(pvAddr, lOffset); + } + else + { + lOffset = pstRun->m_pvCurAddr - pvAddr; + pstTruck = (PSHTruck)pstRun->m_pvCurAddr; + } + + for(lRow = 0; (lRow < ((TblDef *)pvAddr)->m_lValid) && (lOffset < lGetTableSize(t)); + pstTruck = (PSHTruck)pGetNode(pvAddr, lOffset)) + { + if(IS_TRUCK_NULL(pstTruck)) + { + lOffset += lGetRowTruck(t); + continue; + } + + lRow ++; + if(RC_MISMA == lFeildMatch(&pstSavm->stCond, pstTruck->m_pvData, pstRun->pstVoid)) + { + lOffset += lGetRowTruck(t); + continue; + } + + pstRun->m_lCurLine ++; + *ppvOAddr = pstTruck->m_pvData; + lOffset += lGetRowTruck(t); + pstRun->m_pvCurAddr = pGetNode(pvAddr, lOffset); + return RC_SUCC; + } + + return RC_NOTFOUND; +} + +/************************************************************************************************* + description:Cursor-next index data + parameters: + pstSavm --stvm handle + pstRun --table handle + t --table + psvout --result data + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lNextGroup(SATvm *pstSavm, RunTime *pstRun, TABLE t, void **ppvOAddr) +{ + SHList *pstList = NULL; + SHTruck *pstTruck = NULL; + char szIdx[MAX_INDEX_LEN]; + void *pvAddr = pGetAddr(pstSavm, t); + + for(pstList = (SHList *)pstRun->m_pvCurAddr; pstList && (SELF_POS_UNUSE != pstList->m_lPos); + pstList = (SHList *)pGetNode(pvAddr, pstList->m_lNext)) + { + pstTruck = (PSHTruck)pGetNode(pvAddr, pstList->m_lData); + if(RC_MISMA == lFeildMatch(&pstSavm->stCond, pstTruck->m_pvData, pstRun->pstVoid)) + { + if(SELF_POS_UNUSE == pstList->m_lNext) break; + continue; + } + + pstRun->m_lCurLine ++; + *ppvOAddr = pstTruck->m_pvData; + if(SELF_POS_UNUSE == pstList->m_lNext) + pstRun->m_pvCurAddr = NULL; + else + pstRun->m_pvCurAddr = (void *)pGetNode(pvAddr, pstList->m_lNext); + + return RC_SUCC; + } + + return RC_NOTFOUND; +} + +/************************************************************************************************* + description:Cursor-next unique index data + parameters: + pstSavm --stvm handle + pstRun --table handle + t --table + psvout --result data + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lNextIndex(SATvm *pstSavm, RunTime *pstRun, TABLE t, void **ppvOAddr) +{ + SHTree *pstTree = NULL; + SHTruck *pstTruck = NULL; + char szIdx[MAX_INDEX_LEN]; + void *pvAddr = pGetAddr(pstSavm, t); + + memset(szIdx, 0, sizeof(szIdx)); + if(NULL == pPickIndex(lGetIdxNum(t), pGetTblIdx(t), pstSavm->pstVoid, szIdx)) + { + pstSavm->m_lErrno = IDX_FIELD_NIL; + return RC_FAIL; + } + + if(NULL == (pstTree = (SHTree *)pGetNode(pvAddr, ((TblDef *)pvAddr)->m_lTreeRoot))) + { + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + pstTree = (SHTree *)pSearchTree(pvAddr, pstTree, szIdx, lGetIdxLen(t)); + if(!pstTree) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_NOTFOUND; + } + + pstTruck = (PSHTruck)pGetNode(pvAddr, pstTree->m_lData); + if(RC_MISMA == lFeildMatch(&pstSavm->stCond, pstTruck->m_pvData, pstRun->pstVoid)) + { + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + pstRun->m_lCurLine ++; + pstRun->m_pvCurAddr = NULL; + *ppvOAddr = pstTruck->m_pvData; + return RC_SUCC; +} + +/************************************************************************************************* + description:Cursor-next fetch + parameters: + pstSavm --stvm handle + ppvOAddr --result data + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lNextFetch(SATvm *pstSavm, void **ppvOAddr) +{ + long lRet; + RunTime *pstRun = NULL; + + if(!pstSavm) + { + pstSavm->m_lErrno = CURS_IS_INVAL; + return RC_FAIL; + } + + pstRun = (RunTime *)pGetRunTime(pstSavm, pstSavm->tblName); + if(NULL == pstRun->m_pvCurAddr) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_NOTFOUND; + } + + if(RES_REMOT_SID == pstRun->m_lLocal) + { + pstSavm->m_lErrno = RMT_NOT_SUPPT; + return RC_FAIL; + } + + if(EXE_PLAN_IDX == pstRun->m_lCurType) + lRet = _lNextIndex(pstSavm, pstRun, pstSavm->tblName, ppvOAddr); + else if(EXE_PLAN_GRP == pstRun->m_lCurType) + lRet = _lNextGroup(pstSavm, pstRun, pstSavm->tblName, ppvOAddr); + else + lRet = _lNextTruck(pstSavm, pstRun, pstSavm->tblName, ppvOAddr); + if(RC_NOTFOUND == lRet) + { + pstRun->m_pvCurAddr = NULL; + pstSavm->m_lErrno = NO_DATA_FOUND; + } + + return lRet; +} + +/************************************************************************************************* + description:close Cursor + parameters: + pstSavm --stvm handle + return: + *************************************************************************************************/ +void vTableClose(SATvm *pstSavm) +{ + _vTblRelease(pstSavm, pstSavm->tblName, pstSavm->m_bHold); +} + +/************************************************************************************************* + description:Update record hash index + parameters: + pstSavm --stvm handle + pstAddr --table handle + t --table + pstTruck --data truck + lData --offset + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long __lUpdateHash(SATvm *pstSavm, void *pvAddr, TABLE t, SHTruck *pstTruck, size_t lData) +{ + SHList *pstList = NULL; + SHTree *pstTree = NULL; + size_t lIdx, lOld, lOffset, lNext; + char szOld[MAX_INDEX_LEN], szIdx[MAX_INDEX_LEN]; + + memset(szIdx, 0, sizeof(szIdx)); + if(NULL == pPickIndex(lGetGrpNum(t), pGetTblGrp(t), pstSavm->pstVoid, szIdx)) + { + pstSavm->m_lErrno = IDX_FIELD_NIL; + return RC_FAIL; + } + + memset(szOld, 0, sizeof(szOld)); + if(NULL == pPickIndex(lGetGrpNum(t), pGetTblGrp(t), pstTruck->m_pvData, szOld)) + { + pstSavm->m_lErrno = IDX_DATA_MISM; + return RC_FAIL; + } + + lOld = uGetHash(szOld, lGetGrpLen(t)) % ((TblDef *)pvAddr)->m_lMaxRow; + lIdx = uGetHash(szIdx, lGetGrpLen(t)) % ((TblDef *)pvAddr)->m_lMaxRow; + if(lOld == lIdx) return RC_SUCC; + + lOffset = ((TblDef *)pvAddr)->m_lGroupPos + lOld * sizeof(SHTree); + if(NULL == (pstTree = (SHTree *)(pvAddr + lOffset))) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_FAIL; + } + + lOffset = lGetListOfs(t) + ((TblDef *)pvAddr)->m_lValid * sizeof(SHList); + for(pstList = (SHList *)pGetNode(pvAddr, pstTree->m_lData); SELF_POS_UNUSE != pstList->m_lPos; + pstList = (SHList *)pGetNode(pvAddr, lNext)) + { + lNext = pstList->m_lNext; + if(lData != pstList->m_lData) + { + if(SELF_POS_UNUSE == pstList->m_lNext) break; + continue; + } + + lOffset -= sizeof(SHList); + if(RC_SUCC != lReleaseList(pvAddr, t, pstTree, pstList, lOffset, &lNext)) + { + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + ((TblDef *)pvAddr)->m_lValid --; + lOffset = RC_CLOSE; + break; + } + + if(SELF_POS_UNUSE == pstTree->m_lData) + pstTree->m_lSePos = SELF_POS_UNUSE; + + if(RC_CLOSE != lOffset) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_FAIL; + } + + lOffset = ((TblDef *)pvAddr)->m_lGroupPos + lIdx * sizeof(SHTree); + if(NULL == (pstTree = (SHTree *)(pvAddr + lOffset))) + { + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + if(RC_SUCC != __lInsertHash(pstSavm, pvAddr, t, pstTree, lOffset, &pstTruck)) + return RC_FAIL; + + ((TblDef *)pvAddr)->m_lValid ++; + return RC_SUCC; +} + +/************************************************************************************************* + description:Update record index + parameters: + pstSavm --stvm handle + pstAddr --table handle + t --table + pstTruck --data truck + lData --offset + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long __lUpdateGroup(SATvm *pstSavm, void *pvAddr, TABLE t, SHTruck *pstTruck, size_t lData) +{ + SHList *pstList = NULL; + size_t lNext = 0, lOffset; + SHTree *pstRoot, *pstTree = NULL; + char szOld[MAX_INDEX_LEN], szIdx[MAX_INDEX_LEN]; + + memset(szIdx, 0, sizeof(szIdx)); + if(NULL == pPickIndex(lGetGrpNum(t), pGetTblGrp(t), pstSavm->pstVoid, szIdx)) + { + pstSavm->m_lErrno = IDX_FIELD_NIL; + return RC_FAIL; + } + + memset(szOld, 0, sizeof(szOld)); + if(NULL == pPickIndex(lGetGrpNum(t), pGetTblGrp(t), pstTruck->m_pvData, szOld)) + { + pstSavm->m_lErrno = IDX_DATA_MISM; + return RC_FAIL; + } + + if(!memcmp(szIdx, szOld, MAX_INDEX_LEN)) // Index has not changed + return RC_SUCC; + + if(NULL == (pstRoot = (SHTree *)pGetNode(pvAddr, ((TblDef *)pvAddr)->m_lGroupRoot))) + { + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + if(NULL == (pstTree = pSearchTree(pvAddr, pstRoot, szOld, lGetGrpLen(t)))) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_FAIL; + } + + lOffset = lGetListOfs(t) + ((TblDef *)pvAddr)->m_lValid * sizeof(SHList); + for(pstList = (SHList *)pGetNode(pvAddr, pstTree->m_lData); SELF_POS_UNUSE != pstList->m_lPos; + pstList = (SHList *)pGetNode(pvAddr, lNext)) + { + lNext = pstList->m_lNext; + if(lData != pstList->m_lData) + { + if(SELF_POS_UNUSE == pstList->m_lNext) break; + continue; + } + + lOffset -= sizeof(SHList); + if(RC_SUCC != lReleaseList(pvAddr, t, pstTree, pstList, lOffset, &lNext)) + { + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + ((TblDef *)pvAddr)->m_lValid --; + lOffset = RC_CLOSE; + break; + } + + if(SELF_POS_UNUSE == pstTree->m_lData) + { + pstRoot = _pDeleteGroup(pvAddr, pstSavm->tblName, pstRoot, pstTree, &pstSavm->m_lEffect); + ((TblDef *)pvAddr)->m_lGroupRoot = pstRoot->m_lSePos; + } + + if(RC_CLOSE != lOffset) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_FAIL; + } + + if(NULL == (pstRoot = pInsertGroup(pstSavm, pstRoot, szIdx, lGetGrpLen(t), &pstTruck))) + return RC_FAIL; + + ((TblDef *)pvAddr)->m_lValid ++; + ((TblDef *)pvAddr)->m_lGroupRoot = pstRoot->m_lSePos; + + return RC_SUCC; +} + +/************************************************************************************************* + description:Update record unique index + parameters: + pstSavm --stvm handle + pstAddr --table handle + t --table + pstTruck --data truck + lData --offset + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long __lIndexUpdate(SATvm *pstSavm, void *pvAddr, TABLE t, SHTruck *pstTruck, size_t lData) +{ + SHTree *pstRoot, *pstTree = NULL; + char szOld[MAX_INDEX_LEN], szIdx[MAX_INDEX_LEN]; + + memset(szIdx, 0, sizeof(szIdx)); + if(NULL == pPickIndex(lGetIdxNum(t), pGetTblIdx(t), pstSavm->pstVoid, szIdx)) + { + pstSavm->m_lErrno = IDX_FIELD_NIL; + return RC_FAIL; + } + + memset(szOld, 0, sizeof(szOld)); + if(NULL == pPickIndex(lGetIdxNum(t), pGetTblIdx(t), pstTruck->m_pvData, szOld)) + { + pstSavm->m_lErrno = IDX_DATA_MISM; + return RC_FAIL; + } + + if(!memcmp(szIdx, szOld, MAX_INDEX_LEN)) // Index has not changed + return RC_SUCC; + + if(NULL == (pstRoot = (SHTree *)pGetNode(pvAddr, ((TblDef *)pvAddr)->m_lTreeRoot))) + { + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + // frist select, then add The unique index, avoiding the uniqueness error after deletion. + if(NULL != (SHTree *)pSearchTree(pvAddr, pstRoot, szIdx, lGetIdxLen(t))) + { + pstSavm->m_lErrno = UNIQ_IDX_REPT; + return RC_FAIL; + } + + if(NULL == (pstTree = (SHTree *)pSearchTree(pvAddr, pstRoot, szOld, lGetIdxLen(t)))) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_FAIL; + } + + if(lData != pstTree->m_lData) + { + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + if(NULL == (pstRoot = _pDeleteTree(pvAddr, pstSavm->tblName, pstRoot, pstTree))) + { + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + ((TblDef *)pvAddr)->m_lValid --; + + if(NULL == (pstRoot = pInsertTree(pstSavm, pstRoot, szIdx, lGetIdxLen(t), &pstTruck))) + return RC_FAIL; + ((TblDef *)pvAddr)->m_lValid ++; + ((TblDef *)pvAddr)->m_lTreeRoot = pstRoot->m_lSePos; + return RC_SUCC; +} + +/************************************************************************************************* + description:Update record unique index + parameters: + pstSavm --stvm handle + pstAddr --table handle + t --table + pvUpdate --update date + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lUpdateIndex(SATvm *pstSavm, void *pvAddr, TABLE t, void *pvUpdate) +{ + size_t lData; + long lRet = RC_SUCC; + void *pvData = NULL; + SHTruck *pstTruck = NULL; + SHTree *pstRoot, *pstTree = NULL; + RWLock *prwLock = (RWLock *)pGetRWLock(pvAddr); + char szOld[MAX_INDEX_LEN], szIdx[MAX_INDEX_LEN]; + + memset(szOld, 0, sizeof(szOld)); + if(NULL == pGetIndex(&pstSavm->stCond, lGetIdxNum(t), pGetTblIdx(t), pstSavm->pstVoid, szOld)) + return RC_CONTU; + + if(NULL == (pvData = (void *)malloc(lGetRowSize(pstSavm->tblName)))) + { + pstSavm->m_lErrno = MALLC_MEM_ERR; + return RC_FAIL; + } + + if(RC_SUCC != pthread_rwlock_wrlock(prwLock)) + { + pstSavm->m_lErrno = LOCK_DOWR_ERR; + TFree(pvData); + return RC_FAIL; + } + + pstSavm->m_lEType = EXE_PLAN_IDX; + if(NULL == (pstRoot = (SHTree *)pGetNode(pvAddr, ((TblDef *)pvAddr)->m_lTreeRoot))) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = SVR_EXCEPTION; + TFree(pvData); + return RC_FAIL; + } + + if(NULL == (pstTree = (SHTree *)pSearchTree(pvAddr, pstRoot, szOld, lGetIdxLen(t)))) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = NO_DATA_FOUND; + TFree(pvData); + return RC_FAIL; + } + + lData = pstTree->m_lData; + pstTruck = (PSHTruck)pGetNode(pvAddr, pstTree->m_lData); + if(RC_MISMA == lFeildMatch(&pstSavm->stCond, pstTruck->m_pvData, pstSavm->pstVoid)) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = SVR_EXCEPTION; + TFree(pvData); + return RC_FAIL; + } + + memcpy(pvData, pvUpdate, lGetRowSize(pstSavm->tblName)); + memcpy(pvUpdate, pstTruck->m_pvData, lGetRowSize(pstSavm->tblName)); + if(RC_FAIL == lMergeTruck(pstSavm, &pstSavm->stUpdt, pvData, pvUpdate)) + { + pthread_rwlock_unlock(prwLock); + TFree(pvData); + return RC_FAIL; + } + + memset(szIdx, 0, sizeof(szIdx)); + if(NULL == pPickIndex(lGetIdxNum(t), pGetTblIdx(t), pvUpdate, szIdx)) + { + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = IDX_FIELD_NIL; + TFree(pvData); + return RC_FAIL; + } + + pstSavm->pstVoid = pvUpdate; + SET_DATA_TRUCK(pstTruck, DATA_TRUCK_NULL); + if(!memcmp(szIdx, szOld, MAX_INDEX_LEN)) + { + if(HAVE_NORL_IDX(t)) + lRet = __lUpdateGroup(pstSavm, pvAddr, t, pstTruck, lData); + else if(HAVE_HASH_IDX(t)) + lRet = __lUpdateHash(pstSavm, pvAddr, t, pstTruck, lData); + } + else + { + if(NULL != (SHTree *)pSearchTree(pvAddr, pstRoot, szIdx, lGetIdxLen(t))) + { + SET_DATA_TRUCK(pstTruck, DATA_TRUCK_NRML); + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = UNIQ_IDX_REPT; + TFree(pvData); + return RC_FAIL; + } + + if(NULL == (pstRoot = _pDeleteTree(pvAddr, pstSavm->tblName, pstRoot, pstTree))) + { + SET_DATA_TRUCK(pstTruck, DATA_TRUCK_NRML); + pthread_rwlock_unlock(prwLock); + pstSavm->m_lErrno = SVR_EXCEPTION; + TFree(pvData); + return RC_FAIL; + } + + ((TblDef *)pvAddr)->m_lValid --; + if(NULL == (pstRoot = pInsertTree(pstSavm, pstRoot, szIdx, lGetIdxLen(t), &pstTruck))) + { + SET_DATA_TRUCK(pstTruck, DATA_TRUCK_NRML); + pthread_rwlock_unlock(prwLock); + TFree(pvData); + return RC_FAIL; + } + + ((TblDef *)pvAddr)->m_lValid ++; + ((TblDef *)pvAddr)->m_lTreeRoot = pstRoot->m_lSePos; + if(HAVE_NORL_IDX(t)) + lRet = __lUpdateGroup(pstSavm, pvAddr, t, pstTruck, lData); + else if(HAVE_HASH_IDX(t)) + lRet = __lUpdateHash(pstSavm, pvAddr, t, pstTruck, lData); + } + SET_DATA_TRUCK(pstTruck, DATA_TRUCK_NRML); + if(RC_SUCC != lRet) + { + pthread_rwlock_unlock(prwLock); + TFree(pvData); + return RC_FAIL; + } + + if(RC_SUCC != lRecordWork(pstSavm, pstTruck->m_pvData, OPERATE_UPDATE)) + { + pthread_rwlock_unlock(prwLock); + TFree(pvData); + return RC_FAIL; + } + + memcpy(pstTruck->m_pvData, pvUpdate, lGetRowSize(t)); + pthread_rwlock_unlock(prwLock); + pstSavm->m_lEffect = 1; + + TFree(pvData); + return RC_SUCC; +} + +/************************************************************************************************* + description:Update record index + parameters: + pstSavm --stvm handle + pstAddr --table handle + t --table + pvUpdate --update date + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lUpdateGroup(SATvm *pstSavm, void *pvAddr, TABLE t, void *pvUpdate) +{ + SHList *pstList = NULL; + SHTruck *pstTruck = NULL; + size_t lOffset, lNext; + SHTree *pstTree, *pstRoot; + void *pvData, *pvCond = NULL; + RWLock *prwLock = (RWLock *)pGetRWLock(pvAddr); + char szOld[MAX_INDEX_LEN], szIdx[MAX_INDEX_LEN]; + + memset(szOld, 0, sizeof(szOld)); + if(NULL == pGetIndex(&pstSavm->stCond, lGetGrpNum(t), pGetTblGrp(t), pstSavm->pstVoid, szOld)) + return RC_CONTU; + + if(NULL == (pvData = (void *)malloc(lGetRowSize(t)))) + { + pstSavm->m_lErrno = MALLC_MEM_ERR; + return RC_FAIL; + } + + if(RC_SUCC != pthread_rwlock_wrlock(prwLock)) + { + pstSavm->m_lErrno = LOCK_DOWR_ERR; + TFree(pvData); + return RC_FAIL; + } + + if(NULL == (pstRoot = (SHTree *)pGetNode(pvAddr, ((TblDef *)pvAddr)->m_lGroupRoot))) + { + pstSavm->m_lErrno = SVR_EXCEPTION; + goto GROUP_ERROR; + } + + if(NULL == (pstTree = pSearchTree(pvAddr, pstRoot, szOld, lGetGrpLen(t)))) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + goto GROUP_ERROR; + } + + pstSavm->m_lEffect = 0; + pvCond = pstSavm->pstVoid; + pstSavm->m_lEType = EXE_PLAN_GRP; + for(pstList = (SHList *)pGetNode(pvAddr, pstTree->m_lData); SELF_POS_UNUSE != pstList->m_lPos; + pstList = (SHList *)pGetNode(pvAddr, lNext)) + { + lNext = pstList->m_lNext; + pstTruck = (PSHTruck)pGetNode(pvAddr, pstList->m_lData); + if(RC_MISMA == lFeildMatch(&pstSavm->stCond, pstTruck->m_pvData, pvCond)) + { + if(SELF_POS_UNUSE == pstList->m_lNext) break; + continue; + } + + memcpy(pvData, pstTruck->m_pvData, lGetRowSize(t)); + if(RC_FAIL == lMergeTruck(pstSavm, &pstSavm->stUpdt, pvUpdate, pvData)) + goto GROUP_ERROR; + + memset(szIdx, 0, sizeof(szIdx)); + if(NULL == pPickIndex(lGetGrpNum(t), pGetTblGrp(t), pvData, szIdx)) + { + pstSavm->m_lErrno = IDX_FIELD_NIL; + goto GROUP_ERROR; + } + + pstSavm->m_lEffect ++; + pstSavm->pstVoid = pvData; + SET_DATA_TRUCK(pstTruck, DATA_TRUCK_NULL); + if(HAVE_UNIQ_IDX(t)) + { + if(RC_SUCC != __lIndexUpdate(pstSavm, pvAddr, t, pstTruck, pstList->m_lData)) + { + SET_DATA_TRUCK(pstTruck, DATA_TRUCK_NRML); + goto GROUP_ERROR; + } + } + + if(memcmp(szIdx, szOld, MAX_INDEX_LEN)) + { + -- ((TblDef *)pvAddr)->m_lValid; + lOffset = lGetListOfs(t) + ((TblDef *)pvAddr)->m_lValid * sizeof(SHList); + if(RC_SUCC != lReleaseList(pvAddr, t, pstTree, pstList, lOffset, &lNext)) + { + ((TblDef *)pvAddr)->m_lValid ++; + pstSavm->m_lErrno = SVR_EXCEPTION; + SET_DATA_TRUCK(pstTruck, DATA_TRUCK_NRML); + goto GROUP_ERROR; + } + + if(SELF_POS_UNUSE == pstTree->m_lData) + { + pstRoot = _pDeleteGroup(pvAddr, t, pstRoot, pstTree, &pstSavm->m_lEffect); + ((TblDef *)pvAddr)->m_lGroupRoot = pstRoot->m_lSePos; + } + + if(NULL == (pstRoot = pInsertGroup(pstSavm, pstRoot, szIdx, lGetGrpLen(t), &pstTruck))) + { + SET_DATA_TRUCK(pstTruck, DATA_TRUCK_NRML); + goto GROUP_ERROR; + } + + ((TblDef *)pvAddr)->m_lValid ++; + ((TblDef *)pvAddr)->m_lGroupRoot = pstRoot->m_lSePos; + } + + if(RC_SUCC != lRecordWork(pstSavm, pstTruck->m_pvData, OPERATE_UPDATE)) + goto GROUP_ERROR; + + memcpy(pstTruck->m_pvData, pvData, lGetRowSize(t)); + SET_DATA_TRUCK(pstTruck, DATA_TRUCK_NRML); + + if(FIRST_ROW & pstSavm->lFind) break; + } + pthread_rwlock_unlock(prwLock); + TFree(pvData); + + if(0 == pstSavm->m_lEffect) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_FAIL; + } + + return RC_SUCC; + +GROUP_ERROR: + pthread_rwlock_unlock(prwLock); + TFree(pvData); + return RC_FAIL; +} + +/************************************************************************************************* + description:Update record hash index + parameters: + pstSavm --stvm handle + pstAddr --table handle + t --table + pvUpdate --update date + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lUpdateHash(SATvm *pstSavm, void *pvAddr, TABLE t, void *pvUpdate) +{ + SHList *pstList = NULL; + SHTruck *pstTruck = NULL; + SHTree *pstTree, *pstHash; + void *pvData = NULL, *pvCond; + size_t lOld, lIdx, lOffset, lNext; + RWLock *prwLock = (RWLock *)pGetRWLock(pvAddr); + char szOld[MAX_INDEX_LEN], szIdx[MAX_INDEX_LEN]; + + memset(szOld, 0, sizeof(szOld)); + if(NULL == pGetIndex(&pstSavm->stCond, lGetGrpNum(t), pGetTblGrp(t), pstSavm->pstVoid, szOld)) + return RC_CONTU; + + if(NULL == (pvData = (void *)malloc(lGetRowSize(t)))) + { + pstSavm->m_lErrno = MALLC_MEM_ERR; + return RC_FAIL; + } + + lOld = uGetHash(szOld, lGetGrpLen(t)) % ((TblDef *)pvAddr)->m_lMaxRow; + lOffset = ((TblDef *)pvAddr)->m_lGroupPos + lOld * sizeof(SHTree); + if(NULL == (pstHash = (SHTree *)(pvAddr + lOffset))) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + TFree(pvData); + return RC_FAIL; + } + + if(RC_SUCC != pthread_rwlock_wrlock(prwLock)) + { + pstSavm->m_lErrno = LOCK_DOWR_ERR; + TFree(pvData); + return RC_FAIL; + } + + pstSavm->m_lEffect = 0; + pvCond = pstSavm->pstVoid; + pstSavm->m_lEType = EXE_PLAN_GRP; + for(pstList = (SHList *)pGetNode(pvAddr, pstHash->m_lData); SELF_POS_UNUSE != pstList->m_lPos; + pstList = (SHList *)pGetNode(pvAddr, lNext)) + { + lNext = pstList->m_lNext; + pstTruck = (PSHTruck)pGetNode(pvAddr, pstList->m_lData); + if(RC_MISMA == lFeildMatch(&pstSavm->stCond, pstTruck->m_pvData, pvCond)) + { + if(SELF_POS_UNUSE == pstList->m_lNext) break; + continue; + } + + memcpy(pvData, pstTruck->m_pvData, lGetRowSize(t)); + if(RC_FAIL == lMergeTruck(pstSavm, &pstSavm->stUpdt, pvUpdate, pvData)) + goto HASH_ERROR; + + memset(szIdx, 0, sizeof(szIdx)); + if(NULL == pPickIndex(lGetGrpNum(t), pGetTblGrp(t), pvData, szIdx)) + { + pstSavm->m_lErrno = IDX_FIELD_NIL; + goto HASH_ERROR; + } + + pstSavm->m_lEffect ++; + pstSavm->pstVoid = pvData; + lIdx = uGetHash(szIdx, lGetGrpLen(t)) % ((TblDef *)pvAddr)->m_lMaxRow; + SET_DATA_TRUCK(pstTruck, DATA_TRUCK_NULL); + if(HAVE_UNIQ_IDX(t)) + { + if(RC_SUCC != __lIndexUpdate(pstSavm, pvAddr, t, pstTruck, pstList->m_lData)) + { + SET_DATA_TRUCK(pstTruck, DATA_TRUCK_NULL); + goto HASH_ERROR; + } + } + + // Index does not match, rebuild inde + if(lOld != lIdx) + { + -- ((TblDef *)pvAddr)->m_lValid; + lOffset = lGetListOfs(t) + ((TblDef *)pvAddr)->m_lValid * sizeof(SHList); + if(RC_SUCC != lReleaseList(pvAddr, t, pstHash, pstList, lOffset, &lNext)) + { + ((TblDef *)pvAddr)->m_lValid ++; + pstSavm->m_lErrno = SVR_EXCEPTION; + SET_DATA_TRUCK(pstTruck, DATA_TRUCK_NRML); + goto HASH_ERROR; + } + + lOffset = ((TblDef *)pvAddr)->m_lGroupPos + lIdx * sizeof(SHTree); + if(NULL == (pstTree = (SHTree *)(pvAddr + lOffset))) + { + pstSavm->m_lErrno = SVR_EXCEPTION; + SET_DATA_TRUCK(pstTruck, DATA_TRUCK_NRML); + goto HASH_ERROR; + } + + if(RC_SUCC != __lInsertHash(pstSavm, pvAddr, t, pstTree, lOffset, &pstTruck)) + { + pstSavm->m_lErrno = SVR_EXCEPTION; + SET_DATA_TRUCK(pstTruck, DATA_TRUCK_NRML); + goto HASH_ERROR; + } + + ((TblDef *)pvAddr)->m_lValid ++; + } + if(RC_SUCC != lRecordWork(pstSavm, pstTruck->m_pvData, OPERATE_UPDATE)) + goto HASH_ERROR; + + memcpy(pstTruck->m_pvData, pvData, lGetRowSize(t)); + SET_DATA_TRUCK(pstTruck, DATA_TRUCK_NRML); + + if(FIRST_ROW & pstSavm->lFind) break; + } + pthread_rwlock_unlock(prwLock); + TFree(pvData); + + if(0 == pstSavm->m_lEffect) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_FAIL; + } + + return RC_SUCC; + +HASH_ERROR: + pthread_rwlock_unlock(prwLock); + TFree(pvData); + return RC_FAIL; +} + +/************************************************************************************************* + description:Update record truck + parameters: + pstSavm --stvm handle + pstAddr --table handle + t --table + pvUpdate --update date + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lTruckUpdate(SATvm *pstSavm, void *pvAddr, TABLE t, void *pvUpdate) +{ + long lRet = RC_SUCC; + SHTruck *pstTruck = NULL; + void *pvData = NULL, *pvCond; + size_t lRow, lOffset = lGetTblData(t); + RWLock *prwLock = (RWLock *)pGetRWLock(pvAddr); + + if(NULL == (pvData = (void *)malloc(lGetRowSize(t)))) + { + pstSavm->m_lErrno = MALLC_MEM_ERR; + return RC_FAIL; + } + + if(RC_SUCC != pthread_rwlock_wrlock(prwLock)) + { + pstSavm->m_lErrno = LOCK_DOWR_ERR; + TFree(pvData); + return RC_FAIL; + } + + pstSavm->m_lEffect = 0; + pvCond = pstSavm->pstVoid; + pstSavm->m_lEType = EXE_PLAN_ALL; + pstTruck = (PSHTruck)pGetNode(pvAddr, lOffset); + for(lRow = 0; (lRow < ((TblDef *)pvAddr)->m_lValid) && (lOffset < lGetTableSize(t)); + pstTruck = (PSHTruck)pGetNode(pvAddr, lOffset)) + { + if(IS_TRUCK_NULL(pstTruck)) + { + lOffset += lGetRowTruck(t); + continue; + } + + lRow ++; + if(RC_MISMA == lFeildMatch(&pstSavm->stCond, pstTruck->m_pvData, pvCond)) + { + lOffset += lGetRowTruck(t); + continue; + } + + memcpy(pvData, pstTruck->m_pvData, lGetRowSize(t)); + if(RC_FAIL == lMergeTruck(pstSavm, &pstSavm->stUpdt, pvUpdate, pvData)) + goto TRUCK_ERROR; + + pstSavm->m_lEffect ++; + pstSavm->pstVoid = pvData; + SET_DATA_TRUCK(pstTruck, DATA_TRUCK_NULL); + if(HAVE_UNIQ_IDX(t)) + { + if(RC_SUCC != __lIndexUpdate(pstSavm, pvAddr, t, pstTruck, lOffset)) + { + SET_DATA_TRUCK(pstTruck, DATA_TRUCK_NRML); + goto TRUCK_ERROR; + } + } + + if(HAVE_NORL_IDX(t)) + lRet = __lUpdateGroup(pstSavm, pvAddr, t, pstTruck, lOffset); + else if(HAVE_HASH_IDX(t)) + lRet = __lUpdateHash(pstSavm, pvAddr, t, pstTruck, lOffset); + SET_DATA_TRUCK(pstTruck, DATA_TRUCK_NRML); + if(RC_SUCC != lRet) + goto TRUCK_ERROR; + + if(RC_SUCC != lRecordWork(pstSavm, pstTruck->m_pvData, OPERATE_UPDATE)) + goto TRUCK_ERROR; + + memcpy(pstTruck->m_pvData, pvData, lGetRowSize(t)); + if(FIRST_ROW & pstSavm->lFind) break; + lOffset += lGetRowTruck(t); + } + + pthread_rwlock_unlock(prwLock); + TFree(pvData); + if(0 == pstSavm->m_lEffect) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_FAIL; + } + + return RC_SUCC; + +TRUCK_ERROR: + pthread_rwlock_unlock(prwLock); + TFree(pvData); + return RC_FAIL; +} + +/************************************************************************************************* + description:API - Update + parameters: + pstSavm --stvm handle + pvUpdate --update date + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lUpdate(SATvm *pstSavm, void *pvUpdate) +{ + long lRet; + void *pvData; + RunTime *pstRun = NULL; + + if(!pstSavm || !pvUpdate) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + pvData = pstSavm->pstVoid; + if(NULL == (pstRun = (RunTime *)pInitMemTable(pstSavm, pstSavm->tblName))) + return RC_FAIL; + + if(RES_REMOT_SID == pstRun->m_lLocal) + { + Tremohold(pstSavm, pstRun); + return _lUpdateByRt(pstSavm, pvUpdate); + } + + if(HAVE_UNIQ_IDX(pstSavm->tblName)) + { + lRet = _lUpdateIndex(pstSavm, pstRun->m_pvAddr, pstSavm->tblName, pvUpdate); + if(RC_CONTU != lRet) + { + vTblDisconnect(pstSavm, pstSavm->tblName); + pstSavm->pstVoid = pvData; + return lRet; + } + } + + if(HAVE_NORL_IDX(pstSavm->tblName)) + { + lRet = _lUpdateGroup(pstSavm, pstRun->m_pvAddr, pstSavm->tblName, pvUpdate); + if(RC_CONTU != lRet) + { + vTblDisconnect(pstSavm, pstSavm->tblName); + pstSavm->pstVoid = pvData; + return lRet; + } + } + else if(HAVE_HASH_IDX(pstSavm->tblName)) + { + lRet = _lUpdateHash(pstSavm, pstRun->m_pvAddr, pstSavm->tblName, pvUpdate); + if(RC_CONTU != lRet) + { + vTblDisconnect(pstSavm, pstSavm->tblName); + pstSavm->pstVoid = pvData; + return lRet; + } + } + + lRet = _lTruckUpdate(pstSavm, pstRun->m_pvAddr, pstSavm->tblName, pvUpdate); + vTblDisconnect(pstSavm, pstSavm->tblName); + pstSavm->pstVoid = pvData; + return lRet; +} + +/************************************************************************************************* + description:Registry and table fields + parameters: + pstSavm --stvm handle + pstRun --table handle + t --table + lType + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lRegisterTable(SATvm *pstSavm, RunTime *pstRun, TABLE t, long lType) +{ + TIndex stIndex; + TBoot *pstBoot = (TBoot *)pBootInitial(); + + if(TYPE_CLIENT != lType) return RC_SUCC; + + if(RC_SUCC != lInitSATvm(pstSavm, SYS_TVM_INDEX)) + return RC_FAIL; + + if(RC_FAIL == (pstSavm->m_ySey = yGetIPCPath(pstSavm, IPC_SEM))) + return RC_FAIL; + + pstRun->m_semID = semget(pstSavm->m_ySey, pstBoot->m_lMaxTable, IPC_CREAT|0660); + + conditinit(pstSavm, stIndex, SYS_TVM_INDEX); + stIndex.m_lValid = 0; + stIndex.m_yKey = 0; + stIndex.m_table = t; + stIndex.m_lType = lType; + stIndex.m_lMaxRows = lGetTblRow(t); + stIndex.m_lRowSize = lGetRowSize(t); + stIndex.m_shmID = pstRun->m_shmID; + stIndex.m_semID = pstRun->m_semID; + stIndex.m_lLocal = RES_LOCAL_SID; + stIndex.m_lPers = lGetPermit(t); + + strncpy(stIndex.m_szOwner, pstSavm->m_szNode, sizeof(stIndex.m_szOwner)); + strncpy(stIndex.m_szTime, sGetUpdTime(), sizeof(stIndex.m_szTime)); + strncpy(stIndex.m_szTable, sGetTableName(t), sizeof(stIndex.m_szTable)); + strncpy(stIndex.m_szPart, sGetTablePart(t, pstSavm->m_szNode), sizeof(stIndex.m_szPart)); + + if(RC_SUCC != lInsert(pstSavm)) + { + if(UNIQ_IDX_REPT == pstSavm->m_lErrno) + pstSavm->m_lErrno = TBL_ARD_EXIST; + return RC_FAIL; + } + + if(RC_SUCC != lInsertField(pstSavm, t)) + return RC_FAIL; + + if(TVM_BOOT_SIMPLE != pstBoot->m_lBootType) + lRefreshNotify(pstSavm, pstBoot->m_lBootPort); + return RC_SUCC; +} + +/************************************************************************************************* + description:Define the customer table + parameters: + pstSavm --stvm handle + t --table + lRow --table maxrows + bCreate --create type + lType --table type + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lCustomTable(SATvm *pstSavm, TABLE t, size_t lRow, bool bCreate, long lType) +{ + RWAttr attr; + RunTime *pstRun = NULL; + RWLock *prwLock = NULL; + + pstSavm->tblName = t; + ((TblDef *)pGetTblDef(t))->m_lTable = lInitialTable(t, lRow); + if(NULL == (pstRun = (RunTime *)pCreateBlock(pstSavm, t, ((TblDef *)pGetTblDef(t))->m_lTable, + bCreate))) + return RC_FAIL; + + // After the memory is created, it will initialize the index information + if(RC_SUCC != lInitailTree(pstSavm, (void *)pGetNode(pstRun->m_pvAddr, lGetIdxPos(t)), t)) + return RC_FAIL; + + if(RC_SUCC != lInitailGroup(pstSavm, (void *)pGetNode(pstRun->m_pvAddr, lGetGrpPos(t)), t)) + return RC_FAIL; + + memcpy(pstRun->m_pvAddr, (void *)pGetTblDef(t), sizeof(TblDef)); + prwLock = (RWLock *)pGetRWLock(pstRun->m_pvAddr); + pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); + pthread_rwlock_init(prwLock, &attr); + + memset(pstRun->m_pvAddr + lGetTblData(t), 0, lGetTableSize(t) - lGetTblData(t)); + vTblDisconnect(pstSavm, t); + + if(RC_SUCC != lRegisterTable(pstSavm, pstRun, t, lType)) + { + shmctl(pstRun->m_shmID, IPC_RMID, NULL); + return RC_FAIL; + } + + return RC_SUCC; +} + +/************************************************************************************************* + description:create table + parameters: + pstSavm --stvm handle + t --table + lRow --table maxrows + bCreate --create type + lType --table type + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lCreateTable(SATvm *pstSavm, TABLE t, size_t lRow, bool bCreate, long lType, + TCREATE pfCreateFunc) +{ + long lRet; + + if(!pstSavm || lRow <= 0) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + vInitTblDef(t); + pstSavm->tblName = t; + switch(t) + { + case SYS_TVM_INDEX: + lRet = lCreateTvmIndex(); + break; + case SYS_TVM_FIELD: + lRet = lCreateTvmField(); + break; + case SYS_TVM_DOMAIN: + lRet = lCreateTvmDomain(); + break; + case SYS_TVM_SEQUE: + lRet = lCreateTvmSeque(); + break; + default: + if(!pfCreateFunc) + return RC_SUCC; + + lRet = pfCreateFunc(t); + break; + } + if(RC_SUCC != lRet) return lRet; + + return _lCustomTable(pstSavm, t, lRow, bCreate, lType); +} + +/************************************************************************************************* + description:Create a sequence + parameters: + pstSavm --stvm handle + pszSQName --SQL name + uIncre --increment + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lCreateSeque(SATvm *pstSavm, char *pszSQName, uint uIncre) +{ + TSeque stSeque; + + if(RC_SUCC != lInitSATvm(pstSavm, SYS_TVM_SEQUE)) + return RC_FAIL; + + conditinit(pstSavm, stSeque, SYS_TVM_SEQUE); + strncpy(stSeque.m_szSQName, pszSQName, sizeof(stSeque.m_szSQName)); + stSeque.m_uIncrement = uIncre > 0 ? uIncre : 1; + return lInsert(pstSavm); +} + +/************************************************************************************************* + description:Set the starting value of the sequence + parameters: + pstSavm --stvm handle + pszSQName --SQL name + uIncre --increment + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lSetSequence(SATvm *pstSavm, char *pszSQName, ulong uStart) +{ + TSeque stSeque; + SHTree *pstTree = NULL; + RunTime *pstRun = NULL; + RWLock *prwLock = NULL; + SHTruck *pstTruck = NULL; + + if(!pstSavm) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + memset(&stSeque, 0, sizeof(stSeque)); + strncpy(stSeque.m_szSQName, pszSQName, sizeof(stSeque.m_szSQName)); + if(RC_SUCC != lInitSATvm(pstSavm, SYS_TVM_SEQUE)) + return RC_FAIL; + + pstSavm->lSize = sizeof(TSeque); + if(NULL == (pstRun = (RunTime *)pInitMemTable(pstSavm, SYS_TVM_SEQUE))) + return RC_FAIL; + + prwLock = (RWLock *)pGetRWLock(pstRun->m_pvAddr); + if(RC_SUCC != pthread_rwlock_wrlock(prwLock)) + { + pstSavm->m_lErrno = LOCK_DORD_ERR; + vTblDisconnect(pstSavm, SYS_TVM_SEQUE); + return RC_FAIL; + } + + if(NULL == (pstTree = (SHTree *)pGetNode(pstRun->m_pvAddr, + ((TblDef *)pstRun->m_pvAddr)->m_lTreeRoot))) + { + pstSavm->m_lErrno = SVR_EXCEPTION; + pthread_rwlock_unlock(prwLock); + vTblDisconnect(pstSavm, SYS_TVM_SEQUE); + return RC_FAIL; + } + + pstTree = (SHTree *)pSearchTree(pstRun->m_pvAddr, pstTree, stSeque.m_szSQName, + lGetIdxLen(SYS_TVM_SEQUE)); + if(!pstTree) + { + pthread_rwlock_unlock(prwLock); + vTblDisconnect(pstSavm, SYS_TVM_SEQUE); + pstSavm->m_lErrno = SEQ_NOT_FOUND; + return RC_FAIL; + } + + pstTruck = (PSHTruck)pGetNode(pstRun->m_pvAddr, pstTree->m_lData); + pstTruck->m_lTimes = uStart; + pthread_rwlock_unlock(prwLock); + vTblDisconnect(pstSavm, SYS_TVM_SEQUE); + + return RC_SUCC; +} + +/************************************************************************************************* + description:select seque + parameters: + pstSavm --stvm handle + pszSQName --SQL name + pulNumber --number + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lSelectSeque(SATvm *pstSavm, char *pszSQName, ulong *pulNumber) +{ + TSeque stSeque; + SHTree *pstTree = NULL; + RunTime *pstRun = NULL; + RWLock *prwLock = NULL; + SHTruck *pstTruck = NULL; + + if(!pstSavm) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + memset(&stSeque, 0, sizeof(stSeque)); + strncpy(stSeque.m_szSQName, pszSQName, sizeof(stSeque.m_szSQName)); + if(RC_SUCC != lInitSATvm(pstSavm, SYS_TVM_SEQUE)) + return RC_FAIL; + + pstSavm->lSize = sizeof(TSeque); + if(NULL == (pstRun = (RunTime *)pInitMemTable(pstSavm, SYS_TVM_SEQUE))) + return RC_FAIL; + + prwLock = (RWLock *)pGetRWLock(pstRun->m_pvAddr); + if(RC_SUCC != pthread_rwlock_wrlock(prwLock)) + { + pstSavm->m_lErrno = LOCK_DORD_ERR; + vTblDisconnect(pstSavm, SYS_TVM_SEQUE); + return RC_FAIL; + } + + if(NULL == (pstTree = (SHTree *)pGetNode(pstRun->m_pvAddr, + ((TblDef *)pstRun->m_pvAddr)->m_lTreeRoot))) + { + pstSavm->m_lErrno = SVR_EXCEPTION; + pthread_rwlock_unlock(prwLock); + vTblDisconnect(pstSavm, SYS_TVM_SEQUE); + return RC_FAIL; + } + + pstTree = (SHTree *)pSearchTree(pstRun->m_pvAddr, pstTree, stSeque.m_szSQName, + lGetIdxLen(SYS_TVM_SEQUE)); + if(!pstTree) + { + pthread_rwlock_unlock(prwLock); + vTblDisconnect(pstSavm, SYS_TVM_SEQUE); + pstSavm->m_lErrno = SEQ_NOT_FOUND; + return RC_FAIL; + } + + pstTruck = (PSHTruck)pGetNode(pstRun->m_pvAddr, pstTree->m_lData); + pstTruck->m_lTimes += ((TSeque *)pstTruck->m_pvData)->m_uIncrement; + *pulNumber = pstTruck->m_lTimes; + pthread_rwlock_unlock(prwLock); + vTblDisconnect(pstSavm, SYS_TVM_SEQUE); + pstSavm->m_lEffect = 1; + + return RC_SUCC; +} + +/************************************************************************************************* + description:shut down STVM + parameters: + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lShutdownTvm() +{ + size_t lOut = 0; + TIndex *pstIndex = NULL; + RunTime *pstRun = NULL; + RWLock *prwLock = NULL; + SATvm *pstSavm = (SATvm *)pGetSATvm(); + + if(RC_SUCC != lExportTable(SYS_TVM_INDEX, &lOut, (void *)&pstIndex)) + return RC_FAIL; + + if(0 == lOut) return RC_SUCC; + + // Remove from the back forward, root index table last deleted + for(lOut; 0 < lOut; -- lOut) + { + if(RES_REMOT_SID == pstIndex[lOut - 1].m_lLocal) + continue; + + vForceDisconnect(pstSavm, pstIndex[lOut - 1].m_table); + pstRun = (RunTime *)pGetRunTime(pstSavm, pstIndex[lOut - 1].m_table); + pstRun->m_shmID = pstIndex[lOut - 1].m_shmID; + if(NULL == (pstRun = (RunTime *)pInitHitTest(pstSavm, pstIndex[lOut - 1].m_table))) + { + TFree(pstIndex); + return RC_FAIL; + } + + if(RES_REMOT_SID == pstRun->m_lLocal) + continue; + + prwLock = (RWLock *)pGetRWLock(pstRun->m_pvAddr); + pthread_rwlock_destroy(prwLock); + vForceDisconnect(pstSavm, pstIndex[lOut - 1].m_table); + + // The table is deleted, whether successful or not + shmctl(pstIndex[lOut - 1].m_shmID, IPC_RMID, NULL); + } + semctl(pstIndex[0].m_semID, 0, IPC_RMID, NULL); + TFree(pstIndex); + + return RC_SUCC; +} + +/************************************************************************************************* + description:initial domain + parameters: + pstSavm --stvm handle + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lInitDomain(SATvm *pstSavm) +{ + long i, lCount = 0; + TDomain *pstDomain = NULL; + TIndex stIndex, *pstIndex = NULL; + + if(RC_SUCC != lGetDomainIndex(pstSavm, &lCount, &pstIndex)) + return RC_FAIL; + + insertinit(pstSavm, pstIndex[i], SYS_TVM_INDEX) + for(i = 0; i < lCount; i ++) + { + pstIndex[i].m_lValid = 0; + pstIndex[i].m_lType = TYPE_CLIENT; + pstIndex[i].m_lLocal = RES_REMOT_SID; + pstIndex[i].m_lState = RESOURCE_STOP; + pstIndex[i].m_lPers = OPERATE_NULL; + strncpy(pstIndex[i].m_szTime, sGetUpdTime(), sizeof(pstIndex[i].m_szTime)); + + pstSavm->pstVoid = (void *)&pstIndex[i]; + if(RC_SUCC != lInsert(pstSavm)) + { + TFree(pstIndex); + return RC_FAIL; + } + } + lCount = 0; + TFree(pstIndex); + + if(RC_SUCC != lGetDomainTable(pstSavm, &lCount, &pstDomain)) + return RC_FAIL; + + for(i = 0; i < lCount; i ++) + { + pstDomain[i].m_lStatus = RESOURCE_STOP; + + insertinit(pstSavm, pstDomain[i], SYS_TVM_DOMAIN) + if(RC_SUCC != lInsert(pstSavm)) + { + TFree(pstDomain); + return RC_FAIL; + } + } + + lCount = 0; + TFree(pstDomain); + + return RC_SUCC; +} + +/************************************************************************************************* + description:Get table permissions + parameters: + pstSavm --stvm handle + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lGetPermit(TABLE t) +{ + TIndex *pstIndex = NULL; + SATvm *pstSavm = (SATvm *)pGetSATvm(); + long i, lCount = 0, lPers = OPERATE_DEFAULT; + + if(RC_SUCC != lGetLocalIndex(pstSavm, &lCount, &pstIndex)) + return lPers; + + for(i = 0; i < lCount; i ++) + { + if(t == pstIndex[i].m_table) + { + lPers = pstIndex[i].m_lPers; + break; + } + } + TFree(pstIndex); + + return lPers; +} + +/************************************************************************************************* + description:startup STVM + parameters: + pstBoot --boot paramter + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lStartupTvm(TBoot *pstBoot) +{ + long semID; + TIndex stIndex; + RunTime *pstRun = NULL; + SATvm *pstSavm = (SATvm *)pGetSATvm(); + + memset(&stIndex, 0, sizeof(TIndex)); + if(RC_SUCC != _lCreateTable(pstSavm, SYS_TVM_INDEX, pstBoot->m_lMaxTable, TRUE, + TYPE_SYSTEM, NULL)) + return RC_FAIL; + + pstRun = (RunTime *)pGetRunTime(pstSavm, SYS_TVM_INDEX); + if(RC_SUCC != lCreateSems(pstSavm, pstRun, pstBoot->m_lMaxTable, SEM_INIT)) + return RC_FAIL; + + semID = pstRun->m_semID; + stIndex.m_lValid = 0; + stIndex.m_semID = semID; + stIndex.m_lType = TYPE_SYSTEM; + stIndex.m_table = SYS_TVM_INDEX; + stIndex.m_yKey = pstSavm->m_yKey; + stIndex.m_shmID = pstRun->m_shmID; + stIndex.m_lMaxRows = pstBoot->m_lMaxTable; + stIndex.m_lLocal = RES_LOCAL_SID; + stIndex.m_lState = RESOURCE_STOP; + stIndex.m_lPers = OPERATE_NULL; + stIndex.m_lRowSize = lGetRowSize(SYS_TVM_INDEX); + strncpy(stIndex.m_szTime, sGetUpdTime(), sizeof(stIndex.m_szTime)); + strncpy(stIndex.m_szOwner, pstBoot->m_szNode, sizeof(stIndex.m_szOwner)); + strncpy(stIndex.m_szPart, pstBoot->m_szNode, sizeof(stIndex.m_szPart)); + strncpy(stIndex.m_szTable, sGetTableName(SYS_TVM_INDEX), sizeof(stIndex.m_szTable)); + + /* The table was initialized when it was created + if(NULL == (pstSavm = (SATvm *)pInitSATvm(SYS_TVM_INDEX))) + return RC_FAIL; + */ + + insertinit(pstSavm, stIndex, SYS_TVM_INDEX) + if(RC_SUCC != lInsert(pstSavm)) + return RC_FAIL; + + memset(&stIndex, 0, sizeof(TIndex)); + if(RC_SUCC != _lCreateTable(pstSavm, SYS_TVM_FIELD, pstBoot->m_lMaxField, FALSE, + TYPE_INCORE, NULL)) + return RC_FAIL; + + pstRun = (RunTime *)pGetRunTime(pstSavm, SYS_TVM_FIELD); + stIndex.m_lValid = 0; + stIndex.m_semID = semID; + stIndex.m_lType = TYPE_INCORE; + stIndex.m_lLocal = RES_LOCAL_SID; + stIndex.m_table = SYS_TVM_FIELD; + stIndex.m_yKey = pstSavm->m_yKey; + stIndex.m_shmID = pstRun->m_shmID; + stIndex.m_lState = RESOURCE_STOP; + stIndex.m_lPers = OPERATE_NULL; + stIndex.m_lRowSize = lGetRowSize(SYS_TVM_FIELD); + strncpy(stIndex.m_szTime, sGetUpdTime(), sizeof(stIndex.m_szTime)); + strncpy(stIndex.m_szOwner, pstBoot->m_szNode, sizeof(stIndex.m_szOwner)); + strncpy(stIndex.m_szPart, pstBoot->m_szNode, sizeof(stIndex.m_szPart)); + strncpy(stIndex.m_szTable, sGetTableName(SYS_TVM_FIELD), sizeof(stIndex.m_szTable)); + + insertinit(pstSavm, stIndex, SYS_TVM_INDEX) + if(RC_SUCC != lInsert(pstSavm)) + return RC_FAIL; + + if(RC_SUCC != lInsertField(pstSavm, SYS_TVM_FIELD)) + return RC_FAIL; + + memset(&stIndex, 0, sizeof(TIndex)); + if(RC_SUCC != _lCreateTable(pstSavm, SYS_TVM_DOMAIN, pstBoot->m_lMaxDomain, FALSE, + TYPE_INCORE, NULL)) + return RC_FAIL; + + pstRun = (RunTime *)pGetRunTime(pstSavm, SYS_TVM_DOMAIN); + stIndex.m_lValid = 0; + stIndex.m_semID = semID; + stIndex.m_lType = TYPE_INCORE; + stIndex.m_lLocal = RES_LOCAL_SID; + stIndex.m_table = SYS_TVM_DOMAIN; + stIndex.m_yKey = pstSavm->m_yKey; + stIndex.m_shmID = pstRun->m_shmID; + stIndex.m_lState = RESOURCE_STOP; + stIndex.m_lPers = OPERATE_NULL; + stIndex.m_lRowSize = lGetRowSize(SYS_TVM_DOMAIN); + strncpy(stIndex.m_szTime, sGetUpdTime(), sizeof(stIndex.m_szTime)); + strncpy(stIndex.m_szOwner, pstBoot->m_szNode, sizeof(stIndex.m_szOwner)); + strncpy(stIndex.m_szPart, pstBoot->m_szNode, sizeof(stIndex.m_szPart)); + strncpy(stIndex.m_szTable, sGetTableName(SYS_TVM_DOMAIN), sizeof(stIndex.m_szTable)); + + insertinit(pstSavm, stIndex, SYS_TVM_INDEX) + if(RC_SUCC != lInsert(pstSavm)) + return RC_FAIL; + + if(RC_SUCC != lInsertField(pstSavm, SYS_TVM_DOMAIN)) + return RC_FAIL; + + memset(&stIndex, 0, sizeof(TIndex)); + if(RC_SUCC != _lCreateTable(pstSavm, SYS_TVM_SEQUE, pstBoot->m_lMaxSeque, FALSE, + TYPE_INCORE, NULL)) + return RC_FAIL; + + pstRun = (RunTime *)pGetRunTime(pstSavm, SYS_TVM_SEQUE); + stIndex.m_lValid = 0; + stIndex.m_semID = semID; + stIndex.m_lType = TYPE_INCORE; + stIndex.m_lLocal = RES_LOCAL_SID; + stIndex.m_table = SYS_TVM_SEQUE; + stIndex.m_yKey = pstSavm->m_yKey; + stIndex.m_shmID = pstRun->m_shmID; + stIndex.m_lState = RESOURCE_STOP; + stIndex.m_lPers = OPERATE_NULL; + stIndex.m_lRowSize = lGetRowSize(SYS_TVM_SEQUE); + strncpy(stIndex.m_szTime, sGetUpdTime(), sizeof(stIndex.m_szTime)); + strncpy(stIndex.m_szOwner, pstBoot->m_szNode, sizeof(stIndex.m_szOwner)); + strncpy(stIndex.m_szPart, pstBoot->m_szNode, sizeof(stIndex.m_szPart)); + strncpy(stIndex.m_szTable, sGetTableName(SYS_TVM_SEQUE), sizeof(stIndex.m_szTable)); + + insertinit(pstSavm, stIndex, SYS_TVM_INDEX) + if(RC_SUCC != lInsert(pstSavm)) + return RC_FAIL; + + if(RC_SUCC != lInsertField(pstSavm, SYS_TVM_SEQUE)) + return RC_FAIL; + + return lInitDomain(pstSavm); +} + +/************************************************************************************************* + description:API - CreateTable + parameters: + pstSavm --stvm handle + t --table + lRow --table maxrows + pfCreateFunc --table field define + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lCreateTable(SATvm *pstSavm, TABLE t, size_t lRow, TCREATE pfCreateFunc) +{ + return _lCreateTable(pstSavm, t, lRow, FALSE, TYPE_CLIENT, pfCreateFunc); +} + +/************************************************************************************************* + description:Custom template creation + parameters: + pstSavm --stvm handle + t --table + lRow --table maxrows + pstDef --table struck infor + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lCustomTable(SATvm *pstSavm, TABLE t, size_t lRow, TblDef *pstDef) +{ + + memcpy((void *)pGetTblDef(t), (void *)pstDef, sizeof(TblDef)); + + return _lCustomTable(pstSavm, t, lRow, FALSE, TYPE_CLIENT); +} + +/************************************************************************************************* + description:API - lDropTable + parameters: + pstSavm --stvm handle + t --table + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lDropTable(SATvm *pstSavm, TABLE t) +{ + TIndex stIndex; + TField stField; + RunTime *pstRun = NULL; + RWLock *prwLock = NULL; + + pstSavm->bSearch = TYPE_SYSTEM; + conditinit(pstSavm, stIndex, SYS_TVM_INDEX) + numberset(pstSavm, stIndex, m_table, t) + numberset(pstSavm, stIndex, m_lType, TYPE_CLIENT) + if(RC_SUCC != lSelect(pstSavm, (void *)&stIndex)) + return RC_FAIL; + + pstRun = (RunTime *)pGetRunTime(pstSavm, t); + if(RES_REMOT_SID == pstRun->m_lLocal) + { + conditinit(pstSavm, stIndex, SYS_TVM_INDEX) + numberset(pstSavm, stIndex, m_table, t) + numberset(pstSavm, stIndex, m_lType, TYPE_CLIENT) + if(RC_SUCC != lDelete(pstSavm)) + return RC_FAIL; + + memset(pstRun, 0, sizeof(RunTime)); + _vDropTableByRt(pstSavm, t); + pstRun->m_lState = RESOURCE_INIT; + return RC_SUCC; + } + + vForceDisconnect(pstSavm, t); + pstRun->m_shmID = stIndex.m_shmID; + if(NULL == (pstRun = (RunTime *)pInitHitTest(pstSavm, t))) + return RC_FAIL; + + prwLock = (RWLock *)pGetRWLock(pstRun->m_pvAddr); + pthread_rwlock_destroy(prwLock); + vForceDisconnect(pstSavm, t); + + // The table is deleted, whether successful or not + shmctl(stIndex.m_shmID, IPC_RMID, NULL); + semctl(stIndex.m_semID, 0, IPC_RMID, 0); + + conditinit(pstSavm, stIndex, SYS_TVM_INDEX) + numberset(pstSavm, stIndex, m_table, t) + numberset(pstSavm, stIndex, m_lType, TYPE_CLIENT) + if(RC_SUCC != lDelete(pstSavm)) return RC_FAIL; + + // Delete the field table + if(RC_SUCC != lInitSATvm(pstSavm, SYS_TVM_FIELD)) + return RC_FAIL; + + conditinit(pstSavm, stField, SYS_TVM_FIELD) + numberset(pstSavm, stField, m_table, t) + if(RC_SUCC != lDelete(pstSavm)) return RC_FAIL; + + memset(pstRun, 0, sizeof(RunTime)); + pstSavm->m_lEffect = 1; + return RC_SUCC; +} + +/************************************************************************************************* + description:Format the data content for export + parameters: + fp --File descriptor + s --data record + lIdx --field number + pstIdx --field key + f --file descriptor + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lExportContext(FILE *fp, char *s, long lIdx, TblKey *pstIdx, char *f) +{ + long i = 0; + + if(!fp || !s || !pstIdx) return RC_FAIL; + + for(i = 0; i < lIdx; i ++) + { + switch(pstIdx[i].m_lAttr) + { + case FIELD_DOUB: + switch(pstIdx[i].m_lLen) + { + case 4: + fprintf(fp, "%.6f", *((float *)(s + pstIdx[i].m_lFrom))); + break; + case 8: + fprintf(fp, "%.6f", *((double *)(s + pstIdx[i].m_lFrom))); + break; + default: + break; + } + break; + case FIELD_LONG: + switch(pstIdx[i].m_lLen) + { + case 2: + fprintf(fp, "%d", *((sint *)(s + pstIdx[i].m_lFrom))); + break; + case 4: + fprintf(fp, "%d", *((int *)(s + pstIdx[i].m_lFrom))); + break; + case 8: + fprintf(fp, "%lld", *((llong *)(s + pstIdx[i].m_lFrom))); + break; + default: + break; + } + break; + case FIELD_CHAR: +// fwrite(s + pstIdx[i].m_lFrom, 1, pstIdx[i].m_lLen, fp); + fprintf(fp, "%s", s + pstIdx[i].m_lFrom); + break; + default: + fprintf(stderr, "Export field attribute exception\n"); + break; + } + fprintf(fp, "%s", f); + } + + return RC_SUCC; +} + +/************************************************************************************************* + description:Format the data content into the import + parameters: + s --data line + lIdx --field number + pstIdx --field key + pvOut --format to row record + f --file descriptor + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lImportContext(char *s, long lIdx, TblKey *pstIdx, char *pvOut, char *f) +{ + void *p = NULL; + register long i; + + for(i = 0; i < lIdx; i ++) + { + p = sgetvalue(s, f, i + 1); + + switch(pstIdx[i].m_lAttr) + { + case FIELD_DOUB: + switch(pstIdx[i].m_lLen) + { + case 4: + *((float *)(pvOut + pstIdx[i].m_lFrom)) = atof(p); + break; + case 8: + *((double *)(pvOut + pstIdx[i].m_lFrom)) = atof(p); + break; + default: + break; + } + break; + case FIELD_LONG: + switch(pstIdx[i].m_lLen) + { + case 2: + *((sint *)(pvOut + pstIdx[i].m_lFrom)) = atoi(p); + break; + case 4: + *((int *)(pvOut + pstIdx[i].m_lFrom)) = atoi(p); + break; + case 8: + *((llong *)(pvOut + pstIdx[i].m_lFrom)) = atol(p); + break; + default: + break; + } + break; + case FIELD_CHAR: + memcpy(pvOut + pstIdx[i].m_lFrom, p, pstIdx[i].m_lLen); + break; + default: + break; + } + } + + return RC_SUCC; +} + +/************************************************************************************************* + description:API - CreateTable + parameters: + pstSavm --stvm handle + pszFile --file name + pszFlag --separator + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lImportFile(TABLE t, char *pszFile, char *pszFlag) +{ + FILE *fp = NULL; + char szLine[1024]; + RunTime *pstRun = NULL; + void *pvData = NULL; + RWLock *prwLock = NULL; + long lEffect = 0, lRet = RC_SUCC; + SATvm *pstSavm = (SATvm *)pGetSATvm(); + + if(!pszFile || !pszFlag || !strlen(pszFlag)) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + memset(szLine, 0, sizeof(szLine)); + if(NULL == (pstSavm = (SATvm *)pInitSATvm(t))) + return RC_FAIL; + + if(NULL == (pstRun = (RunTime *)pInitHitTest(pstSavm, pstSavm->tblName))) + return RC_FAIL; + + if(RES_REMOT_SID == pstRun->m_lLocal) + { + pstSavm->m_lErrno = RMT_NOT_SUPPT; + return RC_FAIL; + } + + if(NULL == (fp = fopen(pszFile, "rb"))) + { + pstSavm->m_lErrno = FIL_NOT_EXIST; + return RC_FAIL; + } + + if(NULL == (pvData = (void *)malloc(lGetRowSize(t)))) + { + fclose(fp); + pstSavm->m_lErrno = MALLC_MEM_ERR; + return RC_FAIL; + } + + pstSavm->pstVoid = pvData; + pstSavm->lSize = lGetRowSize(t); + prwLock = (RWLock *)pGetRWLock(pstRun->m_pvAddr); + if(RC_SUCC != pthread_rwlock_wrlock(prwLock)) + { + fclose(fp); + TFree(pvData); + pstSavm->m_lErrno = LOCK_DOWR_ERR; + return RC_FAIL; + } + + while(fgets(szLine, sizeof(szLine), fp)) + { + strimcrlf(szLine); + if(!strlen(szLine)) + continue; + + if(lGetTblRow(t) <= ((TblDef *)pstRun->m_pvAddr)->m_lValid) + { + lRet = RC_FAIL; + pstSavm->m_lErrno = DATA_SPC_FULL; + break; + } + + memset(pvData, 0, lGetRowSize(t)); + _lImportContext(szLine, lGetFldNum(t), pGetTblKey(t), pvData, pszFlag); + if(RC_SUCC != (lRet = __lInsert(pstSavm, pstRun->m_pvAddr, pstSavm->tblName, 0))) + break; + + lEffect ++; + memset(szLine, 0, sizeof(szLine)); + if(RC_SUCC != lRecordWork(pstSavm, pstSavm->pstVoid, OPERATE_INSERT)) + break; + } + fclose(fp); + pthread_rwlock_unlock(prwLock); + pstSavm->m_lEffect = lEffect; + vTblDisconnect(pstSavm, pstSavm->tblName); + + TFree(pvData); + return lRet; +} + +/************************************************************************************************* + description:Export the data from the memory table + parameters: + t --table + plOut --plOut + ppsvOut --result data list + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lExportTable(TABLE t, size_t *plOut, void **ppsvOut) +{ + long lRet; + RunTime *pstRun = NULL; + SATvm *pstSavm = NULL; + + if(NULL == (pstSavm = (SATvm *)pInitSATvm(t))) + return RC_FAIL; + + if(NULL == (pstRun = (RunTime *)pInitHitTest(pstSavm, t))) + return RC_FAIL; + + if(RES_REMOT_SID == pstRun->m_lLocal) + { + pstSavm->m_lErrno = RMT_NOT_SUPPT; + return RC_FAIL; + } + + pstSavm->pstVoid = NULL; + lRet = _lQueryTruck(pstSavm, pstRun->m_pvAddr, t, plOut, ppsvOut); + vTblDisconnect(pstSavm, pstSavm->tblName); + if(NO_DATA_FOUND == pstSavm->m_lErrno) + return RC_SUCC; + + return lRet; +} + +/************************************************************************************************* + description:Import the data into the memory table + parameters: + t --table + lCount --count + psvData --record list + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lImportTable(TABLE t, size_t lCount, void *psvData) +{ + RunTime *pstRun = NULL; + SATvm *pstSavm = NULL; + RWLock *prwLock = NULL; + long i, lRet = RC_SUCC; + + if(!psvData || lCount < 0) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + if(NULL == (pstSavm = (SATvm *)pInitSATvm(t))) + return RC_FAIL; + + if(NULL == (pstRun = (RunTime *)pInitHitTest(pstSavm, t))) + return RC_FAIL; + + if(RES_REMOT_SID == pstRun->m_lLocal) + { + pstSavm->m_lErrno = RMT_NOT_SUPPT; + return RC_FAIL; + } + + prwLock = (RWLock *)pGetRWLock(pstRun->m_pvAddr); + if(RC_SUCC != pthread_rwlock_wrlock(prwLock)) + { + pstSavm->m_lErrno = LOCK_DOWR_ERR; + return RC_FAIL; + } + + for(i = 0; i < lCount; i ++) + { + pstSavm->pstVoid = psvData + lGetRowSize(t) * i; + if(RC_SUCC != (lRet = __lInsert(pstSavm, pstRun->m_pvAddr, pstSavm->tblName, 0))) + break; + } + + pthread_rwlock_unlock(prwLock); + vTblDisconnect(pstSavm, pstSavm->tblName); + + return lRet; +} + +/************************************************************************************************* + description:Export the memory table to a file + parameters: + t --table + pszFile --file name + pszFlag --separator + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lExportFile(TABLE t, char *pszFile, char *pszFlag) +{ + FILE *fp = NULL; + char szLine[1024]; + void *psvOut = NULL; + RunTime *pstRun = NULL; + SATvm *pstSavm = NULL; + + if(!pszFile || !pszFlag || !strlen(pszFlag)) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + memset(szLine, 0, sizeof(szLine)); + if(NULL == (pstSavm = (SATvm *)pInitSATvm(t))) + return RC_FAIL; + + if(NULL == (fp = fopen(pszFile, "wb"))) + { + pstSavm->m_lErrno = FIL_NOT_EXIST; + return RC_FAIL; + } + + pstSavm->pstVoid = NULL; + if(NULL == (pstRun = (RunTime *)pInitHitTest(pstSavm, t))) + { + fclose(fp); + return RC_FAIL; + } + + if(RES_REMOT_SID == pstRun->m_lLocal) + { + pstSavm->m_lErrno = RMT_NOT_SUPPT; + return RC_FAIL; + } + + if(NULL == (psvOut = (char *)malloc(lGetRowSize(t)))) + { + fclose(fp); + vTblDisconnect(pstSavm, pstSavm->tblName); + return RC_FAIL; + } + + pstRun->m_lCurLine = 1; + pstRun->m_lCurType = EXE_PLAN_ALL; + pstRun->m_pvCurAddr = pstRun->m_pvAddr; + while(RC_NOTFOUND != _llFetchTruck(pstSavm, pstRun, t, psvOut)) + { + _lExportContext(fp, psvOut, lGetFldNum(t), pGetTblKey(t), pszFlag); + fprintf(fp, "\n"); + } + + fclose(fp); + TFree(psvOut); + vTblDisconnect(pstSavm, pstSavm->tblName); + return RC_SUCC; +} + +/************************************************************************************************* + description:Get the table field + parameters: + t --table + plOut --number + ppstField --out field list + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lGetTblField(TABLE t, size_t *plOut, TField **ppstField) +{ + TField stField; + SATvm *pstSavm = NULL; + + if(NULL == (pstSavm = (SATvm *)pInitSATvm(SYS_TVM_FIELD))) + return RC_FAIL; + + conditinit(pstSavm, stField, SYS_TVM_FIELD) + numberset(pstSavm, stField, m_table, t) + return lQuery(pstSavm, plOut, (void **)ppstField); +} + +/************************************************************************************************* + description:Get the table properties + parameters: + pstSavm --table + pstTable --table name + pszPart --table part + pszIndex --result index + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lGetTblIndex(SATvm *pstSavm, char *pszTable, char *pszPart, TIndex *pstIndex) +{ + TIndex stIndex; + + if(!pszTable || !pstSavm) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + pstSavm->bSearch = TYPE_SYSTEM; + conditinit(pstSavm, stIndex, SYS_TVM_INDEX); + stringset(pstSavm, stIndex, m_szPart, pszPart); + stringset(pstSavm, stIndex, m_szTable, pszTable); + numberset(pstSavm, stIndex, m_lLocal, RES_LOCAL_SID); + if(RC_SUCC != lSelect(pstSavm, (void *)pstIndex)) + { + if(NO_DATA_FOUND == pstSavm->m_lErrno) + pstSavm->m_lErrno = TBL_NOT_FOUND; + return RC_FAIL; + } + + return RC_SUCC; +} + +/************************************************************************************************* + description:Update the table partition + parameters: + pstSavm --stvm handle + t --table + pszPart --table part + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lUpdIndexPart(SATvm *pstSavm, TABLE t, char *pszPart) +{ + TIndex stIndex, stUpdate; + + if(!pstSavm) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + pstSavm->bSearch = TYPE_SYSTEM; + updateinit(stUpdate); + conditinit(pstSavm, stIndex, SYS_TVM_INDEX); + numberset(pstSavm, stIndex, m_table, t) + numberset(pstSavm, stIndex, m_lLocal, RES_LOCAL_SID); + + stringupd(pstSavm, stUpdate, m_szPart, pszPart); + return lUpdate(pstSavm, &stUpdate); +} + +/************************************************************************************************* + description:Does the table exist + parameters: + t --table + return: + true --success + false --failure + *************************************************************************************************/ +bool bTableIsExist(TABLE t) +{ + TIndex stIndex; + SATvm *pstSavm = (SATvm *)pGetSATvm(); + + pstSavm->bSearch = TYPE_SYSTEM; + conditinit(pstSavm, stIndex, SYS_TVM_INDEX) + numberset(pstSavm, stIndex, m_table, t) + if(RC_SUCC != lSelect(pstSavm, (void *)&stIndex)) + return false; + + return true; +} + +/************************************************************************************************* + description:API - renametable + parameters: + pstSavm --stvm handle + to --old table + tn --new table + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lRenameTable(SATvm *pstSavm, TABLE to, TABLE tn) +{ + RunTime *pstRun = NULL; + TIndex stIndex, stNIdx; + TField stField, stNFld; + + pstSavm->bSearch = TYPE_SYSTEM; + updateinit(stNIdx); + conditinit(pstSavm, stIndex, SYS_TVM_INDEX); + numberset(pstSavm, stIndex, m_table, to); + numberupd(pstSavm, stNIdx, m_table, tn); + + if(RC_SUCC != lUpdate(pstSavm, &stNIdx)) + return RC_FAIL; + + _lRenameTableByRt(pstSavm, to, tn); + + memcpy((void *)pGetRunTime(pstSavm, tn), (void *)pGetRunTime(pstSavm, to), sizeof(RunTime)); + if(RC_SUCC != lInitSATvm(pstSavm, tn)) + return RC_FAIL; + + if(NULL == (pstRun = (RunTime *)pInitHitTest(pstSavm, pstSavm->tblName))) + return RC_FAIL; + + if(RES_REMOT_SID == pstRun->m_lLocal) + return RC_SUCC; + + ((TblDef *)pstRun->m_pvAddr)->m_table = tn; + vTblDisconnect(pstSavm, pstSavm->tblName); + memset((void *)pGetRunTime(pstSavm, to), 0, sizeof(RunTime)); + if(RC_SUCC != lInitSATvm(pstSavm, SYS_TVM_FIELD)) + return RC_FAIL; + + updateinit(stNFld); + conditinit(pstSavm, stField, SYS_TVM_FIELD); + numberset(pstSavm, stField, m_table, to); + numberupd(pstSavm, stNFld, m_table, tn); + return lUpdate(pstSavm, &stNFld); +} + +/************************************************************************************************* + description:Does the table part exist + parameters: + t --table + return: + true --success + false --failure + *************************************************************************************************/ +bool bPartIsExist(char *pszTable, char *pszPart) +{ + TIndex stIndex; + SATvm *pstSavm = (SATvm *)pGetSATvm(); + + pstSavm->bSearch = TYPE_SYSTEM; + conditinit(pstSavm, stIndex, SYS_TVM_INDEX) + stringset(pstSavm, stIndex, m_szPart, pszPart) + stringset(pstSavm, stIndex, m_szTable, pszTable) + numberset(pstSavm, stIndex, m_lLocal, RES_LOCAL_SID) + if(RC_SUCC != lSelect(pstSavm, (void *)&stIndex)) + { + if(MORE_ROWS_SEL == pstSavm->m_lErrno) + return true; + + return false; + } + + return true; +} + +/************************************************************************************************* + description:Gets the table maxrows + parameters: + pstSavm --stvm handle + t --table + return: + true --success + false --failure + *************************************************************************************************/ +long lTableMaxRow(SATvm *pstSavm, TABLE t) +{ + TIndex stIndex; + + if(!pstSavm) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + pstSavm->bSearch = TYPE_SYSTEM; + conditinit(pstSavm, stIndex, SYS_TVM_INDEX) + numberset(pstSavm, stIndex, m_table, t) + if(RC_SUCC != lSelect(pstSavm, (void *)&stIndex)) + return RC_FAIL; + + return stIndex.m_lMaxRows; +} + +/************************************************************************************************* + description:Whether or not the STVM is started + parameters: + t --table + return: + true --yes + false --failed + *************************************************************************************************/ +bool bIsTvmBoot() +{ + RunTime *pstRun = NULL; + SATvm *pstSavm = (SATvm *)pGetSATvm(); + + pstSavm->bSearch = TYPE_SYSTEM; + pstSavm->tblName = SYS_TVM_INDEX; + pstSavm->lSize = sizeof(TIndex); + + pstRun = (RunTime *)pGetRunTime(pstSavm, SYS_TVM_INDEX); + pstRun->m_lLocal = RES_LOCAL_SID; + + if(NULL == (pstRun = (RunTime *)pInitMemTable(pstSavm, pstSavm->tblName))) + return FALSE; + + vTblDisconnect(pstSavm, pstSavm->tblName); + return TRUE; +} + +/************************************************************************************************* + description:Returns the row record of the field's extreme value by index + parameters: + pstSavm --stvm handle + pvAddr --memory address + t --table + pFdKey --field key + psvOut --result data + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lExtremGroup(SATvm *pstSavm, void *pvAddr, TABLE t, FdKey *pFdKey, void *psvOut) +{ + TblKey *pstIdx; + void *pvData = NULL; + SHList *pstList = NULL; + SHTree *pstTree = NULL; + SHTruck *pstTruck = NULL; + char szIdx[MAX_INDEX_LEN]; + TblKey *pstKey = pGetTblGrp(t); + + if(NULL == (pstIdx = pGetFldKey(t, pFdKey->uFldpos, pFdKey->uFldlen))) + { + pstSavm->m_lErrno = FLD_NOT_EXIST; + return RC_FAIL; + } + + if(NULL == (pstTree = (SHTree *)pGetNode(pvAddr, ((TblDef *)pvAddr)->m_lGroupRoot))) + { + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + if(NULL == pstSavm->pstVoid && 1 == lGetGrpNum(t) && pstKey[0].m_lFrom == pFdKey->uFldpos + && pstKey[0].m_lAttr == FIELD_CHAR) + { + pstSavm->m_lEType = EXE_PLAN_GRP; + if(NULL == (pstTree = (SHTree *)pExtremeTree(pFdKey->uDecorate, pvAddr, pstTree))) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_FAIL; + } + + if(NULL == (pstList = (SHList *)pGetNode(pvData, pstTree->m_lData))) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_FAIL; + } + + memcpy(psvOut + pFdKey->uFldpos, pstTree->m_szIdx, pFdKey->uFldlen); + return RC_SUCC; + } + + memset(szIdx, 0, sizeof(szIdx)); + if(NULL == pGetIndex(&pstSavm->stCond, lGetGrpNum(t), pGetTblGrp(t), + pstSavm->pstVoid, szIdx)) + return RC_CONTU; + + if(NULL == (pstList = pSearchGroup(pvAddr, pstTree, szIdx, lGetGrpLen(t)))) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_CONTU; + } + + for(pstSavm->m_lEType = EXE_PLAN_GRP; SELF_POS_UNUSE != pstList->m_lPos; + pstList = (SHList *)pGetNode(pvAddr, pstList->m_lNext)) + { + pstTruck = (PSHTruck)pGetNode(pvAddr, pstList->m_lData); + if(RC_MATCH == lFeildMatch(&pstSavm->stCond, pstTruck->m_pvData, pstSavm->pstVoid)) + pvData = pvCompExtrem(pstTruck->m_pvData, pvData, pstIdx, pFdKey->uDecorate); + + if(SELF_POS_UNUSE == pstList->m_lNext) break; + } + + if(!pvData) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_FAIL; + } + + memcpy(psvOut + pFdKey->uFldpos, pvData + pFdKey->uFldpos, pFdKey->uFldlen); + return RC_SUCC; +} + +/************************************************************************************************* + description:Returns the row record of the field's extreme value by hash + parameters: + pstSavm --stvm handle + pvAddr --memory address + t --table + pFdKey --field key + psvOut --result data + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lExtremeHash(SATvm *pstSavm, void *pvAddr, TABLE t, FdKey *pFdKey, void *psvOut) +{ + TblKey *pstIdx; + size_t lData, lIdx; + SHTree *pstTree = NULL; + SHList *pstList = NULL; + SHTruck *pstTruck = NULL; + char szIdx[MAX_INDEX_LEN], *pvData = NULL; + + if(NULL == (pstIdx = pGetFldKey(t, pFdKey->uFldpos, pFdKey->uFldlen))) + { + pstSavm->m_lErrno = FLD_NOT_EXIST; + return RC_FAIL; + } + + memset(szIdx, 0, sizeof(szIdx)); + if(NULL == pGetIndex(&pstSavm->stCond, lGetGrpNum(t), pGetTblGrp(t), + pstSavm->pstVoid, szIdx)) + return RC_CONTU; + + lIdx = uGetHash(szIdx, lGetGrpLen(t)) % ((TblDef *)pvAddr)->m_lMaxRow; + pstTree = pvAddr + ((TblDef *)pvAddr)->m_lGroupRoot + lIdx * sizeof(SHTree); + if(NULL == pstTree || SELF_POS_UNUSE == pstTree->m_lData) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_FAIL; + } + + pstList = (SHList *)pGetNode(pvAddr, pstTree->m_lData); + for(pstSavm->m_lEType = EXE_PLAN_GRP; SELF_POS_UNUSE != pstList->m_lPos; + pstList = (SHList *)pGetNode(pvAddr, pstList->m_lNext)) + { + pstTruck = (PSHTruck)pGetNode(pvAddr, pstList->m_lData); + if(RC_MATCH == lFeildMatch(&pstSavm->stCond, pstTruck->m_pvData, pstSavm->pstVoid)) + pvData = pvCompExtrem(pstTruck->m_pvData, pvData, pstIdx, pFdKey->uDecorate); + + if(SELF_POS_UNUSE == pstList->m_lNext) break; + } + + if(!pvData) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_FAIL; + } + + memcpy(psvOut + pFdKey->uFldpos, pvData + pFdKey->uFldpos, pFdKey->uFldlen); + return RC_SUCC; +} + +/************************************************************************************************* + description:Returns the row record of the field's extreme value by truck + parameters: + pstSavm --stvm handle + pvAddr --memory address + t --table + pFdKey --field key + psvOut --result data + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lExtremeTruck(SATvm *pstSavm, void *pvAddr, TABLE t, FdKey *pFdKey, void *psvOut) +{ + TblKey *pstIdx; + void *pvData = NULL; + SHTruck *pstTruck = NULL; + size_t lRow = 0, lOffset = lGetTblData(t); + + if(NULL == (pstIdx = pGetFldKey(t, pFdKey->uFldpos, pFdKey->uFldlen))) + { + pstSavm->m_lErrno = FLD_NOT_EXIST; + return RC_FAIL; + } + + pstSavm->m_lEffect = 0; + pstSavm->m_lEType = EXE_PLAN_ALL; + pstTruck = (PSHTruck)pGetNode(pvAddr, lOffset); + for(lRow = 0; (lRow < ((TblDef *)pvAddr)->m_lValid) && (lOffset < lGetTableSize(t)); + pstTruck = (PSHTruck)pGetNode(pvAddr, lOffset)) + { + if(IS_TRUCK_NULL(pstTruck)) + { + lOffset += lGetRowTruck(t); + continue; + } + + lRow ++; + if(RC_MISMA == lFeildMatch(&pstSavm->stCond, pstTruck->m_pvData, pstSavm->pstVoid)) + { + lOffset += lGetRowTruck(t); + continue; + } + + lOffset += lGetRowTruck(t); + pvData = pvCompExtrem(pstTruck->m_pvData, pvData, pstIdx, pFdKey->uDecorate); + } + + if(!pvData) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_FAIL; + } + + memcpy(psvOut + pFdKey->uFldpos, pvData + pFdKey->uFldpos, pFdKey->uFldlen); + return RC_SUCC; +} + +/************************************************************************************************* + description:Returns the row record of the field's extreme value + parameters: + pstSavm --stvm handle + pvAddr --memory address + t --table + pFdKey --field key + psvOut --result data + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lExtremIndex(SATvm *pstSavm, void *pvAddr, TABLE t, FdKey *pFdKey, void *psvOut) +{ + SHTree *pstTree = NULL; + SHTruck *pstTruck = NULL; + char szIdx[MAX_INDEX_LEN]; + TblKey *pstKey = pGetTblIdx(t); + + if(NULL == (pstTree = (SHTree *)pGetNode(pvAddr, ((TblDef *)pvAddr)->m_lTreeRoot))) + { + pstSavm->m_lErrno = SVR_EXCEPTION; + return RC_FAIL; + } + + if(NULL == pstSavm->pstVoid && 1 == lGetIdxNum(t) && pstKey[0].m_lFrom == pFdKey->uFldpos + && pstKey[0].m_lAttr == FIELD_CHAR) + { + pstSavm->m_lEType = EXE_PLAN_IDX; + pstTree = (SHTree *)pExtremeTree(pFdKey->uDecorate, pvAddr, pstTree); + } + else + { + memset(szIdx, 0, sizeof(szIdx)); + if(NULL == pGetIndex(&pstSavm->stCond, lGetIdxNum(t), pGetTblIdx(t), + pstSavm->pstVoid, szIdx)) + return RC_CONTU; + + pstSavm->m_lEType = EXE_PLAN_IDX; + pstTree = (SHTree *)pSearchTree(pvAddr, pstTree, szIdx, lGetIdxLen(t)); + } + if(!pstTree) + { + pstSavm->m_lErrno = NO_DATA_FOUND; + return RC_FAIL; + } + + pstTruck = (PSHTruck)pGetNode(pvAddr, pstTree->m_lData); + memcpy(psvOut + pFdKey->uFldpos, pstTruck->m_pvData + pFdKey->uFldpos, pFdKey->uFldlen); + return RC_SUCC; +} + +/************************************************************************************************* + description:Returns extreme value + parameters: + pstSavm --stvm handle + pstRun --table handle + pFdKey --field key + psvOut --result data + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long _lExtreme(SATvm *pstSavm, RunTime *pstRun, FdKey *pFdKey, void *psvOut) +{ + long lRet; + RWLock *prwLock = (RWLock *)pGetRWLock(pstRun->m_pvAddr); + + if(MATCH_MAX != pFdKey->uDecorate && MATCH_MIN != pFdKey->uDecorate) + { + pstSavm->m_lErrno = EXTRE_SET_ERR; + return RC_FAIL; + } + + if(RC_SUCC != pthread_rwlock_rdlock(prwLock)) + { + pstSavm->m_lErrno = LOCK_DORD_ERR; + return RC_FAIL; + } + + if(HAVE_UNIQ_IDX(pstSavm->tblName)) + { + lRet = _lExtremIndex(pstSavm, pstRun->m_pvAddr, pstSavm->tblName, pFdKey, psvOut); + if(RC_CONTU != lRet) + { + pthread_rwlock_unlock(prwLock); + return lRet; + } + } + + if(HAVE_NORL_IDX(pstSavm->tblName)) + { + lRet = _lExtremGroup(pstSavm, pstRun->m_pvAddr, pstSavm->tblName, pFdKey, psvOut); + if(RC_CONTU != lRet) + { + pthread_rwlock_unlock(prwLock); + return lRet; + } + } + else if(HAVE_HASH_IDX(pstSavm->tblName)) + { + lRet = _lExtremeHash(pstSavm, pstRun->m_pvAddr, pstSavm->tblName, pFdKey, psvOut); + if(RC_CONTU != lRet) + { + pthread_rwlock_unlock(prwLock); + return lRet; + } + } + + lRet = _lExtremeTruck(pstSavm, pstRun->m_pvAddr, pstSavm->tblName, pFdKey, psvOut); + pthread_rwlock_unlock(prwLock); + return lRet; +} + +/************************************************************************************************* + description:API - extreme + parameters: + pstSavm --stvm handle + psvOut --result data + return: + RC_SUCC --success + RC_FAIL --failure + *************************************************************************************************/ +long lExtreme(SATvm *pstSavm, void *psvOut) +{ + uint i; + FdCond *pstExm; + RunTime *pstRun = NULL; + + if(!pstSavm || NULL == (pstExm = &pstSavm->stUpdt)) + { + pstSavm->m_lErrno = CONDIT_IS_NIL; + return RC_FAIL; + } + + if(0 == pstExm->uFldcmp) + { + pstSavm->m_lErrno = FIELD_NOT_SET; + return RC_FAIL; + } + + if(NULL == (pstRun = (RunTime *)pInitMemTable(pstSavm, pstSavm->tblName))) + return RC_FAIL; + + if(RES_REMOT_SID == pstRun->m_lLocal) + { + Tremohold(pstSavm, pstRun); + return _lExtremeByRt(pstSavm, psvOut); + } + + for(i = 0; i < pstExm->uFldcmp; i ++) + { + if(RC_FAIL == _lExtreme(pstSavm, pstRun, &pstExm->stFdKey[i], psvOut)) + { + vTblDisconnect(pstSavm, pstSavm->tblName); + return RC_FAIL; + } + } + + vTblDisconnect(pstSavm, pstSavm->tblName); + return RC_SUCC; +} + +/************************************************************************************************* + * debug + *************************************************************************************************/ diff --git a/stvm.conf b/stvm.conf new file mode 100644 index 0000000..c080ef8 --- /dev/null +++ b/stvm.conf @@ -0,0 +1,27 @@ +*GLOBLE +MACHINE="TVM" +MAXTABLE=255 +MAXFILED=3000 +MAXDOMAIN=1024 +MAXSEQUE=1024 +#SERVER_EXEC=4 +SERVER_EXEC=1 +DEPLOY=cluster +#DEPLOY=local +SERVER_PORT=5050 +LOGNAME="/home/stvm/log/stvm.log" + +*LOCAL_RESOURCE +TABLE=15 PERMIT=15 + +*REMOTE_DOMAIN +GROUP=1 DOMAINID="DBS" WSADDR="192.168.5.20:5010" TIMETOUT=2 MAXTRY=3 KEEPALIVE=30 +GROUP=2 DOMAINID="CTS" WSADDR="192.168.5.20:5011" TIMETOUT=2 MAXTRY=3 KEEPALIVE=30 + +*REMOTE_TABLE +TABLE=8 TABLENAME="TBL_BRH_INFO" + MTABLE=17 DOMAINID="DBS" + MTABLE=17 DOMAINID="CTS" +TABLE=9 TABLENAME="TBL_ACCT_INFO" + MTABLE=16 DOMAINID="DBS" + MTABLE=16 DOMAINID="CTS" diff --git a/tbl_user_info.def b/tbl_user_info.def new file mode 100644 index 0000000..ebf7908 --- /dev/null +++ b/tbl_user_info.def @@ -0,0 +1,16 @@ +set TABLE=20 +set TABLESPACE=10000 + +create table TBL_USER_INFO +( + acct_id long, + user_no char(21), + user_type char[2], + user_nm char[81], + user_addr char[161], + user_phone char[31] +); + +-- Create indexes +create unique index (user_no, user_type); +create index (acct_id);